You are viewing a plain text version of this content. The canonical link for it is here.
Posted to docs@cocoon.apache.org by do...@cocoon.apache.org on 2004/11/21 11:45:40 UTC

[Cocoon Wiki] New: BlockBuilder

   Date: 2004-11-21T02:45:40
   Editor: ReinhardPoetz <re...@apache.org>
   Wiki: Cocoon Wiki
   Page: BlockBuilder
   URL: http://wiki.apache.org/cocoon/BlockBuilder

   no comment

New Page:

Block centric build system - User documentation
----
Warning: The described features don't exist completly/at all yet. Consider this document as kind of specification from a users POV.
----
= Goals =

 * 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
 * Enable current behaviour of a 
   * global build
   * a single Eclipse project for all
   * a webapp with all blocks
 * Only rely on Apache Ant. Additional functionality is implemented in custom tasks.


= Building a single block =

== Block descriptor ==
{{{
<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"/>
    <lib id="junit" location="core" type="dev"/>
  </libraries>
  
 </block>
}}}

A block is described in an XML file. {{{name}}}, {{{autor}}} and {{{license}}} are self-explanatory. The {{{requirements}}} element contain all block this block requires. Make sure that the name (e.g. "session") is the same as the name used in block properties (e.g. "root.block.session").

The libraries element contains all Java libraries this block needs to compile. The attribute {{{id}}} contains the unique id used in the library declaration file. The attribute {{{location}}} indicates the libarary repository, e.g. "core" points to the repository set in "lib.dir" in block.build.properties. If you want to add a custom library repository, e.g. "myrep" you have to set the property "lib.dir.myrep" and point to the library file. If the attribute {{{type}}} contains the value "dev" this library is only used during development. An prominent example is JUnit which doesn't need to be part of the block distribution (.COB).


== configure a block ==
A block has to be configured, especially the locations of other blocks and of Cocoon core have to be set. Central configuration file is {{{block.build.properties}}}:

{{{
root.core=../../../trunk
root.block.session=../../session-fw/trunk
}}}

With these properties the root directories of Cocoon core and the block "session" are set. This is necessary as they are required to build the block.

The build system considers a local.block.build.properties file so a developer can override the values at his local machine.

It's also possible to set the parameter {{{project.global.build.properties}}} when calling Ant setting global properties like compiler settings. This is usefull if more than one block is deployed in shell or Ant scripts:

{{{
ant -Dproject.global.build.properties=../project.global.build.properties
}}}

This is the content of {{{global.properties}}} that can be overriden with {{{project.global.properties}}} or {{{local.global.properties}}}:

{{{
---- Compiler -----------------------
compiler=modern
compiler.debug=on
compiler.optimize=on
compiler.deprecation=off
compiler.nowarn=on
source.vm=1.3
target.vm=1.3
}}}

== Recursive building ==
The block building system resolves dependencies and calls the build scripts of blocks the current block depends on (snowball effect). Make sure, that any circular dependencies are declared because this would end in endless loops.

== Compile a block ==
{{{
ant compile
}}}

This compiles the block and resolves all dependencies by compiling those blocks before (snowball effect).

Currently I'm thinking of providing shell/command-line scripts instead of direct Ant calls. This would clean the project specific build files because transforming the block descriptor could be transformed into a build script in the background. The drawback would be that calling the build targets from within Eclipse wouldn't work any more ...

Currently the minimum content of a build script is:

{{{
<!-- build a block -->
<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>
}}}

== package a block ==
Works analog to compile but the target name is "package".

== clean up ==
Works analog to compile but the target name is "clean".

== create a COB ==
Depends on the package target and creates the .COB for this block.

== create the gump project descriptor ==
Auto-generate the gump project descriptor for this block.

{{{
ant gump-project
}}}

== create the eclipse project descriptor ==
Auto-generate the eclipse-project descrtiptor:

{{{
ant eclipse-project
}}}

== add or override Ant targets to the block build file ==
The build script is generated automatically using XSLT. This XSLT takes the project descriptor as source. This generated script is included into the build.xml of the block. This way it is simple to override a task because if the task is available in the main and in the included build script, the task of the main script is taken.

It is also possible to use some kind of "interception mechanism" because every task tries to call a before-* or after-* target:

{{{
<target name="after-compile">
  <!-- to someting after compiling this block -->	
</target>
}}}

Overriden the target "after" breaks the interception unless in the custom implementation before-* and after-* are called.

= Building Cocoon core =
Cocoon core is the root for all blocks and tasks that have a Cocoon core dependency rely on a couple of tasks in the Cocoon core build script:

 * compile
 * package
 * clean
 * empty-webapp

= How does a Cocoon distribution look like? =
A Cocoon distribution contains Cocoon core and a set of blocks that are developed under the umbrella of the Apache Cocoon project.

The user who wants to run Cocoon, unzips Cocoon and gets

 * Cocoon core JAR packages
 * Clean web-application containing a minimum Cocoon
 * a set of COB files that contain blocks developed under the umbrella of Apache Cocoon
 * Cocoon docs (documentation, javadocs)

If a user wants to install Cocoon, he takes the clean web-application and deployes it into his favoirte Servlet container. Then he can use the CocoonBlockDeployer to install all blocks he requires.

== Building a Cocoon distribution ==
??? Is adding blocks an automated task? Doesn't it depend on the lifecycle of a block ???

== Global build properties ==

To ensure that all blocks use the same properties (e.g. compiler settings), a properties file can be passed that is used in all projects.

== A single Eclipse project file for a group of blocks ==
This is supported by a special Ant task that is configured with the root directories of all blocks that should be part of this global Eclipse project. I doubt whether this makes sense after introducing RealBlocks ...