| <html> |
| |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> |
| <meta name="GENERATOR" content="Microsoft FrontPage 4.0"> |
| <meta name="ProgId" content="FrontPage.Editor.Document"> |
| <title>API Concepts and Roles</title> |
| </head> |
| |
| <body> |
| |
| <h1>WTP Server Tools<br> |
| API Concepts and Roles</h1> |
| <p>Last modified Nov. 2, 2004</p> |
| <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 |
| plug-in</a>. Once this document is finalized, our intent is to bring the code |
| and specs into line with this document.]</i></p> |
| <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> |
| <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> |
| <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> |
| <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> |
| <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> |
| <p>The web content that is developed for a web 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 use 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.</p> |
| <p>At any given time, the developer may be working with any number of servers. |
| Each server has a server configuration and a set of modules. From the complete |
| set of modules in the workspace, any particular server may see only a subset, |
| although it is also common 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> |
| <p>Some types of modules can have other modules as children. The standard |
| example of this is a J2EE Enterprise Application (EA) 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> |
| <p>Modules reside in the workspace. The typical arrangement is that each module |
| has its own project, termed a <b>module project</b>. The module 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> |
| <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> |
| <p>A <b>server project</b> is a project used to hold serialized server (server |
| runtime, server configuration) instances. The project is tagged with a special |
| Eclipse server nature. The main reason behind server projects was as an |
| efficient means of making these serialized files visible in the resource |
| navigator and monitoring changes to them.</p> |
| <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> |
| <p>The web tools server architecture allows for an open-ended set of server |
| types, server runtime types, server configuration 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; server configuration types, by serverConfigurationTypes; |
| and module types, by moduleKinds. (Additional extension points are discussed |
| below.) Associated with these extension points are code 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> |
| <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> |
| <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> |
| <p>A <b>publish manager</b> is responsible for deciding whether a file resource |
| will be published or not (note: publishing includes file deletions as well as |
| file creations and modifications). Publish managers are declared via the |
| org.eclipse.wtp.server.core.publish extension point. |
| ServerCore.getPublishManagers() returns list of know publish managers. There are |
| two build-in headless publish managers. The Full Publish Manager is dumb, and |
| publishes all of the module's resource from workspace to server. The Smart |
| Publish Manager only publishes module resources that have been created, changed, |
| or deleted in the workspace, or ones that have been changed (somehow) on the |
| server. A publish operation initiated by IServer.publish(IProgressMonitor |
| monitor) uses the system-wide default publish manager, which defaults to the |
| Smart Publish Manager. (There's also a Visual Publish Manager that lets the user |
| pick and choose which files to publish.)</p> |
| <p>A <b>publisher</b> (IPublisher) is an object that actually publishes the file |
| of a particular module to a particular server. Each server type implements its |
| own publishers. On a particular occasion, the IServerDelegate.getPublisher(List |
| parents, IModule module) returns the publisher to use to publish the files of |
| the given module. IPublisher.publish(IModuleResource[] resource, |
| IProgressMonitor monitor) and IPublisher.delete(IRemoteResource[] resource, |
| IProgressMonitor monitor) do the heavy lifting.</p> |
| <p>The client API exposes:</p> |
| <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>Server configuration types as IServerConfigurationType. |
| ServerCore.getServerConfigurationTypes() returns all known server |
| configuration types.</li> |
| <li>Module types as IModuleKind. ServerCore.getModuleKinds() returns all known |
| module kinds.</li> |
| </ul> |
| <p>The type-level relationships are:</p> |
| <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 type; this is the type |
| of server configuration required to configure the server; exposed as |
| IServerType.getServerConfigurationType()</li> |
| <li>a server runtime type supports 0 or more module types; exposed as |
| IRuntimeType.getModuleTypes()</li> |
| </ul> |
| <p>The API exposes server runtime instances as IRuntime. |
| ServerCore.getResourceManager().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> |
| <p>The API exposes server configuration instances as IServerConfiguration. |
| ServerCore.getResourceManager().getServerConfigurations() returns all known |
| server configuration instances. Server configuration instances are created |
| (only) from server types by |
| IServerConfigurationType.createServerConfiguration(String id, IFile file, |
| IProgressMonitor monitor) or IServerConfigurationType.importFromPath(String id, |
| IFile file, IPath path, IProgressMonitor monitor) or |
| IServerConfigurationType.importFromRuntime(String id, IFile file, IRuntime |
| runtime, IProgressMonitor monitor). The file parameter is used to control where |
| the server configuration instance is serialized. All 3 return an |
| IServerConfigurationWorkingCopy. (There are no aspects of the server |
| configuration instance to adjust.) |
| IServerConfigurationWorkingCopy.save(IProgressMonitor monitor) creates, |
| registers, returns a server configuration instance (IServerConfiguration) |
| capturing the desired settings (the working copy is disposed of). </p> |
| <p>The API exposes server instances as IServer. |
| ServerCore.getResourceManager().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> |
| <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> |
| <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> |
| |
| </body> |
| |
| </html> |