You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beehive.apache.org by do...@apache.org on 2005/10/19 17:31:56 UTC

svn commit: r326581 [4/9] - in /beehive/trunk/netui: ant/ src/bootstrap/org/apache/beehive/netui/tools/tld/xdoclet/ src/jar-assembly/ src/pageflow/org/apache/beehive/netui/pageflow/ src/simple-tags/ src/simple-tags/org/ src/simple-tags/org/apache/ src/...

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/Behavior.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/Behavior.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/Behavior.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/Behavior.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,219 @@
+package org.apache.beehive.netui.simpletags.core;
+
+import org.apache.beehive.netui.core.urls.URLRewriterService;
+import org.apache.beehive.netui.pageflow.PageFlowContext;
+import org.apache.beehive.netui.script.ExpressionEvaluationException;
+import org.apache.beehive.netui.simpletags.appender.Appender;
+import org.apache.beehive.netui.simpletags.core.services.BehaviorStack;
+import org.apache.beehive.netui.simpletags.core.services.ErrorReporter;
+import org.apache.beehive.netui.simpletags.naming.INameInterceptor;
+import org.apache.beehive.netui.simpletags.util.ContextUtils;
+import org.apache.beehive.netui.util.Bundle;
+import org.apache.beehive.netui.util.logging.Logger;
+
+import java.util.List;
+
+abstract public class Behavior
+{
+    private static final Logger logger = Logger.getInstance(Behavior.class);
+    private TagErrorHandling _eh;
+
+    /**
+     * Return the name of the tag.  Used by error reporting to get the name of the tag.
+     * @return the name of the tag.
+     */
+    public abstract String getTagName();
+
+    //public abstract void setAttribute(String name, String value, String facet);
+
+    /**
+     * This will report an error from a tag.  The error will
+     * contain a message.  If error reporting is turned off,
+     * the message will be returned and the caller should throw
+     * a JspException to report the error.
+     * @param message - the message to register with the error
+     */
+    public void registerTagError(String message, Throwable e)
+    {
+        TagErrorHandling eh = getErrorHandling();
+        TagContext tagCtxt = ContextUtils.getTagContext();
+        ErrorReporter er = tagCtxt.getErrorReporter();
+        AbstractPageError err = er.registerTagError(message, getTagName(), e);
+        eh.setError(err);
+    }
+
+    public void registerTagError(AbstractPageError error)
+    {
+        TagErrorHandling eh = getErrorHandling();
+        TagContext tagCtxt = ContextUtils.getTagContext();
+        ErrorReporter er = tagCtxt.getErrorReporter();
+        AbstractPageError err = er.registerTagError(error);
+        eh.setError(err);
+    }
+
+    //******************* Lifecycle Methods ************************************
+
+    public final void start()
+    {
+        TagContext tagCtxt = ContextUtils.getTagContext();
+        BehaviorStack stack = tagCtxt.getBehaviorStack();
+        stack.push(this);
+    }
+
+    /**
+     * This method will push the Behavior on the behavior stack.  All overrides of
+     * this method should call this method so that the stack is maintained correctly.
+     */
+    public void preRender()
+    {
+    }
+
+    /**
+     * This method will render the start tag for the markup generated by the behavior.
+     * @param appender The <code>Appender</code> to write the markup into.
+     */
+    abstract public void renderStart(Appender appender);
+
+    /**
+     * This method will render teh end tag for the markup generted by the behavior.
+     * @param appender The <code>Appender</code> to write the markup into.
+     */
+    abstract public void renderEnd(Appender appender);
+
+    /**
+     * This method will pop the Behavior off of the Behavior stack.  It should always be called when
+     * the method is overriden.
+     */
+    public void postRender()
+    {
+   }
+
+    public final void terminate()
+    {
+        TagContext tagCtxt = ContextUtils.getTagContext();
+        BehaviorStack stack = tagCtxt.getBehaviorStack();
+        Behavior b = stack.pop();
+        assert(b != null) : "The Behavior stack is corrupt: Popped a null, expected a '" + getTagName() + "'";
+        assert(b == this) : "The Behavior stack is corrupt: Popped:" + b.getTagName() + ", exptected a " +
+                getTagName();
+    }
+
+
+    //******************* Protected Methods *************************************
+
+    /**
+     * This method will return <code>true</code> if there have been any errors registered on this
+     * tag.  Otherwise it returns <code>false</code>
+     * @return <code>true</code> if errors have been reported on this tag.
+     */
+    protected boolean hasErrors()
+    {
+        return (_eh != null);
+    }
+
+    /**
+     * This method will write out the <code>String</code> returned by <code>getErrorsReport</code> to the
+     * response output stream.
+     */
+    protected void reportErrors(Appender appender)
+    {
+        assert(_eh != null);
+
+        TagContext tagCtxt = ContextUtils.getTagContext();
+        BehaviorStack behaviorStack = tagCtxt.getBehaviorStack();
+        String err = _eh.getErrorsReport(getTagName());
+        IErrorCollector ec = (IErrorCollector) behaviorStack.findAncestorWithClass(this, IErrorCollector.class);
+        if (ec != null) {
+            ec.collectChildError(err);
+        }
+        else {
+            appender.append(err);
+        }
+    }
+
+    /**
+     * This method walks all of the naming chains and allows them to rewrite the <code>name</code> parameter.
+     * After the naming chain processes the name, it will be passed to <code>rewriteName</code> for final processing.
+     * If the naming chaing returned from <code>getNamingChain</code> returns null, the name will be passed to
+     * <code>rewriteName</code> and returned.  If there is an <code>ExpressionEvaluationException</code> thrown
+     * by a <code>INameInterceptor</code>, the error will be registered with the tag and <code>null</code> will
+     * be returned.
+     * @param name the name to rewrite
+     * @return the name after it was passed to all <code>INameInterceptor</code>s in the naming chain.
+     * @see #rewriteName
+     */
+    protected String applyNamingChain(String name)
+    {
+        assert (name != null) : "The name parameter may not be null";
+
+        List namingChain = getNamingChain();
+        if (namingChain == null)
+            return rewriteName(name);
+
+        try {
+            String newName = name;
+            int cnt = namingChain.size();
+            for (int i = 0; i < cnt; i++) {
+                newName = ((INameInterceptor) namingChain.get(i)).rewriteName(newName, this);
+           }
+
+            return rewriteName(newName);
+        }
+        catch (ExpressionEvaluationException ee) {
+            // if there is an expression evaluation error set the error and return null;
+            logger.error(Bundle.getString("Tags_ExpressionQualifyingFailure", name));
+
+            // create the expression info an add it to the error tracking
+            EvalErrorInfo info = new EvalErrorInfo();
+            info.evalExcp = ee;
+            info.expression = name;
+            info.attr = "dataSource";
+            info.tagType = getTagName();
+
+            // report the error
+            registerTagError(info);
+            return null;
+        }
+    }
+
+    /**
+     * This method will rewrite the name (id) by passing it to the
+     * URL Rewritter and getting back a value.
+     * @param name the name that will be rewritten
+     * @return a name that has been rewritten by the URLRewriterService.
+     */
+    final protected String rewriteName(String name)
+    {
+        PageFlowContext pfCtxt = ContextUtils.getPageFlowContext();
+        return URLRewriterService.getNamePrefix(pfCtxt.getServletContext(), pfCtxt.getRequest(), name) + name;
+    }
+
+
+    /**
+     * Return an <code>List</code> which represents a chain of <code>INameInterceptor</code>
+     * objects.  This method by default returns <code>null</code> and should be overridden
+     * by objects that support naming.
+     * @return an <code>List</code> that will contain <code>INameInterceptor</code> objects.
+     */
+    protected List getNamingChain()
+    {
+        return null;
+    }
+
+    //protected String getInlineError()
+    //{
+    //    return _eh.getInlineError(getTagName());
+    //}
+
+    /**
+     * This method will return an ErrorHandling instance.
+     * @return TagErrorHandling
+     */
+    private TagErrorHandling getErrorHandling()
+    {
+        if (_eh == null) {
+            _eh = new TagErrorHandling();
+        }
+        return _eh;
+    }
+}

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/Behavior.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/EvalErrorInfo.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/EvalErrorInfo.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/EvalErrorInfo.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/EvalErrorInfo.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.simpletags.core;
+
+import org.apache.beehive.netui.script.ExpressionEvaluationException;
+
+
+/**
+ * This is a "struct" class that contains the information for
+ * an expression evaluation error.
+ */
+public class EvalErrorInfo extends AbstractPageError
+{
+    /**
+     * The attribute of the tag that contained the expression
+     */
+    public String attr;
+
+    /**
+     * The expression that was being evaluated.
+     */
+    public String expression;
+
+    /**
+     * The exception which occured
+     */
+    public ExpressionEvaluationException evalExcp;
+}
+

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/EvalErrorInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/ExpressionHandling.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/ExpressionHandling.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/ExpressionHandling.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/ExpressionHandling.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.simpletags.core;
+
+import org.apache.beehive.netui.pageflow.PageFlowContext;
+import org.apache.beehive.netui.script.ExpressionEvaluationException;
+import org.apache.beehive.netui.script.ExpressionEvaluator;
+import org.apache.beehive.netui.script.ExpressionEvaluatorFactory;
+import org.apache.beehive.netui.script.ExpressionUpdateException;
+import org.apache.beehive.netui.script.common.ImplicitObjectUtil;
+import org.apache.beehive.netui.simpletags.util.ContextUtils;
+import org.apache.beehive.netui.util.Bundle;
+import org.apache.beehive.netui.util.logging.Logger;
+
+import javax.servlet.jsp.el.VariableResolver;
+
+public class ExpressionHandling
+{
+    private static final Logger logger = Logger.getInstance(ExpressionHandling.class);
+
+    private ExpressionEvaluator ee = null;      // cache the expression evaluator
+    private Behavior _tag;
+    private VariableResolver _vr;
+
+    public ExpressionHandling(Behavior tag, VariableResolver vr)
+    {
+        _tag = tag;
+        _vr = vr;
+    }
+
+    /**
+     * An internal method that is used for evaluating the <code>dataSource</code>
+     * attribute.  The <code>dataSource</code> attribute is handled specially
+     * becuase it must be of a particular format in order to be usable by
+     * NetUI tags.  This requirement exists in order to facilitate
+     * round-tripping the <code>dataSource</code> attribute as the
+     * <code>name</code> attribute of HTML tags.  Upon a POST, the <code>name</code>
+     * attribute is used as an l-value for an update expression in order
+     * to push any POST-ed data back into the bean from whence it came.
+     */
+    /**
+     * Ensure that the passed in data source is a valid expression.
+     * @param dataSource
+     * @param attrName
+     * @param errorId
+     * @return String
+     */
+    public String ensureValidExpression(String dataSource, String attrName, String errorId)
+    {
+        try {
+            boolean isExpr = isExpression(dataSource);
+
+            // @perf: if the isExpr call fails, this is an error condition, and the containsExpression
+            // call cost is irrelevant
+            if (!isExpr && containsExpression(dataSource)) {
+                String s = Bundle.getString(errorId, new Object[]{dataSource});
+                _tag.registerTagError(s, null);
+                return null;
+            }
+
+            if (!isExpr) {
+                String s = Bundle.getString(errorId, new Object[]{dataSource});
+                _tag.registerTagError(s, null);
+                return null;
+            }
+        }
+        catch (Exception e) {
+            // pass throw JspExceptions
+            //if (e instanceof JspException)
+            //    throw (JspException) e;
+
+            String s = Bundle.getString(errorId, new Object[]{dataSource});
+            _tag.registerTagError(s, e);
+            return null;
+        }
+        return dataSource;
+    }
+
+    /**
+     * @param expression
+     * @param attrName
+     * @return Object
+     */
+    public Object evaluateExpression(String expression, String attrName)
+    {
+        return evaluateExpressionInternal(expression, attrName);
+    }
+
+    /**
+     * This method will update the object identified by the <code>expr</code> parameter with
+     * the value.  If the
+     * @param expr
+     * @param value
+     * @throws org.apache.beehive.netui.script.ExpressionUpdateException
+     *
+     */
+    public void updateExpression(String expr, Object value)
+            throws ExpressionUpdateException
+    {
+        if (isExpression(expr)) {
+
+            PageFlowContext pfCtxt = ContextUtils.getPageFlowContext();
+            VariableResolver vr = ImplicitObjectUtil.getUpdateVariableResolver(pfCtxt.getRequest(), pfCtxt.getResponse(), false);
+            ExpressionEvaluatorFactory.getInstance().update(expr, value, vr, false);
+        }
+        else {
+            String s = Bundle.getString("Tags_BindingUpdateExpressionError", new Object[]{expr});
+            _tag.registerTagError(s, null);
+        }
+    }
+
+    /**
+     * Return a boolean indicating if the string contains an expression or not.
+     * @param expression a <code>String</code> that may or may not contain an expresion.
+     * @return <code>true</code> if the string contains an expression.
+     */
+    private boolean containsExpression(String expression)
+    {
+        // this shouldn't happen because we have checked in isExpression that the expression isn't null
+        assert (expression != null) : "The parameter expression must not be null.";
+        return getExpressionEvaluator().containsExpression(expression);
+    }
+
+    /**
+     */
+    private boolean isExpression(String expression)
+    {
+        if (expression == null)
+            return false;
+        return getExpressionEvaluator().isExpression(expression);
+    }
+
+    /**
+     * This is the real implementation of evaluateExpression.
+     * @param expression
+     * @param attrName
+     * @return The object that is the result of the expression evalution
+     */
+    private Object evaluateExpressionInternal(String expression, String attrName)
+    {
+        if (logger.isDebugEnabled()) logger.debug("evaluate expression=\"" + expression + "\"");
+
+        Object result = null;
+
+        try {
+            result = getExpressionEvaluator().evaluateStrict(expression, _vr);
+        }
+        catch (ExpressionEvaluationException ee) {
+            // if there is an expression evaluation error set the error and
+            // return null;
+
+            if (logger.isWarnEnabled())
+                logger.warn(Bundle.getString("Tags_ExpressionEvaluationFailure", expression));
+
+            // create the expression info an add it to the error tracking
+            EvalErrorInfo info = new EvalErrorInfo();
+            info.evalExcp = ee;
+            info.expression = expression;
+            info.attr = attrName;
+            info.tagType = _tag.getTagName();
+
+            // report the error
+            _tag.registerTagError(info);
+            return null;
+        }
+        catch (Exception e) {
+            String s = Bundle.getString("Tags_ExpressionEvaluationException", new Object[]{expression, e.toString()});
+            _tag.registerTagError(s, e);
+            return null;
+        }
+
+        if (logger.isDebugEnabled()) logger.debug("resulting object: " + result);
+        return result;
+    }
+
+    /**
+     * Return a cached instance of an <code>ExpressionEvaluator</code>.  This will be cached by the
+     * tag and release during <code>localRelease</code>.
+     * @return the <code>ExpressionEvalutor</code> for tis tag.
+     */
+    private final ExpressionEvaluator getExpressionEvaluator()
+    {
+        if (ee == null)
+            ee = ExpressionEvaluatorFactory.getInstance();
+
+        assert(ee != null);
+        return ee;
+    }
+}

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/ExpressionHandling.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IDocumentTypeProducer.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IDocumentTypeProducer.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IDocumentTypeProducer.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IDocumentTypeProducer.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,13 @@
+package org.apache.beehive.netui.simpletags.core;
+
+/**
+ * This interface will produce a Document type, defined in the enum TagRenderBase.
+ */
+public interface IDocumentTypeProducer
+{
+    /**
+     * This method will return the TagRenderBase enum value for the document type.
+     * @return int
+     */
+    public int getTargetDocumentType();
+}

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IDocumentTypeProducer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IErrorCollector.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IErrorCollector.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IErrorCollector.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IErrorCollector.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.simpletags.core;
+
+
+/**
+ * An <code>IErrorCollector</code> collects errors generated by the children and reports them.  This is used
+ * by container type tags who's children reportErrors.
+ */
+public interface IErrorCollector
+{
+    void collectChildError(String error);
+}

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IErrorCollector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IFormattable.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IFormattable.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IFormattable.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IFormattable.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.simpletags.core;
+
+import org.apache.beehive.netui.simpletags.behaviors.formatting.Formatter;
+
+/**
+ * Interface provided by Behaviors which support formatting.  A formatter may be
+ * added to a behavior which will run before the behavior renders it content.
+ */
+public interface IFormattable
+{
+    /**
+     * Adds a FormatTag.Formatter instance to the tag's set of formatters.
+     * @param formatter the formatter instance to add to the IFormattable tag's set of formatters.
+     */
+    public void addFormatter(Formatter formatter);
+
+    /**
+     * Indicate that a formatter has reported an error so the formattable needs to make sure that
+     * the body content is output so the placement of the error is visible in the page.
+     */
+    public void formatterHasError();
+}

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IFormattable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IHasPopupSupport.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IHasPopupSupport.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IHasPopupSupport.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IHasPopupSupport.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.simpletags.core;
+
+public interface IHasPopupSupport
+{
+    /**
+     * Enable popup support.
+     */
+    public void setPopup(boolean popup);
+
+    /**
+     * Get a helper to provide popup support.
+     */
+    public PopupSupport getPopupSupport();
+}

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IHasPopupSupport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IUrlParams.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IUrlParams.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IUrlParams.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IUrlParams.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.simpletags.core;
+
+/**
+ * This interfaces defines the contract allowing tags to add parameters which will
+ * be added to URLs which they generate.  The Parameter and ParameterMap tags both
+ * use this method to add parameters to ancestor tags.
+ */
+public interface IUrlParams
+{
+    /**
+     * This method will allow a tag that produces one or more Urls to have parameters set
+     * on the tag.  The name and value should be required.  The facet is optional, and
+     * allows tags producing more than one URL to have parameters set on different URLs.
+     * @param name  The name of the parameter to be added to the URL.
+     * @param value The value of the parameter.
+     * @param facet The name of a facet for which the parameter should be added.
+     */
+    public void addParameter(String name, Object value, String facet) ;
+}

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/IUrlParams.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/PopupSupport.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/PopupSupport.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/PopupSupport.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/PopupSupport.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License";
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.simpletags.core;
+
+import org.apache.beehive.netui.pageflow.internal.InternalConstants;
+import org.apache.beehive.netui.pageflow.scoping.ScopedRequest;
+import org.apache.beehive.netui.pageflow.scoping.ScopedServletUtils;
+import org.apache.beehive.netui.simpletags.core.services.ScriptReporter;
+import org.apache.beehive.netui.simpletags.javascript.CoreScriptFeature;
+import org.apache.beehive.netui.simpletags.util.RequestUtils;
+import org.apache.beehive.netui.util.internal.InternalStringBuilder;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+public class PopupSupport
+{
+    // @todo: it would be nice if this had a few comments in it
+
+    private static final String VIEW_RENDERER_CLASS_NAME = ReturnActionViewRenderer.class.getName();
+    private static final String ON_POPUP_DONE_FUNC = "Netui_OnPopupDone";
+    private static final String POPUP_FUNC = "Netui_Popup";
+    private static final String POPUP_WINDOW = "Netui_Window";
+
+    private String _name = "";
+    private HashMap _features;
+    private boolean _replace = false;
+    private String _onPopupDone;
+    private String _popupFunc;
+    private String _formName;
+
+    public void setName(String name)
+    {
+        _name = name;
+    }
+
+    // @todo: all of these need to use some form of Constants
+    public void setToolbar(boolean toolbar)
+    {
+        putFeature("toolbar", toolbar);
+    }
+
+    public void setLocation(boolean location)
+    {
+        putFeature("location", location);
+    }
+
+    public void setDirectories(boolean directories)
+    {
+        putFeature("directories", directories);
+    }
+
+    public void setStatus(boolean status)
+    {
+        putFeature("status", status);
+    }
+
+    public void setMenubar(boolean menubar)
+    {
+        putFeature("menubar", menubar);
+    }
+
+    public void setScrollbars(boolean scrollbars)
+    {
+        putFeature("scrollbars", scrollbars);
+    }
+
+    public void setResizable(boolean resizable)
+    {
+        putFeature("resizable", resizable);
+    }
+
+    public void setWidth(int width)
+    {
+        putFeature("width", new Integer(width));
+    }
+
+    public void setHeight(int height)
+    {
+        putFeature("height", new Integer(height));
+    }
+
+    public void setLeft(int left)
+    {
+        putFeature("left", new Integer(left));
+    }
+
+    public void setTop(int top)
+    {
+        putFeature("top", new Integer(top));
+    }
+
+    public void setReplace(boolean replace)
+    {
+        _replace = replace;
+    }
+
+    public void setOnPopupDone(String onPopupDone)
+    {
+        _onPopupDone = onPopupDone;
+    }
+
+    public void setPopupFunc(String popupFunc)
+    {
+        _popupFunc = popupFunc;
+    }
+
+    /**
+     * Sets whether the JavaScript function that opens the popup window should add data
+     * from the form fields to the request. The form name is used in the JavaScript
+     * function of onClick to identify the form object correctly. The JavaScript
+     * will only be set up to pass the names and values for the form fields on the
+     * request if the form name is set. 
+     *
+     * @param formName the name attribute of the form to pass field data from.
+     *                 This must be the real/generated form name and not the
+     *                 netui:form tagId attribute.
+     */
+    public void setFormName(String formName)
+    {
+        _formName = formName;
+    }
+
+    public String getOnClick(String url)
+    {
+        // Build up the string that's passed to javascript open() to specify window features.
+        InternalStringBuilder features = new InternalStringBuilder();
+        
+        if (_features != null) {
+            boolean firstOne = true;
+            for (Iterator i = _features.entrySet().iterator(); i.hasNext();)
+            {
+                Map.Entry entry = (Map.Entry) i.next();
+                if (!firstOne) {
+                    features.append(',');
+                }
+                features.append(entry.getKey());
+                features.append('=');
+                features.append(entry.getValue());
+                firstOne = false;
+            }
+        }
+
+        String onClick = null;
+        String popupWindow = getScopedFunctionName(POPUP_WINDOW);
+
+        String popupFunc = (_popupFunc != null ? _popupFunc : POPUP_FUNC);
+        if (_formName != null && _formName.length() > 0) {
+            Object[] args = new Object[]{popupFunc, url, _name, features.toString(), Boolean.valueOf(_replace), popupWindow, _formName};
+            onClick = ScriptReporter.getString("popupSupportUpdateFormOnClick", args);
+        }
+        else {
+            Object[] args = new Object[]{popupFunc, url, _name, features.toString(), Boolean.valueOf(_replace), popupWindow};
+            onClick = ScriptReporter.getString("popupSupportOnClick", args);
+        }
+
+        return onClick;
+    }
+
+    public void addParams(IUrlParams urlParams)
+    {
+        urlParams.addParameter(InternalConstants.RETURN_ACTION_VIEW_RENDERER_PARAM, VIEW_RENDERER_CLASS_NAME, null);
+        String onPopupDone = (_onPopupDone != null ? _onPopupDone : ON_POPUP_DONE_FUNC);
+        urlParams.addParameter(ReturnActionViewRenderer.getCallbackParamName(), onPopupDone, null);
+        
+        ScopedRequest scopedRequest = RequestUtils.getScopedRequest();
+        if (scopedRequest != null) {
+            urlParams.addParameter(ScopedServletUtils.SCOPE_ID_PARAM, scopedRequest.getScopeKey().toString(), null);
+        }
+    }
+
+    public void writeScript(ScriptReporter scriptReporter)
+    {
+        // Write the generic function for popping a window.
+        scriptReporter.writeFeature(CoreScriptFeature.POPUP_OPEN, true, false, new Object[]{POPUP_FUNC});
+
+        // Write the callback that's triggered when the popup window is closing.
+        scriptReporter.writeFeature(CoreScriptFeature.POPUP_DONE, true, false, new Object[]{ON_POPUP_DONE_FUNC});
+
+        // Write the initialization of the popup window variable.
+        String popupWindow = getScopedFunctionName(POPUP_WINDOW);
+        scriptReporter.writeFeature("popupSupportWindowVariable", new Object[]{popupWindow});
+    }
+
+    //************************** Private Methods ******************************************
+    
+    private static String getScopedFunctionName(String funcName)
+    {
+        ScopedRequest scopedRequest = RequestUtils.getScopedRequest();
+        return (scopedRequest != null) ? funcName + '_' + scopedRequest.getScopeKey() : funcName;
+    }
+
+    private void putFeature(String featureName, boolean val)
+    {
+        putFeature(featureName, val ? new Integer(1) : new Integer(0));
+    }
+
+    private void putFeature(String featureName, Object val)
+    {
+        if (_features == null) {
+            _features = new HashMap();
+        }
+        _features.put(featureName, val);
+    }
+}
+

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/PopupSupport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/ReturnActionViewRenderer.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/ReturnActionViewRenderer.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/ReturnActionViewRenderer.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/ReturnActionViewRenderer.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.simpletags.core;
+
+import org.apache.beehive.netui.pageflow.PageFlowContext;
+import org.apache.beehive.netui.pageflow.internal.InternalConstants;
+import org.apache.beehive.netui.pageflow.internal.InternalExpressionUtils;
+import org.apache.beehive.netui.pageflow.internal.ViewRenderer;
+import org.apache.beehive.netui.simpletags.appender.Appender;
+import org.apache.beehive.netui.simpletags.appender.ResponseAppender;
+import org.apache.beehive.netui.simpletags.rendering.ScriptTag;
+import org.apache.beehive.netui.simpletags.rendering.TagRenderingBase;
+import org.apache.beehive.netui.simpletags.util.ContextUtils;
+import org.apache.beehive.netui.simpletags.core.services.ScriptReporter;
+import org.apache.beehive.netui.util.logging.Logger;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.jsp.el.ELException;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Renderer for the "automatic" script-only page that is produced to send a map of values from a popup window
+ * back to the opener, and to close the popup window.
+ */
+public class ReturnActionViewRenderer
+        implements ViewRenderer, Serializable
+{
+    private static final Logger _log = Logger.getInstance(ReturnActionViewRenderer.class);
+
+    private static char DELIM = ':';
+    private static String ITEM_PARAM = InternalConstants.ATTR_PREFIX + "retrieveItem";
+    private static String CALLBACK_PARAM = InternalConstants.ATTR_PREFIX + "returnActionCallback";
+
+    private HashMap _retrieveMap;
+    private String _callbackFunc;
+
+    public static char getDelim()
+    {
+        return DELIM;
+    }
+
+    public static String getMapItemParamName()
+    {
+        return ITEM_PARAM;
+    }
+
+    public static String getCallbackParamName()
+    {
+        return CALLBACK_PARAM;
+    }
+
+    /**
+     * Initialize, based on request parameters we're looking for.
+     */
+    public void init(ServletRequest request)
+    {
+        String[] vals = request.getParameterValues(ITEM_PARAM);
+
+        if (vals != null) {
+            _retrieveMap = new HashMap();
+
+            for (int i = 0; i < vals.length; i++) {
+                String val = vals[i];
+                int delimPos = val.indexOf(DELIM);
+                if (delimPos != -1) {
+                    String expressionToRetrieve = val.substring(0, delimPos);
+                    String fieldID = val.substring(delimPos + 1);
+                    _retrieveMap.put(fieldID, expressionToRetrieve);
+                }
+            }
+        }
+
+        _callbackFunc = request.getParameter(CALLBACK_PARAM);
+    }
+
+    // @todo: add a comment
+    public void renderView(ServletRequest servletRequest, ServletResponse response, ServletContext servletContext)
+    {
+        Appender appender = new ResponseAppender(response);
+        ScriptTag.State state = new ScriptTag.State();
+        ScriptTag br = (ScriptTag) TagRenderingBase.Factory.getRendering(TagRenderingBase.SCRIPT_TAG);
+        state.suppressComments = false;
+        br.doStartTag(appender, state);
+
+        appender.append(ScriptReporter.getString("popupReturn_begin", null));
+
+        if (_retrieveMap != null) {
+            for (Iterator/*<Map.Entry>*/ i = _retrieveMap.entrySet().iterator(); i.hasNext();) {
+                Map.Entry entry = (Map.Entry) i.next();
+                String fieldID = (String) entry.getKey();
+                String expressionToRetrieve = "${" + (String) entry.getValue() + '}';
+                try {
+                    PageFlowContext pfCtxt = ContextUtils.getPageFlowContext();
+                    HttpServletRequest request = pfCtxt.getRequest();
+                    ServletContext servletCtxt = pfCtxt.getServletContext();
+                    String value = InternalExpressionUtils.evaluateMessage(expressionToRetrieve, null, request, servletCtxt);
+                    String item = ScriptReporter.getString("popupReturn_item", new Object[]{fieldID, value});
+                    appender.append(item);
+                }
+                catch (ELException e) {
+                    _log.error("Error evaluating expression " + expressionToRetrieve, e);
+                }
+            }
+        }
+
+        appender.append(ScriptReporter.getString("popupReturn_end", new Object[]{_callbackFunc}));
+        br.doEndTag(appender, false);
+    }
+}

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/ReturnActionViewRenderer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/TagContext.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/TagContext.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/TagContext.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/TagContext.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,109 @@
+package org.apache.beehive.netui.simpletags.core;
+
+import org.apache.beehive.netui.pageflow.PageFlowContext;
+import org.apache.beehive.netui.pageflow.PageFlowContextActivator;
+import org.apache.beehive.netui.simpletags.core.services.ErrorReporter;
+import org.apache.beehive.netui.simpletags.core.services.BehaviorStack;
+import org.apache.beehive.netui.simpletags.core.services.ScriptReporter;
+import org.apache.beehive.netui.simpletags.core.services.IdScopeStack;
+
+public class TagContext
+{
+    public static PageFlowContextActivator ACTIVATOR = new ContextActivator();
+
+    private ErrorReporter _errorReporter;
+    private ScriptReporter _scriptReporter;
+    private IdScopeStack _idScopeStack;
+    private BehaviorStack _behaviorStack;
+    private int _nextId;
+    private int _renderingType = -1;
+    private IDocumentTypeProducer _docTypeProducer;
+
+    public static final String TAG_CONTEXT_NAME = "netui.velocity.tags";
+
+    /**
+     * This is a static method that will return the TagContext.
+     * @return The tagContext being used in this request.
+     */
+    public static TagContext getContext()
+    {
+        PageFlowContext pfCtxt = PageFlowContext.getContext();
+        assert(pfCtxt != null) : "The PageFlowContext was not found";
+        TagContext tagCtxt = (TagContext) pfCtxt.get(TAG_CONTEXT_NAME,ACTIVATOR);
+        assert (tagCtxt != null) : "The TagContext was not found";
+        return tagCtxt;
+    }
+
+
+    //**************************** Rendering type ***********************
+
+    public int getTagRenderingType()
+    {
+        return _renderingType;
+    }
+
+    public void setTagRenderingType(int renderingType) {
+        _renderingType = renderingType;
+    }
+
+    public IDocumentTypeProducer getDocTypeProducer()
+    {
+        return _docTypeProducer;
+    }
+
+    public void setDocTypeProducer(IDocumentTypeProducer docTypeProducer) {
+        _docTypeProducer = docTypeProducer;
+    }
+
+    //******************************* Error Handling *******************************//
+
+    public ErrorReporter getErrorReporter()
+    {
+        if (_errorReporter == null)
+            _errorReporter = new ErrorReporter();
+        return _errorReporter;
+    }
+
+    //******************************* Error Handling *******************************//
+    public ScriptReporter getScriptReporter()
+    {
+        if (_scriptReporter == null)
+            _scriptReporter = new ScriptReporter();
+        return _scriptReporter;
+    }
+
+    //******************************* Tag Hierarchy ********************************//
+    public BehaviorStack getBehaviorStack()
+    {
+        if (_behaviorStack == null)
+            _behaviorStack = new BehaviorStack();
+        return _behaviorStack;
+    }
+
+    //******************************* Id Scoping Support ********************************//
+    public IdScopeStack getIdScopeMgr()
+    {
+        if (_idScopeStack == null)
+            _idScopeStack = new IdScopeStack();
+        return _idScopeStack;
+    }
+
+    /**
+     * This method will generate the next unique int within the HTML tag.
+     *
+     * @return the next unique integer for this request.
+     */
+    public int getNextId()
+    {
+        return _nextId++;
+    }
+
+    static class ContextActivator implements PageFlowContextActivator
+    {
+
+        public Object activate()
+        {
+            return new TagContext();
+        }
+    }
+}

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/TagContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/TagErrorHandling.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/TagErrorHandling.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/TagErrorHandling.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/TagErrorHandling.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,56 @@
+package org.apache.beehive.netui.simpletags.core;
+
+import org.apache.beehive.netui.util.Bundle;
+
+public class TagErrorHandling
+{
+    /**
+     * static flag indicating if we are reporting errors in-page or throwing JspExceptions.
+     */
+    private AbstractPageError _error;
+
+    /**
+     * Set the error that will be used to generate the inline error representation
+     * within the page.
+     * @param error The error that will be used to report the error.
+     */
+    public void setError(AbstractPageError error) {
+        _error = error;
+    }
+
+    /**
+     * This method will return a <code>String<code> that represents all of the errors that were
+     * registered for the tag.  This method assumes that there are errors in the tag and asserts
+     * this is true.  Code will typically call <code>hasErrors</code> before calling this method.
+     * @return A <code>String</code> that contains all of the errors registered on this tag.
+     */
+    public String getErrorsReport(String tagName)
+    {
+        assert (_error != null) : "No Errors have been reported.";
+
+        String s;
+        if (_error instanceof EvalErrorInfo) {
+            s = Bundle.getString("Expression_Error");
+            s = Bundle.getString("Inline_error",
+                    new Object[]{
+                        s,
+                        Integer.toString(_error.errorNo),
+                        tagName,
+                    });
+        }
+        else if (_error instanceof TagErrorInfo) {
+            s = Bundle.getString("Tag_Error");
+            s = Bundle.getString("Inline_error",
+                    new Object[]{
+                        s,
+                        Integer.toString(_error.errorNo),
+                        tagName,
+                    });
+        }
+        else {
+            s = null;
+            assert true : "Unhandled type";
+        }
+        return s;
+    }
+}

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/TagErrorHandling.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/TagErrorInfo.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/TagErrorInfo.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/TagErrorInfo.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/TagErrorInfo.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * $Header:$
+ */
+package org.apache.beehive.netui.simpletags.core;
+
+/**
+ * This is a "struct" class that contains the information for
+ * an expression evaluation error.
+ */
+public class TagErrorInfo extends AbstractPageError
+{
+    /**
+     * The attribute of the tag that contained the expression
+     */
+    public String message;
+}
+

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/TagErrorInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/BehaviorStack.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/BehaviorStack.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/BehaviorStack.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/BehaviorStack.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,99 @@
+package org.apache.beehive.netui.simpletags.core.services;
+
+import org.apache.beehive.netui.simpletags.core.Behavior;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Collections;
+
+/**
+ * This class implements a stack that represents the current stack of behaviors.  A
+ * stack is maintained that allows a behavior to find their ancestors.
+ */
+public class BehaviorStack
+{
+    private ArrayList _tagStack;
+    private List _readonlyList;
+
+    /**
+     * Push a new Behavior onto the stack.
+     * @param behavior This is the behavior that will be placed on the stack.
+     */
+    public void push(Behavior behavior) {
+        if (_tagStack == null)
+            _tagStack = new ArrayList();
+        _tagStack.add(behavior);
+    }
+
+    /**
+     * Peek will return the current top of stack or null if the stack is empty.
+     * @return the current top of stack of null when the stack is empty.
+     */
+    public Behavior peek() {
+        if (_tagStack == null || _tagStack.size() == 0)
+            return null;
+        return (Behavior) _tagStack.get(_tagStack.size() - 1);
+    }
+
+    /**
+     * This method will pop the top of stack off and return it to the
+     * caller.  If the stack is empty, then null is returned.
+     * @return The top of stack or null if the stack is empty.
+     */
+    public Behavior pop() {
+        if (_tagStack == null || _tagStack.size() == 0)
+            return null;
+        return (Behavior) _tagStack.remove(_tagStack.size() - 1);
+    }
+
+    /**
+     * This method will return the current stack as a readonly <code>list</code>.  The bottom of
+     * the stack is at positon 0, and the top of stack is size()-1.
+     * @return a readonly <code>List</code> that contains entries in the stack.
+     */
+    public List getStackAsList()
+    {
+        if (_readonlyList == null) {
+            if (_tagStack == null) {
+                _tagStack = new ArrayList();
+            }
+            _readonlyList = Collections.unmodifiableList(_tagStack);
+        }
+        return _readonlyList;
+    }
+
+    /**
+     * This method will return an ancestor on the stack that is an instanceof
+     * the passed in class.  The ancestor to start the search from is passed to
+     * this.  Only the parents of <code>start</code> will be checked.
+     * @param start The element who's ancestors will be checked
+     * @param cls The class we are looking for
+     * @return A Behavior that is an instanceof the passed in class or null if not found.
+     */
+    public Behavior findAncestorWithClass(Behavior start, Class cls)
+    {
+        int adjust = (start != null) ? 1 : 0;
+        if (_tagStack == null || _tagStack.size() == 0)
+            return null;
+
+        Object s = (start != null) ? start : _tagStack.get(_tagStack.size() - 1);
+        int idx = _tagStack.size() - 1;
+        while (idx >= 0) {
+            if (_tagStack.get(idx) == s)
+                break;
+            idx--;
+        }
+
+        if (idx <= 0)
+            return null;
+        idx -= adjust;
+
+        while (idx >= 0) {
+            Object o = _tagStack.get(idx);
+            if (cls.isInstance(o))
+                return (Behavior) o;
+            idx--;
+        }
+        return null;
+    }
+}

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/BehaviorStack.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/ErrorReporter.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/ErrorReporter.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/ErrorReporter.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/ErrorReporter.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,129 @@
+package org.apache.beehive.netui.simpletags.core.services;
+
+import org.apache.beehive.netui.simpletags.appender.Appender;
+import org.apache.beehive.netui.simpletags.core.AbstractPageError;
+import org.apache.beehive.netui.simpletags.core.EvalErrorInfo;
+import org.apache.beehive.netui.simpletags.core.TagErrorInfo;
+import org.apache.beehive.netui.util.Bundle;
+
+import java.util.ArrayList;
+
+public class ErrorReporter
+{
+    private ArrayList _errors;
+
+    /**
+     * This will report an error from a tag.  The error will
+     * contain a message.  If error reporting is turned off,
+     * the message will be returned and the caller should throw
+     * a JspException to report the error.
+     * @param message - the message to register with the error
+     */
+    public AbstractPageError registerTagError(String message, String tagName, Throwable e)
+    {
+        assert (message != null) : "parameter 'message' must not be null.";
+
+        TagErrorInfo tei = new TagErrorInfo();
+        tei.tagType = tagName;
+        tei.message = message;
+
+        // add the error to the ErrorReporter tag
+        addError(tei);
+        assert (tei.errorNo > 0);
+        return tei;
+    }
+
+    /**
+     * This method will add an error to the errors begin tracked by the tag. After the first time this method
+     * is called, <code>hasErrors</code> will return true.
+     * @param error The <code>EvalErrorInfo</code> describing the error.
+     */
+    public AbstractPageError registerTagError(AbstractPageError error)
+    {
+        assert (error != null) : "The parameter 'error' must not be null";
+        addError(error);
+        assert (error.errorNo > 0);
+        return error;
+    }
+
+    /**
+     * This method get the current errors and write the formated output
+     *
+     * @param renderer
+     */
+    public void reportCollectedErrors(Appender renderer)
+    {
+        assert (renderer != null) : "Parameter 'renderer' must not be null.";
+        ArrayList errors = returnErrors();
+        if (errors == null || errors.size() == 0)
+            return;
+
+        assert(errors.size() > 0);
+
+        // write the error header
+        String s = Bundle.getString("Footer_Error_Header");
+        renderer.append(s);
+
+        int cnt = errors.size();
+        Object[] args = new Object[5];
+        for (int i = 0; i < cnt; i++) {
+            Object o = errors.get(i);
+            assert (o != null);
+            if (o instanceof EvalErrorInfo) {
+                EvalErrorInfo err = (EvalErrorInfo) o;
+                args[0] = Integer.toString(err.errorNo);
+                args[1] = err.tagType;
+                args[2] = err.attr;
+                args[3] = err.expression;
+                args[4] = err.evalExcp.getMessage();
+                s = Bundle.getString("Footer_Error_Expr_Body", args);
+                renderer.append(s);
+            }
+            else if (o instanceof TagErrorInfo) {
+                TagErrorInfo tei = (TagErrorInfo) o;
+                args[0] = Integer.toString(tei.errorNo);
+                args[1] = tei.tagType;
+                args[2] = tei.message;
+                s = Bundle.getString("Footer_Error_Tag_Body", args);
+                renderer.append(s);
+            }
+        }
+
+        // write the error footer
+        s = Bundle.getString("Footer_Error_Footer");
+        renderer.append(s);
+    }
+
+    /**
+     * This will return the errors currently being reported.  The errors
+     * collection will be reset to allow a new set of errors to be tracked.
+     *
+     * @return An ArrayList containing all of the collected errors.
+     */
+    public ArrayList returnErrors()
+    {
+        ArrayList e = _errors;
+        _errors = null;
+        return e;
+    }
+
+    /**
+     * This method will add an error in the form
+     * of an AbstractPageError to the collection of errors
+     * being handled by this ErrorReporter
+     *
+     * @param ape
+     */
+    private void addError(AbstractPageError ape)
+    {
+        assert (ape != null) : "Parameter 'ape' must not be null";
+
+        // This is the error reporter.
+        if (_errors == null)
+            _errors = new ArrayList();
+
+        // add the error and update it
+        _errors.add(ape);
+        ape.errorNo = _errors.size();
+    }
+}

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/ErrorReporter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/IdScopeStack.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/IdScopeStack.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/IdScopeStack.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/IdScopeStack.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,47 @@
+package org.apache.beehive.netui.simpletags.core.services;
+
+import org.apache.beehive.netui.util.internal.InternalStringBuilder;
+
+import java.util.ArrayList;
+
+/**
+ * This class will manage a stack of scopeIds.  These scopes are added to the stack
+ * by tags that implement scoping.
+ */
+public class IdScopeStack
+{
+    private ArrayList _scopes;
+
+    public void push(String scopeId)
+    {
+        if (_scopes == null)
+            _scopes = new ArrayList();
+        _scopes.add(scopeId);
+    }
+
+    public String pop() {
+        if (_scopes == null || _scopes.size() == 0)
+            return null;
+        return (String) _scopes.remove(_scopes.size() -1);
+    }
+
+    public String peek() {
+        if (_scopes == null || _scopes.size() == 0)
+            return null;
+        return (String)_scopes.get(_scopes.size()-1);
+    }
+
+    public String getIdForTagId(String tagId)
+    {
+        if (_scopes == null || _scopes.size() == 0)
+            return tagId;
+
+        InternalStringBuilder sb = new InternalStringBuilder();
+        for (int i=0;i<_scopes.size();i++) {
+            sb.append((String)_scopes.get(i));
+            sb.append('.');
+        }
+        sb.append(tagId);
+        return sb.toString();
+    }
+}

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/IdScopeStack.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/ScriptReporter.java
URL: http://svn.apache.org/viewcvs/beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/ScriptReporter.java?rev=326581&view=auto
==============================================================================
--- beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/ScriptReporter.java (added)
+++ beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/ScriptReporter.java Wed Oct 19 08:29:22 2005
@@ -0,0 +1,360 @@
+package org.apache.beehive.netui.simpletags.core.services;
+
+import org.apache.beehive.netui.simpletags.appender.Appender;
+import org.apache.beehive.netui.simpletags.javascript.CoreScriptFeature;
+import org.apache.beehive.netui.simpletags.javascript.ScriptPlacement;
+import org.apache.beehive.netui.simpletags.rendering.ScriptTag;
+import org.apache.beehive.netui.simpletags.rendering.TagRenderingBase;
+import org.apache.beehive.netui.util.internal.InternalStringBuilder;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.ResourceBundle;
+
+public class ScriptReporter
+{
+    private static final String BUNDLE_NAME = "org.apache.beehive.netui.tags.javascript.javaScript";
+    private static ResourceBundle _bundle;      // This points to the bundle
+
+    private ArrayList/*<String>*/ _funcBlocks;
+    private ArrayList/*<String>*/ _codeBefore;
+    private ArrayList/*<String>*/ _codeAfter;
+    private HashMap/*<String, String>*/ _idToNameMap;
+
+    private boolean _writeScript = false;
+    private boolean _writeId = false;
+
+    private int _javaScriptFeatures;            // this is a integer bitmap indicating various feature have been written out or not
+
+    /**
+     * Returns the string specified by aKey from the errors.properties bundle.
+     * @param aKey The key for the message pattern in the bundle.
+     * @param args The args to use in the message format.
+     */
+    public static String getString(String aKey, Object[] args)
+    {
+        assert (aKey != null);
+
+        String pattern = getBundle().getString(aKey);
+        if (args == null)
+            return pattern;
+
+        MessageFormat format = new MessageFormat(pattern);
+        return format.format(args).toString();
+    }
+
+    /**
+     * This method will add Script as a function.
+     * @param placement
+     * @param script    the text of the function. This value must not be null.
+     */
+    public void addScriptFunction(ScriptPlacement placement, String script)
+    {
+        assert (script != null) : "The paramter 'script' must not be null";
+
+        // get the list of function blocks and add this script to it.
+        if (placement == null || placement == ScriptPlacement.PLACE_INFRAMEWORK) {
+            if (_funcBlocks == null) {
+                _funcBlocks = new ArrayList/*<String>*/();
+            }
+            assert (_funcBlocks != null) : "_funcBlocks should not be null";
+            _funcBlocks.add(script);
+        }
+        else if (placement == ScriptPlacement.PLACE_BEFORE) {
+            if (_codeBefore == null)
+                _codeBefore = new ArrayList/*<String>*/();
+            _codeBefore.add(script);
+        }
+        else if (placement == ScriptPlacement.PLACE_AFTER) {
+            if (_codeAfter == null)
+                _codeAfter = new ArrayList/*<String>*/();
+            _codeAfter.add(script);
+        }
+        else {
+            assert(false) : "unsupported placement:" + placement;
+        }
+    }
+
+    /**
+     * This will add the mapping between the tagId and the real name to the NameMap hashmap.
+     * @param tagId
+     * @param realId
+     * @param realName
+     */
+    public void addTagIdMappings(String tagId, String realId, String realName)
+    {
+        assert (tagId != null) : "The parameter 'tagId' must not be null";
+        assert (realId != null) : "The parameter 'realId' must not be null";
+
+        // mark the fact that we are writting out the Id methods
+        _writeId = true;
+
+        // If we have a name, then add it to the map mapping tagId to realName
+        if (realName != null) {
+            if (_idToNameMap == null)
+                _idToNameMap = new HashMap/*<String, String>*/();
+            _idToNameMap.put(tagId, realName);
+        }
+    }
+
+    /**
+     * @param featureKey
+     * @param args
+     */
+    public void writeFeature(String featureKey, Object[] args)
+    {
+        String s = getString(featureKey, args);
+        addScriptFunction(null, s);
+    }
+
+    /**
+     * @param feature
+     * @param singleInstance
+     * @param inline
+     * @param args
+     */
+    public void writeFeature(CoreScriptFeature feature, boolean singleInstance, boolean inline, Object[] args)
+    {
+        if (singleInstance) {
+            if ((_javaScriptFeatures & feature.value) != 0)
+                return;
+            _javaScriptFeatures |= feature.value;
+        }
+
+        // get the JavaScript to write out
+        String jsKey = getFeatureKey(feature);
+        String s = getString(jsKey, args);
+        addScriptFunction(null, s);
+    }
+
+    public boolean isFeatureWritten(CoreScriptFeature feature)
+    {
+        return ((_javaScriptFeatures & feature.value) != 0);
+    }
+
+    /**
+     * This method will output all of the Script associated with the script reporter.
+     * @param appender The script is written into the provided InternalStringBuilder. This value must not be null.
+     */
+    public void writeScript(Appender appender)
+    {
+        assert(appender != null) : "The paramter 'appender' must not be null;";
+        if (_writeScript)
+            return;
+
+        _writeScript = true;
+
+        writeBeforeBlocks(appender);
+        writeFrameworkScript(appender);
+        writeAfterBlocks(appender);
+    }
+
+    public void writeBeforeBlocks(Appender appender)
+    {
+        if (_codeBefore == null || _codeBefore.size() == 0)
+            return;
+
+        InternalStringBuilder s = new InternalStringBuilder(256);
+        for (Iterator i = _codeBefore.iterator(); i.hasNext();)
+        {
+            String code = ( String ) i.next();
+            s.append(code);
+            s.append("\n");
+        }
+        writeScriptBlock(appender, s.toString());
+
+    }
+
+    public void writeAfterBlocks(Appender appender)
+    {
+        if (_codeAfter == null || _codeAfter.size() == 0)
+            return;
+
+        InternalStringBuilder s = new InternalStringBuilder(256);
+        for (Iterator i = _codeAfter.iterator(); i.hasNext();)
+        {
+            String code = ( String ) i.next();
+            s.append(code);
+            s.append("\n");
+        }
+        writeScriptBlock(appender, s.toString());
+    }
+
+    /**
+     * This will write the script block.
+     */
+    public void writeFrameworkScript(Appender appender)
+    {
+        boolean script = false;
+        //ScriptRequestState jsu = ScriptRequestState.getScriptRequestState();
+
+        boolean writeName = false;
+
+        String idMap = null;
+        String val = processIdMap(_idToNameMap, "tagIdNameMappingEntry");
+        if (val != null) {
+            idMap = getString("tagIdNameMappingTable", new Object[]{val});
+            writeName = true;
+        }
+
+        // write out the name features...
+        if (_writeId || writeName)
+            writeNetuiNameFunctions(this, _writeId, writeName);
+
+        ScriptTag.State state = null;
+        ScriptTag br = null;
+        if (_funcBlocks != null && _funcBlocks.size() > 0) {
+            if (!script) {
+                state = new ScriptTag.State();
+                state.suppressComments = false;
+                br = (ScriptTag) TagRenderingBase.Factory.getRendering(TagRenderingBase.SCRIPT_TAG);
+                br.doStartTag(appender, state);
+                script = true;
+            }
+            String s = getString("functionComment", null);
+            appender.append(s);
+            if (idMap != null)
+                appender.append(idMap);
+            int cnt = _funcBlocks.size();
+            for (int i = 0; i < cnt; i++) {
+                appender.append((String)_funcBlocks.get(i));
+                if (i != cnt - 1) {
+                    appender.append("\n");
+                }
+            }
+        }
+
+        if (script) {
+            assert(br != null);
+            br.doEndTag(appender, false);
+        }
+    }
+
+    /**
+     * This is a static method that will write a consistent look/feel to the
+     * tags and comment markup that appears around the JavaScript.
+     * @param results the InternalStringBuilder that will have the &lt;script>
+     *                tag written into
+     * @param script  the JavaScript block
+     */
+    public void writeScriptBlock(Appender results, String script)
+    {
+        assert(results != null) : "The parameter 'results' must not be null";
+
+        ScriptTag.State state = new ScriptTag.State();
+        state.suppressComments = false;
+        ScriptTag br = (ScriptTag) TagRenderingBase.Factory.getRendering(TagRenderingBase.SCRIPT_TAG);
+
+        results.append("\n");
+        br.doStartTag(results, state);
+        results.append(script);
+        br.doEndTag(results, false);
+        results.append("\n");
+    }
+
+    private String processIdMap(HashMap/*<String, String>*/ map, String mapEntry)
+    {
+        // if no map or empty then return
+        if (map == null || map.size() == 0)
+            return null;
+
+        InternalStringBuilder results = new InternalStringBuilder(128);
+        Iterator/*<String>*/ ids = map.keySet().iterator();
+        while (ids.hasNext()) {
+            String id = (String) ids.next();
+            String value = (String) map.get(id);
+            String entry = getString(mapEntry, new Object[]{id, value});
+            results.append(entry);
+        }
+        return results.toString();
+    }
+
+   /**
+     * Returns the resource bundle named Bundle[].properties in the
+     * package of the specified class.
+     * This is ok to cache because we don't localize the JavaScript resources.
+     */
+    private static ResourceBundle getBundle()
+    {
+        if (_bundle == null)
+            _bundle = ResourceBundle.getBundle(BUNDLE_NAME);
+        return _bundle;
+    }
+
+    /**
+     * @param scriptReporter
+     * @param writeId
+     * @param writeName
+     */
+    private void writeNetuiNameFunctions(ScriptReporter scriptReporter, boolean writeId, boolean writeName)
+    {
+        assert(scriptReporter != null) : "The parameter 'scriptReporter' must not be null";
+
+        // if we are supporting the default javascript then output the lookup methods for id and name
+        if (writeId)
+            writeLookupMethod("lookupIdByTagId", CoreScriptFeature.ID_LOOKUP.value);
+
+        if (writeName)
+            writeLookupMethod("lookupNameByTagId", CoreScriptFeature.NAME_LOOKUP.value);
+
+        if (writeId || writeName)
+            writeLookupMethod("lookupScopeId", CoreScriptFeature.SCOPE_LOOKUP.value);
+   }
+
+    /**
+     * This method will add the method described by the <code>bundleString</code> to the
+     * scriptReporter's script functions.
+     * @param bundleString
+     * @param feature
+     */
+    private void writeLookupMethod(String bundleString, int feature)
+    {
+        assert(bundleString != null ) : "Parameter 'bundleString' must not be null";
+
+        // see if we've written this feature already
+        if ((_javaScriptFeatures & feature) != 0)
+            return;
+        _javaScriptFeatures |= feature;
+
+        // add the function to the script reporter
+        String s = getString(bundleString, null);
+        addScriptFunction(null, s);
+    }
+
+    /**
+     * This will map the Features into their keys
+     * @param feature
+     * @return String
+     */
+    private String getFeatureKey(CoreScriptFeature feature)
+    {
+        switch (feature.getIntValue()) {
+            case CoreScriptFeature.INT_ANCHOR_SUBMIT:
+                return "anchorFormSubmit";
+            case CoreScriptFeature.INT_SET_FOCUS:
+                return "setFocus";
+            case CoreScriptFeature.INT_POPUP_OPEN:
+                return "popupSupportPopupWindow";
+            case CoreScriptFeature.INT_POPUP_DONE:
+                return "popupDone";
+            case CoreScriptFeature.INT_POPUP_UPDATE_FORM:
+                return "popupSupportUpdateForm";
+            case CoreScriptFeature.INT_ROLLOVER:
+                return "rollover";
+            case CoreScriptFeature.INT_TREE_INIT:
+                return "initTree";
+            case CoreScriptFeature.INT_DIVPANEL_INIT:
+                return "initDivPanel";
+            case CoreScriptFeature.INT_DYNAMIC_INIT:
+                return "writeWebAppName";
+            case CoreScriptFeature.INT_BUTTON_DISABLE_AND_SUBMIT:
+                return "buttonDisableAndSubmitForm";
+            case CoreScriptFeature.INT_BUTTON_DISABLE:
+                return "buttonDisable";
+        }
+        assert(false) : "getFeature fell through on feature:" + feature;
+        return null;
+    }
+}

Propchange: beehive/trunk/netui/src/simple-tags/org/apache/beehive/netui/simpletags/core/services/ScriptReporter.java
------------------------------------------------------------------------------
    svn:eol-style = native