mirror of
https://github.com/apache/ant.git
synced 2025-05-19 14:34:45 +00:00
git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274570 13f79535-47bb-0310-9956-ffa450edef68
396 lines
16 KiB
HTML
396 lines
16 KiB
HTML
|
|
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html lang="en">
|
|
<!-- GENERATED FILE, DO NOT EDIT, EDIT THE XML FILE IN xdocs INSTEAD! -->
|
|
<head>
|
|
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
|
<title>Apache Ant - Roles</title>
|
|
<link type="text/css" href="../../page.css" rel="stylesheet">
|
|
<meta name="author" content="Antoine Levy-Lambert">
|
|
<meta name="email" content="antoine@apache.org">
|
|
</head>
|
|
|
|
<body>
|
|
<p class="navpath">
|
|
<script src="../../breadcrumbs.js" language="JavaScript" type="text/javascript"></script>
|
|
</p>
|
|
|
|
<div class="logobar">
|
|
<table width="100%" border="0" cellspacing="0" cellpadding="0">
|
|
<tr>
|
|
<td align="left"><img border="0" alt="Apache Ant site" src="../../images/group-logo.gif"></td>
|
|
<td align="center" width="100%"><img alt="Apache Ant logo" border="0" src="../../images/project-logo.gif"></td>
|
|
<td align="right">
|
|
<form target="_blank" onsubmit="q.value = query.value + ' site:ant.apache.org'" action="http://www.google.com/search" method="get">
|
|
<table summary="search" border="0" cellspacing="0" cellpadding="0" bgcolor="#4C6C8F">
|
|
<tr>
|
|
<td colspan="3"><img height="10" width="1" alt="" src="../../images/spacer.gif"></td>
|
|
</tr>
|
|
<tr>
|
|
<td><img height="1" width="1" alt="" src="../../images/spacer.gif"></td>
|
|
<td nowrap="nowrap" class="searchcaption">
|
|
<input name="q" type="hidden">
|
|
<input size="15" id="query" type="text">
|
|
<img height="1" width="5" alt="" src="../../images/spacer.gif">
|
|
<input name="Search" value="Search" type="submit">
|
|
<br>
|
|
the Apache Ant site
|
|
</td>
|
|
<td><img height="1" width="1" alt="" src="../../images/spacer.gif"></td>
|
|
</tr>
|
|
<tr>
|
|
<td><img alt="" border="0" height="10" width="9" src="../../images/search-left.gif"></td>
|
|
<td><img height="1" width="1" alt="" src="../../images/spacer.gif"></td>
|
|
<td><img alt="" border="0" height="10" width="9" src="../../images/search-right.gif"></td>
|
|
</tr>
|
|
</table>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="tab">
|
|
<table summary="tab bar" border="0" cellpadding="0" cellspacing="0">
|
|
<tr>
|
|
<td width="5"><img alt="" height="8" width="8" src="../../images/spacer.gif"></td><td valign="bottom">
|
|
<table summary="non selected tab" style="height: 1.4em" border="0" cellpadding="0" cellspacing="0">
|
|
<tr>
|
|
<td valign="top" width="5" bgcolor="#B2C4E0"><img height="5" width="5" alt="" src="../../images/tab-left.gif"></td><td valign="middle" bgcolor="#B2C4E0"><a href="../../index.html"><font size="2" face="Arial, Helvetica, Sans-serif">Home</font></a></td><td valign="top" width="5" bgcolor="#B2C4E0"><img height="5" width="5" alt="" src="../../images/tab-right.gif"></td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
<td width="5"><img alt="" height="8" width="8" src="../../images/spacer.gif"></td><td valign="bottom">
|
|
<table summary="non selected tab" style="height: 1.4em" border="0" cellpadding="0" cellspacing="0">
|
|
<tr>
|
|
<td valign="top" width="5" bgcolor="#B2C4E0"><img height="5" width="5" alt="" src="../../images/tab-left.gif"></td><td valign="middle" bgcolor="#B2C4E0"><a href="../../projects/index.html"><font size="2" face="Arial, Helvetica, Sans-serif">Projects</font></a></td><td valign="top" width="5" bgcolor="#B2C4E0"><img height="5" width="5" alt="" src="../../images/tab-right.gif"></td>
|
|
</tr>
|
|
</table>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="bluebar"></div>
|
|
|
|
<div class="menucontainer">
|
|
<div class="menu">
|
|
<ul>
|
|
</ul>
|
|
</div>
|
|
<img style="float: left" height="10" width="10" border="0" alt="" src="../../images/menu-left.gif">
|
|
<img style="float: right" height="10" width="10" border="0" alt="" src="../../images/menu-right.gif">
|
|
</div>
|
|
<div class="lightbluebar"> </div>
|
|
<div class="main">
|
|
<div class="content">
|
|
<h1 class="title">Roles</h1>
|
|
<h3 class="section">
|
|
<a name="What is a role"></a>
|
|
What is a role
|
|
</h3>
|
|
<p>
|
|
I am quoting here Jose Alberto Fernandez 26.04.2003 22:05:
|
|
Roles allow defining families of objects (members of a role) that can be
|
|
used by tasks or inner elements developed separately.
|
|
The developer of the object accepting a particular role as a subelement
|
|
has no knowledge of the implementation of the object but much more
|
|
importantly it has no knowledge of the XML element tag used to refer
|
|
to this subelement in the XML file.
|
|
</p>
|
|
<p>
|
|
|
|
In the antlib proposal, there are two preset roles :
|
|
<ul>
|
|
<li>task</li>
|
|
<li>datatype</li>
|
|
</ul>
|
|
Examples of other roles are :
|
|
<ul>
|
|
<li>mapper</li>
|
|
<li>filter</li>
|
|
</ul>
|
|
</p>
|
|
<p>
|
|
What does it all mean? It means we can now write a task, well typed, which
|
|
can be accept different XML subelements depending on the declarations of
|
|
other objects present on the build. The vendor specific elements of
|
|
<ejbjar>, <jspc> and others are typical examples of where this capability
|
|
can be very useful. Other parts of core could benefit of course.
|
|
</p>
|
|
<br />
|
|
<h4 class="subsection">
|
|
<a name="What do they do that is no possible in ANT"></a>
|
|
What do they do that is no possible in ANT
|
|
</h4>
|
|
<p>
|
|
They allow IntrospectionHelper to connect an XML subelement eventhough
|
|
introspection cannot find a create or add/Configured method for it.
|
|
It is a well typed methanism, the parent object will only be passed objects
|
|
that it knows how to deal with. And the parent object does not need to have
|
|
any knowledge of what currently available members are on the role.
|
|
</p>
|
|
<h3 class="section">
|
|
<a name="roles versus DynamicConfigurator"></a>
|
|
roles versus DynamicConfigurator
|
|
</h3>
|
|
<p>
|
|
The closest thing in ANT today is DynamicConfigurator but its purpose
|
|
is on the other way around. Given an elementTag with no matching method
|
|
it is up to the parent object to try to make sense of it.
|
|
If we were to use this mechanism to accomplish what roles try to do,
|
|
it would require the parent object implementor to be aware of where
|
|
to find the correct definition (remember it is a 3rd party implementation)
|
|
and perform the creation. It will be also its responsibility to
|
|
resolve type conflicts, name collisions, etc. This are all things
|
|
that should be done by IntrospectionHelper directly.
|
|
</p>
|
|
<p>
|
|
|
|
Also notice that Roles do not supersede DynamicConfigurator. On one hand roles
|
|
let external implementations to be considered as possible subelements
|
|
of a parent object, on the other hand, DynamicConfigurator allows a node
|
|
to decide given its current state what is the meaning of a particular element.
|
|
This cannot be done by roles in the general case, and that is good.
|
|
</p>
|
|
<h3 class="section">
|
|
<a name="Implementation of roles in the proposal"></a>
|
|
Implementation of roles in the proposal
|
|
</h3>
|
|
<p>this section quotes Jose Alberto Fernandez</p>
|
|
<p>
|
|
Here I may deviate from the exact code and add thoughts about where
|
|
do I think it should go.
|
|
</p>
|
|
<h4 class="subsection">
|
|
<a name="Usage of Roles"></a>
|
|
Usage of Roles
|
|
</h4>
|
|
<p>
|
|
The principle is very simple:
|
|
</p>
|
|
<br />
|
|
<ol>
|
|
<li>
|
|
A role is defined by an interface. This interface is the parameter
|
|
for a new special family of addConfigured(<interface>) methods.
|
|
</li>
|
|
<li>
|
|
<p>
|
|
When IntrospectionHelper fails to find a create/add method for the
|
|
element, it will look at all the roles used in the addConfigured
|
|
methods and on each of those roles will try to find an object declared
|
|
with that element-tag name. If one and only one match is found then
|
|
the instantiation is successful and the new object will be configured;
|
|
otherwise it is an error and parsing stops.
|
|
</p>
|
|
<br />
|
|
</li>
|
|
<li>
|
|
<p>
|
|
The configured object may or may not implement the Role interface,
|
|
if it does not, an Adaptor object may be instantiated as a proxy
|
|
for the object. Which adaptor is used depends on how the implementation
|
|
was declared.
|
|
</p>
|
|
<br />
|
|
</li>
|
|
<li>
|
|
<p>
|
|
The resulting object is passed as an argument to the addConfigured() method.
|
|
</p>
|
|
<br />
|
|
</li>
|
|
</ol>
|
|
<h4 class="subsection">
|
|
<a name="Declaration of roles"></a>
|
|
Declaration of roles
|
|
</h4>
|
|
<p>
|
|
A role definition associates a name with an (Interface,Adaptor) pair.
|
|
The only reason for associating a name with the role is to ease notation when
|
|
declaring members of a role.
|
|
</p>
|
|
<br />
|
|
<p>
|
|
Notice that the same interface or the same Adaptor may appear in multiple
|
|
declarations. This only means that depending on the name used the adaptor
|
|
of choice will be different.
|
|
</p>
|
|
<br />
|
|
<p>
|
|
There can only be one pair associated with each name.
|
|
</p>
|
|
<br />
|
|
<h4 class="subsection">
|
|
<a name="Declaration of implementations (members)"></a>
|
|
Declaration of implementations (members)
|
|
</h4>
|
|
<br />
|
|
<p>
|
|
A class is declared as belonging to a role by specifying the name to be used
|
|
when appearing in that role. The same class may belong to multiple roles
|
|
and may specify the same or different names on each one.
|
|
<br />
|
|
</p>
|
|
<p>
|
|
The name used for the role during the declaration only determines which
|
|
Adaptor will be available, if required.
|
|
<br />
|
|
</p>
|
|
<p>
|
|
|
|
Within a role-interface there can only be one object associated
|
|
with each name.
|
|
<br />
|
|
</p>
|
|
<h4 class="subsection">
|
|
<a name="Scoping rules"></a>
|
|
Scoping rules
|
|
</h4>
|
|
<br />
|
|
<p>
|
|
This is probably the more dificult aspect since given the way
|
|
<ant> and <antcall> work it means possible redeclarations on every
|
|
level of recursion. Whether declarations should just supercede
|
|
one another or be smarter is something to look into.
|
|
<br />
|
|
</p>
|
|
<h4 class="subsection">
|
|
<a name="Syntax"></a>
|
|
Syntax
|
|
</h4>
|
|
<br />
|
|
<p>
|
|
I have left out the issues of how the syntax looks like on purpose.
|
|
<br />
|
|
</p>
|
|
<p>
|
|
Syntax is just that and I am sure we can reach agreement somehow.
|
|
It is also clear that we should provide tasks to define roles
|
|
and declare members of roles direclty on the build.
|
|
<br />
|
|
</p>
|
|
<h3 class="section">
|
|
<a name="Making ant aware of tag/role/class associations"></a>
|
|
Making ant aware of tag/role/class associations
|
|
</h3>
|
|
<p>
|
|
The antlib proposal says :
|
|
Let's declare explicitly that a tag can be used in a particular role and is implemented by a specific class.
|
|
The declaration happens inside antlibs in the file META-INF/antlib.xml
|
|
</p>
|
|
<pre class="code">
|
|
<filter name="escapeunicode" class="org.apache.tools.ant.filters.EscapeUnicode"/>
|
|
</pre>
|
|
<p>
|
|
CM says :
|
|
A normal typedef is enough to make ant aware of the existence of the class org.apache.tools.ant.filters.EscapeUnicode.
|
|
Due to the fact that EscapeUnicode implements ChainableReader, the association between EscapeUnicode and the filter role does not need to be stated explicitly.
|
|
</p>
|
|
<h3 class="section">
|
|
<a name="Method names in parent classes supporting roles"></a>
|
|
Method names in parent classes supporting roles
|
|
</h3>
|
|
<p>
|
|
There is a discussion about how methods to add nested elements of a specific roles in a parent class should be called, and what their signature should be like.
|
|
</p>
|
|
<p>
|
|
CM :
|
|
<source>
|
|
addTYPE(TYPE)
|
|
</source>
|
|
for instance <source>addChainableReader(ChainableReader a)</source>
|
|
</p>
|
|
<p>
|
|
PR:
|
|
to add an element before its own attributes and nested elements are configured.
|
|
<source>
|
|
void add(TYPE)
|
|
</source>
|
|
to add an already configured element
|
|
<source>
|
|
void addConfigured(TYPE)
|
|
</source>
|
|
</p>
|
|
<p>
|
|
in the ant code of 1.6 :
|
|
<source>public Object createDynamicElement(String name)</source>
|
|
</p>
|
|
<h3 class="section">
|
|
<a name="Cardinality problems"></a>
|
|
Cardinality problems
|
|
</h3>
|
|
<h4 class="subsection">
|
|
<a name="One tag, several implementations"></a>
|
|
One tag, several implementations
|
|
</h4>
|
|
<p>
|
|
The <weblogic> element in <ejbjar>, <jspc>, <serverdeploy>, has different meanings.
|
|
</p>
|
|
<p>
|
|
This is an argument to introduce roles in ant, and to associate an XML tag with a role and an implementation class.
|
|
</p>
|
|
<h4 class="subsection">
|
|
<a name="Parent classes accepting one interface in different functions"></a>
|
|
Parent classes accepting one interface in different functions
|
|
</h4>
|
|
<p>
|
|
As an example, the dependset task accepts nested filesets for two different functions :
|
|
<ul>
|
|
<li>source</li>
|
|
<li>target</li>
|
|
</ul>
|
|
</p>
|
|
<p>Stefan Bodewig/Costin Manolache suggest :</p>
|
|
<pre class="code">
|
|
<dependset>
|
|
<zipfileset ant:type="srcfileset">
|
|
</dependset>
|
|
</pre>
|
|
<h4 class="subsection">
|
|
<a name="adapters"></a>
|
|
adapters
|
|
</h4>
|
|
<p>
|
|
The antlib proposal mentions adapter classes, which would be connected to roles.
|
|
Costin Manolache says that adapter classes should be tied to components, not roles.
|
|
The reason : two different components implementing the same interface (AKA role) can require different adapters.
|
|
</p>
|
|
<h3 class="section">
|
|
<a name="role proposal"></a>
|
|
role proposal
|
|
</h3>
|
|
<p>
|
|
slightly modified version of something writte by Jose Alberto Fernandez
|
|
</p>
|
|
<pre class="code">
|
|
<role name="roleName" className="...." [adapter="...."] />
|
|
<!-- I have added the possibility to declare a specific adapter per component to take into account what Costin said -->
|
|
<component name="elementName" role="roleName" className="....." [adapter="...."] />
|
|
|
|
</pre>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<p class="copyright">
|
|
Copyright © 2000-2003 The Apache Software Foundation. All rights reserved.
|
|
<script type="text/javascript" language="JavaScript"><!--
|
|
document.write(" - "+"Last Published: " + document.lastModified);
|
|
// -->
|
|
</script>
|
|
</p>
|
|
</body>
|
|
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|