You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by jd...@apache.org on 2007/05/08 19:44:41 UTC
svn commit: r536273 -
/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/
Author: jdonnerstag
Date: Tue May 8 10:44:40 2007
New Revision: 536273
URL: http://svn.apache.org/viewvc?view=rev&rev=536273
Log:
First step in backporting markup fragments
Added:
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/Markup.java
- copied, changed from r535650, incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupFragment.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceData.java
- copied, changed from r535650, incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/Markup.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MergedMarkup.java
Removed:
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupFragment.java
Modified:
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/IMarkup.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupCache.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupElement.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupParser.java
incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupStream.java
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/IMarkup.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/IMarkup.java?view=diff&rev=536273&r1=536272&r2=536273
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/IMarkup.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/IMarkup.java Tue May 8 10:44:40 2007
@@ -30,7 +30,7 @@
public abstract interface IMarkup
{
/** Placeholder that indicates no markup */
- public static final Markup NO_MARKUP = new Markup();
+ public static final MarkupResourceData NO_MARKUP = new MarkupResourceData();
/**
* Find the markup element index of the component with 'path'
Copied: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/Markup.java (from r535650, incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupFragment.java)
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/Markup.java?view=diff&rev=536273&p1=incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupFragment.java&r1=535650&p2=incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/Markup.java&r2=536273
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupFragment.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/Markup.java Tue May 8 10:44:40 2007
@@ -18,8 +18,12 @@
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.apache.wicket.util.string.AppendingStringBuffer;
import org.slf4j.Logger;
@@ -30,35 +34,47 @@
* A list of markup elements associated with a Markup. Might be all elements of
* a markup resource, might be just the elements associated with a specific tag.
*
- * @see org.apache.wicket.markup.Markup
+ * @see org.apache.wicket.markup.MarkupResourceData
* @see org.apache.wicket.markup.MarkupElement
* @see org.apache.wicket.markup.ComponentTag
* @see org.apache.wicket.markup.RawMarkup
*
* @author Juergen Donnerstag
*/
-public class MarkupFragment
+public class Markup
{
- private static final Logger log = LoggerFactory.getLogger(MarkupFragment.class);
+ private static final Logger log = LoggerFactory.getLogger(Markup.class);
/** Placeholder that indicates no markup */
- public static final MarkupFragment NO_MARKUP_FRAGMENT = new MarkupFragment(Markup.NO_MARKUP);
+ public static final Markup NO_MARKUP = new Markup(MarkupResourceData.NO_MARKUP_RESOURCE_DATA);
/** The list of markup elements */
private/* final */List markupElements;
/** The associate markup */
- private final Markup markup;
+ private final MarkupResourceData markupResourceData;
+
+ /**
+ * A cache which maps (componentPath + id) to the componentTags index in the
+ * markup
+ */
+ private Map componentMap;
+
+ /**
+ * Used at markup load time to maintain the current component path (not id)
+ * while adding markup elements to this Markup instance
+ */
+ private StringBuffer currentPath;
/**
* Constructor
*
- * @param markup
+ * @param markupResourceData
* The associated Markup
*/
- MarkupFragment(final Markup markup)
+ Markup(final MarkupResourceData markupResourceData)
{
- this.markup = markup;
+ this.markupResourceData = markupResourceData;
this.markupElements = new ArrayList();
}
@@ -68,7 +84,7 @@
public final String toString()
{
final AppendingStringBuffer buf = new AppendingStringBuffer(400);
- buf.append(this.markup.toString());
+ buf.append(this.markupResourceData.toString());
buf.append("\n");
final Iterator iter = this.markupElements.iterator();
@@ -100,9 +116,9 @@
*
* @return The associated markup
*/
- public final Markup getMarkup()
+ public final MarkupResourceData getMarkupResourceData()
{
- return this.markup;
+ return this.markupResourceData;
}
/**
@@ -122,7 +138,7 @@
*
* @param markupElement
*/
- final void addMarkupElement(final MarkupElement markupElement)
+ final public void addMarkupElement(final MarkupElement markupElement)
{
this.markupElements.add(markupElement);
}
@@ -133,7 +149,7 @@
* @param pos
* @param markupElement
*/
- final void addMarkupElement(final int pos, final MarkupElement markupElement)
+ final public void addMarkupElement(final int pos, final MarkupElement markupElement)
{
this.markupElements.add(pos, markupElement);
}
@@ -154,6 +170,8 @@
}
this.markupElements = Collections.unmodifiableList(this.markupElements);
+
+ initialize();
}
/**
@@ -214,5 +232,222 @@
index -= 1;
}
};
+ }
+
+ /**
+ * Add the tag to the local cache if open or open-close and if wicket:id is
+ * present
+ *
+ * @param index
+ * @param tag
+ */
+ private void addToCache(final int index, final ComponentTag tag)
+ {
+ // Only if the tag has wicket:id="xx" and open or open-close
+ if ((tag.isOpen() || tag.isOpenClose()) && tag.getAttributes().containsKey(getMarkupResourceData().getWicketId()))
+ {
+ // Add the tag to the cache
+ if (this.componentMap == null)
+ {
+ this.componentMap = new HashMap();
+ }
+
+ /*
+ * XXX cleanup - this fragment check probably needs to be in
+ * componenttag.isWantToBeDirectMarkupChild() or something similar
+ * instead of being here
+ */
+ final boolean fragment = (tag instanceof WicketTag && ((WicketTag)tag).isFragementTag());
+
+ final String key;
+
+ if (tag.getPath() != null && !fragment/* WICKET-404 */)
+ {
+ key = tag.getPath() + ":" + tag.getId();
+ }
+ else
+ {
+ key = tag.getId();
+ }
+ this.componentMap.put(key, new Integer(index));
+ }
+ }
+
+ /**
+ * Set the components path within the markup and add the component tag to
+ * the local cache
+ *
+ * @param componentPath
+ * @param tag
+ * @return componentPath
+ */
+ private StringBuffer setComponentPathForTag(final StringBuffer componentPath,
+ final ComponentTag tag)
+ {
+ // Only if the tag has wicket:id="xx" and open or open-close
+ if ((tag.isOpen() || tag.isOpenClose()) && tag.getAttributes().containsKey(markupResourceData.getWicketId()))
+ {
+ // With open-close the path does not change. It can/will not have
+ // children. The same is true for HTML tags like <br> or <img>
+ // which might not have close tags.
+ if (tag.isOpenClose() || tag.hasNoCloseTag())
+ {
+ // Set the components path.
+ if ((this.currentPath != null) && (this.currentPath.length() > 0))
+ {
+ tag.setPath(this.currentPath.toString());
+ }
+ }
+ else
+ {
+ // Set the components path.
+ if (this.currentPath == null)
+ {
+ this.currentPath = new StringBuffer(100);
+ }
+ else if (this.currentPath.length() > 0)
+ {
+ tag.setPath(this.currentPath.toString());
+ this.currentPath.append(':');
+ }
+
+ // .. and append the tags id to the component path for the
+ // children to come
+ this.currentPath.append(tag.getId());
+ }
+ }
+ else if (tag.isClose() && (this.currentPath != null))
+ {
+ // For example <wicket:message> does not have an id
+ if ((tag.getOpenTag() == null)
+ || tag.getOpenTag().getAttributes().containsKey(markupResourceData.getWicketId()))
+ {
+ // Remove the last element from the component path
+ int index = this.currentPath.lastIndexOf(":");
+ if (index != -1)
+ {
+ this.currentPath.setLength(index);
+ }
+ else
+ {
+ this.currentPath.setLength(0);
+ }
+ }
+ }
+
+ return this.currentPath;
+ }
+
+ /**
+ * Create an iterator for the component tags in the markup.
+ *
+ * @param startIndex
+ * The index to start with
+ * @param matchClass
+ * Iterate over elements matching the class
+ * @return ComponentTagIterator
+ */
+ public Iterator componentTagIterator(final int startIndex, final Class matchClass)
+ {
+ return iterator(startIndex, matchClass);
+ }
+
+ /**
+ * Find the markup element index of the component with 'path'
+ *
+ * @param path
+ * The component path expression
+ * @param id
+ * The component's id to search for
+ * @return -1, if not found
+ */
+ public int findComponentIndex(final String path, final String id)
+ {
+ if ((id == null) || (id.length() == 0))
+ {
+ throw new IllegalArgumentException("Parameter 'id' must not be null");
+ }
+
+ // TODO Post 1.2: A component path e.g. "panel:label" does not match 1:1
+ // with the markup in case of ListView, where the path contains a number
+ // for each list item. E.g. list:0:label. What we currently do is simply
+ // remove the number from the path and hope that no user uses an integer
+ // for a component id. This is a hack only. A much better solution would
+ // delegate to the various components recursivly to search within there
+ // realm only for the components markup. ListItems could then simply
+ // do nothing and delegate to their parents.
+ String completePath = (path == null || path.length() == 0 ? id : path + ":" + id);
+
+ // s/:\d+//g
+ Pattern re = Pattern.compile(":\\d+");
+ Matcher matcher = re.matcher(completePath);
+ completePath = matcher.replaceAll("");
+
+ // All component tags are registered with the cache
+ if (this.componentMap == null)
+ {
+ // not found
+ return -1;
+ }
+
+ final Integer value = (Integer)this.componentMap.get(completePath);
+ if (value == null)
+ {
+ // not found
+ return -1;
+ }
+
+ // return the components position in the markup stream
+ return value.intValue();
+ }
+
+ /**
+ * @param that
+ * The markup to compare with
+ * @return True if the two markups are equal
+ */
+ public boolean equalTo(final Markup that)
+ {
+ final MarkupStream thisStream = new MarkupStream(this);
+ final MarkupStream thatStream = new MarkupStream(that);
+
+ // Compare the streams
+ return thisStream.equalTo(thatStream);
+ }
+
+ /**
+ * Initialize the index where wicket tags can be found
+ */
+ protected void initialize()
+ {
+ // Reset
+ this.componentMap = null;
+
+ if (markupElements != null)
+ {
+ // HTML tags like <img> may not have a close tag. But because that
+ // can only be detected until later on in the sequential markup
+ // reading loop, we only can do it now.
+ StringBuffer componentPath = null;
+ for (int i = 0; i < size(); i++)
+ {
+ MarkupElement elem = get(i);
+ if (elem instanceof ComponentTag)
+ {
+ ComponentTag tag = (ComponentTag)elem;
+
+ // Set the tags components path
+ componentPath = setComponentPathForTag(componentPath, tag);
+
+ // and add it to the local cache to be found fast if
+ // required
+ addToCache(i, tag);
+ }
+ }
+ }
+
+ // The variable is only needed while adding markup elements.
+ // initialize() is invoked after all elements have been added.
+ this.currentPath = null;
}
}
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupCache.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupCache.java?view=diff&rev=536273&r1=536272&r2=536273
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupCache.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupCache.java Tue May 8 10:44:40 2007
@@ -171,25 +171,24 @@
}
// get the base markup
- final Markup baseMarkup = getMarkup(container, markup.getResource().getMarkupClass()
+ final Markup baseMarkup = getMarkup(container, markup.getMarkupResourceData().getResource().getMarkupClass()
.getSuperclass());
if (baseMarkup == Markup.NO_MARKUP)
{
throw new MarkupNotFoundException(
"Parent markup of inherited markup not found. Component class: "
- + markup.getResource().getContainerInfo().getContainerClass().getName()
+ + markup.getMarkupResourceData().getResource().getContainerInfo().getContainerClass().getName()
+ " Enable debug messages for org.apache.wicket.util.resource.Resource to get a list of all filenames tried.");
}
- final CharSequence key = markup.getResource().getCacheKey();
+ final CharSequence key = markup.getMarkupResourceData().getResource().getCacheKey();
if (key != null)
{
// register an after-load listener for base markup. The listener
// implementation will remove the derived markup which must be
- // merged
- // with the base markup
- afterLoadListeners.add(baseMarkup.getResource(), new IChangeListener()
+ // merged with the base markup
+ afterLoadListeners.add(baseMarkup.getMarkupResourceData().getResource(), new IChangeListener()
{
/**
* Make sure there is only one listener per derived markup
@@ -215,9 +214,9 @@
{
if (log.isDebugEnabled())
{
- log.debug("Remove derived markup from cache: " + markup.getResource());
+ log.debug("Remove derived markup from cache: " + markup.getMarkupResourceData().getResource());
}
- removeMarkup(markup.getResource());
+ removeMarkup(markup.getMarkupResourceData().getResource());
}
});
}
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupElement.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupElement.java?view=diff&rev=536273&r1=536272&r2=536273
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupElement.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupElement.java Tue May 8 10:44:40 2007
@@ -29,7 +29,7 @@
* Wicket.
* </ul>
*
- * @see Markup
+ * @see MarkupResourceData
* @see org.apache.wicket.markup.RawMarkup
* @see ComponentTag
* @author Jonathan Locke
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupParser.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupParser.java?view=diff&rev=536273&r1=536272&r2=536273
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupParser.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupParser.java Tue May 8 10:44:40 2007
@@ -55,7 +55,7 @@
* @see IMarkupFilter
* @see IMarkupParserFactory
* @see IMarkupSettings
- * @see Markup
+ * @see MarkupResourceData
*
* @author Jonathan Locke
* @author Juergen Donnerstag
@@ -113,8 +113,10 @@
this.xmlParser = xmlParser;
this.markupSettings = Application.get().getMarkupSettings();
- this.markup = new Markup();
- this.markup.setResource(resource);
+ MarkupResourceData markup = new MarkupResourceData();
+ markup.setResource(resource);
+
+ this.markup = new Markup(markup);
// Initialize the markup filter chain
initializeMarkupFilters();
@@ -128,7 +130,7 @@
*/
public final void setWicketNamespace(final String namespace)
{
- this.markup.setWicketNamespace(namespace);
+ this.markup.getMarkupResourceData().setWicketNamespace(namespace);
}
/**
@@ -139,7 +141,7 @@
*/
protected MarkupResourceStream getMarkupResourceStream()
{
- return this.markup.getResource();
+ return this.markup.getMarkupResourceData().getResource();
}
/**
@@ -151,15 +153,17 @@
// Chain together all the different markup filters and configure them
this.markupFilterChain = xmlParser;
- appendMarkupFilter(new WicketTagIdentifier(markup));
+ MarkupResourceData markupResourceData = this.markup.getMarkupResourceData();
+
+ appendMarkupFilter(new WicketTagIdentifier(markupResourceData));
appendMarkupFilter(new TagTypeHandler());
appendMarkupFilter(new HtmlHandler());
appendMarkupFilter(new WicketRemoveTagHandler());
appendMarkupFilter(new WicketLinkTagHandler());
- appendMarkupFilter(new WicketNamespaceHandler(markup));
+ appendMarkupFilter(new WicketNamespaceHandler(markupResourceData));
// Provided the wicket component requesting the markup is known ...
- final MarkupResourceStream resource = markup.getResource();
+ final MarkupResourceStream resource = markupResourceData.getResource();
if (resource != null)
{
final ContainerInfo containerInfo = resource.getContainerInfo();
@@ -171,7 +175,7 @@
// Pages require additional handlers
if (Page.class.isAssignableFrom(containerInfo.getContainerClass()))
{
- appendMarkupFilter(new HtmlHeaderSectionHandler(this.markup));
+ appendMarkupFilter(new HtmlHeaderSectionHandler(markup));
}
appendMarkupFilter(new HeadForceTagIdHandler(containerInfo.getContainerClass()));
@@ -257,16 +261,18 @@
*/
public final Markup parse() throws IOException, ResourceStreamNotFoundException
{
+ MarkupResourceData markupResourceData = this.markup.getMarkupResourceData();
+
// Initialize the xml parser
- this.xmlParser.parse(this.markup.getResource().getInputStream(), this.markupSettings
+ this.xmlParser.parse(markupResourceData.getResource().getInputStream(), this.markupSettings
.getDefaultMarkupEncoding());
// parse the xml markup and tokenize it into wicket relevant markup
// elements
parseMarkup();
- this.markup.setEncoding(xmlParser.getEncoding());
- this.markup.setXmlDeclaration(xmlParser.getXmlDeclaration());
+ markupResourceData.setEncoding(xmlParser.getEncoding());
+ markupResourceData.setXmlDeclaration(xmlParser.getXmlDeclaration());
return this.markup;
}
@@ -361,10 +367,10 @@
this.markup.addMarkupElement(new RawMarkup(text));
}
- this.markup.setEncoding(xmlParser.getEncoding());
- this.markup.setXmlDeclaration(xmlParser.getXmlDeclaration());
+ this.markup.getMarkupResourceData().setEncoding(xmlParser.getEncoding());
+ this.markup.getMarkupResourceData().setXmlDeclaration(xmlParser.getXmlDeclaration());
- final MarkupStream markupStream = new MarkupStream(markup);
+ final MarkupStream markupStream = new MarkupStream(this.markup);
markupStream.setCurrentIndex(this.markup.size() - 1);
throw new MarkupException(markupStream, ex.getMessage(), ex);
}
Copied: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceData.java (from r535650, incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/Markup.java)
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceData.java?view=diff&rev=536273&p1=incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/Markup.java&r1=535650&p2=incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceData.java&r2=536273
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/Markup.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupResourceData.java Tue May 8 10:44:40 2007
@@ -16,12 +16,6 @@
*/
package org.apache.wicket.markup;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,15 +30,12 @@
* @author Jonathan Locke
* @author Juergen Donnerstag
*/
-public class Markup
+public class MarkupResourceData
{
- private static final Logger log = LoggerFactory.getLogger(Markup.class);
+ private static final Logger log = LoggerFactory.getLogger(MarkupResourceData.class);
/** Placeholder that indicates no markup */
- public static final Markup NO_MARKUP = new Markup();
-
- /** The list of markup elements */
- private MarkupFragment markup;
+ public static final MarkupResourceData NO_MARKUP_RESOURCE_DATA = new MarkupResourceData();
/** The markup's resource stream for diagnostic purposes */
private MarkupResourceStream resource;
@@ -58,81 +49,18 @@
/** Wicket namespace: <html xmlns:wicket="http://wicket.apache.org"> */
private String wicketNamespace;
- /** == wicketNamespace + ":id" */
+ /** == wicket namespace name + ":id" */
private String wicketId;
/**
- * Used at markup load time to maintain the current component path (not id)
- * while adding markup elements to this Markup instance
- */
- private StringBuffer currentPath;
-
- /**
- * A cache which maps (componentPath + id) to the componentTags index in the
- * markup
- */
- private Map componentMap;
-
- /**
* Constructor
*/
- Markup()
+ MarkupResourceData()
{
- this.markup = new MarkupFragment(this);
setWicketNamespace(ComponentTag.DEFAULT_WICKET_NAMESPACE);
}
/**
- * Initialize the index where <head> can be found.
- */
- protected void initialize()
- {
- // Reset
- this.componentMap = null;
-
- if (markup != null)
- {
- // HTML tags like <img> may not have a close tag. But because that
- // can only be detected until later on in the sequential markup
- // reading loop, we only can do it now.
- StringBuffer componentPath = null;
- for (int i = 0; i < this.markup.size(); i++)
- {
- MarkupElement elem = this.markup.get(i);
- if (elem instanceof ComponentTag)
- {
- ComponentTag tag = (ComponentTag)elem;
-
- // Set the tags components path
- componentPath = setComponentPathForTag(componentPath, tag);
-
- // and add it to the local cache to be found fast if
- // required
- addToCache(i, tag);
- }
- }
- }
-
- // The variable is only needed while adding markup elements.
- // initialize() is invoked after all elements have been added.
- this.currentPath = null;
- }
-
- /**
- * @param that
- * The markup to compare with
- * @return True if the two markups are equal
- */
- public boolean equalTo(final Markup that)
- {
- final MarkupStream thisStream = new MarkupStream(this);
- final MarkupStream thatStream = new MarkupStream(that);
-
- // Compare the streams
- return thisStream.equalTo(thatStream);
- }
-
- /**
* @return String representation of markup list
*/
public String toString()
@@ -148,28 +76,6 @@
}
/**
- * @return String representation of markup list
- */
- public String toDebugString()
- {
- return this.markup.toString();
- }
-
- /**
- * For Wicket it would be sufficient for this method to be package
- * protected. However to allow wicket-bench easy access to the information
- * ...
- *
- * @param index
- * Index into markup list
- * @return Markup element
- */
- public MarkupElement get(final int index)
- {
- return markup.get(index);
- }
-
- /**
* Gets the resource that contains this markup
*
* @return The resource where this markup came from
@@ -180,18 +86,6 @@
}
/**
- * For Wicket it would be sufficient for this method to be package
- * protected. However to allow wicket-bench easy access to the information
- * ...
- *
- * @return Number of markup elements
- */
- public int size()
- {
- return markup.size();
- }
-
- /**
* Return the XML declaration string, in case if found in the markup.
*
* @return Null, if not found.
@@ -224,54 +118,14 @@
}
/**
- * Find the markup element index of the component with 'path'
*
- * @param path
- * The component path expression
- * @param id
- * The component's id to search for
- * @return -1, if not found
+ * @return usually it is "wicket:id"
*/
- public int findComponentIndex(final String path, final String id)
+ final public String getWicketId()
{
- if ((id == null) || (id.length() == 0))
- {
- throw new IllegalArgumentException("Parameter 'id' must not be null");
- }
-
- // TODO Post 1.2: A component path e.g. "panel:label" does not match 1:1
- // with the markup in case of ListView, where the path contains a number
- // for each list item. E.g. list:0:label. What we currently do is simply
- // remove the number from the path and hope that no user uses an integer
- // for a component id. This is a hack only. A much better solution would
- // delegate to the various components recursivly to search within there
- // realm only for the components markup. ListItems could then simply
- // do nothing and delegate to their parents.
- String completePath = (path == null || path.length() == 0 ? id : path + ":" + id);
-
- // s/:\d+//g
- Pattern re = Pattern.compile(":\\d+");
- Matcher matcher = re.matcher(completePath);
- completePath = matcher.replaceAll("");
-
- // All component tags are registered with the cache
- if (this.componentMap == null)
- {
- // not found
- return -1;
- }
-
- final Integer value = (Integer)this.componentMap.get(completePath);
- if (value == null)
- {
- // not found
- return -1;
- }
-
- // return the components position in the markup stream
- return value.intValue();
+ return wicketId;
}
-
+
/**
* Sets encoding.
*
@@ -322,170 +176,4 @@
{
this.resource = resource;
}
-
- /**
- * Add a MarkupElement
- *
- * @param markupElement
- */
- public final void addMarkupElement(final MarkupElement markupElement)
- {
- this.markup.addMarkupElement(markupElement);
- }
-
- /**
- * Add a MarkupElement
- *
- * @param pos
- * @param markupElement
- */
- final void addMarkupElement(final int pos, final MarkupElement markupElement)
- {
- this.markup.addMarkupElement(pos, markupElement);
- }
-
- /**
- * Add the tag to the local cache if open or open-close and if wicket:id is
- * present
- *
- * @param index
- * @param tag
- */
- private void addToCache(final int index, final ComponentTag tag)
- {
- // Only if the tag has wicket:id="xx" and open or open-close
- if ((tag.isOpen() || tag.isOpenClose()) && tag.getAttributes().containsKey(wicketId))
- {
- // Add the tag to the cache
- if (this.componentMap == null)
- {
- this.componentMap = new HashMap();
- }
-
- /*
- * XXX cleanup - this fragment check probably needs to be in
- * componenttag.isWantToBeDirectMarkupChild() or something similar
- * instead of being here
- */
- final boolean fragment = (tag instanceof WicketTag && ((WicketTag)tag).isFragementTag());
-
- final String key;
-
- if (tag.getPath() != null && !fragment/* WICKET-404 */)
- {
- key = tag.getPath() + ":" + tag.getId();
- }
- else
- {
- key = tag.getId();
- }
- this.componentMap.put(key, new Integer(index));
- }
- }
-
- /**
- * Set the components path within the markup and add the component tag to
- * the local cache
- *
- * @param componentPath
- * @param tag
- * @return componentPath
- */
- private StringBuffer setComponentPathForTag(final StringBuffer componentPath,
- final ComponentTag tag)
- {
- // Only if the tag has wicket:id="xx" and open or open-close
- if ((tag.isOpen() || tag.isOpenClose()) && tag.getAttributes().containsKey(wicketId))
- {
- // With open-close the path does not change. It can/will not have
- // children. The same is true for HTML tags like <br> or <img>
- // which might not have close tags.
- if (tag.isOpenClose() || tag.hasNoCloseTag())
- {
- // Set the components path.
- if ((this.currentPath != null) && (this.currentPath.length() > 0))
- {
- tag.setPath(this.currentPath.toString());
- }
- }
- else
- {
- // Set the components path.
- if (this.currentPath == null)
- {
- this.currentPath = new StringBuffer(100);
- }
- else if (this.currentPath.length() > 0)
- {
- tag.setPath(this.currentPath.toString());
- this.currentPath.append(':');
- }
-
- // .. and append the tags id to the component path for the
- // children to come
- this.currentPath.append(tag.getId());
- }
- }
- else if (tag.isClose() && (this.currentPath != null))
- {
- // For example <wicket:message> does not have an id
- if ((tag.getOpenTag() == null)
- || tag.getOpenTag().getAttributes().containsKey(wicketId))
- {
- // Remove the last element from the component path
- int index = this.currentPath.lastIndexOf(":");
- if (index != -1)
- {
- this.currentPath.setLength(index);
- }
- else
- {
- this.currentPath.setLength(0);
- }
- }
- }
-
- return this.currentPath;
- }
-
- /**
- * Make all tags immutable and the list of elements unmodifable.
- */
- final void makeImmutable()
- {
- this.markup.makeImmutable();
-
- // We assume all markup elements have now been added. It is
- // now time to initialize all remaining variables based
- // on the markup loaded, which could not be initialized
- // earlier on.
- initialize();
- }
-
- /**
- * Reset the markup to its defaults, except for the wicket namespace which
- * remains unchanged.
- */
- final void reset()
- {
- this.markup = new MarkupFragment(this);
- this.resource = null;
- this.xmlDeclaration = null;
- this.encoding = null;
- this.currentPath = null;
- }
-
- /**
- * Create an iterator for the component tags in the markup.
- *
- * @param startIndex
- * The index to start with
- * @param matchClass
- * Iterate over elements matching the class
- * @return ComponentTagIterator
- */
- public Iterator componentTagIterator(final int startIndex, final Class matchClass)
- {
- return this.markup.iterator(startIndex, matchClass);
- }
-}
+}
\ No newline at end of file
Modified: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupStream.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupStream.java?view=diff&rev=536273&r1=536272&r2=536273
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupStream.java (original)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MarkupStream.java Tue May 8 10:44:40 2007
@@ -60,14 +60,14 @@
/**
* Constructor
*
- * @param markup
+ * @param markupFragment
* List of markup elements
*/
- public MarkupStream(final Markup markup)
+ public MarkupStream(final Markup markupFragment)
{
- this.markup = markup;
+ this.markup = markupFragment;
- if (markup.size() > 0)
+ if (markupFragment.size() > 0)
{
current = get(currentIndex);
}
@@ -79,7 +79,7 @@
*/
protected MarkupStream()
{
- markup = null;
+ this.markup = null;
}
/**
@@ -243,7 +243,7 @@
*/
public final Class getContainerClass()
{
- return markup.getResource().getMarkupClass();
+ return markup.getMarkupResourceData().getResource().getMarkupClass();
}
/**
@@ -263,7 +263,7 @@
*/
public final String getEncoding()
{
- return markup.getEncoding();
+ return markup.getMarkupResourceData().getEncoding();
}
/**
@@ -271,7 +271,7 @@
*/
public IResourceStream getResource()
{
- return markup.getResource();
+ return markup.getMarkupResourceData().getResource();
}
/**
@@ -296,7 +296,7 @@
*/
public final String getWicketNamespace()
{
- return this.markup.getWicketNamespace();
+ return markup.getMarkupResourceData().getWicketNamespace();
}
/**
@@ -306,7 +306,7 @@
*/
public String getXmlDeclaration()
{
- return markup.getXmlDeclaration();
+ return markup.getMarkupResourceData().getXmlDeclaration();
}
/**
Added: incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MergedMarkup.java
URL: http://svn.apache.org/viewvc/incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MergedMarkup.java?view=auto&rev=536273
==============================================================================
--- incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MergedMarkup.java (added)
+++ incubator/wicket/trunk/jdk-1.4/wicket/src/main/java/org/apache/wicket/markup/MergedMarkup.java Tue May 8 10:44:40 2007
@@ -0,0 +1,397 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.wicket.markup;
+
+import org.apache.wicket.Page;
+import org.apache.wicket.WicketRuntimeException;
+import org.apache.wicket.markup.parser.XmlTag;
+import org.apache.wicket.markup.parser.filter.HtmlHeaderSectionHandler;
+import org.apache.wicket.util.string.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * A Markup class which represents merged markup, as it is required for markup
+ * inheritance.
+ * <p>
+ * The Markups are merged at load time. Deep markup hierarchies are supported.
+ * Multiple inheritance is not.
+ * <p>
+ * The markup resource file, which is associated with the markup, will be the
+ * resource of the requested markup file. The base markup resources are not.
+ * <p>
+ * Base Markup must have a <wicket:hild/> tag which the position where the
+ * derived markup is inserted. From the derived markup all tags in between
+ * <wicket:extend> and </wicket:extend> will be inserted.
+ * <p>
+ * In addition, all <wicket:head> regions are copied as well as the body
+ * onLoad attribute. This allows to develop completely self-contained plug &
+ * play components including javascript etc.
+ *
+ * @author Juergen Donnerstag
+ */
+public class MergedMarkup extends Markup
+{
+ private final static Logger log = LoggerFactory.getLogger(MergedMarkup.class);
+
+ /**
+ * Merge inherited and base markup.
+ *
+ * @param markup
+ * The inherited markup
+ * @param baseMarkup
+ * The base markup
+ * @param extendIndex
+ * Index where <wicket:extend> has been found
+ */
+ MergedMarkup(final Markup markup, final Markup baseMarkup, int extendIndex)
+ {
+ super(new MarkupResourceData());
+
+ // Copy settings from derived markup
+ getMarkupResourceData().setResource(markup.getMarkupResourceData().getResource());
+ getMarkupResourceData().setXmlDeclaration(markup.getMarkupResourceData().getXmlDeclaration());
+ getMarkupResourceData().setEncoding(markup.getMarkupResourceData().getEncoding());
+ getMarkupResourceData().setWicketNamespace(markup.getMarkupResourceData().getWicketNamespace());
+
+ if (log.isDebugEnabled())
+ {
+ String derivedResource = Strings.afterLast(markup.getMarkupResourceData().getResource().toString(), '/');
+ String baseResource = Strings.afterLast(baseMarkup.getMarkupResourceData().getResource().toString(), '/');
+ log.debug("Merge markup: derived markup: " + derivedResource + "; base markup: "
+ + baseResource);
+ }
+
+ // Merge derived and base markup
+ merge(markup, baseMarkup, extendIndex);
+
+ // Initialize internals based on new markup
+// initialize();
+
+ if (log.isDebugEnabled())
+ {
+ log.debug("Merge markup: " + toString());
+ }
+ }
+
+ /**
+ * Merge inherited and base markup.
+ *
+ * @param markup
+ * The inherited markup
+ * @param baseMarkup
+ * The base markup
+ * @param extendIndex
+ * Index where <wicket:extend> has been found
+ */
+ private void merge(final Markup markup, final Markup baseMarkup, int extendIndex)
+ {
+ // True if either <wicket:head> or <head> has been processed
+ boolean wicketHeadProcessed = false;
+
+ // Add all elements from the base markup to the new list
+ // until <wicket:child/> is found. Convert <wicket:child/>
+ // into <wicket:child> and add it as well.
+ WicketTag childTag = null;
+ int baseIndex = 0;
+ for (; baseIndex < baseMarkup.size(); baseIndex++)
+ {
+ MarkupElement element = baseMarkup.get(baseIndex);
+ if (element instanceof RawMarkup)
+ {
+ // Add the element to the merged list
+ addMarkupElement(element);
+ continue;
+ }
+
+ final ComponentTag tag = (ComponentTag)element;
+
+ // Make sure all tags of the base markup remember where they are
+ // from
+ if ((baseMarkup.getMarkupResourceData().getResource() != null) && (tag.getMarkupClass() == null))
+ {
+ tag.setMarkupClass(baseMarkup.getMarkupResourceData().getResource().getMarkupClass());
+ }
+
+ if (element instanceof WicketTag)
+ {
+ WicketTag wtag = (WicketTag)element;
+
+ // Found org.apache.wicket.child in base markup. In case of 3+ level
+ // inheritance make sure the child tag is not from one of the
+ // deeper levels
+ if (wtag.isChildTag()
+ && (tag.getMarkupClass() == baseMarkup.getMarkupResourceData().getResource().getMarkupClass()))
+ {
+ if (wtag.isOpenClose())
+ {
+ // <wicket:child /> => <wicket:child>...</wicket:child>
+ childTag = wtag;
+ WicketTag childOpenTag = (WicketTag)wtag.mutable();
+ childOpenTag.getXmlTag().setType(XmlTag.OPEN);
+ childOpenTag.setMarkupClass(baseMarkup.getMarkupResourceData().getResource().getMarkupClass());
+ addMarkupElement(childOpenTag);
+ break;
+ }
+ else if (wtag.isOpen())
+ {
+ // <wicket:child>
+ addMarkupElement(wtag);
+ break;
+ }
+ else
+ {
+ throw new WicketRuntimeException("Did not expect a </wicket:child> tag in "
+ + baseMarkup.toString());
+ }
+ }
+
+ // Process the head of the extended markup only once
+ if (wicketHeadProcessed == false)
+ {
+ // if </wicket:head> in base markup
+ if (wtag.isClose() && wtag.isHeadTag())
+ {
+ wicketHeadProcessed = true;
+
+ // Add the current close tag
+ addMarkupElement(wtag);
+
+ // Add the <wicket:head> body from the derived markup.
+ copyWicketHead(markup, extendIndex);
+
+ // Do not add the current tag. It has already been
+ // added.
+ continue;
+ }
+
+ // if <wicket:panel> or ... in base markup
+ if (wtag.isOpen() && wtag.isMajorWicketComponentTag())
+ {
+ wicketHeadProcessed = true;
+
+ // Add the <wicket:head> body from the derived markup.
+ copyWicketHead(markup, extendIndex);
+ }
+ }
+ }
+
+ // Process the head of the extended markup only once
+ if (wicketHeadProcessed == false)
+ {
+ // if <head> in base markup
+ if ((tag.isClose() && TagUtils.isHeadTag(tag))
+ || (tag.isOpen() && TagUtils.isBodyTag(tag)))
+ {
+ wicketHeadProcessed = true;
+
+ // Add the <wicket:head> body from the derived markup.
+ copyWicketHead(markup, extendIndex);
+ }
+ }
+
+ // Add the element to the merged list
+ addMarkupElement(element);
+ }
+
+ if (baseIndex == baseMarkup.size())
+ {
+ throw new WicketRuntimeException("Expected to find <wicket:child/> in base markup: "
+ + baseMarkup.toString());
+ }
+
+ // Now append all elements from the derived markup starting with
+ // <wicket:extend> until </wicket:extend> to the list
+ for (; extendIndex < markup.size(); extendIndex++)
+ {
+ MarkupElement element = markup.get(extendIndex);
+ addMarkupElement(element);
+
+ if (element instanceof WicketTag)
+ {
+ WicketTag wtag = (WicketTag)element;
+ if (wtag.isExtendTag() && wtag.isClose())
+ {
+ break;
+ }
+ }
+ }
+
+ if (extendIndex == markup.size())
+ {
+ throw new WicketRuntimeException(
+ "Missing close tag </wicket:extend> in derived markup: " + markup.toString());
+ }
+
+ // If <wicket:child> than skip the body and find </wicket:child>
+ if (((ComponentTag)baseMarkup.get(baseIndex)).isOpen())
+ {
+ for (baseIndex++; baseIndex < baseMarkup.size(); baseIndex++)
+ {
+ MarkupElement element = baseMarkup.get(baseIndex);
+ if (element instanceof WicketTag)
+ {
+ WicketTag tag = (WicketTag)element;
+ if (tag.isChildTag() && tag.isClose())
+ {
+ // Ok, skipped the childs content
+ tag.setMarkupClass(baseMarkup.getMarkupResourceData().getResource().getMarkupClass());
+ addMarkupElement(tag);
+ break;
+ }
+ else
+ {
+ throw new WicketRuntimeException(
+ "Wicket tags like <wicket:xxx> are not allowed in between <wicket:child> and </wicket:child> tags: "
+ + markup.toString());
+ }
+ }
+ else if (element instanceof ComponentTag)
+ {
+ throw new WicketRuntimeException(
+ "Wicket tags identified by wicket:id are not allowed in between <wicket:child> and </wicket:child> tags: "
+ + markup.toString());
+ }
+ }
+
+ // </wicket:child> not found
+ if (baseIndex == baseMarkup.size())
+ {
+ throw new WicketRuntimeException(
+ "Expected to find </wicket:child> in base markup: " + baseMarkup.toString());
+ }
+ }
+ else
+ {
+ // And now all remaining elements from the derived markup.
+ // But first add </wicket:child>
+ WicketTag childCloseTag = (WicketTag)childTag.mutable();
+ childCloseTag.getXmlTag().setType(XmlTag.CLOSE);
+ childCloseTag.setMarkupClass(baseMarkup.getMarkupResourceData().getResource().getMarkupClass());
+ addMarkupElement(childCloseTag);
+ }
+
+ for (baseIndex++; baseIndex < baseMarkup.size(); baseIndex++)
+ {
+ MarkupElement element = baseMarkup.get(baseIndex);
+ addMarkupElement(element);
+
+ // Make sure all tags of the base markup remember where they are
+ // from
+ if ((element instanceof ComponentTag) && (baseMarkup.getMarkupResourceData().getResource() != null))
+ {
+ ComponentTag tag = (ComponentTag)element;
+ tag.setMarkupClass(baseMarkup.getMarkupResourceData().getResource().getMarkupClass());
+ }
+ }
+
+ // Automatically add <head> if missing and required. On a Page
+ // it must enclose ALL of the <wicket:head> tags.
+ // Note: HtmlHeaderSectionHandler does something similar, but because
+ // markup filters are not called for merged markup again, ...
+ if (Page.class.isAssignableFrom(markup.getMarkupResourceData().getResource().getMarkupClass()))
+ {
+ // Find the position inside the markup for first <wicket:head>,
+ // last </wicket:head> and <head>
+ int hasOpenWicketHead = -1;
+ int hasCloseWicketHead = -1;
+ int hasHead = -1;
+ for (int i = 0; i < size(); i++)
+ {
+ MarkupElement element = get(i);
+
+ if ((hasOpenWicketHead == -1) && (element instanceof WicketTag)
+ && ((WicketTag)element).isHeadTag())
+ {
+ hasOpenWicketHead = i;
+ }
+ else if ((element instanceof WicketTag) && ((WicketTag)element).isHeadTag()
+ && ((WicketTag)element).isClose())
+ {
+ hasCloseWicketHead = i;
+ }
+ else if ((hasHead == -1) && (element instanceof ComponentTag)
+ && TagUtils.isHeadTag((ComponentTag)element))
+ {
+ hasHead = i;
+ }
+ else if ((hasHead != -1) && (hasOpenWicketHead != -1))
+ {
+ break;
+ }
+ }
+
+ // If a <head> tag is missing, insert it automatically
+ if ((hasOpenWicketHead != -1) && (hasHead == -1))
+ {
+ final XmlTag headOpenTag = new XmlTag();
+ headOpenTag.setName("head");
+ headOpenTag.setType(XmlTag.OPEN);
+ final ComponentTag openTag = new ComponentTag(headOpenTag);
+ openTag.setId(HtmlHeaderSectionHandler.HEADER_ID);
+
+ final XmlTag headCloseTag = new XmlTag();
+ headCloseTag.setName(headOpenTag.getName());
+ headCloseTag.setType(XmlTag.CLOSE);
+ final ComponentTag closeTag = new ComponentTag(headCloseTag);
+ closeTag.setOpenTag(openTag);
+ closeTag.setId(HtmlHeaderSectionHandler.HEADER_ID);
+
+ addMarkupElement(hasOpenWicketHead, openTag);
+ addMarkupElement(hasCloseWicketHead + 2, closeTag);
+ }
+ }
+ }
+
+ /**
+ * Append the wicket:head regions from the extended markup to the current
+ * markup
+ *
+ * @param markup
+ * @param extendIndex
+ */
+ private void copyWicketHead(final Markup markup, int extendIndex)
+ {
+ boolean copy = false;
+ for (int i = 0; i < extendIndex; i++)
+ {
+ MarkupElement elem = markup.get(i);
+ if (elem instanceof WicketTag)
+ {
+ WicketTag etag = (WicketTag)elem;
+ if (etag.isHeadTag())
+ {
+ if (etag.isOpen())
+ {
+ copy = true;
+ }
+ else
+ {
+ addMarkupElement(elem);
+ break;
+ }
+ }
+ }
+
+ if (copy == true)
+ {
+ addMarkupElement(elem);
+ }
+ }
+ }
+}