Author: vgritsenko Date: Thu Nov 11 06:36:01 2004 New Revision: 57433 Modified: cocoon/branches/BRANCH_2_1_X/gump.xml cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/java/org/apache/cocoon/samples/castor/TestBeanAction.java cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/java/org/apache/cocoon/transformation/CastorTransformer.java cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/castor/castor-mappings/test-mapping.xml cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/castor/castor-mappings/test-mapping_de.xml cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/castor/sitemap.xmap cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/castor/test.xml cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/scratchpad-samples.xml cocoon/branches/BRANCH_2_1_X/status.xml Log: Scratchpad block: Restored CastorTransformer support for context beans, restored bean lookup logic, fixed sample.
Modified: cocoon/branches/BRANCH_2_1_X/gump.xml ============================================================================== --- cocoon/branches/BRANCH_2_1_X/gump.xml (original) +++ cocoon/branches/BRANCH_2_1_X/gump.xml Thu Nov 11 06:36:01 2004 @@ -152,12 +152,10 @@ <depend project="commons-betwixt"/> <depend project="jakarta-velocity"/> <depend project="jakarta-servletapi-4"/> - <depend project="cocoon-block-velocity"/> - <depend project="cocoon-block-cron"/> + <depend project="cocoon-block-axis"/> <depend project="cocoon-block-batik" type="samples"/> + <depend project="cocoon-block-cron"/> <depend project="cocoon-block-xsp"/> - <depend project="cocoon-block-faces"/> - <depend project="cocoon-block-axis"/> <depend project="apache-garbage"/> <library name="servlet-2_3" bundle="false"/> @@ -165,6 +163,8 @@ <library name="castor"/> <library name="commons-jexl"/> <library name="commons-betwixt"/> + <library name="commons-beanutils"/> + <library name="commons-digester"/> <library name="apache-garbage"/> <work nested="tools/anttasks"/> Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/java/org/apache/cocoon/samples/castor/TestBeanAction.java ============================================================================== --- cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/java/org/apache/cocoon/samples/castor/TestBeanAction.java (original) +++ cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/java/org/apache/cocoon/samples/castor/TestBeanAction.java Thu Nov 11 06:36:01 2004 @@ -1,12 +1,12 @@ /* * Copyright 1999-2004 The Apache Software Foundation. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -29,28 +29,28 @@ /** * - * @version CVS $Id: TestBeanAction.java,v 1.3 2004/03/05 10:07:26 bdelacretaz Exp $ + * @version CVS $Id$ */ public class TestBeanAction extends AbstractAction { - public TestBeanAction() { - } - - public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String src, Parameters param) throws java.lang.Exception { - Request request = ObjectModelHelper.getRequest(objectModel); - Context context = ObjectModelHelper.getContext(objectModel); - if(context != null) - request.setAttribute("Wale",new TestBean("Wale in the big sea","context")); - - Session session =request.getSession(true); - session.setAttribute("Mouse",new TestBean("Liveing in the session","session")); - objectModel.put("Lion", new TestBean("Lion:walking on the sitemap","sitemap") ); - request.setAttribute("Hamster",new TestBean("Hamster:Wer hat nach mir gefragt","request") ); - session.setAttribute("Elefant",new TestBean("Elefant:from Africa","session")); - request.setAttribute("Elefant",new TestBean("Elefant:from India","request")); - + public TestBeanAction() { + } - return objectModel; + public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String src, Parameters param) + throws Exception { + Request request = ObjectModelHelper.getRequest(objectModel); + Context context = ObjectModelHelper.getContext(objectModel); + if (context != null) { + context.setAttribute("Wale",new TestBean("Wale in the big sea", "context")); + } + + Session session =request.getSession(true); + session.setAttribute("Mouse",new TestBean("Liveing in the session","session")); + objectModel.put("Lion", new TestBean("Lion:walking on the sitemap","sitemap") ); + request.setAttribute("Hamster",new TestBean("Hamster:Wer hat nach mir gefragt","request") ); + session.setAttribute("Elefant",new TestBean("Elefant:from Africa","session")); + request.setAttribute("Elefant",new TestBean("Elefant:from India","request")); - } + return objectModel; + } } Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/java/org/apache/cocoon/transformation/CastorTransformer.java ============================================================================== --- cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/java/org/apache/cocoon/transformation/CastorTransformer.java (original) +++ cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/java/org/apache/cocoon/transformation/CastorTransformer.java Thu Nov 11 06:36:01 2004 @@ -1,12 +1,12 @@ /* * Copyright 1999-2004 The Apache Software Foundation. - * + * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,14 +20,15 @@ import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.framework.parameters.Parameters; +import org.apache.cocoon.ProcessingException; +import org.apache.cocoon.environment.Context; +import org.apache.cocoon.environment.ObjectModelHelper; import org.apache.cocoon.environment.Request; import org.apache.cocoon.environment.Session; import org.apache.cocoon.environment.SourceResolver; -import org.apache.cocoon.environment.ObjectModelHelper; import org.apache.cocoon.xml.IncludeXMLConsumer; -import org.apache.cocoon.ProcessingException; -import org.apache.excalibur.source.Source; +import org.apache.excalibur.source.Source; import org.exolab.castor.mapping.Mapping; import org.exolab.castor.mapping.MappingException; import org.exolab.castor.xml.Marshaller; @@ -35,22 +36,23 @@ import org.exolab.castor.xml.Unmarshaller; import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; -import org.xml.sax.SAXException; import org.xml.sax.InputSource; +import org.xml.sax.SAXException; import java.io.IOException; -import java.util.HashMap; -import java.util.Map; import java.util.Collection; +import java.util.HashMap; import java.util.Iterator; +import java.util.Map; /** * Castor transformer marshals a object from the Sitemap, Session, Request or * the Conext into a series of SAX events. * - * Configuation: The CastorTransformer needs to be configured with a + * <h3>Configuation</h3> + * <p>The CastorTransformer needs to be configured with a * default mapping. This mapping is used as long as no other mapping - * is specified as the element. + * is specified as the element.</p> * *<pre> * <map:transformer name="CastorTransformer" src="org.apache.cocoon.transformation.CastorTransformer"> @@ -58,35 +60,37 @@ * </map:transformer> *</pre> * - * A sample for the use: + * <p>Sample usage:</p> * <pre> - * <root xmlns:castor="http://apache.org/cocoon/castor/1.0"> - * <castor:marshall name="invoice"/> - * <castor:unmarshall name="product" scope="sitemap" mapping="castor/specicalmapping.xml"/> - * </root> + * <root xmlns:castor="http://apache.org/cocoon/castor/1.0"> + * <castor:marshal name="invoice"/> + * <castor:unmarshal name="product" scope="sitemap" mapping="castor/specicalmapping.xml"/> + * </root> * </pre> - * The CastorTransfomer supports two elements - * <code>castor:unmarshal</code> and <code>castor:marshal</code>. * - * The marshal element is replaced with the marshalled object. + * <p>The CastorTransfomer supports two elements + * <code>castor:unmarshal</code> and <code>castor:marshal</code>.</p> + * + * <p>The marshal element is replaced with the marshaled object. * The Object given through the attrbute <code>name</code> * will be searched in the <code>sitemap, request, session</code> and at * least in <code>application</code> If the scope is explicitly given, e.g , * the object will ge located only here. The Attribute <code>mapping</code> * specifys the mapping to be used. The attribute <code>command</code> specifies a class that - * implements CastorMarshalCommand and will be called before and after marshalling. + * implements CastorMarshalCommand and will be called before and after marshaling.</p> * - * The elements within the unmarshal element will be sent to the castor unmarshaller - * the resulting java object with be placed in the object specified by name and scope (see also marshall element). + * <p>The elements within the unmarshal element will be sent to the castor unmarshaller + * the resulting java object with be placed in the object specified by name and scope (see also marshal element). * The <code>command</code> attribute specifies the class that implements CastorUnmarshalCommand - * and will be called before and after unmarshalling. + * and will be called before and after unmarshaling.</p> * * @author <a href="mailto:[EMAIL PROTECTED]">Thorsten Mauch</a> * @author <a href="mailto:[EMAIL PROTECTED]">Vadim Gritsenko</a> * @author <a href="mailto:[EMAIL PROTECTED]">Michael Homeijer</a> - * @version CVS $Id: CastorTransformer.java,v 1.8 2004/05/08 01:34:06 joerg Exp $ + * @version CVS $Id$ */ public class CastorTransformer extends AbstractTransformer implements Configurable { + private static final String CASTOR_URI = "http://apache.org/cocoon/castor/1.0"; private static final String CMD_UNMARSHAL = "unmarshal"; @@ -96,13 +100,14 @@ private final static String SCOPE_SITEMAP = "sitemap"; private final static String SCOPE_SESSION = "session"; private final static String SCOPE_REQUEST = "request"; + private final static String SCOPE_CONTEXT = "context"; private final static String ATTRIB_MAPPING = "mapping"; - // Stores all used mappings in the static cache + // FIXME Use Store for mappings cache instead of HashMap private static HashMap mappings; /** The map of namespace prefixes. */ - private Map prefixMap = new HashMap(); + private Map prefixMap; private Unmarshaller unmarshaller; private UnmarshalHandler unmarshalHandler; @@ -116,7 +121,7 @@ private String defaultMappingName; private Mapping defaultMapping; - private boolean in_castor_element = false; + private boolean in_castor_element; public void configure(Configuration conf) throws ConfigurationException { @@ -124,9 +129,11 @@ } public void setup(SourceResolver resolver, Map objectModel, String src, Parameters params) - throws ProcessingException, SAXException, IOException { + throws ProcessingException, SAXException, IOException { this.objectModel = objectModel; this.resolver = resolver; + this.prefixMap = new HashMap(); + this.in_castor_element = false; if (defaultMappingName != null) { try { @@ -137,16 +144,30 @@ } } + public void recycle() { + this.prefixMap = null; + this.unmarshaller = null; + this.unmarshalHandler = null; + this.unmarshalContentHandler = null; + this.beanName = null; + this.beanScope = null; + this.objectModel = null; + this.resolver = null; + this.defaultMappingName = null; + this.defaultMapping = null; + super.recycle(); + } + public void endElement(String uri, String name, String raw) throws SAXException { if (CASTOR_URI.equals(uri)) { in_castor_element = false; } else if (unmarshalContentHandler != null) { - // check if this marks the end of the unmarshalling + // check if this marks the end of the unmarshaling if ((CASTOR_URI.equals(uri)) && (CMD_UNMARSHAL.equals(name))) { - // End marshalling, remove prefixes + // End marshaling, remove prefixes Iterator itt = prefixMap.entrySet().iterator(); - while ( itt.hasNext() ) { + while (itt.hasNext()) { Map.Entry entry = (Map.Entry) itt.next(); unmarshalContentHandler.endPrefixMapping((String)entry.getKey()); } @@ -167,7 +188,8 @@ } } - public void startElement(String uri, String name, String raw, Attributes attr) throws SAXException { + public void startElement(String uri, String name, String raw, Attributes attr) + throws SAXException { if (CASTOR_URI.equals(uri)) { in_castor_element= true; process (name, attr); @@ -184,7 +206,6 @@ private void process (String command, Attributes attr) throws SAXException { if (command.equals(CMD_MARSHAL)) { - String scope = attr.getValue(ATTRIB_SCOPE); String name = attr.getValue(ATTRIB_NAME); String mapping = attr.getValue(ATTRIB_MAPPING); @@ -199,12 +220,12 @@ beanName = attr.getValue(ATTRIB_NAME); if (beanScope == null) { - getLogger().error("Destination for unmarshalled bean not set"); + getLogger().error("Destination for unmarshaled bean not set"); return; } if (beanName == null) { - getLogger().error("Name of unmarshalled bean not set"); + getLogger().error("Name of unmarshaled bean not set"); return; } String mappingpath = attr.getValue(ATTRIB_MAPPING); @@ -278,7 +299,7 @@ getLogger().warn("Unable to load mapping " + mappingpath, e); } - Object bean = this.searchBean(objectModel, name, scope); + Object bean = findBean(objectModel, name, scope); if (bean instanceof Collection) { Iterator i = ((Collection)bean).iterator(); @@ -294,34 +315,52 @@ } /** - * Find the bean that should be marshalled by the transformer + * Find the bean that should be marshaled by the transformer * * @param objectModel The Cocoon objectmodel * @param name The name of the bean * @param scope The source specification of the bean REQUEST/SESSION etc. * @return The bean that was found */ - private Object searchBean(Map objectModel, String name, String scope) { + private Object findBean(Map objectModel, String name, String scope) { + Object bean = null; Request request = ObjectModelHelper.getRequest(objectModel); - // search all maps for the given bean - if ((scope == null) || SCOPE_SITEMAP.equals(scope)) { - return objectModel.get(name); - } - - if ((scope == null) || SCOPE_REQUEST.equals(scope)) { - return request.getAttribute(name); - } - - if ((scope == null) || SCOPE_SESSION.equals(scope)) { + if (scope == null) { + // Search for bean in (1) objectModel, (2) request, (3) session, and (4) context. + bean = objectModel.get(name); + if (bean == null) { + bean = request.getAttribute(name); + } + if (bean == null) { + Session session = request.getSession(false); + if (session != null) { + bean = session.getAttribute(name); + } + } + if (bean == null) { + Context context = ObjectModelHelper.getContext(objectModel); + if (context != null) { + bean = context.getAttribute(name); + } + } + } else if (SCOPE_SITEMAP.equals(scope)) { + bean = objectModel.get(name); + } else if (SCOPE_REQUEST.equals(scope)) { + bean = request.getAttribute(name); + } if (SCOPE_SESSION.equals(scope)) { Session session = request.getSession(false); - if (session != null) { - return session.getAttribute(name); + bean = session.getAttribute(name); + } + } else if (SCOPE_CONTEXT.equals(scope)) { + Context context = ObjectModelHelper.getContext(objectModel); + if (context != null) { + bean = context.getAttribute(name); } } - return null; + return bean; } private void storeBean(Map objectModel, String name, String scope, Object bean) { @@ -332,9 +371,7 @@ } else if (SCOPE_REQUEST.equals(scope)) { request.setAttribute(name, bean); } else if (SCOPE_SESSION.equals(scope)) { - Session session = request.getSession(true); - - session.setAttribute(name, bean); + request.getSession(true).setAttribute(name, bean); } } Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/castor/castor-mappings/test-mapping.xml ============================================================================== --- cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/castor/castor-mappings/test-mapping.xml (original) +++ cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/castor/castor-mappings/test-mapping.xml Thu Nov 11 06:36:01 2004 @@ -14,16 +14,17 @@ See the License for the specific language governing permissions and limitations under the License. --> + <mapping> - <class name="org.apache.cocoon.samples.castor.TestBean"> - <map-to xml="animal"/> - - <field name="name" type="java.lang.String"> - <bind-xml name="name" node="element"/> - </field> - - <field name="scope" type="java.lang.String"> - <bind-xml name="scope" node="element"/> - </field> - </class> + <class name="org.apache.cocoon.samples.castor.TestBean"> + <map-to xml="animal"/> + + <field name="name" type="java.lang.String"> + <bind-xml name="name" node="element"/> + </field> + + <field name="scope" type="java.lang.String"> + <bind-xml name="scope" node="element"/> + </field> + </class> </mapping> Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/castor/castor-mappings/test-mapping_de.xml ============================================================================== --- cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/castor/castor-mappings/test-mapping_de.xml (original) +++ cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/castor/castor-mappings/test-mapping_de.xml Thu Nov 11 06:36:01 2004 @@ -14,16 +14,17 @@ See the License for the specific language governing permissions and limitations under the License. --> + <mapping> - <class name="org.apache.cocoon.samples.castor.TestBean"> - <map-to xml="Tier"/> - - <field name="name" type="java.lang.String"> - <bind-xml name="Name" node="element"/> - </field> - - <field name="scope" type="java.lang.String"> - <bind-xml name="Herkunft" node="element"/> - </field> - </class> + <class name="org.apache.cocoon.samples.castor.TestBean"> + <map-to xml="Tier"/> + + <field name="name" type="java.lang.String"> + <bind-xml name="Name" node="element"/> + </field> + + <field name="scope" type="java.lang.String"> + <bind-xml name="Herkunft" node="element"/> + </field> + </class> </mapping> Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/castor/sitemap.xmap ============================================================================== --- cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/castor/sitemap.xmap (original) +++ cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/castor/sitemap.xmap Thu Nov 11 06:36:01 2004 @@ -32,14 +32,10 @@ <!-- =========================== Pipelines ================================= --> <map:pipelines> <map:pipeline> - <map:match pattern="*"> - <map:act type="TestBeanAction"/> - <map:generate src="test.xml"/> - <map:transform type="castor"/> - <map:serialize/> - </map:match> + <map:act type="TestBeanAction"/> + <map:generate src="test.xml"/> + <map:transform type="castor"/> + <map:serialize type="xml"/> </map:pipeline> </map:pipelines> </map:sitemap> - -<!-- End of File --> Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/castor/test.xml ============================================================================== --- cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/castor/test.xml (original) +++ cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/castor/test.xml Thu Nov 11 06:36:01 2004 @@ -14,11 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. --> -<zoo xmlns:castor="http://castor.exolab.org/cocoontransfomer"> - <castor:InsertBean name="Mouse"/> - <castor:InsertBean name="Lion"/> - <castor:InsertBean name="Hamster" mapping="castor-mappings/test-mapping_de.xml"/> - <castor:InsertBean name="Wale"/> - <castor:InsertBean name="Elefant" scope="session"/> - <castor:InsertBean name="Elefant" scope="request"/> + +<zoo xmlns:castor="http://apache.org/cocoon/castor/1.0"> + <castor:marshal name="Mouse"/> + <castor:marshal name="Lion"/> + <castor:marshal name="Hamster" mapping="castor-mappings/test-mapping_de.xml"/> + <castor:marshal name="Wale"/> + <castor:marshal name="Elefant" scope="session"/> + <castor:marshal name="Elefant" scope="request"/> </zoo> Modified: cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/scratchpad-samples.xml ============================================================================== --- cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/scratchpad-samples.xml (original) +++ cocoon/branches/BRANCH_2_1_X/src/blocks/scratchpad/samples/scratchpad-samples.xml Thu Nov 11 06:36:01 2004 @@ -86,7 +86,7 @@ Remote service returns an xsd string that is mapped to a Javascript string.<br/> (use: http://www.boyzoid.com/comp/randomQuote.cfc?wsdl) </sample> - <sample name="Morgage rate" href="flow-webservices/mortgageIndexWebService"> + <sample name="Mortgage rate" href="flow-webservices/mortgageIndexWebService"> Remote service returns an xsd complex type that is mapped to a Javascript object.<br/> (use: http://www.webservicex.net/MortgageIndex.asmx?WSDL) </sample> Modified: cocoon/branches/BRANCH_2_1_X/status.xml ============================================================================== --- cocoon/branches/BRANCH_2_1_X/status.xml (original) +++ cocoon/branches/BRANCH_2_1_X/status.xml Thu Nov 11 06:36:01 2004 @@ -197,42 +197,49 @@ </actions> </todo> + <changes> <release version="@version@" date="@date@"> + <action dev="VG" type="fix"> + Scratchpad block: Restored CastorTransformer support for context beans, + restored bean lookup logic, fixed sample. + </action> <action dev="SW" type="fix"> - The CocoonBean now creates its own private logger hierarchy, thus avoiding to pollute the CocoonServlet - hierarchy when called in that context (e.g. when generating a static site from a CMS) + The CocoonBean now creates its own private logger hierarchy, thus avoiding to + pollute the CocoonServlet hierarchy when called in that context (e.g. when + generating a static site from a CMS) </action> - <action dev="GP" type="add"> - Added replacement for Excalibur Event package in org.apache.cocoon.components.thread and migrated most - classes using their own threads to that package + Added replacement for Excalibur Event package in + org.apache.cocoon.components.thread and migrated most classes using their own + threads to that package </action> - <action dev="AG" type="update"> Updated antlr to 2.7.4, db-ojb to 1.0.1 </action> <action dev="TC" type="fix" fixes-bug="31297" due-to="Nikolaus Rath" due-to-email="[EMAIL PROTECTED]"> - Javaflow: also support inherited methods + Javaflow block: also support inherited methods </action> <action dev="TC" type="add"> - Javaflow: ported back parameter support from trunk + Javaflow block: ported back parameter support from trunk </action> <action dev="SW" type="add"> - CForms: added widget states. All widgets can now have an "active" (default), "disabled" or "invisible" + CForms block: added widget states. All widgets can now have an "active" (default), "disabled" or "invisible" state. Updated the stylesheets accordingly to use HTML's disabled inputs. </action> <action dev="AG" type="fix" fixes-bug="29945" due-to="Christoph Gaffga" due-to-email="[EMAIL PROTECTED]"> - BetwixtTransformer: removed deprecation warning with latest betwixt + Scratchpad block: BetwixtTransformer: removed deprecation warning with + latest betwixt </action> <action dev="SW" type="fix" fixes-bug="25951"> - Flowscript: enforce the explicit declaration of variables in the global scope (attached to the session). - This avoids the implicit declaration of variables in the global scope when the 'var' keyword is missing, - which leads to weird bugs difficult to track down, especially with continuations. + Flowscript: enforce the explicit declaration of variables in the global + scope (attached to the session). This avoids the implicit declaration of + variables in the global scope when the 'var' keyword is missing, which + leads to weird bugs difficult to track down, especially with continuations. </action> <action dev="ATC" type="update"> Deprecated the PHP block since the PHP servlet the generator depends on - never worked properly. Explicitly excluded the PHP block from blocks.properties. + never worked properly. Explicitly excluded the PHP block from blocks.properties. </action> <action dev="VG" type="fix" fixes-bug="27176" due-to="Guillaume Deflache" due-to-email="[EMAIL PROTECTED]"> XSP Block: Add space="strip" attribute support for <xsp:page>