You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2012/02/02 21:01:26 UTC

svn commit: r1239800 [5/8] - in /myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared: application/ config/ context/flash/ renderkit/ renderkit/html/ renderkit/html/util/ resource/ taglib/ taglib/core/ util/ util/io/ util/xml/

Added: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlSelectableRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlSelectableRendererBase.java?rev=1239800&view=auto
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlSelectableRendererBase.java (added)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlSelectableRendererBase.java Thu Feb  2 20:01:25 2012
@@ -0,0 +1,176 @@
+/*
+ * 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.myfaces.shared.renderkit.html;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UISelectMany;
+import javax.faces.component.UISelectOne;
+import javax.faces.component.behavior.ClientBehavior;
+import javax.faces.component.behavior.ClientBehaviorHolder;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.convert.Converter;
+import org.apache.myfaces.shared.renderkit.RendererUtils;
+import org.apache.myfaces.shared.renderkit.html.util.JavascriptUtils;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+public class HtmlSelectableRendererBase extends HtmlRenderer
+{
+    
+    protected void internalRenderSelect(FacesContext facesContext,
+            UIComponent uiComponent, boolean disabled, int size,
+            boolean selectMany, Converter converter) throws IOException
+    {
+        ResponseWriter writer = facesContext.getResponseWriter();
+        writer.startElement(HTML.SELECT_ELEM, uiComponent);
+        if (uiComponent instanceof ClientBehaviorHolder
+                && JavascriptUtils.isJavascriptAllowed(facesContext
+                        .getExternalContext())
+                && !((ClientBehaviorHolder) uiComponent).getClientBehaviors()
+                        .isEmpty())
+        {
+            writer.writeAttribute(HTML.ID_ATTR,
+                    uiComponent.getClientId(facesContext), null);
+        }
+        else
+        {
+            HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent,
+                    facesContext);
+        }
+        writer.writeAttribute(HTML.NAME_ATTR,
+                uiComponent.getClientId(facesContext), null);
+        List selectItemList;
+        if (selectMany)
+        {
+            writer.writeAttribute(HTML.MULTIPLE_ATTR, HTML.MULTIPLE_ATTR, null);
+            selectItemList = org.apache.myfaces.shared.renderkit.RendererUtils
+                    .getSelectItemList((UISelectMany) uiComponent, facesContext);
+        }
+        else
+        {
+            selectItemList = RendererUtils.getSelectItemList(
+                    (UISelectOne) uiComponent, facesContext);
+        }
+
+        if (size == Integer.MIN_VALUE)
+        {
+            //No size given (Listbox) --> size is number of select items
+            writer.writeAttribute(HTML.SIZE_ATTR,
+                    Integer.toString(selectItemList.size()), null);
+        }
+        else
+        {
+            writer.writeAttribute(HTML.SIZE_ATTR, Integer.toString(size), null);
+        }
+        Map<String, List<ClientBehavior>> behaviors = null;
+        if (uiComponent instanceof ClientBehaviorHolder
+                && JavascriptUtils.isJavascriptAllowed(facesContext
+                        .getExternalContext()))
+        {
+            behaviors = ((ClientBehaviorHolder) uiComponent)
+                    .getClientBehaviors();
+            long commonPropertiesMarked = 0L;
+            if (isCommonPropertiesOptimizationEnabled(facesContext))
+            {
+                commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
+            }
+            if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
+            {
+                CommonPropertyUtils.renderChangeEventProperty(writer, 
+                        commonPropertiesMarked, uiComponent);
+                CommonPropertyUtils.renderEventProperties(writer, 
+                        commonPropertiesMarked, uiComponent);
+                CommonPropertyUtils.renderFieldEventPropertiesWithoutOnchange(writer, 
+                        commonPropertiesMarked, uiComponent);
+            }
+            else
+            {
+                HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer,
+                        uiComponent, behaviors);
+                if (isCommonEventsOptimizationEnabled(facesContext))
+                {
+                    Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(uiComponent);
+                    CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer, 
+                            commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
+                    CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
+                        facesContext, writer, commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
+                }
+                else
+                {
+                    HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, uiComponent,
+                            behaviors);
+                    HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(facesContext,
+                            writer, uiComponent, behaviors);
+                }
+            }
+            if (isCommonPropertiesOptimizationEnabled(facesContext))
+            {
+                CommonPropertyUtils.renderSelectPassthroughPropertiesWithoutDisabledAndEvents(writer, 
+                        CommonPropertyUtils.getCommonPropertiesMarked(uiComponent), uiComponent);
+            }
+            else
+            {
+                HtmlRendererUtils.renderHTMLAttributes(
+                        writer,
+                        uiComponent,
+                        HTML.SELECT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED_AND_EVENTS);
+            }
+        }
+        else
+        {
+            if (isCommonPropertiesOptimizationEnabled(facesContext))
+            {
+                CommonPropertyUtils.renderSelectPassthroughPropertiesWithoutDisabled(writer, 
+                        CommonPropertyUtils.getCommonPropertiesMarked(uiComponent), uiComponent);
+            }
+            else
+            {
+                HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent,
+                        HTML.SELECT_PASSTHROUGH_ATTRIBUTES_WITHOUT_DISABLED);
+            }
+        }
+
+        if (disabled)
+        {
+            writer.writeAttribute(HTML.DISABLED_ATTR, Boolean.TRUE, null);
+        }
+
+        if (HtmlRendererUtils.isReadOnly(uiComponent))
+        {
+            writer.writeAttribute(HTML.READONLY_ATTR, HTML.READONLY_ATTR, null);
+        }
+
+        Set lookupSet = HtmlRendererUtils.getSubmittedOrSelectedValuesAsSet(selectMany,
+                uiComponent, facesContext, converter);
+
+        HtmlRendererUtils.renderSelectOptions(facesContext, uiComponent, converter, lookupSet,
+                selectItemList);
+        // bug #970747: force separate end tag
+        writer.writeText(HtmlRendererUtils.STR_EMPTY, null);
+        writer.endElement(HTML.SELECT_ELEM);
+    }
+    
+}

Propchange: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlSelectableRendererBase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTableRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTableRendererBase.java?rev=1239800&r1=1239799&r2=1239800&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTableRendererBase.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTableRendererBase.java Thu Feb  2 20:01:25 2012
@@ -19,7 +19,6 @@
 package org.apache.myfaces.shared.renderkit.html;
 
 import java.io.IOException;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.logging.Logger;
@@ -154,7 +153,24 @@ public class HtmlTableRendererBase exten
             {
                 HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent, facesContext);
             }
-            HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, uiComponent, behaviors);
+            if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
+            {
+                CommonPropertyUtils.renderEventProperties(writer, 
+                        CommonPropertyUtils.getCommonPropertiesMarked(uiComponent), uiComponent);
+            }
+            else
+            {
+                if (isCommonEventsOptimizationEnabled(facesContext))
+                {
+                    CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer, 
+                           CommonPropertyUtils.getCommonPropertiesMarked(uiComponent),
+                           CommonEventUtils.getCommonEventsMarked(uiComponent), uiComponent, behaviors);
+                }
+                else
+                {
+                    HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, uiComponent, behaviors);
+                }
+            }
             if (isCommonPropertiesOptimizationEnabled(facesContext))
             {
                 HtmlRendererUtils.renderHTMLAttributes(writer, uiComponent, HTML.TABLE_ATTRIBUTES);
@@ -785,9 +801,10 @@ public class HtmlTableRendererBase exten
     {
         int colspan = 0;
         boolean hasColumnFacet = false;
-        for (Iterator it = getChildren(component).iterator(); it.hasNext();)
+        int childCount = component.getChildCount();
+        for (int i = 0; i < childCount; i++)
         {
-            UIComponent uiComponent = (UIComponent) it.next();
+            UIComponent uiComponent = component.getChildren().get(i);
             if(uiComponent.isRendered())
             {
                 // a UIColumn has a span of 1, anything else has a span of 0
@@ -797,11 +814,12 @@ public class HtmlTableRendererBase exten
                 // the specified type.
                 if (!hasColumnFacet)
                 {
-                     hasColumnFacet = hasFacet(header, uiComponent);
+                    hasColumnFacet = hasFacet(header, uiComponent);
                 }
             }
         }
 
+
         UIComponent facet = header ? (UIComponent) component.getFacets().get(HEADER_FACET_NAME)
                 : (UIComponent) component.getFacets().get(FOOTER_FACET_NAME);
         if (facet != null || hasColumnFacet)
@@ -1004,9 +1022,9 @@ public class HtmlTableRendererBase exten
         int newspaperColumns = getNewspaperColumns(component);
         for(int nc = 0; nc < newspaperColumns; nc++)
         {
-            for (Iterator it = getChildren(component).iterator(); it.hasNext();)
+            for (int i = 0, childCount = component.getChildCount(); i < childCount; i++)
             {
-                UIComponent uiComponent = (UIComponent) it.next();
+                UIComponent uiComponent = component.getChildren().get(i);
                 if (uiComponent.isRendered())
                 {
                     if (component instanceof UIData && uiComponent instanceof UIColumn)

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTextRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTextRendererBase.java?rev=1239800&r1=1239799&r2=1239800&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTextRendererBase.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTextRendererBase.java Thu Feb  2 20:01:25 2012
@@ -218,14 +218,42 @@ public class HtmlTextRendererBase
         {
             behaviors = ((ClientBehaviorHolder) component).getClientBehaviors();
             
-            HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, component, behaviors);
-            HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, component, behaviors);
-            HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
-                    facesContext, writer, component, behaviors);
+            long commonPropertiesMarked = 0L;
+            if (isCommonPropertiesOptimizationEnabled(facesContext))
+            {
+                commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(component);
+            }
+            if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
+            {
+                CommonPropertyUtils.renderChangeEventProperty(writer, 
+                        commonPropertiesMarked, component);
+                CommonPropertyUtils.renderEventProperties(writer, 
+                        commonPropertiesMarked, component);
+                CommonPropertyUtils.renderFieldEventPropertiesWithoutOnchange(writer, 
+                        commonPropertiesMarked, component);
+            }
+            else
+            {
+                HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, component, behaviors);
+                if (isCommonEventsOptimizationEnabled(facesContext))
+                {
+                    Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(component);
+                    CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer, 
+                            commonPropertiesMarked, commonEventsMarked, component, behaviors);
+                    CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
+                        facesContext, writer, commonPropertiesMarked, commonEventsMarked, component, behaviors);
+                }
+                else
+                {
+                    HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, component, behaviors);
+                    HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
+                            facesContext, writer, component, behaviors);
+                }
+            }
             if (isCommonPropertiesOptimizationEnabled(facesContext))
             {
                 CommonPropertyUtils.renderInputPassthroughPropertiesWithoutDisabledAndEvents(writer, 
-                        CommonPropertyUtils.getCommonPropertiesMarked(component), component);
+                        commonPropertiesMarked, component);
             }
             else
             {

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTextareaRendererBase.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTextareaRendererBase.java?rev=1239800&r1=1239799&r2=1239800&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTextareaRendererBase.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/HtmlTextareaRendererBase.java Thu Feb  2 20:01:25 2012
@@ -96,10 +96,38 @@ public class HtmlTextareaRendererBase
                 HtmlRendererUtils.writeIdIfNecessary(writer, uiComponent, facesContext);
                 writer.writeAttribute(HTML.NAME_ATTR, uiComponent.getClientId(facesContext), null);
             }
-            HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, uiComponent, behaviors);
-            HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, uiComponent, behaviors);
-            HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
-                    facesContext, writer, uiComponent, behaviors);
+            long commonPropertiesMarked = 0L;
+            if (isCommonPropertiesOptimizationEnabled(facesContext))
+            {
+                commonPropertiesMarked = CommonPropertyUtils.getCommonPropertiesMarked(uiComponent);
+            }
+            if (behaviors.isEmpty() && isCommonPropertiesOptimizationEnabled(facesContext))
+            {
+                CommonPropertyUtils.renderChangeEventProperty(writer, 
+                        commonPropertiesMarked, uiComponent);
+                CommonPropertyUtils.renderEventProperties(writer, 
+                        commonPropertiesMarked, uiComponent);
+                CommonPropertyUtils.renderFieldEventPropertiesWithoutOnchange(writer, 
+                        commonPropertiesMarked, uiComponent);
+            }
+            else
+            {
+                HtmlRendererUtils.renderBehaviorizedOnchangeEventHandler(facesContext, writer, uiComponent, behaviors);
+                if (isCommonEventsOptimizationEnabled(facesContext))
+                {
+                    Long commonEventsMarked = CommonEventUtils.getCommonEventsMarked(uiComponent);
+                    CommonEventUtils.renderBehaviorizedEventHandlers(facesContext, writer, 
+                            commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
+                    CommonEventUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
+                        facesContext, writer, commonPropertiesMarked, commonEventsMarked, uiComponent, behaviors);
+                }
+                else
+                {
+                    HtmlRendererUtils.renderBehaviorizedEventHandlers(facesContext, writer, uiComponent, behaviors);
+                    HtmlRendererUtils.renderBehaviorizedFieldEventHandlersWithoutOnchange(
+                            facesContext, writer, uiComponent, behaviors);
+                }
+            }
             if (isCommonPropertiesOptimizationEnabled(facesContext))
             {
                 CommonPropertyUtils.renderCommonFieldPassthroughPropertiesWithoutDisabledAndEvents(writer, 

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/JavascriptContext.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/JavascriptContext.java?rev=1239800&r1=1239799&r2=1239800&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/JavascriptContext.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/JavascriptContext.java Thu Feb  2 20:01:25 2012
@@ -1,160 +1,160 @@
-/*
- * 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.myfaces.shared.renderkit.html;
-
-/**
- * The ScriptContext offers methods and fields
- * to help with rendering out a script and keeping a
- * proper formatting.
- */
-public class JavascriptContext
-{
-    private static final String LINE_SEPARATOR = System.getProperty(
-            "line.separator", "\r\n");
-    private static final char TABULATOR = '\t';
-
-    private long currentIndentationLevel;
-    private StringBuffer buffer = new StringBuffer();
-    private boolean prettyPrint = false;
-    /**
-     * automatic formatting will render
-     * new-lines and indents if blocks are opened
-     * and closed - attention: you need to append
-     * opening and closing brackets of blocks separately in this case!
-     */
-    private boolean automaticFormatting = true;
-
-    public JavascriptContext()
-    {
-
-    }
-
-    public JavascriptContext(boolean prettyPrint)
-    {
-        this.prettyPrint = prettyPrint;
-    }
-
-    public JavascriptContext(StringBuffer buf, boolean prettyPrint)
-    {
-        this.prettyPrint = prettyPrint;
-        this.buffer = buf;
-    }
-
-    public void increaseIndent()
-    {
-        currentIndentationLevel++;
-    }
-
-    public void decreaseIndent()
-    {
-        currentIndentationLevel--;
-
-        if (currentIndentationLevel < 0)
-        {
-            currentIndentationLevel = 0;
-        }
-    }
-
-    public void prettyLine()
-    {
-        if (prettyPrint)
-        {
-            append(LINE_SEPARATOR);
-
-            for (int i = 0; i < getCurrentIndentationLevel(); i++)
-            {
-                append(TABULATOR);
-            }
-        }
-    }
-
-    public void prettyLineIncreaseIndent()
-    {
-        increaseIndent();
-        prettyLine();
-    }
-
-    public void prettyLineDecreaseIndent()
-    {
-        decreaseIndent();
-        prettyLine();
-    }
-
-    public long getCurrentIndentationLevel()
-    {
-        return currentIndentationLevel;
-    }
-
-    public void setCurrentIndentationLevel(long currentIndentationLevel)
-    {
-        this.currentIndentationLevel = currentIndentationLevel;
-    }
-
-    public JavascriptContext append(String str)
-    {
-
-        if (automaticFormatting && str.length() == 1)
-        {
-            boolean openBlock = str.equals("{");
-            boolean closeBlock = str.equals("}");
-
-            if (openBlock)
-            {
-                prettyLine();
-            }
-            else if (closeBlock)
-            {
-                prettyLineDecreaseIndent();
-            }
-
-            buffer.append(str);
-
-            if (openBlock)
-            {
-                prettyLineIncreaseIndent();
-            }
-            else if (closeBlock)
-            {
-                prettyLine();
-            }
-        }
-        else
-        {
-            buffer.append(str);
-        }
-        return this;
-    }
-
-    public JavascriptContext append(char c)
-    {
-        buffer.append(c);
-        return this;
-    }
-
-    public JavascriptContext append(int i)
-    {
-        buffer.append(i);
-        return this;
-    }
-
-    public String toString()
-    {
-        return buffer.toString();
-    }
-}
+/*
+ * 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.myfaces.shared.renderkit.html;
+
+/**
+ * The ScriptContext offers methods and fields
+ * to help with rendering out a script and keeping a
+ * proper formatting.
+ */
+public class JavascriptContext
+{
+    private static final String LINE_SEPARATOR = System.getProperty(
+            "line.separator", "\r\n");
+    private static final char TABULATOR = '\t';
+
+    private long currentIndentationLevel;
+    private StringBuilder buffer = new StringBuilder();
+    private boolean prettyPrint = false;
+    /**
+     * automatic formatting will render
+     * new-lines and indents if blocks are opened
+     * and closed - attention: you need to append
+     * opening and closing brackets of blocks separately in this case!
+     */
+    private boolean automaticFormatting = true;
+
+    public JavascriptContext()
+    {
+
+    }
+
+    public JavascriptContext(boolean prettyPrint)
+    {
+        this.prettyPrint = prettyPrint;
+    }
+
+    public JavascriptContext(StringBuilder buf, boolean prettyPrint)
+    {
+        this.prettyPrint = prettyPrint;
+        this.buffer = buf;
+    }
+
+    public void increaseIndent()
+    {
+        currentIndentationLevel++;
+    }
+
+    public void decreaseIndent()
+    {
+        currentIndentationLevel--;
+
+        if (currentIndentationLevel < 0)
+        {
+            currentIndentationLevel = 0;
+        }
+    }
+
+    public void prettyLine()
+    {
+        if (prettyPrint)
+        {
+            append(LINE_SEPARATOR);
+
+            for (int i = 0; i < getCurrentIndentationLevel(); i++)
+            {
+                append(TABULATOR);
+            }
+        }
+    }
+
+    public void prettyLineIncreaseIndent()
+    {
+        increaseIndent();
+        prettyLine();
+    }
+
+    public void prettyLineDecreaseIndent()
+    {
+        decreaseIndent();
+        prettyLine();
+    }
+
+    public long getCurrentIndentationLevel()
+    {
+        return currentIndentationLevel;
+    }
+
+    public void setCurrentIndentationLevel(long currentIndentationLevel)
+    {
+        this.currentIndentationLevel = currentIndentationLevel;
+    }
+
+    public JavascriptContext append(String str)
+    {
+
+        if (automaticFormatting && str.length() == 1)
+        {
+            boolean openBlock = str.equals("{");
+            boolean closeBlock = str.equals("}");
+
+            if (openBlock)
+            {
+                prettyLine();
+            }
+            else if (closeBlock)
+            {
+                prettyLineDecreaseIndent();
+            }
+
+            buffer.append(str);
+
+            if (openBlock)
+            {
+                prettyLineIncreaseIndent();
+            }
+            else if (closeBlock)
+            {
+                prettyLine();
+            }
+        }
+        else
+        {
+            buffer.append(str);
+        }
+        return this;
+    }
+
+    public JavascriptContext append(char c)
+    {
+        buffer.append(c);
+        return this;
+    }
+
+    public JavascriptContext append(int i)
+    {
+        buffer.append(i);
+        return this;
+    }
+
+    public String toString()
+    {
+        return buffer.toString();
+    }
+}

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/HTMLEncoder.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/HTMLEncoder.java?rev=1239800&r1=1239799&r2=1239800&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/HTMLEncoder.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/HTMLEncoder.java Thu Feb  2 20:01:25 2012
@@ -156,6 +156,144 @@ public abstract class HTMLEncoder
             return sb.toString();
         }
     }
+    
+    /**
+     * Variant of {@link #encode} where encodeNewline is false and encodeNbsp is true.
+     */
+    public static void encode (Writer writer, String string) throws IOException
+    {
+        encode(writer, string, false, true);
+    }
+
+    /**
+     * Variant of {@link #encode} where encodeNbsp is true.
+     */
+    public static void encode (Writer writer, String string, boolean encodeNewline) throws IOException
+    {
+        encode(writer, string, encodeNewline, true);
+    }
+
+    /**
+     * Variant of {@link #encode} where encodeNbsp and encodeNonLatin are true 
+     */
+    public static void encode (Writer writer, String string, 
+            boolean encodeNewline, boolean encodeSubsequentBlanksToNbsp) throws IOException
+    {
+        encode(writer, string, encodeNewline, encodeSubsequentBlanksToNbsp, true);
+    }
+    
+    public static void encode (Writer writer, String string,
+                                 boolean encodeNewline,
+                                 boolean encodeSubsequentBlanksToNbsp,
+                                 boolean encodeNonLatin) throws IOException
+    {
+        if (string == null)
+        {
+            return;
+        }
+
+        int start = 0;
+        String app;
+        char c;
+        for (int i = 0; i < string.length (); ++i)
+        {
+            app = null;
+            c = string.charAt(i);
+            
+            // All characters before letters
+            if ((int)c < 0x41)
+            {
+                switch (c)
+                {
+                    case '"': app = "&quot;"; break;    //"
+                    case '&': app = "&amp;"; break;     //&
+                    case '<': app = "&lt;"; break;      //<
+                    case '>': app = "&gt;"; break;      //>
+                    case ' ':
+                        if (encodeSubsequentBlanksToNbsp &&
+                                (i == 0 || (i - 1 >= 0 && string.charAt(i - 1) == ' ')))
+                        {
+                            //Space at beginning or after another space
+                            app = "&#160;";
+                        }
+                        break;
+                    case '\n':
+                        if (encodeNewline)
+                        {
+                            app = "<br/>";
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
+            else if (encodeNonLatin && (int)c > 0x80)
+            {
+                 switch(c)
+                 {
+                    //german umlauts
+                    case '\u00E4' : app = "&auml;";  break;
+                    case '\u00C4' : app = "&Auml;";  break;
+                    case '\u00F6' : app = "&ouml;";  break;
+                    case '\u00D6' : app = "&Ouml;";  break;
+                    case '\u00FC' : app = "&uuml;";  break;
+                    case '\u00DC' : app = "&Uuml;";  break;
+                    case '\u00DF' : app = "&szlig;"; break;
+
+                    //misc
+                    //case 0x80: app = "&euro;"; break;  sometimes euro symbol is ascii 128, should we suport it?
+                    case '\u20AC': app = "&euro;";  break;
+                    case '\u00AB': app = "&laquo;"; break;
+                    case '\u00BB': app = "&raquo;"; break;
+                    case '\u00A0': app = "&#160;"; break;
+
+                    default :
+                        //encode all non basic latin characters
+                        app = "&#" + ((int)c) + ";";
+                    break;
+                }
+            }
+            if (app != null)
+            {
+                //if (sb == null)
+                //{
+                //    sb = new StringBuilder(string.substring(0, i));
+                //}
+                //sb.append(app);
+                if (start < i)
+                {
+                    writer.write(string, start, i-start);
+                }
+                start = i+1;
+                writer.write(app);
+            }
+            //else
+            //{
+            //    if (sb != null)
+            //    {
+            //        sb.append(c);
+            //    }
+            //}
+        }
+
+        //if (sb == null)
+        //{
+        //    return string;
+        //}
+        //else
+        //{
+        //    return sb.toString();
+        //}
+        if (start == 0)
+        {
+            writer.write(string);
+        }
+        else if (start < string.length())
+        {
+            writer.write(string,start,string.length()-start);
+        }
+    }
+
 
     /**
      * Variant of {@link #encode} where encodeNewline is false and encodeNbsp is true.
@@ -203,9 +341,10 @@ public abstract class HTMLEncoder
         offset = Math.max(0, offset);
         int realLength = Math.min(length, string.length - offset);
 
-        StringBuilder sb = null;    //create later on demand
+        //StringBuilder sb = null;    //create later on demand
         String app;
         char c;
+        int start = offset;
         
         for (int i = offset; i < offset + realLength; ++i)
         {
@@ -267,29 +406,44 @@ public abstract class HTMLEncoder
             }
             if (app != null)
             {
-                if (sb == null)
+                //if (sb == null)
+                //{
+                //    sb = new StringBuilder(realLength*2);
+                //    sb.append(string, offset, i - offset);
+                //}
+                //sb.append(app);
+                if (start < i)
                 {
-                    sb = new StringBuilder(realLength*2);
-                    sb.append(string, offset, i - offset);
+                    writer.write(string, start, i-start);
                 }
-                sb.append(app);
+                start = i+1;
+                writer.write(app);
             }
+            /*
             else
             {
                 if (sb != null)
                 {
                     sb.append(c);
                 }
-            }
+            }*/
         }
 
-        if (sb == null)
+        //if (sb == null)
+        //{
+        //    writer.write(string, offset, realLength);
+        //}
+        //else
+        //{
+        //    writer.write(sb.toString());
+        //}
+        if (start == offset)
         {
             writer.write(string, offset, realLength);
         }
-        else
+        else if (start < offset+realLength)
         {
-            writer.write(sb.toString());
+            writer.write(string,start,offset+realLength-start);
         }
     }
     
@@ -546,7 +700,7 @@ public abstract class HTMLEncoder
     private static String percentEncodeNonUsAsciiCharacter(char c, String characterEncoding)
     {
         ByteArrayOutputStream baos = new ByteArrayOutputStream(10);
-        StringBuffer builder = new StringBuffer();
+        StringBuilder builder = new StringBuilder();
         try
         {
             OutputStreamWriter writer = new OutputStreamWriter(baos,characterEncoding);
@@ -687,4 +841,481 @@ public abstract class HTMLEncoder
             return sb.toString();
         }
     }
+
+    /**
+     * Encode an URI, escaping or percent-encoding all required characters and
+     * following the rules mentioned on RFC 3986.  
+     * 
+     * @param string
+     * @param encodeNonLatin
+     * @return
+     * @throws IOException
+     */
+    public static void encodeURIAtributte(Writer writer, final String string, final String characterEncoding)
+        throws IOException
+    {
+        //StringBuilder sb = null;    //create later on demand
+        int start = 0;
+        String app;
+        char c;
+        boolean endLoop = false;
+        for (int i = 0; i < string.length (); ++i)
+        {
+            app = null;
+            c = string.charAt(i);
+            
+            // This are the guidelines to be taken into account by this algorithm to encode:
+            
+            // RFC 2396 Section 2.4.3 Excluded US-ASCII Characters
+            //
+            // control     = <US-ASCII coded characters 00-1F and 7F hexadecimal>
+            // space       = <US-ASCII coded character 20 hexadecimal>
+            // delims      = "<" | ">" | "#" | "%" | <">
+            //               %3C   %3E   %23   %25   %22
+            // unwise      = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
+            //               %7D   %7B   %7C   %5C   %5E   %5B   %5D   %60
+            //
+            // ".... Data corresponding to excluded characters must be escaped in order to
+            // be properly represented within a URI....."
+            
+            // RFC 3986 Section 3.  Syntax Components
+            //
+            // "... The generic URI syntax consists of a hierarchical sequence of
+            // components referred to as the scheme, authority, path, query, and
+            // fragment.
+            //
+            //   URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
+            //
+            //   hier-part   = "//" authority path-abempty
+            //               / path-absolute
+            //               / path-rootless
+            //               / path-empty
+            // ...."
+            
+            // RFC 3986 Section 2.2:
+            // Reserved characters (should not be percent-encoded)
+            // reserved    = gen-delims / sub-delims
+            // gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"
+            //               %3A   %2F   %3F   %23   %5B   %5D   %40
+            // sub-delims  = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
+            //               %21   %24   %26   %27   %28   %29   %2A   %2B   %2C   %3B   %3D
+            
+            // Note than chars "[" and "]" are mentioned as they should be escaped on RFC 2396,
+            // but on the part D. Changes from RFC 2396 says about this chars (used on IPv6) 
+            // "...those rules were redefined to directly specify the characters allowed...."
+            // There is also other characters moved from excluded list to reserved:
+            // "[" / "]" / "#"  
+            
+            // RFC 3986 Section 2.3:
+            // "... for consistency, percent-encoded octets in the ranges of ALPHA
+            // (%41-%5A and %61-%7A), DIGIT (%30-%39), hyphen (%2D), period (%2E),
+            // underscore (%5F), or tilde (%7E) should not be created by URI
+            // producers...."
+            
+            // RFC 3986 Section  3.2.2.  Host
+
+            // host = IP-literal / IPv4address / reg-name
+
+            // The reg-name syntax allows percent-encoded octets in order to
+            // represent non-ASCII registered names in a uniform way that is
+            // independent of the underlying name resolution technology.  Non-ASCII
+            // characters must first be encoded according to UTF-8 [STD63], and then
+            // each octet of the corresponding UTF-8 sequence must be percent-
+            // encoded to be represented as URI characters.  URI producing
+            // applications must not use percent-encoding in host unless it is used
+            // to represent a UTF-8 character sequence.
+            
+            // RFC 3986 Section 3.4 Query 
+            //         query       = *( pchar / "/" / "?" )
+            //
+            // "...  However, as query components are often used to carry identifying information 
+            // in the form of "key=value" pairs and one frequently used value is a reference to
+            // another URI, it is sometimes better for usability to avoid percent-encoding those characters....."
+            //
+            // RFC 3986 Section 2.5 Identifying Data (Apply to query section)
+            //
+            // When a new URI scheme defines a component that represents textual
+            // data consisting of characters from the Universal Character Set [UCS],
+            // the data should first be encoded as octets according to the UTF-8
+            // character encoding [STD63]; then only those octets that do not
+            // correspond to characters in the unreserved set should be percent-
+            // encoded.  For example, the character A would be represented as "A",
+            // the character LATIN CAPITAL LETTER A WITH GRAVE would be represented
+            // as "%C3%80", and the character KATAKANA LETTER A would be represented
+            // as "%E3%82%A2".
+            //
+            // RFC 3986 Section 3.5 Fragment
+            //         fragment    = *( pchar / "/" / "?" )
+            //
+            // Note that follows the same as query
+            
+            // Based on the extracts the strategy to apply on this method is:
+            // 
+            // On scheme ":" hier-part
+            //
+            // Escape or percent encode chars inside :
+            // 
+            // - From %00 to %20, 
+            // - <"> %22, "%" %25 (If there is encode of "%", there is a risk of 
+            //                     duplicate encoding, encode it when we are sure 
+            //                     that there are not encoded twice)
+            // - "<" %3C, ">" %3E
+            // - "\" %5C, "^" %5E, "`" %60 
+            // - "{" %7B, "|" %7C, "}" %7D
+            // - From %7F ad infinitum (characters from %100 to infinitum should not be used in this
+            //   part of an URI, but it is preferred to encode it that omit it).
+            //
+            // The remaining characters must not be encoded
+            //
+            // Characters after ? or # should be percent encoding but only the necessary ones:
+            //
+            // - From %00 to %20 (' ' %20 could encode as +, but %20 also works, so we keep %20)
+            // - <"> %22, "%" %25 (If there is encode of "%", there is a risk of 
+            //                     duplicate encoding, encode it when we are sure 
+            //                     that there are not encoded twice)
+            // - "<" %3C, ">" %3E,
+            // - "\" %5C, "^" %5E, "`" %60 
+            // - "{" %7B, "|" %7C, "}" %7D
+            // - From %7F ad infinitum (each character as many bytes as necessary but take into account
+            //   that a single char should contain 2,3 or more bytes!. This data should be encoded 
+            //   translating from the document character encoding to percent encoding, because this values
+            //   could be retrieved from httpRequest.getParameter() and it uses the current character encoding
+            //   for decode values)
+            //
+            // "&" should be encoded as "&amp;" because this link is inside an html page, and 
+            // put only & is invalid in this context.
+
+            if (   (c <= (char)0x20) || (c >= (char)0x7F) || 
+                    c == '"' || c == '<' ||
+                    c == '>' || c == '\\' || c == '^' || c == '`' ||
+                    c == '{' || c == '|' || c == '}')
+            {
+                // The percent encoding on this part should be done using UTF-8 charset
+                // as RFC 3986 Section 3.2.2 says.
+                // Also there is a reference on 
+                // http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars
+                // that recommend use of UTF-8 instead the document character encoding.
+                // Jetty set by default UTF-8 (see http://jira.codehaus.org/browse/JETTY-113)
+                //app = percentEncode(c, "UTF-8");
+                if (start < i)
+                {
+                    writer.write(string, start, i-start);
+                }
+                start = i+1;
+                percentEncode(writer, c, "UTF-8");
+            }
+            else if (c == '%')
+            {
+                if (i + 2 < string.length())
+                {
+                    char c1 = string.charAt(i+1);
+                    char c2 = string.charAt(i+2);
+                    if ((( c1 >= '0' && c1 <='9') || (c1 >='A' && c1 <='Z')) &&
+                        (( c2 >= '0' && c2 <='9') || (c2 >='A' && c2 <='Z')))
+                    {
+                        // do not percent encode, because it could be already encoded
+                        // and we don't want encode it twice
+                    }
+                    else
+                    {
+                        //app = percentEncode(c, UTF8);
+                        if (start < i)
+                        {
+                            writer.write(string, start, i-start);
+                        }
+                        start = i+1;
+                        percentEncode(writer, c, UTF8);
+                    }
+                }
+                else
+                {
+                    //app = percentEncode(c, UTF8);
+                    if (start < i)
+                    {
+                        writer.write(string, start, i-start);
+                    }
+                    start = i+1;
+                    percentEncode(writer, c, UTF8);
+                }
+            }
+            else if (c == '?' || c == '#')
+            {
+                if (i+1 < string.length())
+                {
+                    // The remaining part of the URI are data that should be encoded
+                    // using the document character encoding.
+                    //app = c + encodeURIQuery(string.substring(i+1), characterEncoding);
+                    if (start < i)
+                    {
+                        writer.write(string, start, i-start);
+                    }
+                    start = i+1;
+                    writer.write(c);
+                    //encodeURIQuery(writer, string.substring(i+1), characterEncoding);
+                    encodeURIQuery(writer, string, i+1, characterEncoding);
+                    endLoop = true;
+                }
+            }
+            else
+            {
+                //No encoding, just do nothing, char will be added later.
+            }
+                        
+            if (app != null)
+            {
+                //if (sb == null)
+                //{
+                //    sb = new StringBuilder(string.substring(0, i));
+                //}
+                //sb.append(app);
+                if (start < i)
+                {
+                    writer.write(string, start, i-start);
+                }
+                start = i+1;
+                writer.write(app);
+            }
+            //else
+            //{
+            //    if (sb != null)
+            //    {
+            //        sb.append(c);
+            //    }
+            //}
+            if (endLoop)
+            {
+                start = string.length();
+                break;
+            }
+        }
+        //if (sb == null)
+        //{
+        //    return string;
+        //}
+        //else
+        //{
+        //    return sb.toString();
+        //}
+        if (start == 0)
+        {
+            writer.write(string);
+        }
+        else if (start < string.length())
+        {
+            writer.write(string,start,string.length()-start);
+        }
+    }
+
+    /**
+     * Encode a unicode char value in percentEncode, decoding its bytes using a specified 
+     * characterEncoding.
+     * 
+     * @param c
+     * @param characterEncoding
+     * @return
+     */
+    private static void percentEncode(Writer writer, char c, String characterEncoding) throws IOException
+    {
+        String app = null;
+        if (c > (char)((short)0x007F))
+        {
+            //percent encode in the proper encoding to be consistent
+            //app = percentEncodeNonUsAsciiCharacter(writer c, characterEncoding);
+            percentEncodeNonUsAsciiCharacter(writer, c, characterEncoding);
+        }
+        else
+        {
+            //percent encode US-ASCII char (0x00-0x7F range)
+            //app = "%" + HEX_CHARSET.charAt( ((c >> 0x4) % 0x10)) +HEX_CHARSET.charAt(c % 0x10);
+            writer.write('%');
+            writer.write(HEX_CHARSET.charAt( ((c >> 0x4) % 0x10)));
+            writer.write(HEX_CHARSET.charAt(c % 0x10));
+        }
+        //return app;
+    }
+    
+    private static void percentEncodeNonUsAsciiCharacter(Writer currentWriter, char c, String characterEncoding) 
+        throws IOException
+    {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(10);
+        StringBuilder builder = new StringBuilder();
+        try
+        {
+            OutputStreamWriter writer = new OutputStreamWriter(baos,characterEncoding);
+            writer.write(c);
+            writer.flush();
+        }
+        catch(IOException e)
+        {
+            baos.reset();
+            return;
+        }
+        
+        byte [] byteArray =  baos.toByteArray();
+        for (int i=0; i < byteArray.length; i++)
+        {
+            //builder.append('%');
+            //builder.append(HEX_CHARSET.charAt( (( ((short) byteArray[i] & 0xFF ) >> 0x4) % 0x10)) );
+            //builder.append(HEX_CHARSET.charAt( ((short) byteArray[i] & 0xFF ) % 0x10));
+            currentWriter.write('%');
+            currentWriter.write(HEX_CHARSET.charAt( (( ((short) byteArray[i] & 0xFF ) >> 0x4) % 0x10)) );
+            currentWriter.write(HEX_CHARSET.charAt( ((short) byteArray[i] & 0xFF ) % 0x10));
+        }
+        
+        //return builder.toString();
+    }
+    
+    /**
+     * Encode the query part using the document charset encoding provided.
+     * 
+     * 
+     * @param string
+     * @param characterEncoding
+     * @return
+     */
+    private static void encodeURIQuery(Writer writer, final String string, int offset, final String characterEncoding)
+            throws IOException
+    {
+        //StringBuilder sb = null;    //create later on demand
+        int start = offset;
+        int realLength = string.length()-offset;
+        String app;
+        char c;
+        //boolean endLoop = false;
+        for (int i = offset; i < offset+realLength; ++i)
+        {
+            app = null;
+            c = string.charAt(i);
+            
+            // - From %00 to %20 (' ' %20 could encode as +, but %20 also works, so we keep %20)
+            // - <"> %22 (If there is encode of "%", there is a risk of duplicate encoding, so 
+            //            we make easier and omit this one)
+            // - "<" %3C, ">" %3E,
+            // - "\" %5C, "^" %5E, "`" %60 
+            // - "{" %7B, "|" %7C, "}" %7D
+            // - From %7F ad infinitum (each character as many bytes as necessary but take into account
+            //   that a single char should contain 2,3 or more bytes!. This data should be encoded 
+            //   translating from the document character encoding to percent encoding)
+            //
+            // "&" should be encoded as "&amp;" because this link is inside an html page, and 
+            // put & is invalid in this context   
+            
+            if (   (c <= (char)0x20) || (c >= (char)0x7F) || 
+                    c == '"' || c == '<' ||
+                    c == '>' || c == '\\' || c == '^' || c == '`' ||
+                    c == '{' || c == '|' || c == '}')
+            {
+                // The percent encoding on this part should be done using UTF-8 charset
+                // as RFC 3986 Section 3.2.2 says
+                //app = percentEncode(c, characterEncoding);
+                if (start < i)
+                {
+                    writer.write(string, start, i-start);
+                }
+                start = i+1;
+                percentEncode(writer, c, characterEncoding);
+            }
+            else if (c == '%')
+            {
+                if (i + 2 < string.length())
+                {
+                    char c1 = string.charAt(i+1);
+                    char c2 = string.charAt(i+2);
+                    if ((( c1 >= '0' && c1 <='9') || (c1 >='A' && c1 <='Z')) &&
+                        (( c2 >= '0' && c2 <='9') || (c2 >='A' && c2 <='Z')))
+                    {
+                        // do not percent encode, because it could be already encoded
+                    }
+                    else
+                    {
+                        //app = percentEncode(c, characterEncoding);
+                        if (start < i)
+                        {
+                            writer.write(string, start, i-start);
+                        }
+                        start = i+1;
+                        percentEncode(writer, c, characterEncoding);
+                    }
+                }
+                else
+                {
+                    //app = percentEncode(c, characterEncoding);
+                    if (start < i)
+                    {
+                        writer.write(string, start, i-start);
+                    }
+                    start = i+1;
+                    percentEncode(writer, c, characterEncoding);
+                }
+            }
+            else if (c == '&')
+            {
+                if (i+4 < string.length() )
+                {
+                    if ('a' == string.charAt(i+1) &&
+                        'm' == string.charAt(i+2) &&
+                        'p' == string.charAt(i+3) &&
+                        ';' == string.charAt(i+4))
+                    {
+                        //Skip
+                    }
+                    else
+                    {
+                        app = "&amp;";
+                    }
+                }
+                else
+                {
+                    app = "&amp;";
+                }
+            }
+            else
+            {
+                //No encoding, just do nothing, char will be added later.
+            }
+                        
+            if (app != null)
+            {
+                //if (sb == null)
+                //{
+                //    sb = new StringBuilder(string.substring(0, i));
+                //}
+                //sb.append(app);
+                if (start < i)
+                {
+                    writer.write(string, start, i-start);
+                }
+                start = i+1;
+                writer.write(app);
+            }
+            //else
+            //{
+            //    if (sb != null)
+            //    {
+            //        sb.append(c);
+            //    }
+            //}
+            //if (endLoop)
+            //{
+            //    break;
+            //}
+        }
+        
+        //if (sb == null)
+        //{
+        //    return string;
+        //}
+        //else
+        //{
+        //    return sb.toString();
+        //}
+        if (start == offset)
+        {
+            writer.write(string, offset, realLength);
+        }
+        else if (start < offset+realLength)
+        {
+            writer.write(string,start,offset+realLength-start);
+        }
+    }
 }

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/JavascriptUtils.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/JavascriptUtils.java?rev=1239800&r1=1239799&r2=1239800&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/JavascriptUtils.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/JavascriptUtils.java Thu Feb  2 20:01:25 2012
@@ -125,7 +125,7 @@ public final class JavascriptUtils
             return s + "_";
         }
 
-        StringBuffer buf = null;
+        StringBuilder buf = null;
         for (int i = 0, len = s.length(); i < len; i++)
         {
             char c = s.charAt(i);
@@ -142,7 +142,7 @@ public final class JavascriptUtils
             {
                 if (buf == null)
                 {
-                    buf = new StringBuffer(s.length() + 10);
+                    buf = new StringBuilder(s.length() + 10);
                     buf.append(s.substring(0, i));
                 }
 
@@ -200,7 +200,7 @@ public final class JavascriptUtils
         {
             return "";
         }
-        StringBuffer sb = null;    //create later on demand
+        StringBuilder sb = null;    //create later on demand
         String app;
         char c;
         for (int i = 0; i < string.length (); ++i)
@@ -220,7 +220,7 @@ public final class JavascriptUtils
             {
                 if (sb == null)
                 {
-                    sb = new StringBuffer(string.substring(0, i));
+                    sb = new StringBuilder(string.substring(0, i));
                 }
                 sb.append(app);
             }

Added: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/SharedStringBuilder.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/SharedStringBuilder.java?rev=1239800&view=auto
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/SharedStringBuilder.java (added)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/SharedStringBuilder.java Thu Feb  2 20:01:25 2012
@@ -0,0 +1,77 @@
+/*
+ * 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.myfaces.shared.renderkit.html.util;
+
+import java.util.Map;
+import javax.faces.context.FacesContext;
+
+/**
+ *
+ * @author lu4242
+ */
+public class SharedStringBuilder
+{
+    public static StringBuilder get(String stringBuilderKey)
+    {
+        return get(FacesContext.getCurrentInstance(), stringBuilderKey);
+    }
+
+    // TODO checkstyle complains; does this have to lead with __ ?
+    public static StringBuilder get(FacesContext facesContext, String stringBuilderKey)
+    {
+        Map<Object, Object> attributes = facesContext.getAttributes();
+
+        StringBuilder sb = (StringBuilder) attributes.get(stringBuilderKey);
+
+        if (sb == null)
+        {
+            sb = new StringBuilder();
+            attributes.put(stringBuilderKey, sb);
+        }
+        else
+        {
+
+            // clear out the stringBuilder by setting the length to 0
+            sb.setLength(0);
+        }
+
+        return sb;
+    }
+    
+    public static StringBuilder get(FacesContext facesContext, String stringBuilderKey, int initialSize)
+    {
+        Map<Object, Object> attributes = facesContext.getAttributes();
+
+        StringBuilder sb = (StringBuilder) attributes.get(stringBuilderKey);
+
+        if (sb == null)
+        {
+            sb = new StringBuilder(initialSize);
+            attributes.put(stringBuilderKey, sb);
+        }
+        else
+        {
+
+            // clear out the stringBuilder by setting the length to 0
+            sb.setLength(0);
+        }
+
+        return sb;
+    }
+}

Propchange: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/SharedStringBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/UnicodeEncoder.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/UnicodeEncoder.java?rev=1239800&r1=1239799&r2=1239800&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/UnicodeEncoder.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/renderkit/html/util/UnicodeEncoder.java Thu Feb  2 20:01:25 2012
@@ -18,6 +18,9 @@
  */
 package org.apache.myfaces.shared.renderkit.html.util;
 
+import java.io.IOException;
+import java.io.Writer;
+
 /**
  * Converts characters outside of latin-1 set in a string to numeric character references.
  * 
@@ -60,6 +63,112 @@ public abstract class UnicodeEncoder
 
         return sb != null ? sb.toString() : string;
     }
+    
+    public static void encode (Writer writer, String string) throws IOException
+    {
+        if (string == null)
+        {
+            return;
+        }
+
+        int start = 0;
+        char c;
+        for (int i = 0; i < string.length (); ++i)
+        {
+            c = string.charAt(i);
+            if (((int)c) >= 0x80)
+            {
+                if (start < i)
+                {
+                    writer.write(string, start, i-start);
+                }
+                start = i+1;
+                //encode all non basic latin characters
+                writer.write("&#");
+                writer.write(Integer.toString((int)c));
+                writer.write(";");
+            }
+        }
+
+        if (start == 0)
+        {
+            writer.write(string);
+        }
+        else if (start < string.length())
+        {
+            writer.write(string,start,string.length()-start);
+        }
+    }
+
+    public static void encode (Writer writer, char[] cbuf, int off, int len) throws IOException
+    {
+        if (cbuf == null)
+        {
+            return;
+        }
+
+        int start = off;
+        char c;
+        for (int i = off; i < off+len; ++i)
+        {
+            c = cbuf[i];
+            if (((int)c) >= 0x80)
+            {
+                if (start < i)
+                {
+                    writer.write(cbuf, start, i-start);
+                }
+                start = i+1;
+                //encode all non basic latin characters
+                writer.write("&#");
+                writer.write(Integer.toString((int)c));
+                writer.write(";");
+            }
+        }
+
+        if (start == off)
+        {
+            writer.write(cbuf, off, len);
+        }
+        else if (start < off+len)
+        {
+            writer.write(cbuf,start,off+len-start);
+        }
+    }
+    
+    public static void encode (Writer writer, String cbuf, int off, int len) throws IOException
+    {
+        if (cbuf == null)
+        {
+            return;
+        }
 
+        int start = off;
+        char c;
+        for (int i = off; i < off+len; ++i)
+        {
+            c = cbuf.charAt(i);
+            if (((int)c) >= 0x80)
+            {
+                if (start < i)
+                {
+                    writer.write(cbuf, start, i-start);
+                }
+                start = i+1;
+                //encode all non basic latin characters
+                writer.write("&#");
+                writer.write(Integer.toString((int)c));
+                writer.write(";");
+            }
+        }
 
+        if (start == off)
+        {
+            writer.write(cbuf, off, len);
+        }
+        else if (start < off+len)
+        {
+            writer.write(cbuf,start,off+len-start);
+        }
+    }
 }

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/resource/ResourceLoaderWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/resource/ResourceLoaderWrapper.java?rev=1239800&r1=1239799&r2=1239800&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/resource/ResourceLoaderWrapper.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/resource/ResourceLoaderWrapper.java Thu Feb  2 20:01:25 2012
@@ -1,100 +1,100 @@
-/*
- * 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.myfaces.shared.resource;
-
-import java.io.InputStream;
-import java.net.URL;
-import java.util.Comparator;
-
-import javax.faces.FacesWrapper;
-
-/**
- * 
- * @author Leonardo Uribe
- *
- */
-public abstract class ResourceLoaderWrapper extends ResourceLoader implements FacesWrapper<ResourceLoader>
-{
-    
-    public ResourceLoaderWrapper()
-    {
-        super(null);
-    }
-
-    public String getResourceVersion(String path)
-    {
-        return getWrapped().getResourceVersion(path);
-    }
-
-    public String getLibraryVersion(String path)
-    {
-        return getWrapped().getLibraryVersion(path);
-    }
-
-    public URL getResourceURL(ResourceMeta resourceMeta)
-    {
-        return getWrapped().getResourceURL(resourceMeta);
-    }
-
-    public InputStream getResourceInputStream(ResourceMeta resourceMeta)
-    {
-        return getWrapped().getResourceInputStream(resourceMeta);
-    }
-
-    public ResourceMeta createResourceMeta(String prefix, String libraryName,
-            String libraryVersion, String resourceName, String resourceVersion)
-    {
-        return getWrapped().createResourceMeta(prefix, libraryName, libraryVersion,
-                resourceName, resourceVersion);
-    }
-
-    public boolean libraryExists(String libraryName)
-    {
-        return getWrapped().libraryExists(libraryName);
-    }
-
-    public String getPrefix()
-    {
-        return getWrapped().getPrefix();
-    }
-
-    public void setPrefix(String prefix)
-    {
-        getWrapped().setPrefix(prefix);
-    }
-
-    @Override
-    public boolean resourceExists(ResourceMeta resourceMeta)
-    {
-        return getWrapped().resourceExists(resourceMeta);
-    }
-
-    @Override
-    protected Comparator<String> getVersionComparator()
-    {
-        return getWrapped().getVersionComparator();
-    }
-
-    @Override
-    protected void setVersionComparator(Comparator<String> versionComparator)
-    {
-        getWrapped().setVersionComparator(versionComparator);
-    }
-    
-}
+/*
+ * 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.myfaces.shared.resource;
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Comparator;
+
+import javax.faces.FacesWrapper;
+
+/**
+ * 
+ * @author Leonardo Uribe
+ *
+ */
+public abstract class ResourceLoaderWrapper extends ResourceLoader implements FacesWrapper<ResourceLoader>
+{
+    
+    public ResourceLoaderWrapper()
+    {
+        super(null);
+    }
+
+    public String getResourceVersion(String path)
+    {
+        return getWrapped().getResourceVersion(path);
+    }
+
+    public String getLibraryVersion(String path)
+    {
+        return getWrapped().getLibraryVersion(path);
+    }
+
+    public URL getResourceURL(ResourceMeta resourceMeta)
+    {
+        return getWrapped().getResourceURL(resourceMeta);
+    }
+
+    public InputStream getResourceInputStream(ResourceMeta resourceMeta)
+    {
+        return getWrapped().getResourceInputStream(resourceMeta);
+    }
+
+    public ResourceMeta createResourceMeta(String prefix, String libraryName,
+            String libraryVersion, String resourceName, String resourceVersion)
+    {
+        return getWrapped().createResourceMeta(prefix, libraryName, libraryVersion,
+                resourceName, resourceVersion);
+    }
+
+    public boolean libraryExists(String libraryName)
+    {
+        return getWrapped().libraryExists(libraryName);
+    }
+
+    public String getPrefix()
+    {
+        return getWrapped().getPrefix();
+    }
+
+    public void setPrefix(String prefix)
+    {
+        getWrapped().setPrefix(prefix);
+    }
+
+    @Override
+    public boolean resourceExists(ResourceMeta resourceMeta)
+    {
+        return getWrapped().resourceExists(resourceMeta);
+    }
+
+    @Override
+    protected Comparator<String> getVersionComparator()
+    {
+        return getWrapped().getVersionComparator();
+    }
+
+    @Override
+    protected void setVersionComparator(Comparator<String> versionComparator)
+    {
+        getWrapped().setVersionComparator(versionComparator);
+    }
+    
+}

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/resource/ResourceValidationUtils.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/resource/ResourceValidationUtils.java?rev=1239800&r1=1239799&r2=1239800&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/resource/ResourceValidationUtils.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/resource/ResourceValidationUtils.java Thu Feb  2 20:01:25 2012
@@ -1,114 +1,199 @@
-/*
- * 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.myfaces.shared.resource;
-
-public class ResourceValidationUtils
-{
-    public static boolean isValidResourceName(String resourceName)
-    {
-        return validate(resourceName, true);
-    }
-    
-    public static boolean isValidLibraryName(String libraryName)
-    {
-        return validate(libraryName, false);
-    }
-    
-    public static boolean isValidLocalePrefix(String localePrefix)
-    {
-        for (int i = 0; i < localePrefix.length(); i++)
-        {
-            char c = localePrefix.charAt(i);
-            if ( (c >='A' && c <='Z') || c == '_' || (c >='a' && c <='z') || (c >='0' && c <='9') )
-            {
-                continue;
-            }
-            else
-            {
-                return false;
-            }
-        }
-        return true;
-    }
-    
-    private static boolean validate(String expression, boolean allowSlash)
-    {
-        if (expression.length() == 2 && 
-            expression.charAt(0) == '.' &&
-            expression.charAt(1) == '.')
-        {
-            return false;
-        }
-        for (int i = 0; i < expression.length(); i++)
-        {
-            char c = expression.charAt(i);
-
-            // Enforce NameChar convention as specified
-            // http://www.w3.org/TR/REC-xml/#NT-NameChar
-            // Valid characters for NameChar
-            // ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | 
-            // [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | 
-            // [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] 
-            // | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
-            // "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
-            // Excluding ":" 
-            if ( (c >='A' && c <='Z') || c == '_' || (c >='a' && c <='z') || 
-                 (c >=0xC0 && c <=0xD6) || (c >=0xD8 && c <=0xF6) || 
-                 (c >=0xF8 && c <=0x2FF) || (c >=0x370 && c <=0x37D) || 
-                 (c >=0x37F && c <=0x1FFF) || (c >=0x200C && c <=0x200D) ||
-                 (c >=0x2070 && c <=0x218F) || (c >=0x2C00 && c <=0x2FEF) || 
-                 (c >=0x3001 && c <=0xD7FF) || (c >=0xF900 && c <=0xFDCF) ||
-                 (c >=0xFDF0 && c <=0xFFFD) || (c >=0x10000 && c <=0xEFFFF) ||
-                 c == '-' || (c >='0' && c <='9') || c == 0xB7 || (c >=0x300 && c <=0x36F) || 
-                 (c >=0x203F && c <=0x2040) || (allowSlash && c == '/')
-                 )
-            {
-                continue;
-            }
-            else if (c == '.')
-            {
-                if (i+2 < expression.length())
-                {
-                    char c1 = expression.charAt(i+1);
-                    char c2 = expression.charAt(i+2);
-                    if (c == c1 && (c2 == '/' || c2 == '\\' ) )
-                    {
-                        return false;
-                    }
-                }
-                continue;
-            }
-            else
-            {
-                return false;
-            }
-        }
-        if (expression.length() >= 3)
-        {
-            int length = expression.length();
-            if ( (expression.charAt(length-3) == '/' || expression.charAt(length-3) == '\\' ) && 
-                  expression.charAt(length-2) == '.' &&
-                  expression.charAt(length-1) == '.' )
-            {
-                return false;
-            }
-        }
-        return true;
-    }
-}
+/*
+ * 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.myfaces.shared.resource;
+
+public class ResourceValidationUtils
+{
+    public static boolean isValidResourceName(String resourceName)
+    {
+        return validateResourceName(resourceName, true);
+    }
+    
+    public static boolean isValidLibraryName(String libraryName)
+    {
+        return validate(libraryName, false);
+    }
+    
+    public static boolean isValidLibraryName(String libraryName, boolean allowSlash)
+    {
+        return validate(libraryName, allowSlash);
+    }
+    
+    public static boolean isValidLocalePrefix(String localePrefix)
+    {
+        for (int i = 0; i < localePrefix.length(); i++)
+        {
+            char c = localePrefix.charAt(i);
+            if ( (c >='A' && c <='Z') || c == '_' || (c >='a' && c <='z') || (c >='0' && c <='9') )
+            {
+                continue;
+            }
+            else
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    private static boolean validate(String expression, boolean allowSlash)
+    {
+        if (expression.length() == 2 && 
+            expression.charAt(0) == '.' &&
+            expression.charAt(1) == '.')
+        {
+            return false;
+        }
+        for (int i = 0; i < expression.length(); i++)
+        {
+            char c = expression.charAt(i);
+
+            // Enforce NameChar convention as specified
+            // http://www.w3.org/TR/REC-xml/#NT-NameChar
+            // Valid characters for NameChar
+            // ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | 
+            // [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | 
+            // [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] 
+            // | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
+            // "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
+            // Excluding ":" 
+            if ( (c >='A' && c <='Z') || c == '_' || (c >='a' && c <='z') || 
+                 (c >=0xC0 && c <=0xD6) || (c >=0xD8 && c <=0xF6) || 
+                 (c >=0xF8 && c <=0x2FF) || (c >=0x370 && c <=0x37D) || 
+                 (c >=0x37F && c <=0x1FFF) || (c >=0x200C && c <=0x200D) ||
+                 (c >=0x2070 && c <=0x218F) || (c >=0x2C00 && c <=0x2FEF) || 
+                 (c >=0x3001 && c <=0xD7FF) || (c >=0xF900 && c <=0xFDCF) ||
+                 (c >=0xFDF0 && c <=0xFFFD) || (c >=0x10000 && c <=0xEFFFF) ||
+                 c == '-' || (c >='0' && c <='9') || c == 0xB7 || (c >=0x300 && c <=0x36F) || 
+                 (c >=0x203F && c <=0x2040) || (allowSlash && c == '/')
+                 )
+            {
+                continue;
+            }
+            else if (c == '.')
+            {
+                if (i+2 < expression.length())
+                {
+                    char c1 = expression.charAt(i+1);
+                    char c2 = expression.charAt(i+2);
+                    if (c == c1 && (c2 == '/' || c2 == '\\' ) )
+                    {
+                        return false;
+                    }
+                }
+                continue;
+            }
+            else
+            {
+                return false;
+            }
+        }
+        if (expression.length() >= 3)
+        {
+            int length = expression.length();
+            if ( (expression.charAt(length-3) == '/' || expression.charAt(length-3) == '\\' ) && 
+                  expression.charAt(length-2) == '.' &&
+                  expression.charAt(length-1) == '.' )
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    private static boolean validateResourceName(String expression, boolean allowSlash)
+    {
+        if (expression.length() == 2 && 
+            expression.charAt(0) == '.' &&
+            expression.charAt(1) == '.')
+        {
+            return false;
+        }
+        for (int i = 0; i < expression.length(); i++)
+        {
+            char c = expression.charAt(i);
+
+            // Enforce NameChar convention as specified
+            // http://www.w3.org/TR/REC-xml/#NT-NameChar
+            // Valid characters for NameChar
+            // ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | 
+            // [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | 
+            // [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] 
+            // | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
+            // "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
+            // Excluding ":" 
+            
+            // Forbidden chars by win
+            // < (less than)
+            // > (greater than)
+            // : (colon)
+            // " (double quote)
+            // / (forward slash)
+            // \ (backslash)
+            // | (vertical bar or pipe)
+            // ? (question mark)
+            // * (asterisk)
+            // Do not use chars in UNIX because they have special meaning
+            // *&%$|^/\~
+            if ( (c >='A' && c <='Z') || c == '_' || (c >='a' && c <='z') || 
+                 (c >=0xC0 && c <=0xD6) || (c >=0xD8 && c <=0xF6) || 
+                 (c >=0xF8 && c <=0x2FF) || (c >=0x370 && c <=0x37D) || 
+                 (c >=0x37F && c <=0x1FFF) || (c >=0x200C && c <=0x200D) ||
+                 (c >=0x2070 && c <=0x218F) || (c >=0x2C00 && c <=0x2FEF) || 
+                 (c >=0x3001 && c <=0xD7FF) || (c >=0xF900 && c <=0xFDCF) ||
+                 (c >=0xFDF0 && c <=0xFFFD) || (c >=0x10000 && c <=0xEFFFF) ||
+                 (c == '-') || (c >='0' && c <='9') || c == 0xB7 || (c >=0x300 && c <=0x36F) || 
+                 (c >=0x203F && c <=0x2040) || (allowSlash && c == '/') ||
+                 (c == '!') || (c == '#') || (c == '\'') || (c == '(') || (c == ')') ||
+                 (c == '+') || (c == ',') || (c == ';' ) || (c == '=') || 
+                 (c == '@') || (c == '[') || (c == ']' ) || (c == '{') || (c == '}'))
+            {
+                continue;
+            }
+            else if (c == '.')
+            {
+                if (i+2 < expression.length())
+                {
+                    char c1 = expression.charAt(i+1);
+                    char c2 = expression.charAt(i+2);
+                    if (c == c1 && (c2 == '/' || c2 == '\\' ) )
+                    {
+                        return false;
+                    }
+                }
+                continue;
+            }
+            else
+            {
+                return false;
+            }
+        }
+        if (expression.length() >= 3)
+        {
+            int length = expression.length();
+            if ( (expression.charAt(length-3) == '/' || expression.charAt(length-3) == '\\' ) && 
+                  expression.charAt(length-2) == '.' &&
+                  expression.charAt(length-1) == '.' )
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+}