PageBox for Java: Web application deployment using Java PageBox

for
 PageBox for Java 
 API 
 Demo 
 Background 
Presentation User guide Token API Active naming Extensions Implementation Token implementation

Implementation of the PageBox API

Foreword

Objective

This document presents the implementation of the PageBox API.

Audience

Programmers who want:

  1. To participate to the PageBox development

  2. To adapt or extend PageBox for their needs

Principle

When it installs an archive, PageBox

  1. Inflates the archive in an archive directory

  2. Writes the path of the PageBox working directory in an API.txt file in the archive directory

The PageBox working directory contains four files of interest for the PageBox API:

  1. The log file, log.html

  2. mode.txt. This file contains the initial logging mode, true if all messages must be logged or false if only warning and error messages must be logged

  3. rules.xml describes the resources and JDBC info made available for the installed archives

  4. pbArchives.xml. For each installed archive pbArchives.xml contains the URL of the Repository that deployed the archive


The archive calls the PageBox API constructor with the archive directory as parameter. Then the PageBox API reads API.txt to find the PageBox working directory. Next the PageBox API reads and parses the rules.xml, mode.txt and pbArchives.xml files and can process the requests of the archive.

Design

The PageBox API is made of two classes:

  1. PageBoxAPI.java, a facade class, used by the archive and documented in the API user guide

  2. APIImpl.java, the implementation class, which includes a static factory method, getAPI

The PageBoxAPI is implemented in the PageBoxLib package.

APIImpl.java

getAPI

APIImpl defines an APIs static Map that contains an entry for each PageBox on the Application server.

APIs keys are PageBox working directories and APIs values are APIImpl instances.

getAPI retrieves the working directory from the archive’s API.txt and returns the corresponding instance of APIImpl from APIs if it exists. Otherwise getAPI creates an APIImpl instance and stores this instance in APIs.

APIImpl

The APIImpl constructors

  1. Reads the initial logging mode from mode.txt

  2. Get a Logging object

  3. Calls an initialize method to parse rules.xml and read the JDBC and resource info. To parse rules.xml initialize uses the same SAX handler called RuleHandler as PageBox.

  4. Builds maps of resources (allowedResources) and extensions (allowedExtensions) for which the archive has the permission to access. An archive may have the permission because the PageBox administrator trusts its publisher or its repository or because the PageBox administrator granted access to the extension or resource to all archives. Therefore the extension and resource maps merge the permissions defined in rules.xml that apply either to the archive publisher or to the archive repository and the default permissions.

  5. Loads the JDBC driver

  6. Computes the database name PageBox_directory + "_" + archive_directory

  7. Calls a restorePbArchs to parse pbArchives.xml and (1) read the installed archive data in an archives map (2) retrieve the URL of the DeployIF Web service of this PageBox. To parse pbArchives.xml restorePbArchs uses the same SAX handler called DeployHandler as PageBox.

  8. Instantiates a stub to the RepoQuery Web service of the Repositories

  9. Instantiates a stub to the Deploy Web service of the PageBoxes

getLog

getLog returns the logging object retrieved by the APIImpl constructor.

getConnection

APIImpl maintains an ArrayList of JDBC connections called pool.

Each connection is represented by a PoolEntry object. The PoolEntry class implements the Connection interface:

public class PoolEntry {

private boolean busy = true;

private Connection conn = null;

private Log log;

private JDBCinfo jdbcInfo;

PoolEntry(JDBCinfo jdbcInfo, Log log) throws SQLException;

boolean lock();

void release();

/** Connection methods */

...

}

busy is true when the connection conn is used by an archive.

Connection methods call the corresponding method of the embedded conn object except the close and isClosed methods we present below.

PoolEntry

The PoolEntry constructor gets a new connection from the Driver Manager.

lock

lock returns false when the connection is used by an archive (busy == true). Otherwise lock sets busy to true and returns true.

release

unlock closes the conn connection.

getConnection enumerates the pool entries.

For each PoolEntry getConnection calls its lock method and returns the entry if lock returns true.

If all connections are used getConnection creates a new PoolEntry and returns this new entry.

close

close sets the connection in auto commit mode and set the busy variable to false.

isClosed

isClosed returns true is the connection is not used (busy == false) or if the connection is closed.

relConnections

relConnection removes the APIImpl entry from the APIs map and calls the relConns method.

The static version of relConnections retrieves the working directory from the archive’s API.txt, removes the corresponding instance of APIImpl from APIs and calls the relConns method.

relConns

relConns enumerates the PoolEntry objects in pool and calls their release method. Then relConns clears the pool ArrayList.

getResource

getResource first looks in the allowedResources map to check if the archive is granted permission to use the resource. If the archive doesn’have the permission getResource returns null. Otherwise getResource returns the ResourceInfo object from the resources map.

getExtension

getExtension has three parameters:

  • The name given to the extension in the PageBox configuration

  • The class name of the parameter of the extension constructor. The PageBox API uses reflection to select the right constructor. If the class name is null the PageBox API creates the extension with a constructor without parameter.

  • The parameter of the extension constructor. The PageBox API uses reflection to call the constructor with this parameter.

getExtension first looks in the allowedExtensions map to check if the archive is granted permission to use the extension. If the archive doesn’have the permission getExtension returns null. Otherwise getExtension

  • Retrieves the extension class name from the extensions map

  • Get a class object for the extension class and the parameter class with Class.forName

  • Instantiates the extension in privileged code with the following snippet where extf is the extension class object, parmClsf is the parameter class object and parmf is the parameter value:

if (parmClsf == null)

return extf.newInstance();

Class[] argsClass = new Class[] { parmClsf };

Object[] args = new Object[] { parmf };

Constructor constructor = extf.getConstructor(argsClass);

return constructor.newInstance(args);

  • Returns an ExtensionImpl object that wraps the extension class

Like the extension class ExtensionImpl implements the ExtensionIF interface:

interface ExtensionIF {

Object call(Object obj) throws Exception;

}

ExtensionImpls calls the call method of the extension class in privileged code.

getClones

getClones calls the GetSubscribers method of the RepoQuery Web service of the Repository that deployed the archive. GetSubscribers returns an array made of the URLs of the Deploy Web services of the PageBoxes where the archive was installed.

Then for each PageBox where the archive was installed getClones calls the getArchPath method of the PageBox Deploy Web service.

Eventually getClones returns an array of archive full URL that contains:

  • Archive instances returned by the Repository Web service

  • Whose PageBox answered the getArchPath call

getResourceUsage

getResourceUsage calls UsageFactory.getUsageProbe to get a resource probe if it is not yet instantiated and then calls the collect and init methods of this probe. Resource probes and UsageFactory are described in the Resource probes section of the porting guide.

GetResourceUsage is called by the homonymous method of PageBoxAPI.

relInactiveConns

relInactiveConns is called by relInactiveConnections.

relInactiveConns enumerates the connections (PoolEntry objects) in the APIImpl pool and calls their isInactive method. When isInactive returns true relInactiveConns removes the connection from the pool.

PoolEntry.isInactive checks if the connection was not used for more than a timeout. If this is the case PoolEntry.isInactive closes the connection.

relInactiveConnections

The DynDns thread periodically calls this static method with the PageBox directory, which uniquely defines the PageBox as parameter.

relInactiveConnections enumerates the APIImpl instances of this PageBox and calls their relInactiveConns method.

Contact:support@pagebox.net
©2002-2004 Alexis Grandemange. Last modified .