Improvements to the Jetty documentation.

Ported the Jetty XML syntax.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Simone Bordet 2020-09-29 16:22:20 +02:00
parent 921121afe5
commit ba5f91fe00
5 changed files with 492 additions and 1025 deletions

View File

@ -19,7 +19,6 @@
[[reference-section]]
== Jetty XML Reference
include::jetty-xml-syntax.adoc[]
include::jetty-xml-usage.adoc[]
include::jetty-xml-config.adoc[]
include::jetty-web-xml-config.adoc[]

View File

@ -1,999 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
[[jetty-xml-syntax]]
=== Jetty XML Syntax
The Jetty XML syntax is a straightforward mapping of XML elements to a Java API so that POJOs can be instantiated and getters, setters, and methods called.
It is very similar to Inversion Of Control (IOC) or Dependency Injection (DI) frameworks like Spring or Plexus (but it predates all of them).
Typically Jetty XML is used by `jetty.xml` to configure a Jetty server or by a `context.xml` file to configure a ContextHandler or subclass, but you can also use the mechanism to configure arbitrary POJOs.
This page describes the basic syntax of Jetty XML configuration. See xref:jetty-xml-usage[] for information on how you can use and combine Jetty XML.
See configuration files for specific examples.
[[basic-xml-configuration-file-example]]
==== Basic XML Configuration File Example
The following XML configuration file creates some Java objects and sets some attributes:
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure id="foo" class="com.acme.Foo">
<Set name="name">demo</Set>
<Set name="nested">
<New id="bar" class="com.acme.Bar">
<Arg>true</Arg>
<Set name="wibble">10</Set>
<Set name="wobble">xyz</Set>
<Set name="parent"><Ref refid="foo"/></Set>
<Call name="init">
<Arg>false</Arg>
</Call>
</New>
</Set>
<Ref refid="bar">
<Set name="wibble">20</Set>
<Get name="parent">
<Set name="name">demo2</Set>
</Get>
</Ref>
</Configure>
----
The XML above is equivalent to the following Java code:
[source, java, subs="{sub-order}"]
----
com.acme.Foo foo = new com.acme.Foo();
foo.setName("demo");
com.acme.Bar bar = new com.acme.Bar(true);
bar.setWibble(10);
bar.setWobble("xyz");
bar.setParent(foo);
bar.init(false);
foo.setNested(bar);
bar.setWibble(20);
bar.getParent().setName("demo2");
----
==== Overview
[[jetty-xml-dtd]]
===== Understanding DTD and Parsing
The document type descriptor
(link:{GITBROWSEURL}/jetty-xml/src/main/resources/org/eclipse/jetty/xml/configure_9_0.dtd?h=release-9[configure.dtd]) describes all valid elements in a Jetty XML configuration file using the Jetty IoC format.
The first two lines of an XML must reference the DTD to be used to validate the XML like:
[source, xml, subs="{sub-order}"]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_9_3.dtd">
...
----
Typcically a good XML editor will fetch the DTD from the URL and use it to give syntax highlighting and validation while a configuration file is being edited.
Some editors also allows DTD files to be locally cached.
The URL may point to configure.dtd if you want the latest current version, or to a specific version like configure_9_3.dtd if you want a particular validation feature set.
Files that conform to the configure.dtd format are processed in Jetty by the `XmlConfiguration` class which may also validate the XML (using a version of the DTD from the classes jar file), but is by default run in a forgiving mode that tries to work around validation failures.
To ensure your `web.xml`, `web-fragment.xml` and `webdefault.xml` files are validated, you will also need to set the `validateXml` attribute to true:
[source, xml, subs="{sub-order}"]
----
<Call name="setAttribute">
<Arg>org.eclipse.jetty.webapp.validateXml</Arg>
<Arg type="Boolean">true</Arg>
</Call>
----
===== Jetty XML Configuration Scope
The configuration of object instances with Jetty IoC XML is done on a scoped basis, so that for any given XML element there is a corresponding Object in scope and the nested XML elements apply to that.
The outer most scope is given by a Configure element and elements like Call, New and Get establish new scopes.
The following example uses the name fields to explain the scope.
[source, xml, subs="{sub-order}"]
----
<Configure class="com.example.Foo">
<Set name="fieldOnFoo">value</Set>
<Set name="fieldOnFoo">
<New class="com.example.Bar">
<Set name=fieldOnBar>value</Set>
<Call name="methodOnBarWithNoArgs"/>
</New>
</Set>
<Call name="methodOnFoo">
<Arg>value for first arg of methodOnFoo</Arg>
<Arg><New class="com.example.Bar"/></Arg>
<Set name="fieldOnObjectReturnedByMethodOnFoo">value</Set>
<Call name="methodOnObjectReturnedByMethodOnFooWithNoArgs"/>
</Call>
</Configure>
----
===== Coercing Arguments to a Type
When trying to match XML elements to java elements, Jetty `XmlConfiguration` may need to coerces values to match method arguments.
By default it does so on a best effort basis, but you can also specify explicit types with the `type` attribute.
Supported values for type are: `String`, `Character`, `Short`, `Byte`, `Integer`, `Long`, `Boolean`, `Float`, `Double`, `char`, `short`, `byte`, `int`, `long`, `boolean`, `float`, `double`, `URL`, `InetAddress`, `InetAddrPort`, and `void`.
===== Referring to a Class
If you do not specify the classname, Jetty assumes you are calling the method on the object that is current in scope (eg the object of the surrounding `Configure`, `New` or `Get` clause).
If the class attribute is specified to a fully-qualified class name, then it is either used to create a new instance (`Configure` and `New` elements) or is used to access a static (`Call`, `Set` or `Get` elements).
===== Referring to an Object
You can use the id attribute to store a reference to the current object when first creating or referring to this object.
You can then use the link:#jetty-xml-ref[Ref element] to reference the object later.
The ID must be unique for each object you create.
===== Attribute vs Element Style
For XML elements that contain only other XML Elements, there is a choice of using attributes or elements style.
The following is an example of attribute style:
....
<Call id="result" class="org.example.SomeClass" name="someMethod" arg="value0,value1"/>
....
Attribute style has the benefit of brevity, but is limited by: values can only be Strings; multivalued items can not contain ','; values may not be subject to property expansion or other elements that return values.
Thus, the more verbose element style is available and the following is semantically equivalent to the attribute style above:
....
<Call>
<Id>result</Id>
<Class>org.example.SomeClass</Class>
<Name>someMethod</Name>
<Arg>value0</Arg>
<Arg>value1</Arg>
</Call>
....
Note that multivalued elements like `Arg` must be repeated and may not be comma-separated like they are when provided as attributes.
It is possible to use a mix of styles and the following example shows a moretypical example that uses property expansion as the reason for element style:
....
<Call id="result" name="someMethod">
<Class><Property name="which.class">
<Default><Property name="default.class" default="org.example.SomeClass"/>
</Property></Class>
<Arg>value0</Arg>
<Arg>value1</Arg>
</Call>
....
Attributes may not be expressed as elements when their parent element is one that contains data.
Thus `Arg`, `Item`, `Set`, `Put` and `Get` elements may not have their attributes expressed as elements.
[[jetty-xml-configure]]
==== <Configure>
This is the root element that specifies the class of object that is to be configured.
It is usually either the Server, in `jetty.xml`, or a `WebAppContext` in `jetty-web.xml`.
[cols=",,",options="header",]
|=======================================================================
|Attribute |Required |Description
|id |no |A reference to the object that was created. If you define
multiple link:#jetty-xml-configure[Configure element]s with the same id,
they will be treated as one object, even if they're in different files.
You can use this to break up configuration of an object (such as the
Server) across multiple files.
|class |no |The fully qualified classname of the object to be
configured. Could be `org.eclipse.jetty.server.Server`,
`org.eclipse.jetty.webapp.WebAppContext`, a handler, etc.
|=======================================================================
===== Can Contain
link:#jetty-xml-set[Set element], link:#jetty-xml-get[Get element],
link:#jetty-xml-put[Put element], link:#jetty-xml-call[Call element],
link:#jetty-xml-new[New element], link:#jetty-xml-ref[Ref element],
link:#jetty-xml-array[Array element], link:#jetty-xml-map[Map element],
link:#jetty-xml-property[Property element]
===== Examples
====== Basic Example
[source, xml, subs="{sub-order}"]
----
<Configure class="org.eclipse.jetty.server.Server">
<Set name="port">8080</Set>
</Configure>
----
This is equivalent to:
[source, java, subs="{sub-order}"]
----
org.eclipse.jetty.server.Server server = new org.eclipse.jetty.server.Server();
server.setPort(8080);
----
====== Using id to break up configuration of one object across multiple files
In `etc/jetty.xml`:
[source, xml, subs="{sub-order}"]
----
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- basic configuration here -->
</Configure>
----
In `etc/jetty-logging.xml`:
[source, xml, subs="{sub-order}"]
----
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- assumes that you have the basic server configuration set up; this file only contains additional configuration for logging -->
</Configure>
----
Then run the combined configuration using:
....
java -jar start.jar etc/jetty.xml jetty-logging.xml
....
[[jetty-xml-set]]
==== <Set>
A Set element maps to a call to a setter method or field on the current object.
It can contain text and/or elements such as `Call`, `New`, `SystemProperty`, etc., as values.
The name and optional type attributes are used to select the setter method.
If you do not specify a value type, white space is trimmed out of the value.
If it contains multiple elements as values, they are added as strings before being converted to any specified type.
[cols=",,",options="header",]
|=======================================================================
|Attribute |Required |Description
|name |yes |the name of the setter method to call, or the field to set.
If the name given is xxx, then a setXxx method is used. If the setXxx
method cannot be found, then the xxx field is used.
|type |no |the declared type of the argument. See also discussion of
type for Arg for how to define null and empty string values.
|class |no |if present, then this Set is treated as a static set method
invocation
|=======================================================================
===== Can Contain
value text, link:#jetty-xml-get[Get element], link:#jetty-xml-call[Call
element], link:#jetty-xml-new[New element], link:#jetty-xml-ref[Ref
element], link:#jetty-xml-array[Array element], link:#jetty-xml-map[Map
element], link:#jetty-xml-system-property[System Property element],
link:#jetty-xml-property[Property element]
===== Examples
====== Basic Example
[source, xml, subs="{sub-order}"]
----
<Configure id="server" class="org.eclipse.jetty.server.Server">
<Set name="port">8080</Set>
</Configure>
----
====== Set via a System Property
[source, xml, subs="{sub-order}"]
----
<Configure id="server" class="org.eclipse.jetty.server.Server">
<Set name="port"><SystemProperty name="jetty.http.port" /></Set>
</Configure>
----
====== Creating a NewObject and Setting It on the Server
[source, xml, subs="{sub-order}"]
----
<Configure id="server" class="org.eclipse.jetty.server.Server">
<Set name="threadPool">
<New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<Set name="minThreads">10</Set>
<Set name="maxThreads">1000</Set>
</New>
</Set>
</Configure>
----
This is equivalent to:
[source, java, subs="{sub-order}"]
----
org.eclipse.jetty.server.Server server = new org.eclipse.jetty.server.Server();
org.eclipse.jetty.util.thread.QueuedThreadPool threadPool = new org.eclipse.jetty.util.thread.QueuedThreadPool();
threadPool.setMinThreads(10);
threadPool.setMaxThreads(1000);
server.setThreadPool(threadPool);
----
====== Invoking a Static Setter
[source, xml, subs="{sub-order}"]
----
<Configure id="server" class="org.eclipse.jetty.server.Server">
<Set class="org.eclipse.jetty.util.log.Log" name="logToParent">loggerName</Set>
</Configure>
----
[[jetty-xml-get]]
==== <Get>
A Get element maps to a call to a getter method or field on the current object.
It can contain nested elements such as `Set`, `Put`, `Call`, etc.; these act on the object returned by the `Get` call.
[cols=",,",options="header",]
|=======================================================================
|Attribute |Required |Description
|name |yes |the name of the getter method to call, or the field to get.
If the name given is xxx, then a getXxx method is used. If the getXxx
method cannot be found, then the xxx field is used.
|class |no |f present, then this Get is treated as a static getter or
field.
|id |no |if present, then you can use this id to refer to the returned
object later.
|=======================================================================
===== Can Contain
link:#jetty-xml-set[Set element], link:#jetty-xml-get[Get element],
link:#jetty-xml-put[Put element], link:#jetty-xml-call[Call element],
link:#jetty-xml-new[New element], link:#jetty-xml-ref[Ref element],
link:#jetty-xml-array[Array element], link:#jetty-xml-map[Map element],
link:#jetty-xml-property[Property element]
===== Examples
====== Basic Example
This simple example doesn't do much on its own.
You would normally use this in conjunction with a `<Ref id="Logger" />`.
[source, xml, subs="{sub-order}"]
----
<Configure id="server" class="org.eclipse.jetty.server.Server">
<Get id="Logger" class="org.eclipse.jetty.util.log.Log" name="log"/>
</Configure>
----
====== Invoking a Static Getter and Call Methods on the Returned Object
[source, xml, subs="{sub-order}"]
----
<Configure id="server" class="org.eclipse.jetty.server.Server">
<Get class="java.lang.System" name="out">
<Call name="println">
<Arg>Server version is: <Get class="org.eclipse.jetty.server.Server" name="version"/></Arg>
</Call>
</Get>
</Configure>
----
[[jetty-xml-put]]
==== <Put>
A Put element maps to a call to a put method on the current object, which must implement the Map interface.
It can contain text and/or elements such as `Call`, `New`, `SystemProperty`, etc. as values.
If you do not specify a no value type, white space is trimmed out of the value.
If it contains multiple elements as values, they are added as strings before being converted to any specified type.
[cols=",,",options="header",]
|=======================================================================
|Attribute |Required |Description
|name |yes |used as the put key
|type |no |forces the type of the value. See also discussion of type for
Arg for how to define null and empty string values.
|=======================================================================
===== Can Contain
value text, link:#jetty-xml-get[Get element], link:#jetty-xml-call[Call
element], link:#jetty-xml-new[New element], link:#jetty-xml-ref[Ref
element], link:#jetty-xml-array[Array element], link:#jetty-xml-map[Map
element], link:#jetty-xml-system-property[System Property element],
link:#jetty-xml-property[Property element]
===== Example
[source, xml, subs="{sub-order}"]
----
<Get name="someKindOfMap">
<Put name="keyName">objectValue</Put>
</Get>
----
[[jetty-xml-call]]
==== <Call>
A `Call` element maps to an arbitrary call to a method on the current object.
It can contain a sequence of Arg elements followed by a sequence of configuration elements, such as Set, Put, Call.
The <Arg>s are passed as arguments to the method; the sequence of configuration elements act on the object returned by the original call.
[cols=",,",options="header",]
|=======================================================================
|Attribute |Required |Description
|name |yes |the name of the arbitrary method to call. The method called
will use the exact name you provide it.
|class |no |if present, then this Call is treated as a static method.
|id |no |if present, you can use this id to refer to any object returned
by the call, for later use.
|arg |no |comma separated list of arguments may be used for simple
string values rather than Arg elements
|=======================================================================
===== Can Contain
Attributes as elements (Id, Name, Class) plus link:#jetty-xml-arg[Arg
element], link:#jetty-xml-set[Set element], link:#jetty-xml-get[Get
element], link:#jetty-xml-put[Put element], link:#jetty-xml-call[Call
element], link:#jetty-xml-new[New element], link:#jetty-xml-ref[Ref
element], link:#jetty-xml-array[Array element], link:#jetty-xml-map[Map
element], link:#jetty-xml-property[Property element]
===== Examples
====== Basic example
[source, xml, subs="{sub-order}"]
----
<Call name="doFoo">
<Arg>bar</Arg>
<Set name="test">1, 2, 3</Set>
</Call>
----
This is equivalent to:
[source, java, subs="{sub-order}"]
----
Object o2 = o1.doFoo("bar");
o2.setTest("1, 2, 3");
----
====== Invoking a static method
[source, xml, subs="{sub-order}"]
----
<Call class="com.acme.Foo" name="setString">
<Arg>somestring</Arg>
</Call>
----
Which is equivalent to:
[source, java, subs="{sub-order}"]
----
com.acme.Foo.setString("somestring");
----
====== Invoking the Actual MethodInstead of Relying on Getter/Setter Magic
[source, xml, subs="{sub-order}"]
----
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Call name="getPort" id="port" />
<Call class="com.acme.Environment" name="setPort">
<Arg>
<Ref refid="port"/>
</Arg>
</Call>
</Configure>
----
Which is equivalent to:
[source, java, subs="{sub-order}"]
----
org.mortbay.jetty.Server server = new org.mortbay.jetty.Server();
com.acme.Environment.setPort( server.getPort() );
----
[[jetty-xml-arg]]
==== <Arg>
An Arg element can be an argument of either a method or a constructor.
Use it within xref:jetty-syntax-call[] and xref:jetty-syntax-new[].
It can contain text and/or elements, such as `Call`, `New`, `SystemProperty`, etc., as values.
The optional type attribute can force the type of the value.
If you don't specify a type, white space is trimmed out of the value.
If it contains multiple elements as values, they are added as strings before being converted to any specified type.
Simple `String` arguments can also be specified as a string separated arg attribute on the parent element.
[cols=",,",options="header",]
|=======================================================================
|Attribute |Required |Description
|type |no |force the type of the argument. If you do not provide a value
for the element, if you use type of "String", the value will be the
empty string (""), otherwise it is null.
|=======================================================================
===== Can Contain
value text, link:#jetty-xml-get[Get element], link:#jetty-xml-call[Call
element], link:#jetty-xml-new[New element], link:#jetty-xml-ref[Ref
element], link:#jetty-xml-array[Array element], link:#jetty-xml-map[Map
element], link:#jetty-xml-system-property[System Property element],
link:#jetty-xml-property[Property element]
===== Examples
====== Basic examples
[source, xml, subs="{sub-order}"]
----
<Arg>foo</Arg> <!-- String -->
<Arg>true</Arg> <!-- Boolean -->
<Arg>1</Arg> <!-- int, long, short, float, double -->
<Arg><Ref refid="foo" /></Arg> <!-- any object; reference a previously created object with id "foo", and pass it as a parameter -->
<Arg></Arg> <!-- null value -->
<Arg type="String"></Arg> <!-- empty string "" -->
----
====== Coercing Type
This explicitly coerces the type to a boolean:
[source, xml, subs="{sub-order}"]
----
<Arg type="boolean">False</Arg>
----
====== As a Parameter
Here are a couple of examples of link:#jetty-xml-arg[Arg element] being used as a parameter to methods and to constructors:
[source, xml, subs="{sub-order}"]
----
<Call class="com.acme.Environment" name="setFoo">
<Arg>
<New class="com.acme.Foo">
<Arg>bar</Arg>
</New>
</Arg>
</Call>
----
This is equivalent to:
[source, java, subs="{sub-order}"]
----
com.acme.Environment.setFoo(new com.acme.Foo("bar"));
----
[source, xml, subs="{sub-order}"]
----
<New class="com.acme.Baz">
<Arg>
<Call id="bar" class="com.acme.MyStaticObjectFactory" name="createObject">
<Arg>2</Arg>
</Call>
</Arg>
</New>
----
This is equivalent to:
[source, java, subs="{sub-order}"]
----
new com.acme.Baz(com.acme.MyStaticObjectFactory.createObject(2));
----
[[jetty-xml-new]]
==== <New>
Instantiates an object.
Equivalent to `new` in Java, and allows the creation of a new object.
A `New` element can contain a sequence of link:#jetty-xml-arg[`Arg` element]'s, followed by a sequence of configuration elements (`Set`, `Put`, etc).
link:#jetty-xml-arg[`Arg` element]'s are used to select a constructor for the object to be created.
The sequence of configuration elements then acts on the newly-created object.
[cols=",,",options="header",]
|=======================================================================
|Attribute |Required |Description
|class |yes |fully qualified classname, which determines the type of the
new object that is instantiated.
|id |no |gives a unique name to the object which can be referenced later
by Ref elements.
|arg |no |comma separated list of arguments may be used for simple
string values rather than Arg elements
|=======================================================================
===== Can Contain
Attributes as elements (Id, Class) plus link:#jetty-xml-arg[Arg
element], link:#jetty-xml-set[Set element], link:#jetty-xml-get[Get
element], link:#jetty-xml-put[Put element], link:#jetty-xml-call[Call
element], link:#jetty-xml-new[New element], link:#jetty-xml-ref[Ref
element], link:#jetty-xml-array[Array element], link:#jetty-xml-map[Map
element], link:#jetty-xml-property[Property element]
===== Examples
====== Basic example
[source, xml, subs="{sub-order}"]
----
<New class="com.acme.Foo">
<Arg>bar</Arg>
</New>
----
Which is equivalent to:
[source, java, subs="{sub-order}"]
----
com.acme.Foo foo = new com.acme.Foo("bar");
----
====== Instantiate with the Default Constructor
[source, xml, subs="{sub-order}"]
----
<New class="com.acme.Foo" />
----
Which is equivalent to:
[source, java, subs="{sub-order}"]
----
com.acme.Foo foo = new com.acme.Foo();
----
====== Instantiate with Multiple Arguments, Then Configuring Further
[source, xml, subs="{sub-order}"]
----
<New id="foo" class="com.acme.Foo">
<Arg>bar</Arg>
<Arg>baz</Arg>
<Set name="test">1, 2, 3</Set>
</New>
----
Which is equivalent to:
[source, java, subs="{sub-order}"]
----
Object foo = new com.acme.Foo("bar", "baz");
foo.setTest("1, 2, 3");
----
[[jetty-xml-ref]]
==== <Ref>
A `Ref` element allows a previously created object to be referenced by a unique id.
It can contain a sequence of elements, such as `Set` or `Put` which then act on the referenced object.
You can also use a `Ref` element as a value for other elements such as `Set` and `Arg`.
The `Ref` element provides convenience and eases readability.
You can usually achieve the effect of the `Ref` by nesting elements (method calls), but this can get complicated very easily.
The Ref element makes it possible to refer to the same object if you're using it multiple times, or passing it into multiple methods.
It also makes it possible to split up configuration across multiple files.
[cols=",,",options="header",]
|=======================================================================
|Attribute |Required |Description
|refid |yes |the unique identifier used to name a previously created
object.
|=======================================================================
===== Can Contain
link:#jetty-xml-set[Set element], link:#jetty-xml-get[Get element],
link:#jetty-xml-put[Put element], link:#jetty-xml-call[Call element],
link:#jetty-xml-new[New element], link:#jetty-xml-ref[Ref element],
link:#jetty-xml-array[Array element], link:#jetty-xml-map[Map element],
link:#jetty-xml-property[Property element]
===== Examples
====== Basic example
Use the referenced object as an argument to a method call or constructor:
[source, xml, subs="{sub-order}"]
----
<Get id="foo" name="xFoo" />
<Set name="test"><Ref refid="foo"/></Set>
----
This is equivalent to:
[source, java, subs="{sub-order}"]
----
foo = getXFoo();
setSomeMethod(foo);
----
====== Manipulating the Object Returned by Ref
[source, xml, subs="{sub-order}"]
----
<Get id="foo" name="xFoo" />
<Ref refid="foo">
<Set name="test">1, 2, 3</Set>
</Ref>
----
This is equivalent to:
[source, java, subs="{sub-order}"]
----
foo = getXFoo();
foo.setTest("1, 2, 3");
----
====== Ref vs. Nested Elements
Here is an example of the difference in syntax between using the `Ref` element, and nesting method calls.
They are exactly equivalent:
[source, xml, subs="{sub-order}"]
----
<!-- using Ref in conjunction with Get -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Get id="Logger" class="org.eclipse.jetty.util.log.Log" name="log"/>
<Ref refid="Logger">
<Set name="debugEnabled">true</Set>
</Ref>
</Configure>
<!-- calling the setter directly on the object returned by Get -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Get class="org.eclipse.jetty.util.log.Log" name="log">
<Set name="debugEnabled">true</Set>
</Get>
</Configure>
----
Here is a more practical example, taken from the handler configuration section in `etc/jetty.xml`:
[source, xml, subs="{sub-order}"]
----
<Set name="handler">
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.eclipse.jetty.server.Handler">
<Item>
<!-- create a new instance of a ContextHandlerCollection named "Contexts" -->
<New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
</Item>
<Item>
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
</Item>
<Item>
<!-- create a new instance of a RequestLogHandler named "RequestLog" -->
<New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.deploy.ContextDeployer">
<!-- pass in the ContextHandlerCollection object ("Contexts") that was created earlier, as an argument -->
<Set name="contexts"><Ref refid="Contexts"/></Set>
</New>
</Arg>
</Call>
<!-- configure the RequestLogHandler object ("RequestLog") that we created earlier -->
<Ref refid="RequestLog">
....
</Ref>
----
[[jetty-xml-array]]
==== <Array>
An `Array` element allows the creation of a new array.
[cols=",,",options="header",]
|==================================================================
|Attribute |Required |Description
|type |no |specify what types of items the array can contain.
|id |no |unique identifier you can use to refer to the array later.
|==================================================================
===== Can Contain
link:#jetty-xml-item[Item element]
===== Example
[source, xml, subs="{sub-order}"]
----
<Array type="java.lang.String">
<Item>value0</Item>
<Item><New class="java.lang.String"><Arg>value1</Arg></New></Item>
</Array>
----
This is equivalent to:
[source, java, subs="{sub-order}"]
----
String[] a = new String[] { "value0", new String("value1") };
----
[[jetty-xml-item]]
==== <Item>
An `Item` element defines an entry for Array and Map elements.
[cols=",,",options="header",]
|=======================================================================
|Attribute |Required |Description
|type |no |force the types of value.
|id |no |unique identifier that you can use to refer to the array later.
|=======================================================================
===== Can Contain
link:#jetty-xml-get[Get element], link:#jetty-xml-call[Call element],
link:#jetty-xml-new[New element], link:#jetty-xml-ref[Ref element],
link:#jetty-xml-array[Array element], link:#jetty-xml-map[Map element],
link:#jetty-xml-system-property[System Property element],
link:#jetty-xml-property[Property element]
[[jetty-xml-map]]
==== <Map>
A `Map` element allows the creation of a new HashMap and to populate it with `(key, value)` pairs.
[cols=",,",options="header",]
|================================================================
|Attribute |Required |Description
|id |no |unique identifier you can use to refer to the map later.
|================================================================
===== Can Contain
link:#jetty-xml-entry[Entry element]
===== Example
[source, xml, subs="{sub-order}"]
----
<Map>
<Entry>
<Item>keyName</Item>
<Item><New class="java.lang.String"><Arg>value1</Arg></New></Item>
</Entry>
</Map>
----
This is equivalent to:
[source, java, subs="{sub-order}"]
----
Map m = new HashMap();
m.put("keyName", new String("value1"));
----
[[jetty-xml-entry]]
==== <Entry>
An `Entry` element contains a key-value link:#jetty-xml-item[Item element] pair for a `Map`.
===== Can Contain
link:#jetty-xml-item[Item element]
[[jetty-xml-system-property]]
==== <SystemProperty>
A `SystemProperty` element gets the value of a JVM system property.
It can be used within elements that accept values, such as `Set`, `Put`, `Arg`.
[cols=",,",options="header",]
|=======================================================================
|Attribute |Required |Description
|name |yes |property name
|default |no |a default value as a fallback
|id |no |unique identifier which you can use to refer to the array
later.
|=======================================================================
===== Can Contain
Only attributes as Elements (`Id`, `Name`, `Default`).
===== Example
[source, xml, subs="{sub-order}"]
----
<SystemProperty name="jetty.http.port" default="8080"/>
----
That is equivalent to:
[source, java, subs="{sub-order}"]
----
System.getProperty("jetty.http.port", "8080");
----
Both try to retrieve the value of `jetty.http.port`.
If `jetty.http.port` is not set, then 8080 is used.
[[jetty-xml-property]]
==== <Property>
A `Property` element allows arbitrary properties to be retrieved by name.
It can contain a sequence of elements, such as `Set`, `Put`, `Call` that act on the retrieved object.
[cols=",,",options="header",]
|=======================================================================
|Attribute |Required |Description
|name |yes |property name
|default |no |a default value as a fallback
|id |no |unique identifier which you can use to refer to the array
later.
|=======================================================================
The `Name` attribute may be a comma separated list of property names, with the first property name being the "official" name, and the others names being old, deprecated property names that are kept for backward compatibility.
A warning log is issued when deprecated property names are used.
The `Default` attribute contains the value to use in case none of the property names is found.
===== Can Contain
The attributes may be expressed as contained Elements (`Id`, `Name`, `Default`).
===== Example
[source, xml, subs="{sub-order}"]
----
<Property name="Server">
<Call id="jdbcIdMgr" name="getAttribute">
<Arg>jdbcIdMgr</Arg>
</Call>
</Property>
----

View File

@ -16,4 +16,15 @@
// ========================================================================
//
include::xml.adoc[]
[[og-xml]]
=== Jetty XML
The Jetty XML format is a straightforward mapping of XML elements to Java APIs so that any object can be instantiated and getters, setters, and methods can be called.
The Jetty XML format is very similar to that of frameworks like Spring or Plexus, although it predates all of them and it's typically more powerful as it can invoke any Java API.
The Jetty XML format is used in xref:og-modules[Jetty modules] to create the Jetty server components, as well as in xref:og-deploy[Jetty XML context files] to configure web applications, but it can be used to call any Java API.
include::xml-syntax.adoc[]
// TODO: port the documentation from old_docs/jetty-xml/*.adoc

View File

@ -0,0 +1,480 @@
//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
[[og-xml-syntax]]
==== Jetty XML Syntax
The Jetty XML syntax defines XML element that allow you to call any Java API and that allow you to interact in a simpler way with the xref:og-modules[Jetty module system] and the xref:og-deploy[Jetty deploy system].
The Jetty XML elements define attributes such as `id`, `name`, `class`, etc. that may be replaced by correspondent elements, so that these XML documents are equivalent:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure>
<Get id="stderr" class="java.lang.System" name="err">
<Call name="println" arg="HELLO" />
</Get>
</Configure>
----
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure>
<Get>
<Id>stderr</Id>
<Name>err</Name>
<Class>java.lang.System</Class>
<Call>
<Name>println</Name>
<Arg>HELLO</Arg>
</Call>
</Get>
</Configure>
----
The version using attributes is typically shorter and nicer to read, but sometimes the attribute value cannot be a literal string (for example, it could be the value of a system property) and that's where elements gives you the required flexibility.
[[og-xml-syntax-configure]]
===== `<Configure>`
Element `Configure` must be the root element of the XML document.
The following Jetty XML creates an empty `String` and assigns it the id `mystring`:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure id="mystring" class="java.lang.String" />
----
This is equivalent to the following Java code:
[source,java]
----
var mystring = new String();
----
If an object with the id `mystring` already exists, then it is not created again but rather just referenced.
Typically the `<Configure>` element is used to configure a `Server` instance or `ContextHandler` subclasses such as `WebAppContext` that represent web applications.
[[og-xml-syntax-arg]]
===== `<Arg>`
Element `Arg` is used to pass arguments to xref:og-xml-syntax-new[constructors] and xref:og-xml-syntax-call[method calls].
The following example creates a minimal Jetty `Server`:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.server.Server">
<Arg type="int">8080</Arg>
</Configure>
----
Arguments may have a `type` attribute that explicitly performs xref:og-xml-syntax-types[type coercion].
Arguments may also have a `name` attribute, which is matched with the corresponding Java annotation in the source class, that helps to identify arguments:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.server.Server">
<Arg name="port" type="int">8080</Arg>
</Configure>
----
[[og-xml-syntax-new]]
===== `<New>`
Element `<New>` creates a new object of the type specified by the mandatory `class` attribute.
A sequence of `Arg` elements, that must be contiguous and before other elements, may be present to specify the constructor arguments.
Within element `<New>` the newly created object is in xref:og-xml-syntax-scope[scope] and may be the implicit target of other, nested, elements.
The following example creates an `ArrayList`:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure>
<New id="mylist" class="java.util.ArrayList">
<Arg type="int">16</Arg>
</New>
</Configure>
----
This is equivalent to the following Java code:
[source,java]
----
var mylist = new ArrayList(16);
----
[[og-xml-syntax-call]]
===== `<Call>`
Element `<Call>` invokes a method specified by the mandatory `name` attribute.
A sequence of `Arg` elements, that must be contiguous and before other elements, may be present to specify the method arguments.
Within element `<Call>` the return value, if the return type is not `void`, is in xref:og-xml-syntax-scope[scope] and may be the implicit target of other, nested, elements.
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure>
<New class="java.util.ArrayList">
<Call name="listIterator">
<Arg type="int">0</Arg>
</Call>
<Call name="next" />
</New>
</Configure>
----
This is equivalent to the following Java code:
[source,java]
----
new ArrayList().listIterator(0).next();
----
It is possible to call `static` methods by specifying the `class` attribute:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure>
<Call id="myhost" name="getByName" class="java.net.InetAddress">
<Arg>jdk.java.net</Arg>
</Call>
</Configure>
----
This is equivalent to the following Java code:
[source,java]
----
var myhost = InetAddress.getByName("jdk.java.net");
----
[[og-xml-syntax-get]]
===== `<Get>`
Element `<Get>` retrieves the value of a JavaBean property specified by the mandatory `name` attribute.
If the JavaBean property is `foo` (or `Foo`), `<Get>` first attempts to invoke _method_ `getFoo()`; failing that, attempts to retrieve the value from _field_ `foo` (or `Foo`).
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure id="server" class="org.eclipse.jetty.server.Server">
<!-- Invokes getter method server.getVersion() -->
<Get id="version" name="version" />
<!-- Gets the System.err field -->
<Get class="java.lang.System" name="err">
<Call name="println">
<Arg>Jetty</Arg>
</Call>
</Get>
</Configure>
----
[[og-xml-syntax-set]]
===== `<Set>`
Element `<Set>` stores the value of a JavaBean property specified by the mandatory `name` attribute.
If the JavaBean property is `foo` (or `Foo`), `<Set>` first attempts to invoke _method_ `setFoo(...)` with the value in the xref:og-xml-syntax-scope[scope] as argument; failing that, attempts to store the value in the scope to _field_ `foo` (or `Foo`).
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure id="server" class="org.eclipse.jetty.server.Server">
<!-- The value in the <Set> scope is the string "true" -->
<Set name="dryRun">true</Set>
<!-- The value in the <Set> scope is the instance created by <New> -->
<Set name="requestLog">
<New class="org.eclipse.jetty.server.CustomRequestLog" />
</Set>
</Configure>
----
[[og-xml-syntax-map]]
===== `<Map>` and `<Entry>`
Element `<Map>` allows the creation of a new `java.util.Map` implementation, specified by the `class` attribute -- by default a `HashMap`.
The map entries are specified with a sequence of `<Entry>` elements, each with exactly 2 `<Item>` elements, for example:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure>
<Map class="java.util.concurrent.ConcurrentHashMap">
<Entry>
<Item>host</Item>
<Item>
<Call class="java.net.InetAddress" name="getByName">
<Arg>localhost</Arg>
</Call>
</Item>
</Entry>
</Map>
</Configure>
----
[[og-xml-syntax-put]]
===== `<Put>`
Element `<Put>` is a convenience element that puts a key/value pair into objects that implement `java.util.Map`.
You can only specify the key value via the `name` attribute, so the key can only be a literal string (for keys that are not literal strings, use the `<Call>` element).
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure>
<New class="java.util.Properties">
<Put name="host">
<Call class="java.net.InetAddress" name="getByName">
<Arg>localhost</Arg>
</Call>
</Put>
</New>
</Configure>
----
[[og-xml-syntax-array]]
===== `<Array>` and `<Item>`
Element `<Array>` creates a new array, whose component type may be specified by the `type` attribute.
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure>
<Array type="java.lang.Object">
<Item /> <!-- null -->
<Item>literalString</Item>
<Item type="String"></Item> <!-- empty string -->
<Item type="Double">1.0D</Item>
<Item>
<New class="java.lang.Exception" />
</Item>
</Array>
</Configure>
----
[[og-xml-syntax-ref]]
===== `<Ref>`
Element `<Ref>` allows you to reference an object via the `refid` attribute`, putting it into xref:og-xml-syntax-scope[scope] so that nested elements can operate on it.
You must give a unique `id` attribute to the objects you want to reference.
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<!-- The Jetty Server has id="server" -->
<Configure id="server" class="org.eclipse.jetty.server.Server">
<Get class="java.lang.System" name="err">
<!-- Here the System.err field is in scope, but you
want to operate on the server to get its version -->
<Ref refid="server">
<!-- Store the server version under id="myversion" -->
<Get id="myversion" name="version" />
</Ref>
<Call name="println">
<!-- Reference the server version stored above -->
<Arg>Server version is: <Ref refid="myversion" /></Arg>
</Call>
</Get>
</Configure>
----
[[og-xml-syntax-property]]
===== `<Property>`
Element `<Property>` retrieves the value of the Jetty module property specified by the `name` attribute, and it is mostly used when creating xref:og-modules[custom Jetty modules] or when using xref:og-deploy-jetty[Jetty context XML files].
// TODO: xref to the custom module section.
The `deprecated` attribute allows you to specify a comma separated list of old, deprecated, property names for backward compatibility.
The `default` attribute allows you to specify a default value for the property, if it has not been explicitly defined.
For example, you may want to configure the context path of your web application in this way:
[source,xml,subs=normal]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Set name="contextPath">
#<Property name="com.myapps.mywiki.context.path" default="/wiki" />#
</Set>
<Set name="war">/opt/myapps/mywiki.war</Set>
</Configure>
----
The `contextPath` value is resolved by looking for the Jetty module property `com.myapps.mywiki.context.path`; if this property is not set, then the default value of `/wiki` is used.
[[og-xml-syntax-system-property]]
===== `<SystemProperty>`
Element `<SystemProperty>` retrieves the value of the JVM system property specified by the `name` attribute, via `System.getProperty(...)`.
The `deprecated` attribute allows you to specify a comma separated list of old, deprecated, system property names for backward compatibility.
The `default` attribute allows you to specify a default value for the system property value, if it has not been explicitly defined.
The following example creates a minimal Jetty `Server` that listens on a port specified by the `com.acme.http.port` system property:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure id="server" class="org.eclipse.jetty.server.Server">
<Arg type="int">
<SystemProperty name="com.acme.http.port" default="8080" />
</Arg>
</Configure>
----
[[og-xml-syntax-env]]
===== `<Env>`
Element `<Env>` retrieves the value of the environment variable specified by the `name` attribute, via `System.getenv(...)`.
The `deprecated` attribute allows you to specify a comma separated list of old, deprecated, environment variable names for backward compatibility.
The `default` attribute allows you to specify a default value for the environment variable value, if it has not been explicitly defined.
The following example creates a minimal Jetty `Server` that listens on a port specified by the `COM_ACME_HTTP_PORT` environment variable:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure id="server" class="org.eclipse.jetty.server.Server">
<Arg type="int">
<Env name="COM_ACME_HTTP_PORT" default="8080" />
</Arg>
</Configure>
----
[[og-xml-syntax-types]]
===== Type Coercion
Elements that have the `type` attribute explicitly perform the type coercion of the string value present in the XML document to the Java type specified by the `type` attribute.
Supported types are the following:
* all primitive types and their boxed equivalents, for example `type="int"` but also `type="Integer"` (short form) and `type="java.lang.Integer"` (fully qualified form)
* `java.lang.String`, in both short form and fully qualified form
* `java.net.URL`, in both short form and fully qualified form
* `java.net.InetAddress`, in both short form and fully qualified form
[[og-xml-syntax-scope]]
===== Scopes
Elements that create new objects or that return a value create a _scope_.
Within these elements there may be nested elements that will operate on that scope, i.e. on the new object or returned value.
The following example illustrates how scopes work:
[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<Configure id="server" class="org.eclipse.jetty.server.Server">
<Arg type="int">8080</Arg>
<!-- Here the Server object has been created and is in scope -->
<!-- Calls the setter on the Server object that is in scope -->
<Set name="stopTimeout">5000</Set>
<!-- Creates a new object -->
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<!-- Here the HttpConfiguration just created is in a nested scope -->
<!-- Calls the setter on the HttpConfiguration object that is in scope -->
<Set name="secureScheme">https</Set>
</New>
<!-- Calls the getter on the Server object that is in scope -->
<Get name="ThreadPool">
<!-- Here the ThreadPool object returned by the getter is in a nested scope -->
<!-- Calls the setter on the ThreadPool object that is in scope -->
<Set name="maxThreads" type="int">256</Set>
</Get>
<!-- Gets the System.err field -->
<Get class="java.lang.System" name="err">
<!-- Here the System.err object is in scope -->
<!-- Equivalent to: var myversion = server.getVersion() -->
<Ref refid="server">
<!-- Here the "server" object is in scope -->
<Get id="myversion" name="version" />
</Ref>
<!-- Calls println() on the System.err object -->
<Call name="println">
<Arg>Server version is: <Ref refid="myversion" /></Arg>
</Call>
</Get>
</Configure>
----

View File

@ -1,24 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
[[og-xml]]
=== Jetty XML
TODO
// TODO: port the documentation from old_docs/jetty-xml/*.adoc