Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

Wiki Markup
{scrollbar}

Service Configurations

This is an area of Tapestry IoC that is often least well understood. Tapestry services often must have some configuration to fine tune exactly what they do. One of the interactions between modules is that these service configurations are shared: they may be contributed into by any module.

...

One of Tapestry's features is the ability to package assets (images, style sheets, javascript JavaScript libraries, etc.) inside JAR files and expose those to the client. For example, an application URL /assets/org/example/mylib/mylib.js would refer to a file, myllib.js, stored on the classpath in the /org/example/mylib folder.

...

Code Block
borderStylesolid

  public static void contributeResourceDigestGenerator(Configuration&lt;String&gt;Configuration<String> configuration)
  {
    configuration.add("class");
    configuration.add("tml");
  }

...

Code Block
borderStylesolid

public class MyAppModule
{
 public static void contributeResourceDigestGenerator(Configuration&lt;String&gt;Configuration<String> configuration)
 {
   configuration.add("pgp");
 }
}

...

Code Block
borderStylesolid

public class ResourceDigestGeneratorImpl implements ResourceDigestGenerator
{
  private final Set&lt;String&gt;Set<String> digestExtensions;

  public ResourceDigestGeneratorImpl(Collection&lt;String&gt;Collection<String> configuration)
  {
      digestExtensions = new HashSet&lt;String&gt;HashSet<String>(configuration);
  }

  . . .
}

...

These kinds of unordered configurations are surprisingly rare in Tapestry (the only other notable one is for the TypeCoercer service). However, as you can see, setting up such a configuration is quite easy.

...

Code Block
borderStylesolid

public void contributeMasterDispatcher(OrderedConfiguration&lt;Dispatcher&gt;OrderedConfiguration<Dispatcher> configuration, . . .)
{
  // Looks for the root path and renders the start page

  configuration.add("RootPath", new RootPathDispatcher(. . .), "before:Asset");

  // This goes first because an asset to be streamed may have an file extension, such as
  // ".html", that will confuse the later dispatchers.

  configuration.add(
          "Asset",
          new AssetDispatcher(. . .),
          "before:PageRender");

  configuration.add("PageRender", new PageRenderDispatcher(. . .));

  configuration.add("ComponentAction", new ComponentActionDispatcher(. . .), "after:PageRender");
}

...

Code Block
borderStylesolid

  public static Dispatcher buildMasterDispatcher(List&lt;Dispatcher&gt;List<Dispatcher> configuration, ChainBuilder chainBuilder)
  {
    return chainBuilder.build(Dispatcher.class, configuration);
  }

...

Tapestry IoC's symbol mechanism allows configuration values to be defined and perhaps overridden, then provided to services via injection, using the @Value annotation.

The first step is to contribute values.

Code Block
borderStylesolid

  public static void contributeFactoryDefaults(MappedConfiguration&lt;StringMappedConfiguration<String, String&gt;String> configuration)
  {
    configuration.add(SymbolConstants.FILE_CHECK_INTERVAL, "1000"); // 1 second
    configuration.add(SymbolConstants.FILE_CHECK_UPDATE_TIMEOUT, "50"); // 50 milliseconds
    configuration.add(SymbolConstants.SUPPORTED_LOCALES, "en");
    configuration.add("tapestry.default-cookie-max-age", "604800"); // One week
    configuration.add("tapestry.start-page-name", "start");
    configuration.add("tapestry.scriptaculous", "classpath:${tapestry.scriptaculous.path}");
    configuration.add(
            "tapestry.scriptaculous.path",
            "org/apache/tapestry5/scriptaculous_1_7_1_beta_3");
    configuration.add("tapestry.jscalendar.path", "org/apache/tapestry5/jscalendar-1.0");
    configuration.add("tapestry.jscalendar", "classpath:${tapestry.jscalendar.path}");
  }

...

Mapped configurations don't have to be keyed on Strings (enums or Class are other common key types). When a mapped configuration is keyed on String, then a case-insensitive map is used.

Wiki Markup
{scrollbar}