You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2005/03/29 15:35:43 UTC
cvs commit: jakarta-tapestry/framework/src/java/org/apache/tapestry/util PageRenderSupportImpl.java
hlship 2005/03/29 05:35:42
Modified: framework/src/java/org/apache/tapestry IRequestCycle.java
TapestryMessages.java TapestryStrings2.properties
IScript.java IScriptProcessor.java
framework/src/java/org/apache/tapestry/html Body.jwc
Rollover.java Body.java Script.java
contrib/src/java/org/apache/tapestry/contrib/inspector
InspectorButton.java
framework/src/java/org/apache/tapestry/asset
ClasspathAssetFactory.java PrivateAsset.java
framework/src/java/org/apache/tapestry/valid
BaseValidator.java ValidField.java
eclipse Tapestry-Workbench.launch
framework/src/scripts TestLinkRenderers.xml
TestValidFieldNoBody.xml
framework/src/java/org/apache/tapestry/link
AbstractLinkComponent.java
framework/src/descriptor/META-INF tapestry.asset.xml
contrib/src/java/org/apache/tapestry/contrib/palette
Palette.java
framework/src/java/org/apache/tapestry/form DatePicker.java
Form.java LinkSubmit.java FormStrings.properties
FormMessages.java
Added: framework/src/java/org/apache/tapestry
PageRenderSupport.java TapestryUtils.java
framework/src/test/org/apache/tapestry
TestTapestryUtils.java
framework/src/test/org/apache/tapestry/util
TestPageRenderSupport.java
framework/src/java/org/apache/tapestry/util
PageRenderSupportImpl.java
Log:
Factor out much of the behavior of the Body component as a new interface (PageRenderSupport) and implementation, so that it can be reused seperately.
Revision Changes Path
1.14 +2 -1 jakarta-tapestry/framework/src/java/org/apache/tapestry/IRequestCycle.java
Index: IRequestCycle.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/IRequestCycle.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- IRequestCycle.java 27 Mar 2005 17:42:23 -0000 1.13
+++ IRequestCycle.java 29 Mar 2005 13:35:42 -0000 1.14
@@ -105,7 +105,8 @@
* request cycle, that page is returned. Otherwise, the engine's page loader is used to load the
* page.
*
- * @throws PageNotFoundException if the page does not exist.
+ * @throws PageNotFoundException
+ * if the page does not exist.
* @see org.apache.tapestry.engine.IPageSource#getPage(IRequestCycle, String, IMonitor)
*/
1.9 +13 -3 jakarta-tapestry/framework/src/java/org/apache/tapestry/TapestryMessages.java
Index: TapestryMessages.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/TapestryMessages.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- TapestryMessages.java 24 Mar 2005 16:50:15 -0000 1.8
+++ TapestryMessages.java 29 Mar 2005 13:35:42 -0000 1.9
@@ -25,19 +25,29 @@
private static final MessageFormatter _formatter = new MessageFormatter(TapestryMessages.class,
"TapestryStrings2");
- public static String servletInitFailure(Throwable cause)
+ static String servletInitFailure(Throwable cause)
{
return _formatter.format("servlet-init-failure", cause);
}
- public static String componentIsLocked(IComponent component)
+ static String componentIsLocked(IComponent component)
{
return _formatter.format("component-is-locked", component.getExtendedId());
}
- public static String servletInit(String name, long elapsedToRegistry, long elapsedOverall)
+ static String servletInit(String name, long elapsedToRegistry, long elapsedOverall)
{
return _formatter.format("servlet-init", name, new Long(elapsedToRegistry), new Long(
elapsedOverall));
}
+
+ static String nonUniqueAttribute(Object newInstance, String key, Object existingInstance)
+ {
+ return _formatter.format("non-unique-attribute", newInstance, key, existingInstance);
+ }
+
+ public static String noPageRenderSupport()
+ {
+ return _formatter.getMessage("no-page-render-support");
+ }
}
\ No newline at end of file
1.8 +2 -0 jakarta-tapestry/framework/src/java/org/apache/tapestry/TapestryStrings2.properties
Index: TapestryStrings2.properties
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/TapestryStrings2.properties,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- TapestryStrings2.properties 24 Mar 2005 16:50:15 -0000 1.7
+++ TapestryStrings2.properties 29 Mar 2005 13:35:42 -0000 1.8
@@ -16,3 +16,5 @@
servlet-init-failure=Unable to initialize application servlet: {0}
no-accessor=Component {0} does not have accessor methods for property {1}.
component-is-locked=Component {0} is active and its configuration state may not be changed.
+non-unique-attribute=Unable to store {0} into request cycle as attribute ''{1}'' because existing object {2} has already been stored. This usually indicates that components are improperly nested.
+no-page-render-support=No PageRenderSupport object has been stored into the request cycle. This object is typically provided by a Body component. You should add a Body component to your template.
\ No newline at end of file
1.4 +1 -1 jakarta-tapestry/framework/src/java/org/apache/tapestry/IScript.java
Index: IScript.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/IScript.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- IScript.java 6 Jan 2005 02:17:12 -0000 1.3
+++ IScript.java 29 Mar 2005 13:35:42 -0000 1.4
@@ -48,7 +48,7 @@
* @param symbols Map of input symbols; execution of the script may modify the map,
* creating new output symbols
*
- * @see org.apache.tapestry.html.Body#get(IRequestCycle)
+ * @see TapestryUtils#getPageRenderSupport(IRequestCycle, Object)
*
*/
1.4 +32 -34 jakarta-tapestry/framework/src/java/org/apache/tapestry/IScriptProcessor.java
Index: IScriptProcessor.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/IScriptProcessor.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- IScriptProcessor.java 6 Jan 2005 02:17:12 -0000 1.3
+++ IScriptProcessor.java 29 Mar 2005 13:35:42 -0000 1.4
@@ -17,9 +17,8 @@
import org.apache.hivemind.Resource;
/**
- * Defines methods needed by a {@link org.apache.tapestry.IScript} to
- * execute.
- *
+ * Defines methods needed by a {@link org.apache.tapestry.IScript}to execute.
+ *
* @author Howard Lewis Ship
* @since 3.0
* @see org.apache.tapestry.html.Body
@@ -27,34 +26,33 @@
public interface IScriptProcessor
{
- /**
- * Adds scripting code to the main body. During the render, multiple scripts may
- * render multiple bodies; all are concatinated together to form
- * a single block.
- */
-
- public void addBodyScript(String script);
-
- /**
- * Adds initialization script. Initialization script is executed once, when
- * the containing page loads. Effectively, this means that initialization script
- * is stored inside the HTML <body> element's <code>onload</code>
- * event handler.
- */
- public void addInitializationScript(String script);
-
- /**
- * Adds an external script. The processor is expected to ensure
- * that external scripts are only loaded a single time per page.
- */
-
- public void addExternalScript(Resource resource);
-
- /**
- * Ensures that the given string is unique. The string
- * is either returned unchanged, or a suffix is appended to
- * ensure uniqueness.
- */
-
- public String getUniqueString(String baseValue);
-}
+ /**
+ * Adds scripting code to the main body. During the render, multiple scripts may render multiple
+ * bodies; all are concatinated together to form a single block. The
+ * {@link org.apache.tapestry.html.Body} component will write the body script contents
+ * just inside the <code><body></code> tag.
+ */
+
+ public void addBodyScript(String script);
+
+ /**
+ * Adds initialization script. Initialization script is executed once, when the containing page
+ * loads. Initialization script content is written only after all HTML content that could be
+ * referenced from the script (in effect, just before the <code></body> tag).
+ */
+ public void addInitializationScript(String script);
+
+ /**
+ * Adds an external script. The processor is expected to ensure that external scripts are only
+ * loaded a single time per page.
+ */
+
+ public void addExternalScript(Resource resource);
+
+ /**
+ * Ensures that the given string is unique. The string is either returned unchanged, or a suffix
+ * is appended to ensure uniqueness.
+ */
+
+ public String getUniqueString(String baseValue);
+}
\ No newline at end of file
1.1 jakarta-tapestry/framework/src/java/org/apache/tapestry/PageRenderSupport.java
Index: PageRenderSupport.java
===================================================================
// Copyright 2005 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.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry;
/**
* Extends {@link org.apache.tapestry.IScriptProcessor} with a handful of additional methods
* needed when rendering a page response.
*
* @author Howard M. Lewis Ship
* @since 3.1
* @see org.apache.tapestry.html.Body
* @see org.apache.tapestry.TapestryUtils#getPageRenderSupport(IRequestCycle, Object)
*/
public interface PageRenderSupport extends IScriptProcessor
{
/**
* Sets up the given URL to preload, and returns a reference to the loaded image, in the form of
* a snippet of JavaScript expression that can be inserted into some larger block of JavaScript
* as a function parameter, or as a property assignment. A typical return value might be
* <code>tapestry_preload[7].src</code>.
*/
public String getPreloadedImageReference(String url);
}
1.1 jakarta-tapestry/framework/src/java/org/apache/tapestry/TapestryUtils.java
Index: TapestryUtils.java
===================================================================
// Copyright 2005 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.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.HiveMind;
import org.apache.hivemind.util.Defense;
/**
* Constants and static methods.
*
* @author Howard M. Lewis Ship
* @since 3.1
*/
public class TapestryUtils
{
/**
* Stores an attribute into the request cycle, verifying that no object with that key is already
* present.
*
* @param cycle
* the cycle to store the attribute into
* @param key
* the key to store the attribute as
* @param object
* the attribute value to store
* @throws IllegalStateException
* if a non-null value has been stored into the cycle with the provided key.
*/
public static void storeUniqueAttribute(IRequestCycle cycle, String key, Object object)
{
Defense.notNull(cycle, "cycle");
Defense.notNull(key, "key");
Defense.notNull(object, "object");
Object existing = cycle.getAttribute(key);
if (existing != null)
throw new IllegalStateException(TapestryMessages.nonUniqueAttribute(
object,
key,
existing));
cycle.setAttribute(key, object);
}
static final String PAGE_RENDER_SUPPORT_ATTRIBUTE = "org.apache.tapestry.PageRenderSupport";
/**
* Stores the support object using {@link #storeUniqueAttribute(IRequestCycle, String, Object)}.
*/
public static void storeRenderPageSupport(IRequestCycle cycle, PageRenderSupport support)
{
storeUniqueAttribute(cycle, PAGE_RENDER_SUPPORT_ATTRIBUTE, support);
}
/**
* Gets the previously stored {@link org.apache.tapestry.PageRenderSupport}object.
*
* @param cycle
* the request cycle storing the support object
* @param caller
* the caller of this method (used in exception messages)
* @throws ApplicationRuntimeException
* if no support object has been stored
*/
public static PageRenderSupport getPageRenderSupport(IRequestCycle cycle, Object caller)
{
Defense.notNull(cycle, "cycle");
PageRenderSupport result = (PageRenderSupport) cycle
.getAttribute(PAGE_RENDER_SUPPORT_ATTRIBUTE);
if (result == null)
throw new ApplicationRuntimeException(TapestryMessages.noPageRenderSupport(), HiveMind
.getLocation(caller), null);
return result;
}
public static void removePageRenderSupport(IRequestCycle cycle)
{
cycle.removeAttribute(PAGE_RENDER_SUPPORT_ATTRIBUTE);
}
/**
* Returns the {@link PageRenderSupport} object if previously stored, or null otherwise.
* This is used in the rare case that a component wishes to adjust its behavior based on whether
* the page render support services are avaiable (typically, adjust for whether enclosed by a
* Body component, or not).
*/
public static PageRenderSupport getOptionalPageRenderSupport(IRequestCycle cycle)
{
return (PageRenderSupport) cycle.getAttribute(PAGE_RENDER_SUPPORT_ATTRIBUTE);
}
}
1.4 +2 -0 jakarta-tapestry/framework/src/java/org/apache/tapestry/html/Body.jwc
Index: Body.jwc
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/html/Body.jwc,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Body.jwc 27 Jan 2005 05:43:13 -0000 1.3
+++ Body.jwc 29 Mar 2005 13:35:42 -0000 1.4
@@ -33,5 +33,7 @@
</parameter>
<reserved-parameter name="onload"/>
+
+ <inject property="assetService" object="engine-service:asset"/>
</component-specification>
1.4 +25 -42 jakarta-tapestry/framework/src/java/org/apache/tapestry/html/Rollover.java
Index: Rollover.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/html/Rollover.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Rollover.java 5 Jan 2005 23:17:22 -0000 1.3
+++ Rollover.java 29 Mar 2005 13:35:42 -0000 1.4
@@ -25,33 +25,30 @@
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.IScript;
+import org.apache.tapestry.PageRenderSupport;
import org.apache.tapestry.Tapestry;
+import org.apache.tapestry.TapestryUtils;
import org.apache.tapestry.components.ILinkComponent;
import org.apache.tapestry.components.LinkEventType;
import org.apache.tapestry.engine.IScriptSource;
/**
- * Combines a link component (such as {@link org.apache.tapestry.link.DirectLink})
- * with an <img> and JavaScript code
- * to create a rollover effect that works with both Netscape Navigator and
- * Internet Explorer.
- *
- * [<a href="../../../../../ComponentReference/Rollover.html">Component Reference</a>]
- *
- *
- * @author Howard Lewis Ship
+ * Combines a link component (such as {@link org.apache.tapestry.link.DirectLink}) with an
+ * <img> and JavaScript code to create a rollover effect that works with both Netscape
+ * Navigator and Internet Explorer. [ <a
+ * href="../../../../../ComponentReference/Rollover.html">Component Reference </a>]
*
- **/
+ * @author Howard Lewis Ship
+ */
public abstract class Rollover extends AbstractComponent
{
private IScript _parsedScript;
/**
- * Converts an {@link IAsset} binding into a usable URL. Returns null
- * if the binding does not exist or the binding's value is null.
- *
- **/
+ * Converts an {@link IAsset}binding into a usable URL. Returns null if the binding does not
+ * exist or the binding's value is null.
+ */
protected String getAssetURL(IAsset asset, IRequestCycle cycle)
{
@@ -75,23 +72,14 @@
boolean dynamic = false;
String imageName = null;
- Body body = Body.get(cycle);
- if (body == null)
- throw new ApplicationRuntimeException(
- Tapestry.getMessage("Rollover.must-be-contained-by-body"),
- this,
- null,
- null);
+ PageRenderSupport pageRenderSupport = TapestryUtils.getPageRenderSupport(cycle, this);
- ILinkComponent serviceLink =
- (ILinkComponent) cycle.getAttribute(Tapestry.LINK_COMPONENT_ATTRIBUTE_NAME);
+ ILinkComponent serviceLink = (ILinkComponent) cycle
+ .getAttribute(Tapestry.LINK_COMPONENT_ATTRIBUTE_NAME);
if (serviceLink == null)
- throw new ApplicationRuntimeException(
- Tapestry.getMessage("Rollover.must-be-contained-by-link"),
- this,
- null,
- null);
+ throw new ApplicationRuntimeException(Tapestry
+ .getMessage("Rollover.must-be-contained-by-link"), this, null, null);
boolean linkDisabled = serviceLink.isDisabled();
@@ -128,7 +116,7 @@
if (blurURL == null)
blurURL = imageURL;
- imageName = writeScript(cycle, body, serviceLink, focusURL, blurURL);
+ imageName = writeScript(cycle, pageRenderSupport, serviceLink, focusURL, blurURL);
writer.attribute("name", imageName);
}
@@ -146,9 +134,8 @@
IEngine engine = getPage().getEngine();
IScriptSource source = engine.getScriptSource();
- Resource scriptLocation =
- getSpecification().getSpecificationLocation().getRelativeResource(
- "Rollover.script");
+ Resource scriptLocation = getSpecification().getSpecificationLocation()
+ .getRelativeResource("Rollover.script");
_parsedScript = source.getScript(scriptLocation);
}
@@ -156,16 +143,12 @@
return _parsedScript;
}
- private String writeScript(
- IRequestCycle cycle,
- Body body,
- ILinkComponent link,
- String focusURL,
- String blurURL)
+ private String writeScript(IRequestCycle cycle, PageRenderSupport pageRenderSupport,
+ ILinkComponent link, String focusURL, String blurURL)
{
- String imageName = body.getUniqueString(getId());
- String focusImageURL = body.getPreloadedImageReference(focusURL);
- String blurImageURL = body.getPreloadedImageReference(blurURL);
+ String imageName = pageRenderSupport.getUniqueString(getId());
+ String focusImageURL = pageRenderSupport.getPreloadedImageReference(focusURL);
+ String blurImageURL = pageRenderSupport.getPreloadedImageReference(blurURL);
Map symbols = new HashMap();
@@ -173,7 +156,7 @@
symbols.put("focusImageURL", focusImageURL);
symbols.put("blurImageURL", blurImageURL);
- getParsedScript().execute(cycle, body, symbols);
+ getParsedScript().execute(cycle, pageRenderSupport, symbols);
// Add attributes to the link to control mouse over/out.
// Because the script is written before the <body> tag,
1.6 +33 -224 jakarta-tapestry/framework/src/java/org/apache/tapestry/html/Body.java
Index: Body.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/html/Body.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Body.java 27 Jan 2005 14:20:45 -0000 1.5
+++ Body.java 29 Mar 2005 13:35:42 -0000 1.6
@@ -14,21 +14,14 @@
package org.apache.tapestry.html;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.hivemind.util.ClasspathResource;
-import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.Resource;
import org.apache.tapestry.AbstractComponent;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
-import org.apache.tapestry.IScriptProcessor;
-import org.apache.tapestry.Tapestry;
-import org.apache.tapestry.asset.PrivateAsset;
-import org.apache.tapestry.util.IdAllocator;
+import org.apache.tapestry.PageRenderSupport;
+import org.apache.tapestry.TapestryUtils;
+import org.apache.tapestry.engine.IEngineService;
+import org.apache.tapestry.util.PageRenderSupportImpl;
/**
* The body of a Tapestry page. This is used since it allows components on the page access to an
@@ -39,40 +32,9 @@
* @author Howard Lewis Ship
*/
-public abstract class Body extends AbstractComponent implements IScriptProcessor
+public abstract class Body extends AbstractComponent implements PageRenderSupport
{
- // Lines that belong inside the onLoad event handler for the <body> tag.
- private StringBuffer _initializationScript;
-
- // Any other scripting desired
-
- private StringBuffer _bodyScript;
-
- // Contains text lines related to image initializations
-
- private StringBuffer _imageInitializations;
-
- /**
- * Map of URLs to Strings (preloaded image references).
- */
-
- private Map _imageMap;
-
- /**
- * List of included scripts. Values are Strings.
- *
- * @since 1.0.5
- */
-
- private List _externalScripts;
-
- private IdAllocator _idAllocator;
-
- private static final String ATTRIBUTE_NAME = "org.apache.tapestry.active.Body";
-
- /**
- * Tracks a particular preloaded image.
- */
+ private PageRenderSupportImpl _pageRenderSupport;
/**
* Adds to the script an initialization for the named variable as an Image(), to the given URL.
@@ -85,33 +47,7 @@
public String getPreloadedImageReference(String URL)
{
- if (_imageMap == null)
- _imageMap = new HashMap();
-
- String reference = (String) _imageMap.get(URL);
-
- if (reference == null)
- {
- int count = _imageMap.size();
- String varName = "tapestry_preload[" + count + "]";
- reference = varName + ".src";
-
- if (_imageInitializations == null)
- _imageInitializations = new StringBuffer();
-
- _imageInitializations.append(" ");
- _imageInitializations.append(varName);
- _imageInitializations.append(" = new Image();\n");
- _imageInitializations.append(" ");
- _imageInitializations.append(reference);
- _imageInitializations.append(" = \"");
- _imageInitializations.append(URL);
- _imageInitializations.append("\";\n");
-
- _imageMap.put(URL, reference);
- }
-
- return reference;
+ return _pageRenderSupport.getPreloadedImageReference(URL);
}
/**
@@ -122,12 +58,7 @@
public void addInitializationScript(String script)
{
- if (_initializationScript == null)
- _initializationScript = new StringBuffer(script.length() + 1);
-
- _initializationScript.append(script);
- _initializationScript.append('\n');
-
+ _pageRenderSupport.addInitializationScript(script);
}
/**
@@ -149,10 +80,7 @@
public void addBodyScript(String script)
{
- if (_bodyScript == null)
- _bodyScript = new StringBuffer(script.length());
-
- _bodyScript.append(script);
+ _pageRenderSupport.addBodyScript(script);
}
/**
@@ -165,70 +93,34 @@
public void addExternalScript(Resource scriptLocation)
{
- if (_externalScripts == null)
- _externalScripts = new ArrayList();
-
- if (_externalScripts.contains(scriptLocation))
- return;
-
- // Alas, this won't give a good ILocation for the actual problem.
-
- if (!(scriptLocation instanceof ClasspathResource))
- throw new ApplicationRuntimeException(Tapestry.format(
- "Body.include-classpath-script-only",
- scriptLocation), this, null, null);
-
- // Record the URL so we don't include it twice.
-
- _externalScripts.add(scriptLocation);
- }
-
- /**
- * Writes <script> elements for all the external scripts.
- */
- private void writeExternalScripts(IMarkupWriter writer)
- {
- int count = Tapestry.size(_externalScripts);
- for (int i = 0; i < count; i++)
- {
- ClasspathResource scriptLocation = (ClasspathResource) _externalScripts.get(i);
-
- // This is still very awkward! Should move the code inside PrivateAsset somewhere
- // else, so that an asset does not have to be created to to build the URL.
- PrivateAsset asset = new PrivateAsset(scriptLocation, null);
- String url = asset.buildURL(getPage().getRequestCycle());
-
- // Note: important to use begin(), not beginEmpty(), because browser don't
- // interpret <script .../> properly.
-
- writer.begin("script");
- writer.attribute("language", "JavaScript");
- writer.attribute("type", "text/javascript");
- writer.attribute("src", url);
- writer.end();
- writer.println();
- }
-
+ _pageRenderSupport.addExternalScript(scriptLocation);
}
/**
* Retrieves the <code>Body</code> that was stored into the request cycle. This allows
* components wrapped by the <code>Body</code> to locate it and access the services it
* provides.
+ *
+ * @deprecated To be removed in 3.2. Use
+ * {@link org.apache.tapestry.TapestryUtils#getPageRenderSupport(IRequestCycle)}
+ * instead.
*/
public static Body get(IRequestCycle cycle)
{
- return (Body) cycle.getAttribute(ATTRIBUTE_NAME);
+ return (Body) TapestryUtils.getPageRenderSupport(cycle, null);
}
- protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
+ protected void prepareForRender(IRequestCycle cycle)
{
- if (cycle.getAttribute(ATTRIBUTE_NAME) != null)
- throw new ApplicationRuntimeException(Tapestry.getMessage("Body.may-not-nest"), this,
- null, null);
+ super.prepareForRender(cycle);
- cycle.setAttribute(ATTRIBUTE_NAME, this);
+ _pageRenderSupport = new PageRenderSupportImpl(getAssetService(), getLocation());
+ }
+
+ protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
+ {
+ TapestryUtils.storeRenderPageSupport(cycle, this);
IMarkupWriter nested = writer.getNestedWriter();
@@ -244,7 +136,7 @@
// Write the page's scripting. This is included scripts
// and dynamic JavaScript.
- writeScript(writer);
+ _pageRenderSupport.writeBodyScript(writer, cycle);
// Close the nested writer, which dumps its buffered content
// into its parent.
@@ -256,7 +148,7 @@
// would create a window.onload event handler, but this is better
// (it doesn't have to wait for external images to load).
- writeInitializationScript(writer);
+ _pageRenderSupport.writeInitializationScript(writer);
writer.end(); // <body>
}
@@ -265,99 +157,19 @@
{
super.cleanupAfterRender(cycle);
- if (_idAllocator != null)
- _idAllocator.clear();
-
- if (_imageMap != null)
- _imageMap.clear();
+ _pageRenderSupport = null;
- if (_externalScripts != null)
- _externalScripts.clear();
-
- if (_initializationScript != null)
- _initializationScript.setLength(0);
-
- if (_imageInitializations != null)
- _imageInitializations.setLength(0);
-
- if (_bodyScript != null)
- _bodyScript.setLength(0);
- }
-
- /**
- * Writes a single large JavaScript block containing:
- * <ul>
- * <li>Any image initializations
- * <li>Any scripting
- * <li>Any initializations
- * </ul>
- * <p>
- * The script is written into a nested markup writer.
- * <p>
- * If there are any other initializations (see {@link #addOtherInitialization(String)}), then a
- * function to execute them is created.
- */
-
- private void writeScript(IMarkupWriter writer)
- {
- if (!Tapestry.isEmpty(_externalScripts))
- writeExternalScripts(writer);
-
- if (!(any(_bodyScript) || any(_imageInitializations)))
- return;
-
- writer.begin("script");
- writer.attribute("language", "JavaScript");
- writer.attribute("type", "text/javascript");
- writer.printRaw("<!--");
-
- if (any(_imageInitializations))
- {
- writer.printRaw("\n\nvar tapestry_preload = new Array();\n");
- writer.printRaw("if (document.images)\n");
- writer.printRaw("{\n");
- writer.printRaw(_imageInitializations.toString());
- writer.printRaw("}\n");
- }
-
- if (any(_bodyScript))
- {
- writer.printRaw("\n\n");
- writer.printRaw(_bodyScript.toString());
- }
-
- writer.printRaw("\n\n// -->");
- writer.end();
- }
-
- /** @since 3.1 */
- private void writeInitializationScript(IMarkupWriter writer)
- {
- if (!any(_initializationScript))
- return;
-
- writer.begin("script");
- writer.attribute("language", "JavaScript");
- writer.attribute("type", "text/javascript");
- writer.printRaw("<!--\n");
-
- writer.printRaw(_initializationScript.toString());
-
- writer.printRaw("\n// -->");
- writer.end();
- }
-
- private boolean any(StringBuffer buffer)
- {
- if (buffer == null)
- return false;
-
- return buffer.length() > 0;
+ TapestryUtils.removePageRenderSupport(cycle);
}
public abstract String getElement();
public abstract void setElement(String element);
+
+ /** Injected
+ * @since 3.1
+ */
+ public abstract IEngineService getAssetService();
/**
* Sets the element parameter property to its default, "body".
@@ -373,10 +185,7 @@
public String getUniqueString(String baseValue)
{
- if (_idAllocator == null)
- _idAllocator = new IdAllocator();
-
- return _idAllocator.allocateId(baseValue);
+ return _pageRenderSupport.getUniqueString(baseValue);
}
}
\ No newline at end of file
1.4 +26 -41 jakarta-tapestry/framework/src/java/org/apache/tapestry/html/Script.java
Index: Script.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/html/Script.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Script.java 6 Jan 2005 02:17:23 -0000 1.3
+++ Script.java 29 Mar 2005 13:35:42 -0000 1.4
@@ -26,40 +26,37 @@
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.IScript;
+import org.apache.tapestry.PageRenderSupport;
import org.apache.tapestry.Tapestry;
+import org.apache.tapestry.TapestryUtils;
import org.apache.tapestry.engine.IScriptSource;
/**
- * Works with the {@link Body} component to add a script (and perhaps some initialization)
- * to the HTML response.
- *
- * [<a href="../../../../../ComponentReference/Script.html">Component Reference</a>]
- *
- * @author Howard Lewis Ship
- *
- **/
+ * Works with the {@link Body}component to add a script (and perhaps some initialization) to the
+ * HTML response. [ <a href="../../../../../ComponentReference/Script.html">Component Reference
+ * </a>]
+ *
+ * @author Howard Lewis Ship
+ */
public abstract class Script extends AbstractComponent
{
private Map _baseSymbols;
/**
- * A Map of input and output symbols visible to the body of the Script.
+ * A Map of input and output symbols visible to the body of the Script.
*
- * @since 2.2
- *
- **/
+ * @since 2.2
+ */
private Map _symbols;
/**
- * Constructs the symbols {@link Map}. This starts with the
- * contents of the symbols parameter (if specified) to which is added
- * any informal parameters. If both a symbols parameter and informal
- * parameters are bound, then a copy of the symbols parameter's value is made
- * (that is, the {@link Map} provided by the symbols parameter is read, but not modified).
- *
- **/
+ * Constructs the symbols {@link Map}. This starts with the contents of the symbols parameter
+ * (if specified) to which is added any informal parameters. If both a symbols parameter and
+ * informal parameters are bound, then a copy of the symbols parameter's value is made (that is,
+ * the {@link Map}provided by the symbols parameter is read, but not modified).
+ */
private Map getInputSymbols()
{
@@ -69,7 +66,7 @@
result.putAll(_baseSymbols);
// Now, iterate through all the binding names (which includes both
- // formal and informal parmeters). Skip the formal ones and
+ // formal and informal parmeters). Skip the formal ones and
// access the informal ones.
Iterator i = getBindingNames().iterator();
@@ -93,10 +90,8 @@
}
/**
- * Gets the {@link IScript} for the correct script.
- *
- *
- **/
+ * Gets the {@link IScript}for the correct script.
+ */
private IScript getParsedScript(IRequestCycle cycle)
{
@@ -111,8 +106,7 @@
// If the script path is relative, it should be relative to the Script component's
// container (i.e., relative to a page in the application).
- Resource rootLocation =
- getContainer().getSpecification().getSpecificationLocation();
+ Resource rootLocation = getContainer().getSpecification().getSpecificationLocation();
Resource scriptLocation = rootLocation.getRelativeResource(scriptPath);
try
@@ -130,18 +124,11 @@
{
if (!cycle.isRewinding())
{
- Body body = Body.get(cycle);
-
- if (body == null)
- throw new ApplicationRuntimeException(
- Tapestry.getMessage("Script.must-be-contained-by-body"),
- this,
- null,
- null);
+ PageRenderSupport pageRenderSupport = TapestryUtils.getPageRenderSupport(cycle, this);
_symbols = getInputSymbols();
- getParsedScript(cycle).execute(cycle, body, _symbols);
+ getParsedScript(cycle).execute(cycle, pageRenderSupport, _symbols);
}
// Render the body of the Script;
@@ -161,13 +148,11 @@
}
/**
- * Returns the complete set of symbols (input and output)
- * from the script execution. This is visible to the body
- * of the Script, but is cleared after the Script
- * finishes rendering.
+ * Returns the complete set of symbols (input and output) from the script execution. This is
+ * visible to the body of the Script, but is cleared after the Script finishes rendering.
*
- * @since 2.2
- **/
+ * @since 2.2
+ */
public Map getSymbols()
{
1.7 +4 -6 jakarta-tapestry/contrib/src/java/org/apache/tapestry/contrib/inspector/InspectorButton.java
Index: InspectorButton.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/contrib/src/java/org/apache/tapestry/contrib/inspector/InspectorButton.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- InspectorButton.java 6 Feb 2005 15:08:50 -0000 1.6
+++ InspectorButton.java 29 Mar 2005 13:35:42 -0000 1.7
@@ -25,7 +25,9 @@
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.IScript;
+import org.apache.tapestry.PageRenderSupport;
import org.apache.tapestry.Tapestry;
+import org.apache.tapestry.TapestryUtils;
import org.apache.tapestry.engine.DirectServiceParameter;
import org.apache.tapestry.engine.IEngineService;
import org.apache.tapestry.engine.ILink;
@@ -89,13 +91,9 @@
symbols.put("URL", link.getURL());
- Body body = Body.get(cycle);
+ PageRenderSupport pageRenderSupport = TapestryUtils.getPageRenderSupport(cycle, this);
- if (body == null)
- throw new ApplicationRuntimeException(Tapestry
- .getMessage("InspectorButton.must-be-contained-by-body"), this, null, null);
-
- script.execute(cycle, body, symbols);
+ script.execute(cycle, pageRenderSupport, symbols);
// Now, go render the rest from the template.
1.3 +11 -1 jakarta-tapestry/framework/src/java/org/apache/tapestry/asset/ClasspathAssetFactory.java
Index: ClasspathAssetFactory.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/asset/ClasspathAssetFactory.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ClasspathAssetFactory.java 6 Jan 2005 02:17:19 -0000 1.2
+++ ClasspathAssetFactory.java 29 Mar 2005 13:35:42 -0000 1.3
@@ -21,12 +21,18 @@
import org.apache.hivemind.Resource;
import org.apache.hivemind.util.ClasspathResource;
import org.apache.tapestry.IAsset;
+import org.apache.tapestry.engine.IEngineService;
/**
+ * Creates instances of {@link org.apache.tapestry.asset.PrivateAsset}, which are the holders of
+ * classpath: resources.
+ *
* @author Howard M. Lewis Ship
+ * @since 3.1
*/
public class ClasspathAssetFactory implements AssetFactory
{
+ private IEngineService _assetService;
public IAsset createAsset(Resource baseResource, String path, Locale locale, Location location)
{
@@ -37,7 +43,11 @@
throw new ApplicationRuntimeException(AssetMessages.missingAsset(path, baseResource),
location, null);
- return new PrivateAsset((ClasspathResource) localized, location);
+ return new PrivateAsset((ClasspathResource) localized, _assetService, location);
}
+ public void setAssetService(IEngineService assetService)
+ {
+ _assetService = assetService;
+ }
}
\ No newline at end of file
1.6 +24 -5 jakarta-tapestry/framework/src/java/org/apache/tapestry/asset/PrivateAsset.java
Index: PrivateAsset.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/asset/PrivateAsset.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- PrivateAsset.java 5 Jan 2005 23:17:24 -0000 1.5
+++ PrivateAsset.java 29 Mar 2005 13:35:42 -0000 1.6
@@ -17,10 +17,10 @@
import java.io.InputStream;
import java.net.URL;
-import org.apache.hivemind.util.ClasspathResource;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.Location;
import org.apache.hivemind.Resource;
+import org.apache.hivemind.util.ClasspathResource;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.Tapestry;
import org.apache.tapestry.engine.IEngineService;
@@ -37,9 +37,23 @@
public class PrivateAsset extends AbstractAsset
{
+ private IEngineService _assetService;
+
+ /**
+ * @deprecated To be removed (someday). Use
+ * {@link #PrivateAsset(ClasspathResource, IEngineService, Location)} instead.
+ */
public PrivateAsset(ClasspathResource resourceLocation, Location location)
{
+ this(resourceLocation, null, location);
+ }
+
+ public PrivateAsset(ClasspathResource resourceLocation, IEngineService assetService,
+ Location location)
+ {
super(resourceLocation, location);
+
+ _assetService = assetService;
}
/**
@@ -50,11 +64,16 @@
public String buildURL(IRequestCycle cycle)
{
- IEngineService service = cycle.getEngine().getService(Tapestry.ASSET_SERVICE);
+ String path = getResourceLocation().getPath();
+
+ // ClasspathAssetFactory will provide the asset service as a constructor
+ // parameter, but there are a few odd uses of PrivateAsset where this
+ // is not handy.
+
+ if (_assetService == null)
+ _assetService = cycle.getEngine().getService(Tapestry.ASSET_SERVICE);
- String path = getResourceLocation().getPath();
-
- ILink link = service.getLink(cycle, path);
+ ILink link = _assetService.getLink(cycle, path);
return link.getURL();
}
1.4 +6 -5 jakarta-tapestry/framework/src/java/org/apache/tapestry/valid/BaseValidator.java
Index: BaseValidator.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/valid/BaseValidator.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- BaseValidator.java 6 Jan 2005 02:17:23 -0000 1.3
+++ BaseValidator.java 29 Mar 2005 13:35:42 -0000 1.4
@@ -29,7 +29,9 @@
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.IScript;
+import org.apache.tapestry.PageRenderSupport;
import org.apache.tapestry.Tapestry;
+import org.apache.tapestry.TapestryUtils;
import org.apache.tapestry.engine.IScriptSource;
import org.apache.tapestry.form.FormEventType;
import org.apache.tapestry.form.IFormComponent;
@@ -274,13 +276,12 @@
IScript script = source.getScript(location);
- Body body = Body.get(cycle);
+ // If there's an error, report it against the field (this validator object doesn't
+ // have a location).
- if (body == null)
- throw new ApplicationRuntimeException(Tapestry
- .getMessage("ValidField.must-be-contained-by-body"), field, null, null);
+ PageRenderSupport pageRenderSupport = TapestryUtils.getPageRenderSupport(cycle, field);
- script.execute(cycle, body, finalSymbols);
+ script.execute(cycle, pageRenderSupport, finalSymbols);
String functionName = (String) finalSymbols.get(FUNCTION_SYMBOL);
1.4 +8 -6 jakarta-tapestry/framework/src/java/org/apache/tapestry/valid/ValidField.java
Index: ValidField.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/valid/ValidField.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ValidField.java 6 Jan 2005 02:17:23 -0000 1.3
+++ ValidField.java 29 Mar 2005 13:35:42 -0000 1.4
@@ -19,7 +19,9 @@
import org.apache.tapestry.IForm;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.PageRenderSupport;
import org.apache.tapestry.Tapestry;
+import org.apache.tapestry.TapestryUtils;
import org.apache.tapestry.form.AbstractTextField;
import org.apache.tapestry.form.Form;
import org.apache.tapestry.form.IFormComponent;
@@ -112,8 +114,8 @@
/**
* Creates JavaScript to set the cursor on the first required or error field encountered while
- * rendering. This only works if the text field is wrapped by a {@link Body}component (which is
- * almost always true).
+ * rendering. This only works if the text field is wrapped by a {@link Body} component
+ * (which is almost always true).
*/
protected void addSelect(IRequestCycle cycle)
@@ -123,11 +125,11 @@
if (cycle.getAttribute(SELECTED_ATTRIBUTE_NAME) != null)
return;
- Body body = Body.get(cycle);
+ PageRenderSupport pageRenderSupport = TapestryUtils.getOptionalPageRenderSupport(cycle);
// If not wrapped by a Body, then do nothing.
- if (body == null)
+ if (pageRenderSupport == null)
return;
IForm form = Form.get(cycle);
@@ -137,8 +139,8 @@
String fullName = "document." + formName + "." + textFieldName;
- body.addInitializationScript(fullName + ".focus();");
- body.addInitializationScript(fullName + ".select();");
+ pageRenderSupport.addInitializationScript(fullName + ".focus();");
+ pageRenderSupport.addInitializationScript(fullName + ".select();");
// Put a marker in, indicating that the selected field is known.
1.19 +16 -6 jakarta-tapestry/eclipse/Tapestry-Workbench.launch
Index: Tapestry-Workbench.launch
===================================================================
RCS file: /home/cvs/jakarta-tapestry/eclipse/Tapestry-Workbench.launch,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- Tapestry-Workbench.launch 22 Mar 2005 13:40:54 -0000 1.18
+++ Tapestry-Workbench.launch 29 Mar 2005 13:35:42 -0000 1.19
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
+<booleanAttribute key="yk-capture-cpu-on-exit" value="true"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.mortbay.jetty.Server"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="jetty.xml"/>
+<booleanAttribute key="yk-startup-with-sampling" value="true"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="src/config/jetty.xml"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dorg.apache.tapestry.disable-caching=false"/>
<listAttribute key="org.eclipse.jdt.launching.SOURCE_PATH">
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JRE_LIB" path="2" sourceAttachmentPath="JRE_SRC" sourceRootPath="JRE_SRCROOT" type="3"/> "/>
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/config" path="3" type="2"/> "/>
@@ -32,19 +35,26 @@
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JDK_DIR/lib/tools.jar" path="3" type="3"/> "/>
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JETTY_DIR/ext/ant.jar" path="3" type="3"/> "/>
</listAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dorg.apache.tapestry.disable-caching=true"/>
-<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="jakarta-tapestry/examples/Workbench"/>
+<stringAttribute key="yk-snapshot-dir" value=""/>
<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
-<stringAttribute key="org.eclipse.debug.ui.target_run_perspective" value="perspective_default"/>
+<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="jakarta-tapestry/examples/Workbench"/>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_SOURCE_PATH" value="false"/>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="jakarta-tapestry"/>
+<stringAttribute key="org.eclipse.debug.ui.target_run_perspective" value="perspective_default"/>
+<booleanAttribute key="yk-capture-memory-on-exit" value="false"/>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry type="3" path="1" containerPath="JRE_LIB"/> "/>
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento project="jakarta-tapestry"/> </runtimeClasspathEntry> "/>
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry type="3" path="3" containerPath="JETTY_DIR/lib/javax.servlet.jar"/> "/>
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry type="3" path="3" containerPath="JETTY_DIR/lib/org.mortbay.jetty.jar"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry type="3" path="3" containerPath="JETTY_DIR/lib/org.mortbay.jetty-jdk1.2.jar"/> "/>
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry type="3" path="3" containerPath="JETTY_DIR/lib/org.mortbay.jmx.jar"/> "/>
+<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry type="3" path="3" containerPath="JETTY_DIR/ext/ant.jar"/> "/>
+<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry type="3" path="3" containerPath="JETTY_DIR/ext/crimson.jar"/> "/>
+<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry type="3" path="3" containerPath="JETTY_DIR/ext/jasper-compiler.jar"/> "/>
+<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry type="3" path="3" containerPath="JETTY_DIR/ext/jasper-runtime.jar"/> "/>
+<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry type="3" path="3" containerPath="JETTY_DIR/ext/javax.xml.jaxp.jar"/> "/>
</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="jakarta-tapestry"/>
<stringAttribute key="org.eclipse.debug.ui.target_debug_perspective" value="perspective_default"/>
+<booleanAttribute key="yk-startup-with-tracing" value="false"/>
+<booleanAttribute key="yk-startup-with-object-allocations" value="false"/>
</launchConfiguration>
1.6 +1 -1 jakarta-tapestry/framework/src/scripts/TestLinkRenderers.xml
Index: TestLinkRenderers.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/scripts/TestLinkRenderers.xml,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- TestLinkRenderers.xml 31 Jan 2005 20:35:47 -0000 1.5
+++ TestLinkRenderers.xml 29 Mar 2005 13:35:42 -0000 1.6
@@ -113,7 +113,7 @@
</assert-output>
<assert-output name="Message">
- A link component with multiple functions for a single event type must be contained within a Body.
+ No PageRenderSupport object has been stored into the request cycle. This object is typically provided by a Body component. You should add a Body component to your template.
</assert-output>
</request>
1.4 +1 -1 jakarta-tapestry/framework/src/scripts/TestValidFieldNoBody.xml
Index: TestValidFieldNoBody.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/scripts/TestValidFieldNoBody.xml,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- TestValidFieldNoBody.xml 6 Jan 2005 02:17:19 -0000 1.3
+++ TestValidFieldNoBody.xml 29 Mar 2005 13:35:42 -0000 1.4
@@ -39,7 +39,7 @@
</assert-output>
<assert-output name="Message">
- A ValidField using client-side validation must be enclosed by a Body component.
+ No PageRenderSupport object has been stored into the request cycle. This object is typically provided by a Body component. You should add a Body component to your template.
</assert-output>
</request>
1.6 +13 -13 jakarta-tapestry/framework/src/java/org/apache/tapestry/link/AbstractLinkComponent.java
Index: AbstractLinkComponent.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/link/AbstractLinkComponent.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- AbstractLinkComponent.java 6 Jan 2005 02:17:28 -0000 1.5
+++ AbstractLinkComponent.java 29 Mar 2005 13:35:42 -0000 1.6
@@ -20,16 +20,15 @@
import java.util.List;
import java.util.Map;
-import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.tapestry.AbstractComponent;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
-import org.apache.tapestry.Tapestry;
+import org.apache.tapestry.PageRenderSupport;
+import org.apache.tapestry.TapestryUtils;
import org.apache.tapestry.components.ILinkComponent;
import org.apache.tapestry.components.LinkEventType;
import org.apache.tapestry.engine.IEngineService;
import org.apache.tapestry.engine.ILink;
-import org.apache.tapestry.html.Body;
/**
* Base class for implementations of {@link ILinkComponent}. Includes a disabled attribute (that
@@ -110,11 +109,7 @@
if (_eventHandlers == null)
return;
- Body body = Body.get(cycle);
-
- if (body == null)
- throw new ApplicationRuntimeException(Tapestry
- .getMessage("AbstractLinkComponent.events-need-body"), this, null, null);
+ PageRenderSupport pageRenderSupport = TapestryUtils.getPageRenderSupport(cycle, this);
Iterator i = _eventHandlers.entrySet().iterator();
@@ -123,13 +118,18 @@
Map.Entry entry = (Map.Entry) i.next();
LinkEventType type = (LinkEventType) entry.getKey();
- name = writeEventHandler(writer, body, name, type.getAttributeName(), entry.getValue());
+ name = writeEventHandler(
+ writer,
+ pageRenderSupport,
+ name,
+ type.getAttributeName(),
+ entry.getValue());
}
}
- protected String writeEventHandler(IMarkupWriter writer, Body body, String name,
- String attributeName, Object value)
+ protected String writeEventHandler(IMarkupWriter writer, PageRenderSupport pageRenderSupport,
+ String name, String attributeName, Object value)
{
String wrapperFunctionName;
@@ -139,7 +139,7 @@
}
else
{
- String finalName = name == null ? body.getUniqueString("Link") : name;
+ String finalName = name == null ? pageRenderSupport.getUniqueString("Link") : name;
wrapperFunctionName = attributeName + "_" + finalName;
@@ -160,7 +160,7 @@
buffer.append("}\n\n");
- body.addBodyScript(buffer.toString());
+ pageRenderSupport.addBodyScript(buffer.toString());
}
writer.attribute(attributeName, "javascript:" + wrapperFunctionName + "();");
1.1 jakarta-tapestry/framework/src/test/org/apache/tapestry/TestTapestryUtils.java
Index: TestTapestryUtils.java
===================================================================
// Copyright 2005 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.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.Location;
import org.apache.hivemind.test.HiveMindTestCase;
import org.easymock.MockControl;
/**
* Tests for {@link org.apache.tapestry.TapestryUtils}.
*
* @author Howard M. Lewis Ship
* @since 3.1
*/
public class TestTapestryUtils extends HiveMindTestCase
{
private IRequestCycle newCycle(String key, Object attribute)
{
MockControl control = newControl(IRequestCycle.class);
IRequestCycle cycle = (IRequestCycle) control.getMock();
cycle.getAttribute(key);
control.setReturnValue(attribute);
return cycle;
}
public void testStoreUniqueAttributeSuccess()
{
Object newInstance = new Object();
MockControl control = newControl(IRequestCycle.class);
IRequestCycle cycle = (IRequestCycle) control.getMock();
String key = "foo.bar.Baz";
cycle.getAttribute(key);
control.setReturnValue(null);
cycle.setAttribute(key, newInstance);
replayControls();
TapestryUtils.storeUniqueAttribute(cycle, key, newInstance);
verifyControls();
}
public void testStoreUniqueAttributeFailure()
{
Object existing = "*EXISTING*";
Object newInstance = "*NEW*";
String key = "foo.bar.Baz";
IRequestCycle cycle = newCycle(key, existing);
replayControls();
try
{
TapestryUtils.storeUniqueAttribute(cycle, key, newInstance);
unreachable();
}
catch (IllegalStateException ex)
{
assertEquals(TapestryMessages.nonUniqueAttribute(newInstance, key, existing), ex
.getMessage());
}
verifyControls();
}
public void testGetPageRenderSupportSuccess()
{
PageRenderSupport support = (PageRenderSupport) newMock(PageRenderSupport.class);
IRequestCycle cycle = newCycle(TapestryUtils.PAGE_RENDER_SUPPORT_ATTRIBUTE, support);
replayControls();
PageRenderSupport actual = TapestryUtils.getPageRenderSupport(cycle, null);
assertSame(support, actual);
verifyControls();
}
public void testGetPageRenderSupportFailure()
{
Location l = fabricateLocation(22);
IRequestCycle cycle = newCycle(TapestryUtils.PAGE_RENDER_SUPPORT_ATTRIBUTE, null);
replayControls();
try
{
TapestryUtils.getPageRenderSupport(cycle, l);
unreachable();
}
catch (ApplicationRuntimeException ex)
{
assertEquals(TapestryMessages.noPageRenderSupport(), ex.getMessage());
assertSame(l, ex.getLocation());
}
verifyControls();
}
}
1.10 +5 -2 jakarta-tapestry/framework/src/descriptor/META-INF/tapestry.asset.xml
Index: tapestry.asset.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/descriptor/META-INF/tapestry.asset.xml,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- tapestry.asset.xml 15 Mar 2005 16:44:17 -0000 1.9
+++ tapestry.asset.xml 29 Mar 2005 13:35:42 -0000 1.10
@@ -74,8 +74,11 @@
AssetFactory used when the prefix is "classpath:" or the
base resource is a ClasspathResource.
- <create-instance class="ClasspathAssetFactory"/>
-
+ <invoke-factory>
+ <construct class="ClasspathAssetFactory">
+ <set-object property="assetService" value="engine-service:asset"/>
+ </construct>
+ </invoke-factory>
</service-point>
<configuration-point id="AssetFactoryAdapters" schema-id="hivemind.lib.AdapterRegistry"/>
1.6 +49 -43 jakarta-tapestry/contrib/src/java/org/apache/tapestry/contrib/palette/Palette.java
Index: Palette.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/contrib/src/java/org/apache/tapestry/contrib/palette/Palette.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Palette.java 8 Mar 2005 15:36:38 -0000 1.5
+++ Palette.java 29 Mar 2005 13:35:42 -0000 1.6
@@ -30,7 +30,9 @@
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.IScript;
+import org.apache.tapestry.PageRenderSupport;
import org.apache.tapestry.Tapestry;
+import org.apache.tapestry.TapestryUtils;
import org.apache.tapestry.components.Block;
import org.apache.tapestry.engine.IScriptSource;
import org.apache.tapestry.form.Form;
@@ -160,36 +162,42 @@
* <pre>
*
*
- * TABLE.tapestry-palette TH
- * {
- * font-size: 9pt;
- * font-weight: bold;
- * color: white;
- * background-color: #330066;
- * text-align: center;
- * }
- *
- * TD.available-cell SELECT
- * {
- * font-weight: normal;
- * background-color: #FFFFFF;
- * width: 200px;
- * }
- *
- * TD.selected-cell SELECT
- * {
- * font-weight: normal;
- * background-color: #FFFFFF;
- * width: 200px;
- * }
*
- * TABLE.tapestry-palette TD.controls
- * {
- * text-align: center;
- * vertical-align: middle;
- * width: 60px;
- * }
*
+ *
+ * TABLE.tapestry-palette TH
+ * {
+ * font-size: 9pt;
+ * font-weight: bold;
+ * color: white;
+ * background-color: #330066;
+ * text-align: center;
+ * }
+ *
+ * TD.available-cell SELECT
+ * {
+ * font-weight: normal;
+ * background-color: #FFFFFF;
+ * width: 200px;
+ * }
+ *
+ * TD.selected-cell SELECT
+ * {
+ * font-weight: normal;
+ * background-color: #FFFFFF;
+ * width: 200px;
+ * }
+ *
+ * TABLE.tapestry-palette TD.controls
+ * {
+ * text-align: center;
+ * vertical-align: middle;
+ * width: 60px;
+ * }
+ *
+ *
+ *
+ *
*
* </pre>
*
@@ -324,37 +332,35 @@
_script = source.getScript(scriptResource);
}
- Body body = Body.get(cycle);
- if (body == null)
- throw new ApplicationRuntimeException("Palette component must be wrapped by a Body.",
- this, null, null);
+ PageRenderSupport pageRenderSupport = TapestryUtils.getPageRenderSupport(cycle, this);
- setImage(body, cycle, "selectImage", getSelectImage());
- setImage(body, cycle, "selectDisabledImage", getSelectDisabledImage());
- setImage(body, cycle, "deselectImage", getDeselectImage());
- setImage(body, cycle, "deselectDisabledImage", getDeselectDisabledImage());
+ setImage(pageRenderSupport, cycle, "selectImage", getSelectImage());
+ setImage(pageRenderSupport, cycle, "selectDisabledImage", getSelectDisabledImage());
+ setImage(pageRenderSupport, cycle, "deselectImage", getDeselectImage());
+ setImage(pageRenderSupport, cycle, "deselectDisabledImage", getDeselectDisabledImage());
if (isSortUser())
{
- setImage(body, cycle, "upImage", getUpImage());
- setImage(body, cycle, "upDisabledImage", getUpDisabledImage());
- setImage(body, cycle, "downImage", getDownImage());
- setImage(body, cycle, "downDisabledImage", getDownDisabledImage());
+ setImage(pageRenderSupport, cycle, "upImage", getUpImage());
+ setImage(pageRenderSupport, cycle, "upDisabledImage", getUpDisabledImage());
+ setImage(pageRenderSupport, cycle, "downImage", getDownImage());
+ setImage(pageRenderSupport, cycle, "downDisabledImage", getDownDisabledImage());
}
_symbols.put("palette", this);
- _script.execute(cycle, body, _symbols);
+ _script.execute(cycle, pageRenderSupport, _symbols);
}
/**
* Extracts its asset URL, sets it up for preloading, and assigns the preload reference as a
* script symbol.
*/
- private void setImage(Body body, IRequestCycle cycle, String symbolName, IAsset asset)
+ private void setImage(PageRenderSupport pageRenderSupport, IRequestCycle cycle,
+ String symbolName, IAsset asset)
{
String URL = asset.buildURL(cycle);
- String reference = body.getPreloadedImageReference(URL);
+ String reference = pageRenderSupport.getPreloadedImageReference(URL);
_symbols.put(symbolName, reference);
}
1.6 +4 -10 jakarta-tapestry/framework/src/java/org/apache/tapestry/form/DatePicker.java
Index: DatePicker.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/DatePicker.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- DatePicker.java 15 Mar 2005 16:44:17 -0000 1.5
+++ DatePicker.java 29 Mar 2005 13:35:42 -0000 1.6
@@ -23,7 +23,6 @@
import java.util.Locale;
import java.util.Map;
-import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.HiveMind;
import org.apache.hivemind.Resource;
import org.apache.tapestry.IAsset;
@@ -31,9 +30,9 @@
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.IScript;
-import org.apache.tapestry.Tapestry;
+import org.apache.tapestry.PageRenderSupport;
+import org.apache.tapestry.TapestryUtils;
import org.apache.tapestry.engine.IScriptSource;
-import org.apache.tapestry.html.Body;
/**
* Provides a Form <tt>java.util.Date</tt> field component for selecting dates. [ <a
@@ -123,12 +122,7 @@
if (!cycle.isRewinding())
{
- Body body = Body.get(cycle);
-
- if (body == null)
- throw new ApplicationRuntimeException(Tapestry.format(
- "must-be-contained-by-body",
- "DatePicker"), this, null, null);
+ PageRenderSupport pageRenderSupport = TapestryUtils.getPageRenderSupport(cycle, this);
Locale locale = getPage().getLocale();
DateFormatSymbols dfs = new DateFormatSymbols(locale);
@@ -151,7 +145,7 @@
symbols.put(SYM_FORMNAME, form.getName());
symbols.put(SYM_VALUE, value);
- _script.execute(cycle, body, symbols);
+ _script.execute(cycle, pageRenderSupport, symbols);
writer.beginEmpty("input");
writer.attribute("type", "text");
1.11 +4 -6 jakarta-tapestry/framework/src/java/org/apache/tapestry/form/Form.java
Index: Form.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/Form.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- Form.java 27 Jan 2005 19:03:03 -0000 1.10
+++ Form.java 29 Mar 2005 13:35:42 -0000 1.11
@@ -32,9 +32,11 @@
import org.apache.tapestry.IForm;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.PageRenderSupport;
import org.apache.tapestry.RenderRewoundException;
import org.apache.tapestry.StaleLinkException;
import org.apache.tapestry.Tapestry;
+import org.apache.tapestry.TapestryUtils;
import org.apache.tapestry.engine.ActionServiceParameter;
import org.apache.tapestry.engine.DirectServiceParameter;
import org.apache.tapestry.engine.IEngineService;
@@ -464,11 +466,7 @@
if (_events == null || _events.isEmpty())
return;
- Body body = Body.get(cycle);
-
- if (body == null)
- throw new ApplicationRuntimeException(FormMessages.formNeedsBodyForEventHandlers(),
- this, null, null);
+ PageRenderSupport pageRenderSupport = TapestryUtils.getPageRenderSupport(cycle, this);
StringBuffer buffer = new StringBuffer();
@@ -537,7 +535,7 @@
buffer.append("\n\n");
}
- body.addInitializationScript(buffer.toString());
+ pageRenderSupport.addInitializationScript(buffer.toString());
}
/**
1.6 +6 -7 jakarta-tapestry/framework/src/java/org/apache/tapestry/form/LinkSubmit.java
Index: LinkSubmit.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/LinkSubmit.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- LinkSubmit.java 8 Mar 2005 15:36:37 -0000 1.5
+++ LinkSubmit.java 29 Mar 2005 13:35:42 -0000 1.6
@@ -20,8 +20,9 @@
import org.apache.tapestry.IForm;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.PageRenderSupport;
import org.apache.tapestry.Tapestry;
-import org.apache.tapestry.html.Body;
+import org.apache.tapestry.TapestryUtils;
/**
* Implements a component that submits its enclosing form via a JavaScript link. [ <a
@@ -69,17 +70,15 @@
{
if (!rewinding)
{
- Body body = Body.get(cycle);
- if (body == null)
- throw new ApplicationRuntimeException(Tapestry.format(
- "must-be-contained-by-body",
- "LinkSubmit"), this, null, null);
+ PageRenderSupport pageRenderSupport = TapestryUtils.getPageRenderSupport(
+ cycle,
+ this);
// make sure the submit function is on the page (once)
if (cycle.getAttribute(ATTRIBUTE_FUNCTION_NAME) == null)
{
- body
+ pageRenderSupport
.addBodyScript("function submitLink(form, elementId) { form._linkSubmit.value = elementId; if (form.onsubmit == null || form.onsubmit()) form.submit(); }");
cycle.setAttribute(ATTRIBUTE_FUNCTION_NAME, this);
}
1.2 +0 -1 jakarta-tapestry/framework/src/java/org/apache/tapestry/form/FormStrings.properties
Index: FormStrings.properties
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/FormStrings.properties,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- FormStrings.properties 27 Jan 2005 18:40:29 -0000 1.1
+++ FormStrings.properties 29 Mar 2005 13:35:42 -0000 1.2
@@ -16,6 +16,5 @@
form-id-mismatch=Rewind of form {0} expected allocated id #{1} to be ''{2}'', but was ''{3}'' (requested by component {4}).
forms-may-not-nest=Forms may not be nested.
form-too-few-ids=Rewind of form {0} expected {1} more form elements, starting with id ''{2}''.
-form-needs-body-for-event-handlers=A Form with event handlers must be enclosed by a Body component.
encoding-type-contention=Components within Form {0} have requested conflicting encoding types ''{1}'' and ''{2}''.
1.2 +0 -5 jakarta-tapestry/framework/src/java/org/apache/tapestry/form/FormMessages.java
Index: FormMessages.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/form/FormMessages.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- FormMessages.java 27 Jan 2005 18:40:29 -0000 1.1
+++ FormMessages.java 29 Mar 2005 13:35:42 -0000 1.2
@@ -53,11 +53,6 @@
return _formatter.format("form-too-few-ids", form.getExtendedId(), new Integer(remainingCount), nextExpectedId);
}
- public static String formNeedsBodyForEventHandlers()
- {
- return _formatter.getMessage("form-needs-body-for-event-handlers");
- }
-
public static String encodingTypeContention(IComponent form, String establishedEncodingType,
String newEncodingType)
{
1.1 jakarta-tapestry/framework/src/test/org/apache/tapestry/util/TestPageRenderSupport.java
Index: TestPageRenderSupport.java
===================================================================
// Copyright 2005 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.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.util;
import java.io.CharArrayWriter;
import java.io.PrintWriter;
import org.apache.hivemind.ClassResolver;
import org.apache.hivemind.Location;
import org.apache.hivemind.Resource;
import org.apache.hivemind.impl.DefaultClassResolver;
import org.apache.hivemind.test.HiveMindTestCase;
import org.apache.hivemind.util.ClasspathResource;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.engine.IEngineService;
import org.apache.tapestry.engine.ILink;
import org.apache.tapestry.markup.AsciiMarkupFilter;
import org.apache.tapestry.markup.MarkupWriterImpl;
import org.easymock.MockControl;
/**
* Tests for {@link org.apache.tapestry.util.PageRenderSupportImpl}.
*
* @author Howard M. Lewis Ship
* @since 3.1
*/
public class TestPageRenderSupport extends HiveMindTestCase
{
private IEngineService newService()
{
return (IEngineService) newMock(IEngineService.class);
}
private IRequestCycle newCycle()
{
return (IRequestCycle) newMock(IRequestCycle.class);
}
private ILink newLink(String URL)
{
MockControl control = newControl(ILink.class);
ILink link = (ILink) control.getMock();
link.getURL();
control.setReturnValue(URL);
return link;
}
private CharArrayWriter _writer;
private IMarkupWriter newWriter()
{
_writer = new CharArrayWriter();
return new MarkupWriterImpl("text/html", new PrintWriter(_writer), new AsciiMarkupFilter());
}
private void assertOutput(String[] expectedLines)
{
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < expectedLines.length; i++)
{
// Note: PageRenderSupport is a bit sloppy; a lot of code just uses \n for
// a newline seperator, other parts go through IMarkupWriter.println() and get
// a proper newline seperator (which may be different).
if (i > 0)
buffer.append("\n");
buffer.append(expectedLines[i]);
}
assertOutput(buffer.toString());
}
private void assertOutput(String expected)
{
String actual = _writer.toString();
assertEquals(expected, actual);
_writer.reset();
}
public void testGetLocation()
{
IEngineService service = newService();
Location l = fabricateLocation(99);
replayControls();
PageRenderSupportImpl prs = new PageRenderSupportImpl(service, l);
assertSame(l, prs.getLocation());
verifyControls();
}
public void testGetPreloadedImageReference()
{
IEngineService service = newService();
Location l = fabricateLocation(99);
IRequestCycle cycle = newCycle();
IMarkupWriter writer = newWriter();
replayControls();
PageRenderSupportImpl prs = new PageRenderSupportImpl(service, l);
assertEquals("tapestry_preload[0].src", prs.getPreloadedImageReference("/foo/bar.gif"));
assertEquals("tapestry_preload[1].src", prs.getPreloadedImageReference("/zip/zap.png"));
assertEquals("tapestry_preload[0].src", prs.getPreloadedImageReference("/foo/bar.gif"));
prs.addBodyScript("myBodyScript();");
prs.writeBodyScript(writer, cycle);
assertOutput(new String[]
{ "<script language=\"JavaScript\" type=\"text/javascript\"><!--", "",
"var tapestry_preload = new Array();", "if (document.images)", "{",
" tapestry_preload[0] = new Image();",
" tapestry_preload[0].src = \"/foo/bar.gif\";",
" tapestry_preload[1] = new Image();",
" tapestry_preload[1].src = \"/zip/zap.png\";", "}", "", "", "myBodyScript();",
"", "// --></script>" });
verifyControls();
}
public void testAddBodyScript()
{
IEngineService service = newService();
Location l = fabricateLocation(99);
IRequestCycle cycle = newCycle();
IMarkupWriter writer = newWriter();
replayControls();
PageRenderSupportImpl prs = new PageRenderSupportImpl(service, l);
prs.addBodyScript("myBodyScript();");
prs.writeBodyScript(writer, cycle);
assertOutput(new String[]
{ "<script language=\"JavaScript\" type=\"text/javascript\"><!--", "", "myBodyScript();",
"", "// --></script>" });
verifyControls();
}
public void testGetUniqueValue()
{
IEngineService service = newService();
Location l = fabricateLocation(99);
replayControls();
PageRenderSupportImpl prs = new PageRenderSupportImpl(service, l);
assertEquals("foo", prs.getUniqueString("foo"));
assertEquals("foo$0", prs.getUniqueString("foo"));
assertEquals("bar", prs.getUniqueString("bar"));
assertEquals("foo$1", prs.getUniqueString("foo"));
verifyControls();
}
public void testAddInitializationScript()
{
IEngineService service = newService();
Location l = fabricateLocation(99);
IMarkupWriter writer = newWriter();
replayControls();
PageRenderSupportImpl prs = new PageRenderSupportImpl(service, l);
prs.addInitializationScript("myInitializationScript1();");
prs.addInitializationScript("myInitializationScript2();");
prs.writeInitializationScript(writer);
assertOutput(new String[]
{ "<script language=\"JavaScript\" type=\"text/javascript\"><!--",
"myInitializationScript1();", "myInitializationScript2();", "", "// --></script>" });
verifyControls();
}
public void testAddExternalScript() throws Exception
{
String newline = System.getProperty("line.separator");
Location l = fabricateLocation(22);
ClassResolver resolver = new DefaultClassResolver();
Resource filea = new ClasspathResource(resolver, "org/apache/tapestry/utils/filea.txt");
Resource fileb = new ClasspathResource(resolver, "org/apache/tapestry/utils/fileb.txt");
MockControl assetServicec = newControl(IEngineService.class);
IEngineService assetService = (IEngineService) assetServicec.getMock();
IRequestCycle cycle = newCycle();
assetService.getLink(cycle, "org/apache/tapestry/utils/filea.txt");
assetServicec.setReturnValue(newLink("/app?filea.txt"));
assetService.getLink(cycle, "org/apache/tapestry/utils/fileb.txt");
assetServicec.setReturnValue(newLink("/app?fileb.txt"));
IMarkupWriter writer = newWriter();
replayControls();
PageRenderSupportImpl prs = new PageRenderSupportImpl(assetService, l);
prs.addExternalScript(filea);
prs.addExternalScript(fileb);
prs.addExternalScript(filea);
prs.writeBodyScript(writer, cycle);
// PageRenderSupport is a little sloppy about using \n for a newline, vs. using
// the property line seperator sequence and it bites us right here.
assertOutput(scriptTagFor("/app?filea.txt") + newline + scriptTagFor("/app?fileb.txt")
+ newline);
verifyControls();
}
private String scriptTagFor(String url)
{
return "<script language=\"JavaScript\" type=\"text/javascript\" src=\"" + url
+ "\"></script>";
}
}
1.1 jakarta-tapestry/framework/src/java/org/apache/tapestry/util/PageRenderSupportImpl.java
Index: PageRenderSupportImpl.java
===================================================================
// Copyright 2005 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.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.Locatable;
import org.apache.hivemind.Location;
import org.apache.hivemind.Resource;
import org.apache.hivemind.util.ClasspathResource;
import org.apache.hivemind.util.Defense;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.PageRenderSupport;
import org.apache.tapestry.Tapestry;
import org.apache.tapestry.asset.PrivateAsset;
import org.apache.tapestry.engine.IEngineService;
/**
* Implementation of {@link org.apache.tapestry.PageRenderSupport}. The
* {@link org.apache.tapestry.html.Body} component uses an instance of this class.
*
* @author Howard M. Lewis Ship
* @since 3.1
*/
public class PageRenderSupportImpl implements Locatable, PageRenderSupport
{
private final IEngineService _assetService;
private final Location _location;
// Lines that belong inside the onLoad event handler for the <body> tag.
private StringBuffer _initializationScript;
// Any other scripting desired
private StringBuffer _bodyScript;
// Contains text lines related to image initializations
private StringBuffer _imageInitializations;
/**
* Map of URLs to Strings (preloaded image references).
*/
private Map _imageMap;
/**
* List of included scripts. Values are Strings.
*
* @since 1.0.5
*/
private List _externalScripts;
private IdAllocator _idAllocator;
public PageRenderSupportImpl(IEngineService assetService, Location location)
{
Defense.notNull(assetService, "assetService");
_assetService = assetService;
_location = location;
}
/**
* Returns the location, which may be used in error messages. In practical terms, this is the
* location of the {@link org.apache.tapestry.html.Body} component.
*/
public Location getLocation()
{
return _location;
}
public String getPreloadedImageReference(String URL)
{
if (_imageMap == null)
_imageMap = new HashMap();
String reference = (String) _imageMap.get(URL);
if (reference == null)
{
int count = _imageMap.size();
String varName = "tapestry_preload[" + count + "]";
reference = varName + ".src";
if (_imageInitializations == null)
_imageInitializations = new StringBuffer();
_imageInitializations.append(" ");
_imageInitializations.append(varName);
_imageInitializations.append(" = new Image();\n");
_imageInitializations.append(" ");
_imageInitializations.append(reference);
_imageInitializations.append(" = \"");
_imageInitializations.append(URL);
_imageInitializations.append("\";\n");
_imageMap.put(URL, reference);
}
return reference;
}
public void addBodyScript(String script)
{
if (_bodyScript == null)
_bodyScript = new StringBuffer(script.length());
_bodyScript.append(script);
}
public void addInitializationScript(String script)
{
if (_initializationScript == null)
_initializationScript = new StringBuffer(script.length() + 1);
_initializationScript.append(script);
_initializationScript.append('\n');
}
public void addExternalScript(Resource scriptLocation)
{
if (_externalScripts == null)
_externalScripts = new ArrayList();
if (_externalScripts.contains(scriptLocation))
return;
// Alas, this won't give a good Location for the actual problem.
if (!(scriptLocation instanceof ClasspathResource))
throw new ApplicationRuntimeException(Tapestry.format(
"Body.include-classpath-script-only",
scriptLocation), this, null, null);
// Record the URL so we don't include it twice.
_externalScripts.add(scriptLocation);
}
public String getUniqueString(String baseValue)
{
if (_idAllocator == null)
_idAllocator = new IdAllocator();
return _idAllocator.allocateId(baseValue);
}
private void writeExternalScripts(IMarkupWriter writer, IRequestCycle cycle)
{
int count = Tapestry.size(_externalScripts);
for (int i = 0; i < count; i++)
{
ClasspathResource scriptLocation = (ClasspathResource) _externalScripts.get(i);
// This is still very awkward! Should move the code inside PrivateAsset somewhere
// else, so that an asset does not have to be created to to build the URL.
PrivateAsset asset = new PrivateAsset(scriptLocation, _assetService, null);
String url = asset.buildURL(cycle);
// Note: important to use begin(), not beginEmpty(), because browser don't
// interpret <script .../> properly.
writer.begin("script");
writer.attribute("language", "JavaScript");
writer.attribute("type", "text/javascript");
writer.attribute("src", url);
writer.end();
writer.println();
}
}
/**
* Writes a single large JavaScript block containing:
* <ul>
* <li>Any image initializations (via {@link #getPreloadedImageReference(String)})
* <li>Any included scripts (via {@link #addExternalScript(Resource)})
* <li>Any contributions (via {@link #addBodyScript(String)})
* </ul>
*
* @see #writeInitializationScript(IMarkupWriter)
*/
public void writeBodyScript(IMarkupWriter writer, IRequestCycle cycle)
{
if (!Tapestry.isEmpty(_externalScripts))
writeExternalScripts(writer, cycle);
if (!(any(_bodyScript) || any(_imageInitializations)))
return;
writer.begin("script");
writer.attribute("language", "JavaScript");
writer.attribute("type", "text/javascript");
writer.printRaw("<!--");
if (any(_imageInitializations))
{
writer.printRaw("\n\nvar tapestry_preload = new Array();\n");
writer.printRaw("if (document.images)\n");
writer.printRaw("{\n");
writer.printRaw(_imageInitializations.toString());
writer.printRaw("}\n");
}
if (any(_bodyScript))
{
writer.printRaw("\n\n");
writer.printRaw(_bodyScript.toString());
}
writer.printRaw("\n\n// -->");
writer.end();
}
/**
* Writes any image initializations; this should be invoked at the end of the render, after all
* the related HTML will have already been streamed to the client and parsed by the web browser.
* Earlier versions of Tapestry uses a <code>window.onload</code> event handler.
*/
public void writeInitializationScript(IMarkupWriter writer)
{
if (!any(_initializationScript))
return;
writer.begin("script");
writer.attribute("language", "JavaScript");
writer.attribute("type", "text/javascript");
writer.printRaw("<!--\n");
writer.printRaw(_initializationScript.toString());
writer.printRaw("\n// -->");
writer.end();
}
private boolean any(StringBuffer buffer)
{
return buffer != null && buffer.length() > 0;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org