Author: hlship
Date: Sat Mar 10 16:39:28 2007
New Revision: 516817
URL: http://svn.apache.org/viewvc?view=rev&rev=516817
Log:
TAPESTRY-1339: Update Tapestry IoC Documentation to remove references to
private services and module ids.
Modified:
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/case.apt
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/coerce.apt
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/command.apt
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/configuration.apt
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/decorator.apt
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/index.apt
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/module.apt
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/order.apt
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/pipeline.apt
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/provider.apt
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/service.apt
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/strategy.apt
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/symbols.apt
Modified:
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/case.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/case.apt?view=diff&rev=516817&r1=516816&r2=516817
==============================================================================
---
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/case.apt
(original)
+++
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/case.apt
Sat Mar 10 16:39:28 2007
@@ -18,7 +18,7 @@
[]
- Thus, <<<getService("foo.bar.Baz", Baz.class)>>> is preferred, but
<<<getService("FOO.BAR.BAZ", Baz.class)>>> (or any variation thereof) will work
just exactly as well. This also extends to other naming conventions,
+ Thus, <<<getService("fBaz", Baz.class)>>> is preferred, but
<<<getService("BAZ", Baz.class)>>> (or any variation thereof) will work just
exactly as well. This also extends to other naming conventions,
such as <<<contributeFoo>>> methods. It also applies to values inside
annotations.
Just case is ignored --
Modified:
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/coerce.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/coerce.apt?view=diff&rev=516817&r1=516816&r2=516817
==============================================================================
---
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/coerce.apt
(original)
+++
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/coerce.apt
Sat Mar 10 16:39:28 2007
@@ -41,8 +41,7 @@
inform the TypeCoercer about this coercion.
+---+
- @Contribute("tapestry.ioc.TypeCoercer")
- public void contributeMoneyCoercion(Configuration<CoercionTuple>
configuration)
+ public void contributeTypeCoercer(Configuration<CoercionTuple>
configuration)
{
Coercion<BigDecimal, Money> coercion = new Coercion<BigDecimal, Money>()
{
Modified:
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/command.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/command.apt?view=diff&rev=516817&r1=516816&r2=516817
==============================================================================
---
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/command.apt
(original)
+++
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/command.apt
Sat Mar 10 16:39:28 2007
@@ -32,7 +32,7 @@
Because this pattern is used so often inside Tapestry, a built-in service
exists
to create implementations of the pattern as needed. The
-
{{{apidocs/org/apache/tapestry/ioc/services/ChainBuilder.html}tapestry.ioc.ChainBuilder}}
+ {{{apidocs/org/apache/tapestry/ioc/services/ChainBuilder.html}ChainBuilder}}
service takes care of all the work:
+----+
@@ -55,7 +55,7 @@
+----+
public static MyChainService buildMyChainService(List<MyChainService>
commands,
- @InjectService("tapestry.ioc.ChainBuilder")
+ @InjectService("ChainBuilder")
ChainBuilder chainBuilder)
{
return chainBuilder.build(MyChainService.class, commands);
Modified:
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/configuration.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/configuration.apt?view=diff&rev=516817&r1=516816&r2=516817
==============================================================================
---
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/configuration.apt
(original)
+++
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/configuration.apt
Sat Mar 10 16:39:28 2007
@@ -53,7 +53,9 @@
+------+
@Contribute("FileServicerDispatcher")
public static void
contributeFileServicers(MappedConfiguration<String,FileServicer> configuration,
+
@InjectService("TextFileServicer") FileServicer textFileServicer,
+
@InjectService("PDFFileServicer") FileServicer pdfFileServicer,
{
configuration.add("txt", textFileServicer);
@@ -61,13 +63,11 @@
}
+------+
- The <<extensibility>> comes from the fact that many different methods in all
kinds
- of different module builder classes can make these contributions. So,
another module
- might understand Microsoft Office formats:
+ The <<extensibility>> comes from the fact multiple modules may all
contribute to the same
+ service configuration:
+------+
- @Contribute("some.module.FileServicerDispatcher")
- public static void
contributeOfficeFileServicers(MappedConfiguration<String,FileServicer>
configuration)
+ public static void
contributeFileServicers(MappedConfiguration<String,FileServicer> configuration)
{
configuration.add("doc", new WordFileServicer());
configuration.add("ppt", new PowerPointFileServicer());
@@ -134,8 +134,7 @@
{{{apidocs/org/apache/tapestry/ioc/Configuration.html}Configuration}} object:
+------+
- @Contribute("some.module.Startup")
- public static void contributeStartups(Configuration<Runnable> configuration)
+ public static void contributeStartup(Configuration<Runnable> configuration)
{
configuration.add(new JMSStartup());
configuration.add(new FileSystemStartup());
@@ -194,21 +193,18 @@
{{{apidocs/org/apache/tapestry/ioc/OrderedConfiguration.html}OrderedConfiguration}}:
+------+
- @Contribute("some.module.Startup")
- public static void contributeStartups(OrderedConfiguration<Runnable>
configuration)
+ public static void contributeStartup(OrderedConfiguration<Runnable>
configuration)
{
configuration.add("JMS", new JMSStartup());
- configuration.add("FileSystem", new FileSystemStartup(),
"after:*.CacheSetup");
+ configuration.add("FileSystem", new FileSystemStartup(),
"after:CacheSetup");
}
+------+
- Often, you don't care about ordering, the first form of the add method is
used then. The id value you
- provide will be prefixed with the contributing module's id. The ordering
algorithm will find a spot for the
+ Often, you don't care about ordering, the first form of the add method is
used then. The ordering algorithm will find a spot for the
object (here the JMSStartup instance) based on the constraints of other
contributed objects.
For the "FileSystem" contribution, a constraint has been specified,
indicating
- that FileSystem should be ordered after some other contribution named
"CacheSetup"
- in an unspecified module (the "*" part). Any number of such
+ that FileSystem should be ordered after some other contribution named
"CacheSetup". Any number of such
{{{order.html}ordering constraints}} may be specified (the add() method
accepts
a variable number of arguments).
@@ -228,6 +224,11 @@
the conflict), and ignore the conflicting value.
The value may not be null.
+
+ <<TODO:>> It is planned that for mapped configurations where the key is
String, a
+
{{{apidocs/org/apache/tapestry/ioc/util/CaseInsensitiveMap.html}CaseInsensitiveMap}}
+ will be used automatically, to help ensure that case insensitivity is
automatic and pervasive. This has not yet been
+ implemented.
Injecting Resources
Modified:
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/decorator.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/decorator.apt?view=diff&rev=516817&r1=516816&r2=516817
==============================================================================
---
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/decorator.apt
(original)
+++
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/decorator.apt
Sat Mar 10 16:39:28 2007
@@ -57,10 +57,8 @@
+---------------------+
package org.example.myapp.services;
-import org.apache.tapestry.ioc.annotations.Id;
import org.apache.tapestry.ioc.services.LoggingDecorator;
[EMAIL PROTECTED]("myapp")
public class MyAppModule
{
public static Indexer buildIndexer()
@@ -70,7 +68,8 @@
public static <T> T decorateIndexer(Class<T> serviceInterface, T delegate,
String serviceId, Log serviceLog,
- @InjectService("tapestry.ioc.LoggingDecorator")
+
+ @InjectService("LoggingDecorator")
LoggingDecorator decorator)
{
return decorator.build(serviceInterface, delegate, serviceId, serviceLog);
@@ -99,7 +98,7 @@
and an interceptor factory that generates logging interceptors.
The "heavy lifting" is provided by the factory, which will create a new
interceptor
- that logs methods entry before delegating to the core service
implementation. The interceptor
+ that logs method entry before delegating to the core service
implementation. The interceptor
will also log method parameters, return values, and even log exceptions.
The return value of the method is the new interceptor. You may return null
if your
@@ -112,14 +111,12 @@
+---------------------+
package org.example.myapp.services;
-import org.apache.tapestry.ioc.annotations.Id;
import org.apache.tapestry.ioc.services.LoggingDecorator;
[EMAIL PROTECTED]("myapp")
public class MyAppModule
{
public static Indexer buildIndexer(Class serviceInterface, Log serviceLog,
- @InjectService("tapestry.ioc.LoggingDecorator")
+ @InjectService("LoggingDecorator")
LoggingInterceptorFactory decorator)
{
return decorator.build(serviceInterface, serviceLog, new IndexerImpl());
@@ -146,7 +143,7 @@
@Match("*")
public static <T> T decorateLogging(Class<T> serviceInterface, T delegate,
String serviceId, Log serviceLog,
- @InjectService("tapestry.ioc.LoggingDecorator")
+ @InjectService("LoggingDecorator")
LoggingDecorator decorator)
{
return decorator.build(serviceInterface, delegate, serviceId, serviceLog);
@@ -158,17 +155,21 @@
logging for your data access and business logic services, you might end up
with
<<<@Match("Data*", "*Logic")>>> (based, of course, on how you name your
services).
- For example, you might add <<<@Match("myapp.internal.*.*")>>> to match all
services within
- any of your application's internal modules.
-
- Thus, <<<@Match("*.*")>>> is dangerous, because it will match every (public)
service in every
+ As the precending example showed, a simple "glob" matching is supported,
where a asterisk ('*')
+ may be used at the start or end of the match string to match any number of
characters.
+ As elsewhere, matching is case insensitive.
+
+
+ Thus, <<<@Match("*")>>> is dangerous, because it will match every (public)
service in every
module.
- <Note: It is not possible to decorate the services of the tapestry.ioc
module.>
+ <Note: It is not possible to decorate the services of the TapestryIOCModule.>
<Note: Another idea will be other ways of matching services: base on
inheritance of the
service interface and/or based on the presence of particular class
annotations on the
- service interface.>
+ service interface. None of this has been implemented yet, and can readily be
accompllished
+ inside the decorator method (which will return null if it decides the
service doesn't
+ need decoration).>
Ordering of Decorators
@@ -185,10 +186,10 @@
+---------------------+
@Match("*")
- @Order("before:*.*")
+ @Order("before:*")
public static <T> T decorateLogging(Class<T> serviceInterface, T delegate,
String serviceId, Log serviceLog,
- @InjectService("tapestry.ioc.LoggingDecorator")
+ @InjectService("LoggingDecorator")
LoggingDecorator decorator)
{
return decorator.build(serviceInterface, delegate, serviceId, serviceLog);
@@ -196,14 +197,13 @@
+---------------------+
- "before:*.*" indicates that this decorator should come before any decorator
in <any> module.
+ "before:*" indicates that this decorator should come before any decorator
in <any> module.
- <<Note:>> the ordering of decorators is in terms of the <effect> desired.
In the earlier
- example, the order of the effects is logging, then timing, then security,
then transactions
- (then the core service implementation). Internally, the decorators are
invoked
+ <<Note:>> the ordering of decorators is in terms of the <effect> desired.
+ Internally, the decorators are invoked
last to first (since each once receives the "next" interceptor as its
delegate).
So the core service implementation is created (via a service builder method)
- and that is passed to the transaction decorator method. The interceptor
created there
- is passed to the the security decorator, and so forth.
+ and that is passed to the last decorator method. The interceptor created
there
+ is passed to the the next-to-last decorator method, and so forth.
Modified:
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/index.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/index.apt?view=diff&rev=516817&r1=516816&r2=516817
==============================================================================
---
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/index.apt
(original)
+++
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/index.apt
Sat Mar 10 16:39:28 2007
@@ -18,7 +18,7 @@
specifically for use as the IoC container for Tapestry 4. Tapestry 4 has
met its goals for extensibility and configurability, largely
because of HiveMind's flexibility.
- Tapestry 5 extends on this, replacing HiveMind with a new container
specifically build for Tapestry,
+ Tapestry 5 extends on this, replacing HiveMind with a new container
specifically build for Tapestry 5,
designed for greater ease of use, expressiveness and performance. And it
can be used seperately from the rest of Tapestry!
* Why Not Spring?
@@ -27,15 +27,10 @@
integrated {{{http://aspectj.org}AspectJ}} support, and a large number of
libraries built on top of the container. Spring is an excellent
<application> container, but lacks a number of features necessary for a
<framework> container:
- * Spring does not have the concept of a <namespace>. The names of beans are
simple and unqualified, which could lead to naming conflicts.
-
* Spring beans can be wired together by name (or id), but it is not possible
to introduce additional naming abstractions. Tapestry 4's
"infrastructure:" abstraction was the key to allowing easy spot overrides
of internal Tapestry services without having to
duplicate the large web of interrelated services (nearly 200 in Tapestry
4.0).
-
- * Spring doesn't have a concept of <visibility>, whereby some service
implementations are internal to a module (Spring doesn't
- have modules), which makes it easier to create service facades.
-
+
* Although Spring allows beans to be intercepted, it does so in the form of
a new bean, leaving the un-intercepted bean visible
(and subject to misuse). HiveMind and Tapestry IoC "wrap" the service
inside interceptors, preventing unintercepted access
to the core service implementation.
@@ -148,17 +143,14 @@
only be a single service per service interface, but in some situations,
there may be many different services and service implementations
all sharing the same service interface.
- Services have a visibility: either public (the default) or private (only
visible within the same module).
- Services are identified by a unique id, which combines an unqualified id for
the service with the containing module's id (see below).
- Typically, a service id matches the name of the service interface.
+ Services are identified by a unique id. Typically, a service id matches the
unqualified name of the service interface, but
+ this is simply a convention.
Services are aggregated into <<modules>>:
-
- * A module defines a <<module id>> that is used as a prefix when naming
services within the module. This is very much equivalent
- to a Java package name. Module ids must be unique within the registry of
modules.
-
- * A module is defined by a <<module builder>>, a specific class containing
static or instance methods.
+
+ * A module is defined by a <<module builder>>, a specific class containing a
mix of static or instance methods, used to define
+ services, decorate them (see below), or contribute to service
configurations (again, more below).
* Methods of the module builder class define the services provided by the
module,
and the same methods are responsible
@@ -169,7 +161,8 @@
The methods which define and construct services are called <<service builder
methods>>.
The <<registry>> is the outside world's view of the modules and services.
From the registry, it is possible to obtain
- a service, via its qualified id or by its service interface.
+ a service, via its unique id or by its service interface. Access by unique
id is <caseless> (meaning, a match will be found
+ even the case of the search key doesn't match the case of the service
itself).
Services may be <<decorated>> by <<service decorator methods>>. These
methods create
@@ -187,10 +180,11 @@
to linked pairs of similarily named services and configurations. For
Tapestry IoC, each service is allowed to have a single configuration,
which is normally sufficient.>
- Services are typically instantiated as needed. In this case, "need"
translates to "when a method of the service is invoked".
- In nearly all cases, a service is represented (to the outside world, or to
other services) as a <<proxy>> that implements
- the service interface. The first time a method is invoked on the proxy, the
full service (implementation and interceptors) is
- constructed. This occurs in a completely <<thread-safe>> manner.
+ Services are instantiated as needed. In this case, "need" translates to
"when a method of the service is invoked".
+ A service is represented (to the outside world, or to other services) as a
<<proxy>> that implements
+ the service interface. The first time a method is invoked on the proxy, the
full service (consisting of the core service implementation wrapped with any
interceptors) is
+ constructed. This occurs in a completely <<thread-safe>> manner.
Just-in-time instantiation allows for more complex, more finely grained
networks of services, and improves
+ startup time.
Services define a <<lifecycle>> that controls when the service is
constructed. The default lifecycle is <<singleton>>, meaning a single
global instance created as needed. Other lifecycles allow service
implementations to be bound to the current thread (i.e., the current
Modified:
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/module.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/module.apt?view=diff&rev=516817&r1=516816&r2=516817
==============================================================================
---
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/module.apt
(original)
+++
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/module.apt
Sat Mar 10 16:39:28 2007
@@ -25,51 +25,25 @@
}
+-----------------------------------------------------------------------------------+
- By default, a module's id is the same as its package name (we'll see how to
override
- that shortly). Here the module id will be org.example.myapp.services.
-
Any public method (static or instance) whose name starts with "build" is a
service builder method, implicitly
defining a service within the module. Here we're defining a service around
the Indexer service interface (presumably also in the
org.example.myapp.services
package).
- The service's unqualified id (the part after the module id) is derived from
the method name.
- Here "build" was stripped off of "buildIndexer", leaving "Indexer". That's
the unqualified id.
- Prefixing with the module id results in the fully qualfied id
- org.example.myapp.services.Indexer.
+ The service's unique id is derived from the method name.
+ Here "build" was stripped off of "buildIndexer", leaving "Indexer". This id
is how
+ other services will refer to the Indexer service. Tapestry IoC is case
insensitive; later we can
+ refer to this service as "indexer" or "INDEXER" or any variation thereof,
and connect to
+ this service.
+
+ Service ids must be unique; if another module contributes a service with the
id "Indexer"
+ (or any case variation thereof) a runtime exception will occur when the
Registry is created.
We could extend this example by adding additional service builder methods,
or by showing
how to inject dependencies. See {{{service.html#Injecting Dependencies}the
service documentation}}
for more details.
-
-Overriding the Module id
-
- Adding an {{{apidocs/org/apache/tapestry/ioc/annotations/[EMAIL PROTECTED]
annnotation}}
- to the module builder class will control the module's id.
-
-+-----------------------------------------------------------------------------------+
-package org.example.myapp.services;
-
-import org.apache.tapestry.ioc.annotations.Id;
-
[EMAIL PROTECTED]("myapp")
-public class MyAppModule
-{
- public static Indexer buildIndexer()
- {
- return new IndexerImpl();
- }
-}
-+-----------------------------------------------------------------------------------+
-
- This time, the module's id is "myapp" and the service's id is
"myapp.Indexer".
-
- Remember that module ids must be unique, no other module builder class, even
one
- in a different package, may declare the id "myapp", or runtime warnings or
- errors will occur.
-
-{Caching Services}
+{Cacheing Services}
You will often find yourself in the position of injecting the same services
into your service builder or service decorator methods repeatedly. This can
be quite
@@ -90,6 +64,7 @@
public MyModule(
@Inject("service:JobScheduler")
JobScheduler scheduler,
+
@Inject("service:FileSystem")
FileSystem fileSystem)
{
@@ -115,15 +90,21 @@
In addition to injecting dependencies with the @InjectService and @Inject
annotations,
you may also inject a number of <module> resources:
-
- * java.lang.String: the module id
-
- * org.apache.commons.logging.Log: log for the module
+
+ * org.apache.commons.logging.Log: log for the module (derived from the
module's class name)
* {{{apidocs/org/apache/tapestry/ioc/ServiceLocator.html}ServiceLocator}}:
access to other services
[]
+ Note that the fields are final: this is important. Tapestry IoC is
thread-safe and you largely
+ never have to think about concurrency issues. But in a busy application,
different services may be
+ built by different threads simultaneously. Each module builder class is
instantiated at most once, and
+ making these fields final ensures that the values are available across
multiple threads.
+ Refer to Brian Goetz's {{{http://www.javaconcurrencyinpractice.com/}Java
Concurrency in Practice}}
+ for a more complete explantation of the relationship between final fields,
constructors, and threads ...
+ or just trust us!
+
Care should be taken with this approach: in some circustances, you may force
a situtation in which
the module constructor is dependent on itself. For example, if you invoke a
method on any injected services
defined within the same module from the module builder's constructor,
@@ -199,7 +180,6 @@
exactly as if they were identified in the manifest. For example:
+----+
[EMAIL PROTECTED]("tapestry.internal.services")
@SubModule(
{ InternalTransformModule.class })
public final class InternalModule
Modified:
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/order.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/order.apt?view=diff&rev=516817&r1=516816&r2=516817
==============================================================================
---
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/order.apt
(original)
+++
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/order.apt
Sat Mar 10 16:39:28 2007
@@ -34,8 +34,6 @@
Often a single contribution will have more than one constraint.
Constraint Types
-
- Constraint types can be "before" or "after".
Each constraint string begins with a prefix, "before:" or "after:", used to
identify the type of constraint.
@@ -52,15 +50,7 @@
appear at the start, or end, or both of the pattern, and will match zero or
more
characters there. Thus you can have patterns such as "Data*" or "*Logic" or
even "*User*".
- Patterns that do not contain a period ('.') character are <simple> patterns;
simple patterns
- only match within their own module. When a period does exist, it is the
seperator between
- the module id pattern and the service id pattern. When there is more than
one period, it is
- the <last> period that is the divider (which makes sense, as unqualified
service ids
- can't contain a period).
-
- Because a pattern with a period in it is really <two> patterns, you can
create patterns like
- "app.internal*.*Data". This matches services whose id ends with "Data"
inside modules whose id
- starts with "app.internal".
+ Matching is case insensitive.
Modified:
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/pipeline.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/pipeline.apt?view=diff&rev=516817&r1=516816&r2=516817
==============================================================================
---
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/pipeline.apt
(original)
+++
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/pipeline.apt
Sat Mar 10 16:39:28 2007
@@ -59,7 +59,7 @@
+-----+
The
-
{{{apidocs/org/apache/tapestry/ioc/services/PipelineBuilder.html}tapestry.ioc.PipelineBuilder}}
+
{{{apidocs/org/apache/tapestry/ioc/services/PipelineBuilder.html}PipelineBuilder}}
service is useful for constructing pipelines. The service is often injected
into a service builder method, along with an ordered configuration of
services.
@@ -73,7 +73,7 @@
+-----+
public static StringTransformService buildStringTransform(
- @InjectService("tapestry.ioc.PipelineBuilder")
+ @InjectService("PipelineBuilder")
PipelineBuilder builder,
List<StringTransformFilter> configuration,
Log serviceLog)
Modified:
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/provider.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/provider.apt?view=diff&rev=516817&r1=516816&r2=516817
==============================================================================
---
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/provider.apt
(original)
+++
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/provider.apt
Sat Mar 10 16:39:28 2007
@@ -17,25 +17,24 @@
understands the expression.
In practice, @InjectService("Foo") and @Inject("service:Foo") work
identically,
- even with regards to the relative visibility of
- private services. Here, the provider prefix is "service" and the expression
+ Here, the provider prefix is "service" and the expression
is "Foo".
* service provider
As outlined above, the service provider interprets the expression as
- a service id, either fully qualified or local.
+ a service id.
* infrastructure provider
The tapestry module (provided by the
{{{http://tapestry.apache.org/tapestry5/tapestry-core/}tapestry-core library}})
provides the
-
{{{http://tapestry.apache.org/tapestry5/tapestry-core/guide/infrastructure.html}infrastructure}}
object provider, which exists
- to provide shorter names for injecting services and to support overrides.
+
{{{http://tapestry.apache.org/tapestry5/tapestry-core/guide/infrastructure.html}infrastructure}}
object provider, which to allow
+ for various forms of overrides.
* default provider
If the string does not contain a prefix, then the value is treated as a
literal string.
- It will be coerced to the proper type (such as int or long).
+ It will be {{{coerce.html}coerced}} to the proper type (such as int or long).
Defining New Providers
@@ -47,8 +46,7 @@
Example:
+-----+
- @Contribution("tapestry.ioc.MasterObjectProvider")
- public void contributeMyProvider(MappedConfiguration<String,ObjectProvider>
configuration)
+ public void
contributeMasterObjectProvider(MappedConfiguration<String,ObjectProvider>
configuration)
{
configuration.add("myprefix", new MyObjectProvider());
}
Modified:
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/service.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/service.apt?view=diff&rev=516817&r1=516816&r2=516817
==============================================================================
---
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/service.apt
(original)
+++
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/service.apt
Sat Mar 10 16:39:28 2007
@@ -20,7 +20,6 @@
import org.apache.tapestry.ioc.annotations.Id;
[EMAIL PROTECTED]("myapp")
public class MyAppModule
{
public static Indexer buildIndexer()
@@ -31,7 +30,7 @@
+-----------------------------------------------------------------------------------+
Here the service interface is Indexer (presumably inside the
org.example.myapp.services package,
- since there isn't an import). Tapestry doesn't know about the IndexerImpl
class (the
+ since there isn't an import). Tapestry IoC doesn't know about the
IndexerImpl class (the
service implementation of the Indexer service), but it does know
about the buildIndexer() method.
@@ -43,7 +42,9 @@
+-----------------------------------------------------------------------------------+
public static Indexer buildIndexer(@InjectService("JobScheduler")
- JobScheduler scheduler, @InjectService("FileSystem")
+ JobScheduler scheduler,
+
+ @InjectService("FileSystem")
FileSystem fileSystem)
{
IndexerImpl indexer = new IndexerImpl(fileSystem);
@@ -55,9 +56,8 @@
+-----------------------------------------------------------------------------------+
Here we've annotated the parameters of the service builder method to
identify what
- service to inject for that parameter. We used unqualified ids ... these are
the names
- of other services within the <same module>: there will be a
buildJobScheduler()
- and a buildFileSystem() service builder methods as well.
+ service to inject for that parameter. It doesn't matter in which module
+ these services are defined, and whether the service builder methods are
static or instance.
Note that we don't invoke those service builder methods ... we just
"advertise" that we need
the named services. Tapestry IoC will provide the necessary proxies and,
when we start to
@@ -65,9 +65,6 @@
interceptors and its dependencies, are ready to go. Again, this is done in a
thread-safe manner.
- If we used fully qualified service ids, such as
"org.examples.myapps.jobs.JobScheduler",
- then we can access services from some other module entirely.
-
If you find yourself injecting the same dependencies into multiple service
builder
(or service decorator) methods, you can
{{{module.html#Caching Services}cache dependency injections}} in your
module, by defining
@@ -97,17 +94,6 @@
}
+-----------------------------------------------------------------------------------+
-Defining Visibility
-
- Normally, a service can be referenced from any other module, simply by
providing a
- fully qualified service id.
-
- In some cases, it is desirable to mark a service a private, in which case,
it is only
- visible within the same module.
-
- The {{{apidocs/org/apache/tapestry/ioc/annotations/[EMAIL PROTECTED]
annotation}} can
- be attached to a service builder method to indicate that the service in
question is private.
-
Defining Service Lifecycle
Each service has a <lifecycle> that controls when the service implementation
is instantiated.
@@ -133,6 +119,12 @@
As the first method is invoked, the service builder method is invoked, then
any service
decorations occur. This construction process occurs only once.
+ You should be aware when writing services that your code must be thread
safe; any service
+ you define could be invoked simulataneously by multiple threads. This is
rarely an issue
+ in practice, since most services take input, use local variables, and invoke
methods on other services,
+ without making use of non-final instance variables. The few instance
variables
+ in a service implementation are usually references to other Tapestry IoC
services.
+
* perthread
The perthread service lifecycle exists primarily to help multi-threaded
servlet applications,
@@ -189,7 +181,7 @@
In addition to injecting services, Tapestry will key off of the parameter
type to allow
other things to be injected.
- * java.lang.String: fully qualified service id for the service being created
+ * java.lang.String: unique id for the service
* org.apache.commons.logging.Log: to which service logging can occur
@@ -207,8 +199,12 @@
Example:
+-----------------------------------------------------------------------------------+
- public static Indexer buildIndexer(String serviceId, Log serviceLog,
@InjectService("JobScheduler")
- JobScheduler scheduler, @InjectService("FileSystem")
+ public static Indexer buildIndexer(String serviceId, Log serviceLog,
+
+ @InjectService("JobScheduler")
+ JobScheduler scheduler,
+
+ @InjectService("FileSystem")
FileSystem fileSystem)
{
IndexerImpl indexer = new IndexerImpl(serviceLog, fileSystem);
@@ -227,6 +223,9 @@
id of service dependencies is known at build time), it is easier
to use the @InjectService annotation.
+ The Log's name (used when configuring logging settings for the service)
consists of
+ the module class name and the service id seperated by a period, i.e.
"org.example.myapp.MyModule.Indexer".
+
Automatic Dependency Resolution
When injecting another service, you may choose to not provide the
@InjectService annotation.
@@ -235,12 +234,12 @@
from the parameter type). If it finds exactly one match, then the
corresponding service will be
injected.
- If it finds more than one match, that's an error.
+ If there are no matches, or multiple matches, then a runtime exception is
thrown.
Obviously, this is only useful when you can be sure that there's only one
service in the entire registry
that implements the service interface. When you are building a framework
for others to use, you should
not use this feature ... it's all too likely that some end-user application
will create a second service
- with the same implementation and break your injections.
+ with the same service interface and break your injections.
On the other hand, if you are using Tapestry IoC as part of an application,
then you can save yourself
a small amount of effort and maintenance by letting Tapestry automatically
identify dependencies.
@@ -269,18 +268,19 @@
in the
{{{apidocs/org/apache/tapestry/ioc/services/TapestryIOCModule.html}TapestryIOCModule}}
class.
-*----------------------------------+-----------------------------------------------------------------------------------------+
-| <<Service Id>> | <<Service Interface>>
|
-*----------------------------------+-----------------------------------------------------------------------------------------+
-| tapestry.ioc.ClassFactory |
{{{apidocs/org/apache/tapestry/ioc/services/ClassFactory.html}ClassFactory}}
|
-*----------------------------------+-----------------------------------------------------------------------------------------+
-| tapestry.ioc.LogSource |
{{{apidocs/org/apache/tapestry/ioc/LogSource.html}LogSource}}
|
-*----------------------------------+-----------------------------------------------------------------------------------------+
-| tapestry.ioc.RegistryShutdownHub |
{{{apidocs/org/apache/tapestry/ioc/RegistryShutdownHub.html}RegistryShutdownHub}}
|
-*----------------------------------+-----------------------------------------------------------------------------------------+
-| tapestry.ioc.ThreadCleanupHub |
{{{apidocs/org/apache/tapestry/ioc/services/ThreadCleanupHub.html}ThreadCleanupHub}}
|
-*----------------------------------+-----------------------------------------------------------------------------------------+
+*---------------------+-----------------------------------------------------------------------------------------+
+| <<Service Id>> | <<Service Interface>>
|
+*---------------------+-----------------------------------------------------------------------------------------+
+| ClassFactory |
{{{apidocs/org/apache/tapestry/ioc/services/ClassFactory.html}ClassFactory}}
|
+*---------------------+-----------------------------------------------------------------------------------------+
+| LogSource |
{{{apidocs/org/apache/tapestry/ioc/LogSource.html}LogSource}}
|
+*---------------------+-----------------------------------------------------------------------------------------+
+| RegistryShutdownHub |
{{{apidocs/org/apache/tapestry/ioc/RegistryShutdownHub.html}RegistryShutdownHub}}
|
+*---------------------+-----------------------------------------------------------------------------------------+
+| ThreadCleanupHub |
{{{apidocs/org/apache/tapestry/ioc/services/ThreadCleanupHub.html}ThreadCleanupHub}}
|
+*---------------------+-----------------------------------------------------------------------------------------+
+ Consult the JavaDoc for each of these services to identify under what
circumstances you'll need to use them.
Mutually Dependant Services
Modified:
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/strategy.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/strategy.apt?view=diff&rev=516817&r1=516816&r2=516817
==============================================================================
---
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/strategy.apt
(original)
+++
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/strategy.apt
Sat Mar 10 16:39:28 2007
@@ -17,7 +17,7 @@
As a special case, the value null is search for as if it was an instance of
the class void.
- The
{{{apidocs/org/apache/tapestry/ioc/services/StrategyBuilder.html}tapestry.ioc.StrategyBuilder}}
service creates a service implementation around a strategy registry.
+ The
{{{apidocs/org/apache/tapestry/ioc/services/StrategyBuilder.html}StrategyBuilder}}
service creates a service implementation around a strategy registry.
+---+
public interface StrategyBuilder
@@ -43,7 +43,7 @@
+---+
public static MyStrategyService buildMyStrategyService(Map<Class,
MyStrategyService> configuration,
- @InjectService("tapestry.ioc.StrategyBuilder")
+ @InjectService("StrategyBuilder")
StrategyBuilder builder)
{
StategyRegistry<MyStrategyService> registry =
StrategyRegistry.newInstance(MyStrategyService.class, configuration);
Modified:
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/symbols.apt
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/symbols.apt?view=diff&rev=516817&r1=516816&r2=516817
==============================================================================
---
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/symbols.apt
(original)
+++
tapestry/tapestry5/tapestry-ioc/branches/hlship-20070309-simplifyioc/src/site/apt/symbols.apt
Sat Mar 10 16:39:28 2007
@@ -18,16 +18,16 @@
For example:
+----+
- public static MyService buildMyService(@Inject("${mymodule.some-reference}")
CollaboratorA collabA,
- @InjectService("${mymodule.some-service-id}") CollaboratorB collabB)
+ public static MyService buildMyService(@Inject("${some-reference}")
CollaboratorA collabA,
+ @InjectService("${some-service-id}") CollaboratorB collabB)
{
return . . . ;
}
+---+
- Here, the first symbol is <<<mymodule.some-reference>>> whose value should
be an
+ Here, the first symbol is <<<some-reference>>> whose value should be an
{{{provider.html}object reference}} such as <<<service:CollaboratorA>>>.
The second symbol,
- <<<mymodule.some-service-id>>> is just a service id, such as
<<<CollaboratorB>>>.
+ <<<some-service-id>>> is just a service id, such as <<<CollaboratorB>>>.
Although not shown here, it is possible to use multple symbols inside the
string, or mix literal text with
symbols.
@@ -58,8 +58,7 @@
From the previous example:
+----+
- @Contribute("tapestry.ioc.ApplicationDefaults")
- public void contributeDefaults(MappedConfiguration<String, String>
configuration)
+ public void contributeApplicationDefaults(MappedConfiguration<String,
String> configuration)
{
configuration.add("mymodule.some-reference", "service:CollaboratorA");
configuration.add("mymodule.some-service-id", "CollaboratorB");
@@ -81,8 +80,7 @@
+----+
- @Contribute("tapestry.ioc.FactoryDefaults")
- public void contributeDefaults(MappedConfiguration<String, String>
configuration)
+ public void contributeFactoryDefaults(MappedConfiguration<String, String>
configuration)
{
configuration.add("report.url",
"http://${report.host}:${report.port}/${report.path}");
configuration.add("report.host", "www.myreportsite.com");
@@ -99,8 +97,7 @@
illegal:
+----+
- @Contribute("tapestry.ioc.ApplicationDefaults")
- public void contributeOverrides(MappedConfiguration<String, String>
configuration)
+ public void contributeApplicationDefaults(MappedConfiguration<String,
String> configuration)
{
configuration.add("report.path", "${report.url}/report.cgi");
}