Thorsten Scherler wrote:

I do not like this expression 'programming in xml' it is more (like I
stated in other threads) 'configuring components with xml'.

the crucial question will be where to draw the boundaries.

This code should help *user* easily change the output of forrest. In the
end this code should be produced by tools.
...and btw I would like to see such clear intuitive configuration and
separation in lenya and not a parameter overkilled framework that allows
user to extend the framework if they *exactly* follow the *not easy* to
understand boundaries and rules of the framework where you can do
everything you want as long it is the lenya way.

what you are proposing as an alternative is a domain-specific language (DSL). i don't think that is any easier than java, especially considering that you lose all the nice autocomplete, javadocs, refactoring, testing etc features that have sprung up around java. it's not the fault of the language if you use vi to write java when there are better alternatives available.

*User* want to have a configuration file (or better (in the future) a
tool where they can create such a file) to alter the behavior of their
application. They do not want to learn cocoon/java to alter the default
behavior. You have worked on PostNuke, you should know that for
yourself, as a user you do not want to learn php. ;-)

if you have a tool, you don't need a DSL :) the effort spent on coming up with a DSL could alternatively be spent on creating wizards for common functionality, like 'create new publication' in the lenya case.

speaking of postnuke, that was a total disaster, totally unmaintainable code. take a look at xaraya (and it's history), it's a rewrite that avoids the problems postnuke has.

The goal is that a normal user do not have to understand much of
programming (nor cocoon or java) but rather can configure forrest in an
easy intuitive way to customize it the way they want. The view e.g.
should be created by a webdesigner that have *no* knowledge of
programming at all.

why not use CSS?

Devs on the other hand want an easy to understand and clear defined
interface where they can plugin new components.

are you suggesting that it is easier to learn and use a DSL than to use java? i don't buy that, sorry. the DSL is just a layer of indirection, the real implementation (at least in lenya, dunno about forrest) will be java classes anyway, so why not try to have a sensible API rather than hide it behind a bunch of xml?

i like xml as much as anyone, but there are limits (see below for a case where the limit has been violated in a drastic way)

Search the ml for view;view helper;leather;...

cool, will do.


...or do you *really* consider <logic:filter value="dirCut" parameter="p">
  <forrest:view format="inx" />
</logic:filter>
<logic:filter value="actorCut" parameter="p">
  <forrest:view format="inx" />
</logic:filter>
as programming???

if the expressive power of that XML is not severely restricted, then yes.

see http://ant.apache.org/ant2/features.html, heading "Simple Flow-Control" for a similar argument.

cocoon moved away from having logic in the sitemap, and lenya 1.4 has removed all the logic in XSP and other XML places, because XSP turned out to be brittle: you don't get compile errors if a XSP has calls to an API that has been removed.

i just refactored a cocoon app that has a 4000 line sitemap. below is a sample of how things looked before the refactoring. this experience is the reason why i am asking these questions.

i will try to find your RT to better understand what you have in mind.

best,

-gregor

                <map:resource name="submitApproved">
                        <map:select type="parameter">
<map:parameter name="parameter-selector-test" value="{cct-package:/deliveryMethod}"/>
                                
                                <map:when test="email"> 
                                        <map:act type="resource-load" 
src="cocoon:/letter.submission">
                                                <map:parameter name="write-to" 
value="session"/>
                                                <map:parameter name="attribute-name" 
value="packageQueue.package"/>
                                                <map:select type="parameter">
<map:parameter name="parameter-selector-test" value="{cct-package:/lsttestmode}"/>
                                                        <map:when test="">      
                                                                <map:act 
type="jmsSender">
                                                                        <map:parameter 
name="packageID" value="{cct-package:/id}"/>
<map:parameter name="srcPattern" value="cocoon:/letter.*.*.archive"/> <map:parameter name="appendSrcPattern" value="cocoon:/letter.*.*.email"/> <map:parameter name="ccRecipients" value="{cct-package:count(/recipient/advisor)}"/> <map:parameter name="requiredRecipients" value="{cct-package:count(/requiredRecipients/requiredRecipient)}"/>
                                                                        <map:act 
type="sendmail">
                                                                                <map:parameter 
name="from"        value="@EMAIL_REPLYTO@"/>
<map:parameter name="to" value="{cct-package:/recipient/email}"/> <map:parameter name="cc" value="{cct-package-concat:/recipient/advisor/email | /copies-to/copy-to/email}"/> <map:parameter name="requiredRecipients" value="{cct-package:count(/requiredRecipients/requiredRecipient)}"/>
                                                                                <map:parameter 
name="subject"     value="@EMAIL_SUBJECT@"/>
<map:parameter name="src" value="cocoon:/letter.*.*.email"/>
                                                                                <map:parameter 
name="srcMimeType"            value="text/html"/>
<map:parameter name="inlineparts" value="cocoon:/letter.*.*.email.txt cocoon:/letter.*.*.email"/> <map:parameter name="inlinepartsMimeType" value="text/plain text/html"/>
                                                                                <map:parameter 
name="subtype" value="alternative"/>
                                                                                <map:act 
type="dbms-emailPackage">
<map:parameter name="table-set" value="EmailPackage{../../../../fromInstance}"/>
                                                                                        
<map:call resource="processUnlockPackage">
                                                                                                
<map:parameter name="unlock" value="{../../../../../unlock}"/>
<map:parameter name="actionType" value="{../../../../actionType}"/>
                                                                                                
<map:parameter name="redirect" value="showConfPage"/>
                                                                                      
  </map:call>
                                                                                
</map:act>
                                                                                <map:call 
resource="processUnlockPackage">
                                                                                        <map:parameter 
name="unlock" value="{../../../../unlock}"/>
<map:parameter name="redirect" value="cocoon:/emailPackage.error"/>
                                                                                
</map:call>
                                                                        
</map:act>
                                                                        <map:call 
resource="processUnlockPackage">
                                                                                <map:parameter 
name="unlock" value="{../../../unlock}"/>
                                                                                <map:parameter 
name="redirect" value="cocoon:/emailLetter.error"/>
                                                                        
</map:call>
                                                                </map:act>
                                                        </map:when>             
                  
                                                        <map:otherwise>
                                                                <map:act 
type="jmsSenderTest">
                                                                        <map:parameter 
name="packageID" value="{cct-package:/id}"/>
<map:parameter name="srcPattern" value="cocoon:/letter.*.*.archive"/> <map:parameter name="appendSrcPattern" value="cocoon:/letter.*.*.email"/> <map:parameter name="ccRecipients" value="{cct-package:count(/recipient/advisor)}"/> <map:parameter name="requiredRecipients" value="{cct-package:count(/requiredRecipients/requiredRecipient)}"/>
                                                                        <map:act 
type="sendmail">
                                                                                <map:parameter 
name="from"        value="@EMAIL_REPLYTO@"/>
<map:parameter name="to" value="{cct-package:/recipient/email}"/> <map:parameter name="cc" value="{cct-package-concat:/recipient/advisor/email | /copies-to/copy-to/email}"/> <map:parameter name="requiredRecipients" value="{cct-package:count(/requiredRecipients/requiredRecipient)}"/>
                                                                                <map:parameter 
name="subject"     value="@EMAIL_SUBJECT@"/>
<map:parameter name="src" value="cocoon:/letter.*.*.email"/>
                                                                                <map:parameter 
name="srcMimeType"            value="text/html"/>
<map:parameter name="inlineparts" value="cocoon:/letter.*.*.email.txt cocoon:/letter.*.*.email"/> <map:parameter name="inlinepartsMimeType" value="text/plain text/html"/>
                                                                                <map:parameter 
name="subtype" value="alternative"/>
                                                                                <map:act 
type="dbms-emailPackage">
<map:parameter name="table-set" value="EmailPackage{../../../../fromInstance}"/>
                                                                                        
<map:call resource="processUnlockPackage">
                                                                                                
<map:parameter name="unlock" value="{../../../../../unlock}"/>
<map:parameter name="actionType" value="{../../../../actionType}"/>
                                                                                                
<map:parameter name="redirect" value="showConfPage"/>
                                                                                      
  </map:call>
                                                                                
</map:act>
                                                                                <map:call 
resource="processUnlockPackage">
                                                                                        <map:parameter 
name="unlock" value="{../../../../unlock}"/>
<map:parameter name="redirect" value="cocoon:/emailPackage.error"/>
                                                                                
</map:call>
                                                                        
</map:act>
                                                                        <map:call 
resource="processUnlockPackage">
                                                                                <map:parameter 
name="unlock" value="{../../../unlock}"/>
                                                                                <map:parameter 
name="redirect" value="cocoon:/emailLetter.error"/>
                                                                        
</map:call>
                                                                </map:act>
                                                        </map:otherwise>        
                  
                                                </map:select>
                                                
                                                <map:call 
resource="processUnlockPackage">
                                                        <map:parameter name="unlock" 
value="{../../unlock}"/>
<map:parameter name="redirect" value="cocoon:/onDemandArchive.error"/>
                                                </map:call>
                                        </map:act>
                                        <map:call 
resource="processUnlockPackage">
                                                <map:parameter name="unlock" 
value="{../unlock}"/>
<map:parameter name="redirect" value="cocoon:/generateSubmission.error"/>
                                        </map:call>
                                </map:when>
                                
                                <map:when test="local"> 
                                        <map:act type="resource-load" 
src="cocoon:/letter.submission">
                                                <map:parameter name="write-to" 
value="session"/>
                                                <map:parameter name="attribute-name" 
value="packageQueue.package"/>
                                                <map:select type="parameter">
<map:parameter name="parameter-selector-test" value="{cct-package:/lsttestmode}"/>
                                                        <map:when test="">      
                                                                <map:act 
type="jmsSender">
                                                                        <map:parameter 
name="packageID" value="{cct-package:/id}"/>
<map:parameter name="srcPattern" value="cocoon:/letter.*.*.archive"/> <map:parameter name="appendSrcPattern" value="cocoon:/letter.*.*.view.ondemand"/> <map:parameter name="ccRecipients" value="{cct-package:count(/recipient/advisor)}"/> <map:parameter name="requiredRecipients" value="{cct-package:count(/requiredRecipients/requiredRecipient)}"/>
                                                                        <map:act 
type="dbms-printLocalPackage">
<map:parameter name="table-set" value="PrintLocalPackage{../../../fromInstance}"/>
                                                                                
<map:redirect-to uri="cctUserIndex.html"/>
                                                                        
</map:act>
                                                                        <map:redirect-to 
uri="cocoon:/printLocalPackage.error"/>
                                                                </map:act>
                                                        </map:when>             
                  
                                                        <map:otherwise>
                                                                <map:act 
type="jmsSenderTest">
                                                                        <map:parameter 
name="packageID" value="{cct-package:/id}"/>
<map:parameter name="srcPattern" value="cocoon:/letter.*.*.archive"/> <map:parameter name="appendSrcPattern" value="cocoon:/letter.*.*.view.ondemand"/> <map:parameter name="ccRecipients" value="{cct-package:count(/recipient/advisor)}"/> <map:parameter name="requiredRecipients" value="{cct-package:count(/requiredRecipients/requiredRecipient)}"/>
                                                                        <map:act 
type="dbms-printLocalPackage">
<map:parameter name="table-set" value="PrintLocalPackage{../../../fromInstance}"/>
                                                                                
<map:redirect-to uri="cctUserIndex.html"/>
                                                                        
</map:act>
                                                                        <map:redirect-to 
uri="cocoon:/printLocalPackage.error"/>
                                                                </map:act>
                                                        </map:otherwise>        
                  
                                                </map:select>
                                                <map:redirect-to 
uri="cocoon:/onDemandArchive.error"/>
                                        </map:act>
                                        <map:redirect-to 
uri="cocoon:/generateSubmission.error"/>
                                </map:when>
                                
                                <map:when test="central">       
                                        <map:act type="resource-load" 
src="cocoon:/letter.submission">
                                                <map:parameter name="write-to" 
value="session"/>
                                                <map:parameter name="attribute-name" 
value="packageQueue.package"/>
                                                
<!-- Determine if we should queue this package or render/send it immediately -->
                                                <map:select type="parameter">
<map:parameter name="parameter-selector-test" value="{cct-package:/sendAfter}{cct-package:/sendBefore}"/>
                                                        <map:when test="">      
                                                                <map:act 
type="set">
                                                                        <map:parameter 
name="write-to" value="request"/>
                                                                        <map:parameter 
name="attribute-name" value="QueuePackage"/>
                                                                        <map:parameter 
name="attribute-value" value="false"/>
                                                                </map:act>
                                                        </map:when>
                                                        <map:otherwise>
                                                                <map:select 
type="parameter">
<map:parameter name="parameter-selector-test" value="{request-param:/RenderImmediately}"/>
                                                                        <map:when 
test="true">  
                                                                                <map:act 
type="set">
                                                                                        <map:parameter 
name="write-to" value="request"/>
                                                                                        <map:parameter 
name="attribute-name" value="QueuePackage"/>
                                                                                        <map:parameter 
name="attribute-value" value="false"/>
                                                                                
</map:act>
                                                                        
</map:when>
                                                                        
<map:otherwise>
                                                                                <map:act 
type="set">
                                                                                        <map:parameter 
name="write-to" value="request"/>
                                                                                        <map:parameter 
name="attribute-name" value="QueuePackage"/>
                                                                                        <map:parameter 
name="attribute-value" value="true"/>
                                                                                
</map:act>
                                                                        
</map:otherwise>
                                                                </map:select>   
          
                                                        </map:otherwise>
                                                </map:select>
                                                
                                                <map:select type="parameter">
<map:parameter name="parameter-selector-test" value="{request-attr:QueuePackage}"/> <!-- Should we queue instead of render/send immediately? -->
                                                        <map:when test="false"> 
                                                                <!-- Render/Send 
Immediately -->
                                                                <map:select 
type="parameter">
<map:parameter name="parameter-selector-test" value="{cct-package:/lsttestmode}"/>
                                                                        <map:when 
test="">      
                                                                                <map:act 
type="jmsSender">
                                                                                        <map:parameter 
name="packageID" value="{cct-package:/id}"/>
<map:parameter name="srcPattern" value="cocoon:/letter.*.*.archive"/> <map:parameter name="appendSrcPattern" value="cocoon:/letter.*.*.view.ondemand"/> <map:parameter name="ccRecipients" value="{cct-package:count(/recipient/advisor)}"/> <map:parameter name="requiredRecipients" value="{cct-package:count(/requiredRecipients/requiredRecipient)}"/>
                                                                                        
<map:act type="centralPrintCopy">
                                                                                                
<map:parameter name="packageID" value="{cct-package:/id}"/>
<map:parameter name="srcPattern" value="cocoon:/letter.*.*.print"/> <map:parameter name="ccRecipients" value="{cct-package:count(/recipient/advisor)}"/> <map:parameter name="requiredRecipients" value="{cct-package:count(/requiredRecipients/requiredRecipient)}"/> <map:parameter name="lst_test_mode" value="{request-param:lst_test_mode}"/>
                                                                                                
<map:act type="dbms-printCentralPackage">
<map:parameter name="table-set" value="PrintCentralPackage{../../../../fromInstance}"/>
                                                                                                
        <map:call resource="processUnlockPackage">
                                                                                                          
      <map:parameter name="unlock" value="{../../../../../unlock}"/>
<map:parameter name="actionType" value="{../../../../../actionType}"/>
                                                                                                          
      <map:parameter name="redirect" value="showConfPage"/>
                                                                                      
                  </map:call>
                                                                                      
          </map:act>
                                                                                                
<map:call resource="processUnlockPackage">
                                                                                                        
<map:parameter name="unlock" value="{../../../../unlock}"/>
<map:parameter name="redirect" value="cocoon:/printCentralPackage.error"/>
                                                                                      
          </map:call>
                                                                                      
  </map:act>
                                                                                        
<map:call resource="processUnlockPackage">
                                                                                                
<map:parameter name="unlock" value="{../../../unlock}"/>
<map:parameter name="redirect" value="cocoon:/printCentralLetter.error"/>
                                                                                      
  </map:call>
                                                                                
</map:act>
                                                                        
</map:when>                               
                                                                        
<map:otherwise>                                                           
                                                                                <map:act 
type="jmsSenderTest">
                                                                                        <map:parameter 
name="packageID" value="{cct-package:/id}"/>
<map:parameter name="srcPattern" value="cocoon:/letter.*.*.archive"/> <map:parameter name="appendSrcPattern" value="cocoon:/letter.*.*.view.ondemand"/> <map:parameter name="ccRecipients" value="{cct-package:count(/recipient/advisor)}"/> <map:parameter name="requiredRecipients" value="{cct-package:count(/requiredRecipients/requiredRecipient)}"/>
                                                                                        
<map:act type="centralPrintCopy">
                                                                                                
<map:parameter name="packageID" value="{cct-package:/id}"/>
<map:parameter name="srcPattern" value="cocoon:/letter.*.*.print"/> <map:parameter name="ccRecipients" value="{cct-package:count(/recipient/advisor)}"/> <map:parameter name="requiredRecipients" value="{cct-package:count(/requiredRecipients/requiredRecipient)}"/> <map:parameter name="lst_test_mode" value="{request-param:lst_test_mode}"/>
                                                                                                
<map:act type="dbms-printCentralPackage">
<map:parameter name="table-set" value="PrintCentralPackage{../../../../fromInstance}"/>
                                                                                                
        <map:call resource="processUnlockPackage">
                                                                                                          
      <map:parameter name="unlock" value="{../../../../../unlock}"/>
<map:parameter name="actionType" value="{../../../../../actionType}"/>
                                                                                                          
      <map:parameter name="redirect" value="showConfPage"/>
                                                                                      
                  </map:call>
                                                                                      
          </map:act>
                                                                                                
<map:call resource="processUnlockPackage">
                                                                                                        
<map:parameter name="unlock" value="{../../../../unlock}"/>
<map:parameter name="redirect" value="cocoon:/printCentralPackage.error"/>
                                                                                      
          </map:call>
                                                                                      
  </map:act>
                                                                                        
<map:call resource="processUnlockPackage">
                                                                                                
<map:parameter name="unlock" value="{../../../unlock}"/>
<map:parameter name="redirect" value="cocoon:/printCentralLetter.error"/>
                                                                                      
  </map:call>
                                                                                
</map:act>
                                                                        
</map:otherwise>                          
                                                                </map:select>   
                                                                                      
                                    
                                                                <map:call 
resource="processUnlockPackage">
                                                                        <map:parameter 
name="unlock" value="{../../unlock}"/>
<map:parameter name="redirect" value="cocoon:/onDemandArchive.error"/>
                                                                </map:call>
                                                        </map:when>       
                                                        
                                                        <map:otherwise>
                                                                <!-- Queue the 
Central Print Package instead -->
                                                                
                                                                <map:act 
type="dbms-queueCentralPackage">
<map:parameter name="table-set" value="QueueCentralPackage{../../fromInstance}"/>
                                                                        <map:call 
resource="processUnlockPackage">
                                                                                <map:parameter 
name="unlock" value="{../../../unlock}"/>
<map:parameter name="actionType" value="{../../../actionType}"/>
                                                                                <map:parameter 
name="redirect" value="showConfPage"/>
                                                                        
</map:call>
                                                                </map:act>
                                                                <map:call 
resource="processUnlockPackage">
                                                                        <map:parameter 
name="unlock" value="{../../unlock}"/>
<map:parameter name="redirect" value="cocoon:/queueCentralPackage.error"/>
                                                                </map:call>
                                                        </map:otherwise>  
                                                </map:select>     
                                                
                                        </map:act>                
                                        <map:call 
resource="processUnlockPackage">
                                                <map:parameter name="unlock" 
value="{../unlock}"/>
<map:parameter name="redirect" value="cocoon:/generateSubmission.error"/>
                                        </map:call>
                                </map:when>
                                
                                <map:otherwise>
<map:redirect-to uri="cocoon:/invalidDeliveryMethodForSubmission.error"/>
                                </map:otherwise>
                        </map:select>
                </map:resource>


Reply via email to