The Print License Dip provides the capability of limiting the printing of any bean instance to which it is applied. This dip can be applied only to bean instances that extend from the java.awt.Component hierarchy. While the dipped instance is not licensed, the print license dip prevents the instance's print and printAll methods from executing by vetoing their method calls. When the dipped instance is licensed, the print license dip will not prevent these method calls. The current model of the print license restricts use based on host name and expiration date.
There are three parties involved in a print license dip. These parties are:
The following documentation uses these parties to clarify the actions each party performs.
This dip is provided as a sample source from which other licensing dips can be generated. Deriving new licensing dips from the source is discussed in "Deriving New License Dips".
This section explains the operation issues of developing, deploying, installing and using a bean instance that uses licensing to restrict printing. It is assumed that a bean developer has access to or has developed a bean, we'll refer to as a Jelly bean, without considering licensing.
It is important to note that the print license dip is applied to an instance of the Jelly bean. The print license dip is not applied to the implementation class.
The Jelly bean is a full function bean. The Jelly bean has no concept of licensing or dipping. The developer decides to add the Print License Dip but must first make the Jelly bean dippable. The developer must do the following:
For additional information on bean morphing, see "The Morphing Interface".
After the developer makes the Jelly bean dippable, the developer can add a print license by doing the following:
For additional information on the dip application, see "The Dipping Interface".
A customizer for the license dip is displayed before the dip is applied to
the Jelly bean.
The dip customizer determines whether licensing is initialized. If the license is not initialized, an initialization interface is displayed. The developer uses the initialization interface to specify where a serialized copy, a .ser file, of the license policy is saved by clicking on the SAVE POLICY... button. The serialized copy is used by the license issuer. When the license policy for the dip is initialized, the dip application tool saves this instance as a .ser file. The .ser file represents the instance of the dippable Jelly bean with the print license dip applied to it. When the .ser file is distributed, appropriate .class files must be distributed to it.
As the user of the dippable Jelly bean, you might decide to use the serialized instance of the dippable Jelly bean and install the files on your system. When you try to use the bean instance, you might find that it works except for printing. When you try to print, a warning is displayed stating that printing is not licensed.
To obtain a license, you would normally contact a license issuer. The license issuer would run the LicenseIssuer tool. In this example, you play the role of the license issuer. To run the LicenseIssuer tool from the command line, enter the following command:
java com.ibm.beans.samples.dips.license.LicenseIssuer
When the interface is displayed, click on the Load Policy button
and select the policy object saved during initialization.
This time, the license policy customizer determines it is dealing with the license issuer's license policy copy and displays an appropriate interface to obtain proper licensing data for you. In this case, the licensing data is the host name and the expiration date.
You provide the host name that the dippable Jelly bean is expected to run
on and negotiate an expiration date. Both pieces of data are entered by the
license issuer. The license issuer then uses this data to generate an encoded
signature for the license policy by clicking on the Generate
License... button. This action causes a Save File dialog to be
displayed. The Save File dialog is used to specify the location to store the
encoded signature data. This encoded signature is given to you.
As a user, you use the encoded signature provided by the license issuer to license the Jelly bean. A tool, such as the Assembly Surface or a JavaSoft beanbox, is started and the .ser file for the dippable Jelly bean is selected and instantiated. The customizer for the dippable Jelly bean is started. You enter the expiration date and import the encoded signature. You do not need to enter the host name because it is determined by the license policy at runtime. After customization, the bean is saved, or reserialized, as a fully licensed bean.
Licensing is handled by having two copies of the licensing policy. Your copy that retains a public key and the license issuer's copy that retains a private key. These keys are a matched pair that are generated during the initialization phase.
The Print License Dip is separated into the following pieces:
The PrintLicenseDip class restricts the use of the print() and printAll() methods. These methods are the only methods the Print License Dip vetoes. When deriving a new restriction, focus on key methods, properties, or events that your license dip will restrict.
Besides these methods, the Print License Dip restricts its use to any dippable object that has the print() and printAll() methods. This check is done when the createImplementation() method of the dip is called. An introspection is performed on the dippable bean to which the dip is being applied and, if the dippable bean does not support the methods, it is vetoed. During a veto, an exception is thrown and caught by the Dipping Framework. The Dipping Framework then ensures that the dip is removed.
Licensing is done by using the java.security.Signature class and associated classes. Licensing is encapsulated by the HostAndDurationLicensePolicy class. The policy class uses the Signature class to provide general license validation services while implementing the specific details of licensing. In this case, the validation services determine whether the proper license is installed and that the conditions of the license are met.
The Signature class ensures that someone without authorization does not change the license conditions. Any number of conditions are possible, but these conditions should be made into properties of the license policy. The update method must feed these conditions to the Signature class' update methods during signing and verification.
There are two kinds of conditions: programmatic and non-programmatic. Programmatic conditions are determined at runtime. You can set non-programmatic conditions. You must never set programmatic conditions for the license policy with the public key. These settings should be enforced by the license policy class. A programmatic condition, for example, is the hostname property of the HostAndDurationLicensePolicy.
There is only one customizer for a license dip, but the customizer must support the following modes:
A copy of the license policy must be saved for the license issuer. The license dip must be serialized to retain a public key. The license dip cannot be used until it is initialized.
Both the license issuer interface and the user interface of the license policy customizer class need to be modified to handle any new conditions. The license issuer must be given a chance to enter information for all the conditions. The license policy class must allow these conditions to be set if the policy object is for use by a license issuer. Remember that the license issuer has a private key.
The interface that you, as the user, use allows for only the setting of non-programmatic conditions, including the encoded signature generated by the license issuer. The license policy object will not allow you to set programmatic conditions.