Date: 2004-10-28T04:33:56
   Editor: ReinhardPoetz <[EMAIL PROTECTED]>
   Wiki: Cocoon Wiki
   Page: CocoonBlockBuilder
   URL: http://wiki.apache.org/cocoon/CocoonBlockBuilder

   Proposal for CocoonBlockBuilder

New Page:

=== Goal ===
Cocoon is a large beast as it integrates so many technologies. We did the first 
step by moving some parts of Cocoon into blocks. Still, it is not possible to 
develop a single block without having to care of all the other blocks.

I have been working on a proposal 
(http://svn.apache.org/repos/asf/cocoon/whiteboard/block-builder) that 
prototypes my ideas where we should move to with our build system.

My goals for the CocoonBlockBuilder are:

 * decouple core and block development
 * it should be possible to develop a single block
 * Have a small footprint in Eclipse (load only necessary libraries and sources)
 * drive the build from a block descriptor file
 * create Gump scripts based on block descriptor
 * gump makes sure that everything integrates well
 * Go towards ["Blocks"]
   * create a block descriptor that contains all necessary block infos 
(dependencies on other blocks, libraries)
   * separate public and private classes
 * two modes of deployment (both modes take care of sitemap, cocoon.xconf, 
logkit.xconf and roles update)
   * development deployment: web application uses compiled classes (via 
ParanoidCocoonServlet) and examples (without copying them around) --> "live 
editing"
   * production deployment: create a "valid" web application without external 
links
 * Enable current behaviour of a 
   * global build
   * a single Eclipse project for all
   * a webapp with all blocks

Please consider this as a proposal. I don't know build tools like Maven in 
depth so that I couldn't have prototyped my ideas like I've done it with Ant. 
For the first, let's talk about functionality and then about tools.

=== How to use it? ===
Checkout http(s)://svn.apache.org/repos/asf/cocoon/whiteboard/block-builder. 
Make sure, that block.build.properties and blockbuilder.properties are correct 
(which should work if you have the complete Cocoon SVN tree). Call "ant 
compile" at /test/blocks/myblock/trunk.

=== Directory structure ===
In order to explain what I have done, let's take a look at the file system:


{{{
cocoon
 |
 +--blocks
 |    |
 |    +--authentication-fw
 |        |
 |        +--trunk
 |        |   +--descriptor.xml
 |        |   +--build.xml
 |        |   +--legal [DIR]
 |        |   +--src
 |        |   |   +--java
 |        |   |       +--public
 |        |   |       +--private
 |        |   +--samples
 |        |    
 |        +--branches
 |
 +--trunk
 |    +--build.xml
 |    +--src
 |    |   +--java
 |    |       +--core
 |    |       +--public
 |    |       +--private
 |    +--samples
 |    +--lib
 |        +--core
 |        +--endorsed
 |        +--blocks
 +--branches
 +--tags     
}}}   

 * Blocks should move into its own place in SVN - as long as possible we only 
maintain trunk, if necessary (e.g. for XSP) branches too
 * each block has a descriptor (see below)
 * the java sources a separated into a public and a private section. We should 
move as much as possible into private
 * if a block depends on another block it can only use public classes/interfaces
 * in /trunk/lib there is a repository of all available libraries, rule is that 
a block ""has to"" use these libs (see block descriptor) if available, 
otherwise we end in jar versioning hell
 
=== Projekt descriptor ===
{{{
<?xml version="1.0" encoding="UTF-8"?>
<block id="http://apache.org/cocoon/autentication-fw/1.0";>
   
  <name>Autentication Framework</name>
  <author href="http://cocoon.apache.org";>Cocoon Community</author>
  <license href="http://www.apache.org/LICENSE-2.0/";>Apache Software License 
2.0</license>
   
  <requirements>
    <requires
      block="http://apache.org/cocoon/session-fw/1.0";
      name="session"
      />
  </requirements>
  
  <libraries>
    <lib id="avalon-framework-api" location="core"/>
    <lib id="avalon-framework-impl" location="core"/>
    <lib id="excalibur-xmlutil" location="core"/>        
    <lib id="excalibur-pool" location="core"/>
    <lib id="excalibur-sourceresolve" location="core"/>
  </libraries>
  
 </block>
}}}

The project descriptor gives global information of the block (name, author, 
...), the required blocks and and required libraries. Note that libraries are 
only references via their names and not their versions.

To make this useable, a small addition to our jars.xml is necessary:

{{{
<jars>
  <file id="util.concurrent">
    <title>Doug Lea's Concurrent Utilities</title>
    <description>
      The concurrency management primitives that will be the 
      foundation of JDK 1.5 concurrency management.
    </description>
    <used-by>Cocoon</used-by>
    <lib>core/util.concurrent-1.3.4.jar</lib>
    
<homepage>http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html</homepage>
  </file>
  ...
</jars>
}}}
Note the id attribute in the file element.


=== Build system and Ant tasks ===
The build system is based on the descriptor. It uses its information to resolve 
 all dependencies. Technically, the Ant script is generated via XSTL. This way, 
it can be reused in all blocks via Ant import statements. If necessary, for a 
block a certain build target can be overriden locally

{{{
<project default="compile" name="Build autentication-fw block">

    <property file="local.block.build.properties"/>
        <available file="${blockbuilder.root}" 
property="available.blockbuilder.root"/>
    <fail unless="available.blockbuilder.root" 
        message="Property blockbuilder.root has to be set!"/>
        
        <xslt in="descriptor.xml" 
                  out="build/temp/build-by-xslt.xml"
              
style="${blockbuilder.root}/targets/block-descriptor2ant-script.xsl">
        </xslt>
        
        <import file="build/temp/build-by-xslt.xml"/>
        
</project>

}}}

To make it run, the property blockbuilder.root has to be set.

Each block has its block.build.properties (e.g. for the authentication-fw 
block):

{{{
# ---- Paths -------------------------------------------------------------------

src.public=src/public
lib.dir=../../../trunk/lib

# ---- References --------------------------------------------------------------
root.core=../../../trunk
root.block.session=../../session-fw/trunk

}}}

As you can see, the directories for the sources, the library repository, cocoon 
core and the session block are specified. Using Ant mechanisms this properties 
can be overriden locally.

Currently following build targets for external use are available

==== compile ====
The block and all blocks it depends on and Cocoon core are compiled.

==== package ====
The block and all blocks it depends on and Cocoon core are packaged into single 
packages.

==== clean ====
The block and all blocks it depends on and Cocoon core build directories are 
deleted.

==== eclipse-project ====
An Eclipse project file is generated that only points to the necessary 
libraries. This target is based on an custom Ant task that creates a .classpath 
file for Eclipse resolving path information correctly (WARNING: currently only 
relative paths for core.root and block.xxx.root are working).


=== What's done so far? ===
 * compiling and packaging that resolves dependencies (snowball effect)
 * create the eclipse project for a single block that only loads the necessary 
libraries

=== Open issues ===
 * global tasks (compile, webapp, javadoc, ...)
 * create gump script
 * block deployment
 * What about referencing the classes directories instead of block libraries 
(ensures that development is done using the latest classes) AFAIK this is 
difficult (or at least buggy in Eclipse)
 * How much flexibility do we need? (strict directory structure, package names, 
...)
 * user libraries repository
 * splitting Cocoon core and the block sources in private and public parts

Reply via email to