blob: 1ffe6777c80dbbdd5c912999955e6e493163f14b [file] [log] [blame]
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type">
<link type="text/css" href="../../../..//default_style.css" rel="stylesheet">
<link type="text/css" href="../../../..//webtools/wtp.css" rel="stylesheet">
<title>wst.server API Overview</title>
</head>
<body>
<table border="0" cellpadding="2" cellspacing="5" width="100%">
<tbody>
<tr>
<td align="left" width="60%"><font class="indextop">WTP Server Tools API Concepts and Roles</font>
<br>
<font class="indexsub">wst.server API Overview</font></td><td width="40%"><img src="../../../..//webtools/images/wtplogosmall.jpg" align="middle" height="129" hspace="50" width="207"></td>
</tr>
</tbody>
</table>
<table border="0" cellpadding="2" cellspacing="5" width="100%">
<col width="16">
<col width="*">
<tbody>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>Last modified Feb 10, 2005</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>[<i>This document is a work in progress. The document is an attempt to
capture the key concepts required for understanding and working with the WTP
Server Core API. Note that the concepts may differ subtly from what is currently
found in the currently released
<a href="http://dev.eclipse.org/viewcvs/index.cgi/wst/components/server/plugins/org.eclipse.wst.server.core/?cvsroot=WebTools_Project">org.eclipse.wst.server.core</a>
plug-in. Once this document is finalized, our intent is to bring the code
and specs into line with this document.]</i>
</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>The key concepts for understanding the API (and SPI) are servers and modules.
The notions of server runtimes and server configurations play an important, but
secondary role.</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>Not surprisingly, the notion of <b>server</b> is central in the web tools
server infrastructure. In this context we are to understand that the server is a
web server of some ilk (a more exact definition is not required for our
purposes). From a tool-centric point of view, a server is something that the
developer is writing "content" for. (In a sense, the server exists,
but lacks useful content. The development task is to provide that content.) The
content can include anything from simple, static HTML web pages to complex,
highly dynamic web applications. In the course of writing and debugging this
content, they will want to test their content on a web server, to see how it
gets served up. For this they will need to launch a server process running on
some host machine (often the local host on which the Eclipse IDE is running), or
attach to a server that's already running. And we must arrange that the newly
developed content sitting in the developer's workspace ends up in a location and
format that a running server can use for its serving purposes.</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>(The server objects in the API are in fact intermediary "proxy"
objects that mediate between the tools running in Eclipse and the real server. A
server proxy object has a somewhat independent life from that of a real server.
In cases where the server process must be launched, the proxy object exists in
advance of the server process, and lives past the termination of the server
process. The same server proxy may be serially reused to relaunch server
processes. In cases where we are connecting to a server process running on a
remote host, the server process may well outlive the proxy.)</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>Servers have a <b>server runtime</b>. The server runtime corresponds to the
installed code base for the server. The main role played by the server runtime
is in identifying code libraries to compile or build against. In the case of
local servers, the server runtime may play a secondary role of being used to
launch the server for testing. Having the server runtimes identified as an
entity separate from the server itself facilitates sharing server runtimes
between several servers.</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>Servers have an optional <b>server configuration</b>. The server
configuration is information used to configure a running server. Simple types of
servers might not require any configuration, whereas full-featured web server
have an extensive set of parameters for adjusting the server's behavior. Even
though server configuration information usually takes the form of one or more
files, configuration information is treated separately from actual content.
Actual web content can be deployed on different servers without change, whereas
server configuration information is usually highly dependent on the particulars
of the server. Having the server configuration identified as an entity separate
from the server itself facilitates switching an existing server between
configurations, and sharing server configurations between several servers (e.g.,
a local test server and a remote server running on another host).</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>The content that is developed for a server comes in <b>modules</b>. A
module usually consists of a tree of files; a static HTML web is one simple
example. Different types of modules consist of possibly constrained arrangements
files of certain file types. The files making up a module under development
reside in the Eclipse workspace. In order for a server to access the content
within a module, the module in the workspace must be <b>published</b> to the
server (we use the term <i>publish</i> rather than <i>deploy</i> which is
overused in J2EE). The module is the unit of content that is published to a
server. In the case of J2EE servers, the notion of module aligns with the J2EE
notion of a module (a server concept). But that needn't be the case; some
types of servers, such as a simple HTTP server, don't have a notion of module.
Either way, publishing a module to the server entails whatever it takes to get
the publishable content from the workspace to the server in a form that the
server can access it. Different types of server runtimes are capable of support
various module types. Some server types may be able to serve modules directly
out of the workspace without copying.</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>At any given time, the developer may be working with any number of servers.
Each server has a set of modules and may have a server configuration. From the complete
set of modules in the workspace, any particular server may see only a subset,
although it is also possible for all servers to see all available modules. After
the developer makes changes to the modules in the workspace and now wants to
test their modification, they republish the modules to the server. Depending on
the type of server, republishing a module may entail stopping and restarting the
server.</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>Some types of modules can have other modules as children. The standard
example of this is a J2EE Enterprise Application (EAR) module, whose children are
simple J2EE modules like Enterprise Java Beans and Web Applications. The
parent-child relationship is weak: two parent modules can share the same child
module, and the same child can be parented by several modules (on the same or on
different servers). The file trees for modules are normally mutually disjoint.
Module containment is not reflected by any sort of directory nesting. Parent and
child modules map to non-overlapping file trees.</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>Modules typically reside in the workspace. The arrangement is usually that each
module exists in a single project, where the content usually
corresponds to a particular folder within a project rather than the root of the
project. This allows the project to contain other files (e.g., .project, .classpath,
source code) that are not considered part of the module content proper. Each
different type of module has its own rules for how the content files within it
are laid out. For instance, a J2EE web module has the same structure as an
unzipped WAR file. (Note that the module structure rules are largely implicit
and not reflected directly in the APIs.) It is possible for a project to
contains more than one module (although this arrangement is less common, and not
as well supported).</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>During development, projects containing modules can be <b>targeted</b> to a
particular server runtime. Targeting allows the IDE to set up various
development time properties of the project (such as the backbone of the Java
build path) appropriately. The most common scenario is where the project is
targeted to the server runtime for the server to which the module is being
published. However, it is also possible to target one server runtime (e.g., a
generic J2EE 1.3 server runtime) while publishing to a server with a different
server runtime (e.g., a Tomcat v5.0 server). Targeting a project to a particular
server runtime typically establishes the Java build classpath of the project to
include the libraries containing the Java APIs for that server runtime (e.g.,
the appropriate J2EE class libraries). The Java build classpath also needs to
reflect inter-module dependencies; for J2EE module types, the appropriate
entries are typically derived from the module's manifest.</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>The main goals of the Server Core client APIs are to allow clients to create,
configure, and launch instances of particular server types. Due to differences
in the behavior (and APIs) of different server types, a client must generally be
knowledgeable of rules for a particular server type. Clients that have no
knowledge of any specific server type are limited to doing things like starting,
stopping, and relaunching existing servers. In other words, the clients APIs are
generally server-type-specific, rather than sever-type-generic.</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>The web tools server architecture allows for an open-ended set of server
types, server runtime types, and module types. New
types are declared via extension points in the Server Core plug-in (org.eclipse.wtp.server.core).
Server types are declared by the serverTypes extension point; server runtime
types, by runtimeTypes; and module types, by moduleKinds.
(Additional extension points are discussed below.)
Associated with these extension points are core APIs designed for use by
clients contributing to the Server Core extension points; these are more
correctly called SPIs (service provider interfaces) to distinguish them from the
code designed to be used by other clients (which we refer to here as client
APIs).</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>Many of the extension points provide for a dynamic code component in addition
to the static information supplied in the extension declaration. These are
termed <i>delegates</i>. For instance, all communication with the running server
is handled by a <b>server delegate</b> contributed via the server type extension
point. Clients generally deal directly with a layer of objects exposed by the
API expressly for client use. In the case of server, clients deal with an
IServer. IServer has a fixed, hidden implementation (the internal class Server),
which hangs on to a lazily-created server delegate of type IServerDelegate. The
IServerDelegate implementation is a server-type-specific object. The more
interesting IServer methods (e.g., getServerState()) are handled by the
delegate. There are also getDelegate() methods that bridge API to SPI, allowing
clients to call methods on the delegate directly. Service providers may also
choose to expose their delegate implementation as API. This allows, for example,
the provider of a server type to offer additional API that is
server-type-specific.</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>A <b>module factory</b> is responsible for creating modules. There can be any
number of registered module factories, declared via the
org.eclipse.wtp.server.core.moduleFactory extension point. A module factory may
create one or more types of modules (also declared in the extension point). The
module factory API does not prescribe a way to create modules; it does, however,
provide methods for retrieving extant modules that it was responsible for
creating (IModuleFactoryDelegate.getModules() and
IModuleFactoryDelegate.getModule(String memento)).</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>To sync up changes in the local workspace with the server, clients call
IServer.publish(IProgressMonitor monitor), which will publish the changes to
the server. The server framework handles figuring out which modules have been
changed and what resources have changed within the module, but the server
delegate is called to do the actual publish operation.</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>The client API exposes:</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<ul>
<li>Server runtime types as IRuntimeType. ServerCore.getRuntimeTypes() returns
all known server runtime types.</li>
<li>Server types as IServerType. ServerCore.getServerTypes() returns all known
server types.</li>
<li>Module types as IModuleType.</li>
</ul>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>The type-level relationships are:</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<ul>
<li>a server type has a server runtime type; this is the type of server
runtime required to run the server; exposed as IServerType.getRuntimeType()</li>
<li>a server type has an optional server configuration</li>
<li>a server runtime type supports 0 or more module types; exposed as
IRuntimeType.getModuleTypes()</li>
</ul>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>The API exposes server runtime instances as IRuntime.
ServerCore.getRuntimes() returns all known server runtime
instances. Server runtime instances are created (only) from server runtime types
by IRuntimeType.createRuntime(String id), which returns an IRuntimeWorkingCopy.
Any number of aspects of the server runtime instance (including location in the
file system) can be established or adjusted from their defaults. When editing is
complete, IRuntimeWorkingCopy.save(IProgressMonitor monitor) creates, registers,
returns a server runtime instance (IRuntime) capturing the desired settings (the
working copy is disposed of).</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>The API exposes server instances as IServer.
ServerCore.getServers() returns all known server instances.
Server instances are created (only) from server types by
IServerType.createServer(String id, IFile file, IRuntime runtime,
IProgressMonitor monitor) or IServerType.createServer(String id, IFile file,
IRuntime runtime, IProgressMonitor monitor). The file parameter is used to
control where the server instance is serialized. Both return an
IServerWorkingCopy. Any number of aspects of the server instance (host name,
server runtime, server configuration, modules, ...) can be established or
adjusted from their defaults. When editing is complete,
IServerWorkingCopy.save(IProgressMonitor monitor) creates, registers, returns a
server instance (IServer) capturing the desired settings (the working copy is
disposed of).</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>The instance-level relationship between servers and server runtimes and
server configurations is exposed at the API: for a given server,
IServer.getRuntime() returns the server runtime (IRuntime),
IServer.getServerConfiguration() returns the server configuration (IServerConfiguration).</p>
</td>
</tr>
<tr>
<td align="right" valign="top">&nbsp;</td><td valign="top">
<p>IServer.start(String mode, IProgressMonitor monitor), stop(), and
restart(String mode) are used to start, stop, and restart a server, respectively
(there are also synchronous methods for starting and stopping). The predicates
IServer.canStart(String mode), canRestart(String mode), and canStop() indicate
whether the server is receptive to being controlled. IServer.getServerState()
can be used to query the overall state of the server (one of starting, started,
stopping, stopped, or unknown), and IServer.getModuleState(IModule module) can
be used to query the state of any of its modules.</p>
</td>
</tr>
</tbody>
</table>
</body>
</html>