[gatein-commits] gatein SVN: r459 - in portal/branches/performance: component/common/src/test/java/org/exoplatform/commons/utils and 9 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Fri Oct 30 10:38:37 EDT 2009


Author: julien_viet
Date: 2009-10-30 10:38:36 -0400 (Fri, 30 Oct 2009)
New Revision: 459

Added:
   portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/BinaryOutput.java
   portal/branches/performance/component/common/src/test/java/org/exoplatform/commons/utils/TestBufferingOutputStream.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/BaseScript.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyPrinter.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyScriptBuilder.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyTemplate.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyTemplateEngine.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyText.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/LineBreakItem.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/OutputStreamWriterGroovyPrinter.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/SectionItem.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/SectionType.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateCompiler.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateParser.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateSection.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TextItem.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/WriterGroovyPrinter.java
   portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/
   portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateCompiler.java
   portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateParser.java
   portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateRendering.java
   portal/branches/performance/component/scripting/src/test/resources/
   portal/branches/performance/component/scripting/src/test/resources/UIPortalApplication.gtmpl
Removed:
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/text/SimpleTemplateEngine.java
Modified:
   portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/CharEncoder.java
   portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/CharsetCharEncoder.java
   portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/CharsetTextEncoder.java
   portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/OutputStreamPrinter.java
   portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/Printer.java
   portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/TableCharEncoder.java
   portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/Text.java
   portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/TextEncoder.java
   portal/branches/performance/component/common/src/test/java/org/exoplatform/commons/utils/TestPrinter.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/commons/utils/PortalPrinter.java
   portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/text/TemplateService.java
   portal/branches/performance/webui/core/src/main/java/org/exoplatform/webui/application/portlet/PortletApplication.java
   portal/branches/performance/webui/core/src/main/java/org/exoplatform/webui/application/portlet/PortletRequestContext.java
   portal/branches/performance/webui/portal/src/main/java/org/exoplatform/portal/webui/application/UIPortletLifecycle.java
Log:
GTNPORTAL-142 : Optimized Groovy Template Engine


Added: portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/BinaryOutput.java
===================================================================
--- portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/BinaryOutput.java	                        (rev 0)
+++ portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/BinaryOutput.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.commons.utils;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public interface BinaryOutput
+{
+
+   Charset getCharset();
+
+   void write(byte b) throws IOException;
+
+   void write(byte[] bytes) throws IOException;
+
+   void write(byte[] b, int off, int len) throws IOException;
+
+}

Modified: portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/CharEncoder.java
===================================================================
--- portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/CharEncoder.java	2009-10-30 10:54:06 UTC (rev 458)
+++ portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/CharEncoder.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -19,6 +19,8 @@
 
 package org.exoplatform.commons.utils;
 
+import java.nio.charset.Charset;
+
 /**
  * A char encoder that encodes chars to a suite of bytes. No assumptions must be made about the
  * statefullness nature of an encoder as some encoder may be statefull and some encoder may be stateless.
@@ -36,4 +38,11 @@
     * @return the serie of bytes corresponding to the encoded char
     */
    byte[] encode(char c);
+
+   /**
+    * Returns the charset that will perform the encoding.
+    *
+    * @return the charset for encoding
+    */
+   Charset getCharset();
 }

Modified: portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/CharsetCharEncoder.java
===================================================================
--- portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/CharsetCharEncoder.java	2009-10-30 10:54:06 UTC (rev 458)
+++ portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/CharsetCharEncoder.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -61,6 +61,11 @@
       this.arrays = new byte[][]{new byte[0], new byte[1], new byte[2], new byte[3], new byte[4], new byte[5]};
    }
 
+   public Charset getCharset()
+   {
+      return charset;
+   }
+
    public byte[] encode(char c)
    {
       /*

Modified: portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/CharsetTextEncoder.java
===================================================================
--- portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/CharsetTextEncoder.java	2009-10-30 10:54:06 UTC (rev 458)
+++ portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/CharsetTextEncoder.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -52,6 +52,11 @@
       this(new TableCharEncoder(new CharsetCharEncoder(Charset.forName(encoding))));
    }
 
+   public Charset getCharset()
+   {
+      return charEncoder.getCharset();
+   }
+
    public void encode(char c, OutputStream out) throws IOException
    {
       if (c > -1 && c < 128)

Modified: portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/OutputStreamPrinter.java
===================================================================
--- portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/OutputStreamPrinter.java	2009-10-30 10:54:06 UTC (rev 458)
+++ portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/OutputStreamPrinter.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -21,6 +21,7 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.nio.charset.Charset;
 
 /**
  * <p>An extension of {@link Printer} that encodes the text with a provided encoder and sends the resulting
@@ -48,7 +49,7 @@
  * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
  * @version $Revision$
  */
-public class OutputStreamPrinter extends Printer
+public class OutputStreamPrinter extends Printer implements BinaryOutput
 {
 
    private final IOFailureFlow failureFlow;
@@ -84,6 +85,7 @@
     * @param encoder the encoder
     * @param out the output
     * @param flushOnClose flush when stream is closed
+    * @param bufferSize the size of the buffer
     * @throws IllegalArgumentException if any argument is null
     */
    public OutputStreamPrinter(TextEncoder encoder, OutputStream out, boolean flushOnClose, int bufferSize) throws IllegalArgumentException
@@ -105,13 +107,14 @@
    }
 
    /**
-    * Builds a new instance.
+    * Builds a new instance with the specified parameters and the delegate output.
     *
     * @param encoder the encoder
     * @param out the output
     * @param failureFlow the control flow failureFlow
     * @param ignoreOnFailure the behavior on failure
     * @param flushOnClose flush when stream is closed
+    * @param bufferSize the buffer size
     * @throws IllegalArgumentException if any argument is null
     */
    public OutputStreamPrinter(
@@ -155,12 +158,17 @@
       this.flushOnClose = flushOnClose;
    }
 
+   public final Charset getCharset()
+   {
+      return encoder.getCharset();
+   }
+
    /**
     * Returns the failure flow.
     *
     * @return the failure flow
     */
-   public IOFailureFlow getFailureFlow()
+   public final IOFailureFlow getFailureFlow()
    {
       return failureFlow;
    }
@@ -170,19 +178,19 @@
     * 
     * @return the ignore on failure property
     */
-   public boolean getIgnoreOnFailure()
+   public final boolean getIgnoreOnFailure()
    {
       return ignoreOnFailure;
    }
 
-   public boolean isFailed()
+   public final boolean isFailed()
    {
       return failed;
    }
 
    // Bytes access interface
 
-   public void write(byte b) throws IOException
+   public final void write(byte b) throws IOException
    {
       if (!failed)
       {
@@ -197,7 +205,7 @@
       }
    }
 
-   public void write(byte[] bytes) throws IOException
+   public final void write(byte[] bytes) throws IOException
    {
       if (!failed)
       {
@@ -212,7 +220,7 @@
       }
    }
 
-   public void write(byte[] b, int off, int len) throws IOException
+   public final void write(byte[] b, int off, int len) throws IOException
    {
       if (!failed)
       {
@@ -230,7 +238,9 @@
    //
 
    @Override
-   public void write(int c) throws IOException
+   // Note that the parent method has a synchronisation that we want to avoid
+   // for performance reasons
+   public final void write(int c) throws IOException
    {
       if (!failed)
       {
@@ -246,7 +256,7 @@
    }
 
    @Override
-   public void write(char[] cbuf) throws IOException
+   public final void write(char[] cbuf) throws IOException
    {
       if (!failed)
       {
@@ -262,7 +272,7 @@
    }
 
    @Override
-   public void write(String str) throws IOException
+   public final void write(String str) throws IOException
    {
       if (!failed)
       {
@@ -278,7 +288,9 @@
    }
 
    @Override
-   public void write(String str, int off, int len) throws IOException
+   // Note that the parent method has a synchronisation that we want to avoid
+   // for performance reasons
+   public final void write(String str, int off, int len) throws IOException
    {
       if (!failed)
       {
@@ -293,7 +305,7 @@
       }
    }
 
-   public void write(char[] cbuf, int off, int len) throws IOException
+   public final void write(char[] cbuf, int off, int len) throws IOException
    {
       if (!failed)
       {
@@ -308,7 +320,7 @@
       }
    }
 
-   public void flush() throws IOException
+   public final void flush() throws IOException
    {
       if (!failed && !flushOnClose)
       {
@@ -323,7 +335,7 @@
       }
    }
 
-   public void close() throws IOException
+   public final void close() throws IOException
    {
       try
       {

Modified: portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/Printer.java
===================================================================
--- portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/Printer.java	2009-10-30 10:54:06 UTC (rev 458)
+++ portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/Printer.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -19,7 +19,6 @@
 
 package org.exoplatform.commons.utils;
 
-import java.io.IOException;
 import java.io.Writer;
 
 /**
@@ -30,47 +29,7 @@
  */
 public abstract class Printer extends Writer
 {
-
    public Printer()
    {
    }
-
-   public final void println(Object o)
-   {
-      print(o);
-      println();
-   }
-
-   public final void println()
-   {
-      try
-      {
-         write('\n');
-      }
-      catch (IOException ignore)
-      {
-      }
-   }
-
-   public final void print(Object o)
-   {
-      try
-      {
-         if (o == null)
-         {
-            write("null");
-         }
-         else if (o instanceof Text)
-         {
-            ((Text)o).writeTo(this);
-         }
-         else
-         {
-            write(o.toString());
-         }
-      }
-      catch (IOException ignore)
-      {
-      }
-   }
 }
\ No newline at end of file

Modified: portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/TableCharEncoder.java
===================================================================
--- portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/TableCharEncoder.java	2009-10-30 10:54:06 UTC (rev 458)
+++ portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/TableCharEncoder.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -19,6 +19,8 @@
 
 package org.exoplatform.commons.utils;
 
+import java.nio.charset.Charset;
+
 /**
  * A char encoder that use a table to cache the result produced by a delegate char encoder. This encoder
  * is stateless and should only be composed with stateless char encoder otherwise an unexpected result
@@ -47,6 +49,11 @@
       this.table = new byte[MAX + 1][];
    }
 
+   public Charset getCharset()
+   {
+      return charEncoder.getCharset();
+   }
+
    public byte[] encode(char c)
    {
       byte[] bytes = table[c];

Modified: portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/Text.java
===================================================================
--- portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/Text.java	2009-10-30 10:54:06 UTC (rev 458)
+++ portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/Text.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -20,11 +20,12 @@
 package org.exoplatform.commons.utils;
 
 import java.io.IOException;
-import java.io.UnsupportedEncodingException;
 import java.io.Writer;
+import java.nio.charset.Charset;
 
 /**
  * Represents text that can have several internal representations in order to minimize serialization when it is possible.
+ * The bytes returned by the byte oriented method must returned the data encoded with the UTF-8 encoding.
  *
  * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
  * @version $Revision$
@@ -36,12 +37,13 @@
     * Create a text object from the provided byte array.
     * 
     * @param bytes the markup as bytes
+    * @param charset the charset
     * @return the text object
     * @throws IllegalArgumentException if the bytes is null
     */
-   public static Text create(byte[] bytes) throws IllegalArgumentException
+   public static Text create(byte[] bytes, Charset charset) throws IllegalArgumentException
    {
-      return new Bytes(bytes);
+      return new Bytes(bytes, charset);
    }
 
    /**
@@ -61,7 +63,6 @@
     *
     * @param s the markup as bytes
     * @return the text object
-    * @todo provide an optimized subclass but it's not much used for now
     * @throws IllegalArgumentException if the string is null
     */
    public static Text create(String s) throws IllegalArgumentException
@@ -69,59 +70,46 @@
       return new Chars(s.toCharArray());
    }
 
-   public abstract byte[] getBytes();
-
-   public abstract char[] getChars();
-
-   public abstract void appendTo(Appendable appendable) throws IOException;
-
    public abstract void writeTo(Writer writer) throws IOException;
 
    private static class Bytes extends Text
    {
 
+      /** . */
       private final byte[] bytes;
 
-      private Bytes(byte[] bytes)
-      {
-         this.bytes = bytes;
-      }
+      /** . */
+      private final Charset charset;
 
-      public byte[] getBytes()
-      {
-         return bytes;
-      }
+      /** . */
+      private volatile String s;
 
-      public char[] getChars()
+      private Bytes(byte[] bytes, Charset charset)
       {
-         try
-         {
-            return new String(bytes, "utf-8").toCharArray();
-         }
-         catch (java.io.UnsupportedEncodingException e)
-         {
-            return new String(bytes).toCharArray();
-         }
+         this.bytes = bytes;
+         this.charset = charset;
       }
 
-      public void appendTo(Appendable appendable) throws IOException
+      public void writeTo(Writer writer) throws IOException
       {
-         for (char c : getChars())
+         if (writer instanceof BinaryOutput)
          {
-            appendable.append(c);
+            BinaryOutput osw = (BinaryOutput)writer;
+            if (charset.equals(osw.getCharset()))
+            {
+               osw.write(bytes);
+               return;
+            }
          }
-      }
-
-      public void writeTo(Writer writer) throws IOException
-      {
-         for (char c : getChars())
+         if (s == null)
          {
-            writer.append(c);
+            s = new String(bytes, charset);
          }
+         writer.append(s);
       }
    }
 
-   private static class Chars extends Text implements CharSequence
+   private static class Chars extends Text
    {
 
       /** Inclusive from index. */
@@ -147,73 +135,11 @@
          this.count = count;
       }
 
-      public byte[] getBytes()
-      {
-         String s = new String(chars, offset, count);
-         try
-         {
-            return s.getBytes("UTF-8");
-         }
-         catch (UnsupportedEncodingException e)
-         {
-            return s.getBytes();
-         }
-      }
-
-      public char[] getChars()
-      {
-         // Recompute the internal state
-         if (offset > 0 || count < chars.length)
-         {
-            char[] tmp = new char[count];
-            System.arraycopy(chars, offset, tmp, 0, count);
-            chars = tmp;
-            offset = 0;
-         }
-         return chars;
-      }
-
       public void writeTo(Writer writer) throws IOException
       {
          writer.write(chars, offset, count);
       }
 
-      public void appendTo(Appendable appendable) throws IOException
-      {
-         appendable.append(this);
-      }
-
-      public int length()
-      {
-         return count;
-      }
-
-      public char charAt(int index)
-      {
-         return chars[index - offset];
-      }
-
-      public CharSequence subSequence(int start, int end)
-      {
-         if (start < 0)
-         {
-            throw new ArrayIndexOutOfBoundsException("Start index cannot be negative");
-         }
-         if (end < 0)
-         {
-            throw new ArrayIndexOutOfBoundsException("End index cannot be negative");
-         }
-         if (start > end)
-         {
-            throw new ArrayIndexOutOfBoundsException("Start index cannot be greater than the end index");
-         }
-         if (end > count)
-         {
-            throw new ArrayIndexOutOfBoundsException("End index cannot be greater than the sequence length");
-         }
-         return new Chars(chars, offset + start, end - start);
-      }
-
       @Override
       public String toString()
       {

Modified: portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/TextEncoder.java
===================================================================
--- portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/TextEncoder.java	2009-10-30 10:54:06 UTC (rev 458)
+++ portal/branches/performance/component/common/src/main/java/org/exoplatform/commons/utils/TextEncoder.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -21,6 +21,7 @@
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.nio.charset.Charset;
 
 /**
  * A text encoder that encodes text to an output stream. No assumptions must be made about the
@@ -32,6 +33,13 @@
 public interface TextEncoder
 {
 
+   /**
+    * Returns the charset that will perform the encoding.
+    *
+    * @return the charset for encoding
+    */
+   Charset getCharset();
+
    void encode(char c, OutputStream out) throws IOException;
 
    void encode(char[] chars, int off, int len, OutputStream out) throws IOException;

Added: portal/branches/performance/component/common/src/test/java/org/exoplatform/commons/utils/TestBufferingOutputStream.java
===================================================================
--- portal/branches/performance/component/common/src/test/java/org/exoplatform/commons/utils/TestBufferingOutputStream.java	                        (rev 0)
+++ portal/branches/performance/component/common/src/test/java/org/exoplatform/commons/utils/TestBufferingOutputStream.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.commons.utils;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class TestBufferingOutputStream extends TestCase
+{
+
+   private ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+   private BufferingOutputStream out = new BufferingOutputStream(bytes, 5);
+
+   @Override
+   protected void setUp() throws Exception
+   {
+      bytes = new ByteArrayOutputStream();
+      out = new BufferingOutputStream(bytes, 5);
+   }
+
+   @Override
+   protected void tearDown() throws Exception
+   {
+      bytes = null;
+      out = null;
+   }
+
+   public void testCtorIAE()
+   {
+      try
+      {
+         new BufferingOutputStream(bytes, 0);
+      }
+      catch (IllegalArgumentException e)
+      {
+      }
+      try
+      {
+         new BufferingOutputStream(bytes, -1);
+      }
+      catch (IllegalArgumentException e)
+      {
+      }
+   }
+
+   public void testCtorNPE()
+   {
+      try
+      {
+         new BufferingOutputStream(null, 1);
+      }
+      catch (NullPointerException e)
+      {
+      }
+   }
+
+   public void testStreamClose() throws Exception
+   {
+      final AtomicBoolean closed = new AtomicBoolean(false);
+      BufferingOutputStream out = new BufferingOutputStream(new ByteArrayOutputStream()
+      {
+         @Override
+         public void close() throws IOException
+         {
+            closed.set(true);
+            super.close();
+         }
+      }, 1);
+      out.close();
+      assertTrue(closed.get());
+      try
+      {
+         out.write(0);
+      }
+      catch (IOException ignore)
+      {
+      }
+      try
+      {
+         out.write(new byte[]{0});
+      }
+      catch (IOException ignore)
+      {
+      }
+      try
+      {
+         out.flush();
+      }
+      catch (IOException ignore)
+      {
+      }
+      try
+      {
+         out.close();
+      }
+      catch (IOException ignore)
+      {
+      }
+   }
+
+   public void testFlush() throws Exception
+   {
+      out.write(0);
+      assertBytes();
+      out.flush();
+      assertBytes(0);
+      out.write(new byte[]{1, 2, 3, 4});
+      assertBytes();
+      out.close();
+      assertBytes(1, 2, 3, 4);
+   }
+
+   public void testWriteByte() throws Exception
+   {
+      out.write(0);
+      assertBytes();
+      out.close();
+      assertBytes(0);
+   }
+
+   public void testAlmostFill() throws Exception
+   {
+      out.write(new byte[]{0, 1, 2, 3});
+      assertBytes();
+      out.close();
+      assertBytes(0, 1, 2, 3);
+   }
+   
+   public void testFill() throws Exception
+   {
+      out.write(new byte[]{0, 1, 2, 3, 4});
+      assertBytes(0, 1, 2, 3, 4);
+      out.close();
+      assertBytes();
+   }
+
+   public void testBufferOverflowWithByte() throws Exception
+   {
+      out.write(new byte[]{0, 1, 2, 3});
+      assertBytes();
+      out.write(4);
+      assertBytes();
+      out.write(5);
+      assertBytes(0, 1, 2, 3, 4);
+      out.close();
+      assertBytes(5);
+   }
+   public void testBufferOverflowWithArray() throws Exception
+   {
+      out.write(new byte[]{0, 1, 2, 3});
+      assertBytes();
+      out.write(new byte[]{4});
+      assertBytes(0, 1, 2, 3);
+      out.close();
+      assertBytes(4);
+   }
+
+   public void testBufferOverflowWithLongArray() throws Exception
+   {
+      out.write(new byte[]{0, 1, 2, 3});
+      assertBytes();
+      out.write(new byte[]{4, 5, 6, 7, 8, 9});
+      assertBytes(0, 1, 2, 3, 4, 5, 6, 7, 8);
+      out.close();
+      assertBytes(9);
+   }
+
+   public void testBufferOverflowWithVeryLongArray() throws Exception
+   {
+      out.write(new byte[]{0, 1, 2, 3});
+      assertBytes();
+      out.write(new byte[]{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14});
+      assertBytes(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
+      out.close();
+      assertBytes(14);
+   }
+
+   private void assertBytes(int... expectedBytes)
+   {
+      int len = expectedBytes.length;
+      assertEquals(len, bytes.size());
+      if (len > 0)
+      {
+         byte[] actualBytes = bytes.toByteArray();
+         for (int i = 0;i < len;i++)
+         {
+            int expectedByte = expectedBytes[i];
+            byte actualByte = actualBytes[i];
+            assertEquals("Was expecting byte at index " + i + " to be equals to " + expectedByte + " instead of " + actualByte, expectedByte, actualByte);
+         }
+         bytes.reset();
+      }
+   }
+
+}

Modified: portal/branches/performance/component/common/src/test/java/org/exoplatform/commons/utils/TestPrinter.java
===================================================================
--- portal/branches/performance/component/common/src/test/java/org/exoplatform/commons/utils/TestPrinter.java	2009-10-30 10:54:06 UTC (rev 458)
+++ portal/branches/performance/component/common/src/test/java/org/exoplatform/commons/utils/TestPrinter.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -44,6 +44,7 @@
       printer = null;
    }
 
+/*
    public void testPrintNull()
    {
       printer.print(null);
@@ -73,6 +74,7 @@
       printer.println();
       assertEquals("\n", printer.buffer.toString());
    }
+*/
 
    public void testWriteNull() throws IOException
    {

Modified: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/commons/utils/PortalPrinter.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/commons/utils/PortalPrinter.java	2009-10-30 10:54:06 UTC (rev 458)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/commons/utils/PortalPrinter.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -20,7 +20,6 @@
 package org.exoplatform.commons.utils;
 
 import java.io.OutputStream;
-import java.nio.charset.Charset;
 
 /**
  * The portal printer convert char to bytes based on a charset encoder.
@@ -34,21 +33,8 @@
    /** The optimized encoder. */
    private static final TextEncoder encoder = new CharsetTextEncoder(new TableCharEncoder(CharsetCharEncoder.getUTF8()));
 
-   /** The charset used. */
-   private static final Charset charset = Charset.forName("UTF8");
-
    public PortalPrinter(OutputStream out, boolean flushOnClose, int bufferSize) throws IllegalArgumentException
    {
       super(encoder, out, flushOnClose, bufferSize);
    }
-
-   /**
-    * Returns the charset used for the conversion
-    *
-    * @return the charset used
-    */
-   public Charset getCharset()
-   {
-      return charset;
-   }
 }

Added: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/BaseScript.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/BaseScript.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/BaseScript.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+import groovy.lang.Binding;
+import groovy.lang.Script;
+
+import java.io.IOException;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class BaseScript extends Script
+{
+
+   GroovyPrinter printer;
+
+   protected BaseScript()
+   {
+   }
+
+   protected BaseScript(Binding binding)
+   {
+      super(binding);
+   }
+
+   @Override
+   public void println(Object o)
+   {
+      printer.println(o);
+   }
+
+   @Override
+   public void println()
+   {
+      printer.println();
+   }
+
+   @Override
+   public void print(Object o)
+   {
+      printer.print(o);
+   }
+
+   public void flush()
+   {
+      try
+      {
+         printer.flush();
+      }
+      catch (IOException e)
+      {
+         //TODO: need to check again
+         //      	e.printStackTrace();
+      }
+   }
+}

Added: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyPrinter.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyPrinter.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyPrinter.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+import org.exoplatform.commons.utils.Text;
+
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class GroovyPrinter extends Writer
+{
+
+   public final void println(Object o)
+   {
+      print(o);
+      println();
+   }
+
+   public final void println()
+   {
+      try
+      {
+         write('\n');
+      }
+      catch (IOException ignore)
+      {
+      }
+   }
+
+   public final void print(Object o)
+   {
+      try
+      {
+         if (o == null)
+         {
+            write("null");
+         }
+         else if (o instanceof Text)
+         {
+            ((Text)o).writeTo(this);
+         }
+         else
+         {
+            write(o.toString());
+         }
+      }
+      catch (IOException ignore)
+      {
+      }
+   }
+}

Added: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyScriptBuilder.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyScriptBuilder.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyScriptBuilder.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class GroovyScriptBuilder 
+{
+
+   /** . */
+   private SectionType currentType = null;
+
+   /** . */
+   private StringBuilder accumulatedText = new StringBuilder();
+
+   /** . */
+   private Script script = new Script();
+
+   public void begin(SectionType sectionType)
+   {
+      if (sectionType == null)
+      {
+         throw new NullPointerException();
+      }
+      if (currentType != null)
+      {
+         throw new IllegalStateException();
+      }
+      this.currentType = sectionType;
+
+      //
+      switch (currentType)
+      {
+         case STRING:
+            break;
+         case SCRIPTLET:
+            break;
+         case EXPR:
+            script.appendGroovy(";out.print(\"${");
+            break;
+      }
+   }
+
+   public void append(String text)
+   {
+      switch (currentType)
+      {
+         case STRING:
+            accumulatedText.append(text);
+            break;
+         case SCRIPTLET:
+            script.appendGroovy(text);
+            break;
+         case EXPR:
+            script.appendGroovy(text);
+            break;
+      }
+   }
+
+   public void lineBreak()
+   {
+      switch (currentType)
+      {
+         case STRING:
+            accumulatedText.append("\n");
+//            script.appendText(accumulatedText.toString());
+//            accumulatedText.setLength(0);
+            break;
+         case SCRIPTLET:
+            script.appendGroovy("\n");
+            break;
+         case EXPR:
+            script.appendGroovy("\n");
+            break;
+      }
+   }
+
+   public void end()
+   {
+      if (currentType == null)
+      {
+         throw new IllegalStateException();
+      }
+
+      //
+      switch (currentType)
+      {
+         case STRING:
+            if (accumulatedText.length() > 0)
+            {
+               script.appendText(accumulatedText.toString());
+               accumulatedText.setLength(0);
+            }
+            break;
+         case SCRIPTLET:
+            break;
+         case EXPR:
+            script.appendGroovy("}\");");
+            break;
+      }
+
+      //
+      this.currentType = null;
+   }
+
+   public String getScript()
+   {
+      return script.toString();
+   }
+
+
+
+   private static class Script
+   {
+
+      /** . */
+      private StringBuilder out = new StringBuilder();
+
+      /** . */
+      private List<TextContant> textMethods = new ArrayList<TextContant>();
+
+      /** . */
+      private int methodCount = 0;
+
+      @Override
+      public String toString()
+      {
+         StringBuilder builder = new StringBuilder();
+         builder.append(out.toString());
+         builder.append("\n");
+         builder.append("public class Constants\n");
+         builder.append("{\n");
+         for (TextContant method : textMethods)
+         {
+            builder.append(method.getDeclaration()).append("\n");
+         }
+         builder.append("}\n");
+         return builder.toString();
+      }
+
+      public void appendText(String text)
+      {
+         TextContant m = new TextContant("s" + methodCount++, text);
+         out.append(";out.print(Constants.").append(m.name).append(");\n");
+         textMethods.add(m);
+      }
+
+      public void appendGroovy(String s)
+      {
+         out.append(s);
+      }
+   }
+
+   /**
+    * This object encapsulate the generation of a method that outputs the specified text.
+    */
+   private static class TextContant
+   {
+
+      /** . */
+      private final String name;
+
+      /** . */
+      private final String text;
+
+      private TextContant(String name, String text)
+      {
+         this.name = name;
+         this.text = text;
+      }
+
+      public String getDeclaration()
+      {
+         StringBuilder builder = new StringBuilder("");
+         for (int i = 0;i < text.length();i++)
+         {
+            char c = text.charAt(i);
+            if (c == '\n')
+            {
+               builder.append("\\n");
+            }
+            else if (c == '\"')
+            {
+               builder.append("\\\"");
+            }
+            else
+            {
+               String code = Integer.toHexString(c);
+               switch (code.length())
+               {
+                  default:
+                     throw new AssertionError();
+                  case 1:
+                     code = "000" + code;
+                     break;
+                  case 2:
+                     code = "00" + code;
+                     break;
+                  case 3:
+                     code = "0" + code;
+                     break;
+                  case 4:
+                     break;
+               }
+               builder.append("\\u").append(code);
+            }
+         }
+         return "public static final " + GroovyText.class.getName() + " " + name + " = new " + GroovyText.class.getName() + "(\"" + builder + "\");";
+      }
+   }
+}
\ No newline at end of file

Added: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyTemplate.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyTemplate.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyTemplate.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+import groovy.lang.Binding;
+import groovy.lang.GroovyClassLoader;
+import groovy.lang.GroovyCodeSource;
+import groovy.lang.Writable;
+import groovy.text.Template;
+import org.codehaus.groovy.control.CompilationFailedException;
+import org.codehaus.groovy.control.CompilerConfiguration;
+import org.codehaus.groovy.runtime.InvokerHelper;
+import org.exoplatform.commons.utils.OutputStreamPrinter;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class GroovyTemplate implements Template
+{
+
+   private static String read(Reader reader) throws IOException
+   {
+      StringBuilder builder = new StringBuilder();
+      char[] chars = new char[256];
+      for (int s = reader.read(chars);s != -1; s = reader.read(chars))
+      {
+         builder.append(chars, 0, s);
+      }
+      return builder.toString();
+   }
+
+   /** . */
+   private final String name;
+
+   /** . */
+   private final String scriptText;
+
+   /** . */
+   private final String groovyText;
+
+   /** . */
+   private final Class<?> scriptClass;
+
+   public GroovyTemplate(String name, Reader scriptReader) throws IOException
+   {
+      this(name, read(scriptReader));
+   }
+
+   public GroovyTemplate(Reader scriptReader) throws IOException
+   {
+      this(read(scriptReader));
+   }
+
+   public GroovyTemplate(String scriptText) throws IOException
+   {
+      this(null, scriptText);
+   }
+
+   public GroovyTemplate(String name, String scriptText) throws IOException
+   {
+      if (name == null)
+      {
+         name = "fic";
+      }
+
+      //
+      TemplateCompiler compiler = new TemplateCompiler();
+      String groovyText = compiler.compile(scriptText);
+
+      //
+      CompilerConfiguration config = new CompilerConfiguration();
+      config.setScriptBaseClass(BaseScript.class.getName());
+      byte[] bytes = groovyText.getBytes(config.getSourceEncoding());
+      InputStream in = new ByteArrayInputStream(bytes);
+      GroovyCodeSource gcs = new GroovyCodeSource(in, name, "/groovy/shell");
+      GroovyClassLoader loader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader(), config);
+
+      Class<?> scriptClass;
+      try
+      {
+         scriptClass = loader.parseClass(gcs, false);
+      }
+      catch (CompilationFailedException e)
+      {
+         System.out.println("Could not compile script <<<" + groovyText + ">>>");
+         throw e;
+      }
+      catch (ClassFormatError e)
+      {
+         System.out.println("Could not compile script <<<" + groovyText + ">>>");
+         throw e;
+      }
+
+      //
+      this.name = name;
+      this.scriptText = scriptText;
+      this.groovyText = groovyText;
+      this.scriptClass = scriptClass;
+   }
+
+   public String getName()
+   {
+      return name;
+   }
+
+   public String getScriptText()
+   {
+      return scriptText;
+   }
+
+   public String getGroovyText()
+   {
+      return groovyText;
+   }
+
+   public void render(GroovyPrinter writer) throws IOException
+   {
+      render(writer, null);
+   }
+
+   public void render(GroovyPrinter writer, Map binding) throws IOException
+   {
+      Writable writable = make(binding);
+      writable.writeTo(writer);
+   }
+
+   public String render() throws IOException
+   {
+      return render((Map)null);
+   }
+
+   public String render(Map binding) throws IOException
+   {
+      StringWriter buffer = new StringWriter();
+      WriterGroovyPrinter printer = new WriterGroovyPrinter(buffer);
+      render(printer, binding);
+      printer.close();
+      return buffer.toString();
+   }
+
+   public Writable make()
+   {
+      return make(null);
+   }
+
+   public Writable make(final Map binding)
+   {
+      Writable writable = new Writable()
+      {
+         /**
+          * Write the template document with the set binding applied to the writer.
+          *
+          * @see groovy.lang.Writable#writeTo(java.io.Writer)
+          */
+         public Writer writeTo(Writer writer)
+         {
+            Binding context;
+            if (binding == null)
+               context = new Binding();
+            else
+               context = new Binding(binding);
+
+            //
+            BaseScript script = (BaseScript)InvokerHelper.createScript(scriptClass, context);
+            if (writer instanceof OutputStreamPrinter)
+            {
+               script.printer = new OutputStreamWriterGroovyPrinter((OutputStreamPrinter)writer);
+            }
+            else
+            {
+               script.printer = new WriterGroovyPrinter(writer);
+            }
+            script.setProperty("out", script.printer);
+            script.run();
+            script.flush();
+            return writer;
+         }
+      };
+
+      //
+      return writable;
+   }
+}

Added: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyTemplateEngine.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyTemplateEngine.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyTemplateEngine.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+import groovy.text.Template;
+import groovy.text.TemplateEngine;
+import org.codehaus.groovy.control.CompilationFailedException;
+
+import java.io.IOException;
+import java.io.Reader;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class GroovyTemplateEngine extends TemplateEngine
+{
+
+   @Override
+   public Template createTemplate(Reader reader) throws CompilationFailedException, ClassNotFoundException, IOException
+   {
+      return new GroovyTemplate(reader);
+   }
+}

Added: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyText.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyText.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyText.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+import org.exoplatform.commons.utils.BinaryOutput;
+import org.exoplatform.commons.utils.Text;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.nio.charset.Charset;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class GroovyText extends Text 
+{
+
+   /** . */
+   private final String s;
+
+   /** . */
+   private final byte[] bytes;
+
+   /** . */
+   private static final Charset UTF_8 = Charset.forName("UTF-8");
+
+   public GroovyText(String s)
+   {
+      try
+      {
+         this.s = s;
+         this.bytes = s.getBytes("UTF-8");
+      }
+      catch (UnsupportedEncodingException e)
+      {
+         throw new UndeclaredThrowableException(e);
+      }
+   }
+
+   @Override
+   public void writeTo(Writer writer) throws IOException
+   {
+      if (writer instanceof BinaryOutput)
+      {
+         BinaryOutput osw = (BinaryOutput)writer;
+         if (UTF_8.equals(osw.getCharset()))
+         {
+            osw.write(bytes);
+            return;
+         }
+      }
+      writer.append(s);
+   }
+}

Added: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/LineBreakItem.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/LineBreakItem.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/LineBreakItem.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class LineBreakItem extends SectionItem
+{
+
+   public LineBreakItem()
+   {
+   }
+
+   @Override
+   public String toString()
+   {
+      return "LineBreak[]";
+   }
+
+   @Override
+   public boolean equals(Object obj)
+   {
+      return obj == this || obj instanceof LineBreakItem;
+   }
+}

Added: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/OutputStreamWriterGroovyPrinter.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/OutputStreamWriterGroovyPrinter.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/OutputStreamWriterGroovyPrinter.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+import org.exoplatform.commons.utils.BinaryOutput;
+import org.exoplatform.commons.utils.OutputStreamPrinter;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class OutputStreamWriterGroovyPrinter extends GroovyPrinter implements BinaryOutput
+{
+
+   /** . */
+   private final OutputStreamPrinter out;
+
+   public OutputStreamWriterGroovyPrinter(OutputStreamPrinter out)
+   {
+      if (out == null)
+      {
+         throw new NullPointerException();
+      }
+      this.out = out;
+   }
+
+   public Charset getCharset()
+   {
+      return out.getCharset();
+   }
+
+   public void write(byte[] bytes) throws IOException
+   {
+      out.write(bytes);
+   }
+
+   public void write(byte[] b, int off, int len) throws IOException
+   {
+      out.write(b, off, len);
+   }
+
+   public void write(byte b) throws IOException
+   {
+      out.write(b);
+   }
+
+   @Override
+   public void write(char[] cbuf, int off, int len) throws IOException
+   {
+      out.write(cbuf, off, len);
+   }
+
+   @Override
+   public void flush() throws IOException
+   {
+      out.flush();
+   }
+
+   @Override
+   public void close() throws IOException
+   {
+      out.close();
+   }
+}

Added: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/SectionItem.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/SectionItem.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/SectionItem.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public abstract class SectionItem
+{
+}

Added: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/SectionType.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/SectionType.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/SectionType.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public enum SectionType
+{
+
+   STRING,
+
+   SCRIPTLET,
+
+   EXPR
+
+}

Added: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateCompiler.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateCompiler.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateCompiler.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class TemplateCompiler
+{
+
+   public String compile(String script) throws IOException
+   {
+      List<TemplateSection> sections = new TemplateParser().parse(script);
+      return compile(sections);
+   }
+
+   public String compile(List<TemplateSection> sections)
+   {
+      GroovyScriptBuilder scriptBuilder = new GroovyScriptBuilder();
+      for (TemplateSection section : sections)
+      {
+         scriptBuilder.begin(section.getType());
+         for (SectionItem item : section.getItems())
+         {
+            if (item instanceof TextItem)
+            {
+               scriptBuilder.append(((TextItem)item).getData());
+            }
+            else
+            {
+               scriptBuilder.lineBreak();
+            }
+         }
+         scriptBuilder.end();
+      }
+      return scriptBuilder.getScript();
+   }
+}

Added: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateParser.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateParser.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateParser.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class TemplateParser
+{
+
+   private enum Status
+   {
+      TEXT,
+
+      EXPR,
+
+      SCRIPTLET,
+
+      START_ANGLE,
+
+      SCRIPLET_OR_EXPR,
+
+      MAYBE_SCRIPLET_END,
+
+      MAYBE_EXPR_END,
+
+      MAYBE_GSTRING_EXPR,
+
+      GSTRING_CURLY_EXPR,
+
+      GSTRING_EXPR
+   }
+
+   public List<TemplateSection> parse(String s) throws IOException
+   {
+      return parse(new StringReader(s));
+   }
+
+   public List<TemplateSection> parse(Reader reader) throws IOException
+   {
+      if (!reader.markSupported())
+      {
+         reader = new BufferedReader(reader);
+      }
+
+      //
+      ArrayList<TemplateSection> sections = new ArrayList<TemplateSection>();
+      StringBuilder accumulator = new StringBuilder();
+
+      //
+      Status status = Status.TEXT;
+      int c;
+      while ((c = reader.read()) != -1)
+      {
+         switch (status)
+         {
+            case TEXT:
+               if (c == '<')
+               {
+                  status = Status.START_ANGLE;
+               }
+               else if (c == '$')
+               {
+                  status = Status.MAYBE_GSTRING_EXPR;
+               }
+               else
+               {
+                  accumulator.append((char)c);
+               }
+               break;
+            case EXPR:
+               if (c == '%')
+               {
+                  status = Status.MAYBE_EXPR_END;
+               }
+               else
+               {
+                  accumulator.append((char)c);
+               }
+               break;
+            case SCRIPTLET:
+               if (c == '%')
+               {
+                  status = Status.MAYBE_SCRIPLET_END;
+               }
+               else
+               {
+                  accumulator.append((char)c);
+               }
+               break;
+            case START_ANGLE:
+               if (c == '%')
+               {
+                  status = Status.SCRIPLET_OR_EXPR;
+               }
+               else
+               {
+                  status = Status.TEXT;
+                  accumulator.append('<').append((char)c);
+               }
+               break;
+            case SCRIPLET_OR_EXPR:
+               if (accumulator.length() > 0)
+               {
+                  sections.add(new TemplateSection(SectionType.STRING, accumulator.toString()));
+                  accumulator.setLength(0);
+               }
+               if (c == '=')
+               {
+                  status = Status.EXPR;
+               }
+               else if (c == '%')
+               {
+                  status = Status.MAYBE_SCRIPLET_END;
+               }
+               else
+               {
+                  status = Status.SCRIPTLET;
+                  accumulator.append((char)c);
+               }
+               break;
+            case MAYBE_SCRIPLET_END:
+               if (c == '>')
+               {
+                  status = Status.TEXT;
+                  sections.add(new TemplateSection(SectionType.SCRIPTLET, accumulator.toString()));
+                  accumulator.setLength(0);
+               }
+               else if (c == '%')
+               {
+                  accumulator.append('%');
+               }
+               else
+               {
+                  status = Status.SCRIPTLET;
+                  accumulator.append('%').append((char)c);
+               }
+               break;
+            case MAYBE_EXPR_END:
+               if (c == '>')
+               {
+                  status = Status.TEXT;
+                  sections.add(new TemplateSection(SectionType.EXPR, accumulator.toString()));
+                  accumulator.setLength(0);
+               }
+               else if (c == '%')
+               {
+                  accumulator.append('%');
+               }
+               else
+               {
+                  status = Status.EXPR;
+                  accumulator.append('%').append((char)c);
+               }
+               break;
+            case MAYBE_GSTRING_EXPR:
+               if (c == '{')
+               {
+                  if (accumulator.length() > 0)
+                  {
+                     sections.add(new TemplateSection(SectionType.STRING, accumulator.toString()));
+                     accumulator.setLength(0);
+                  }
+                  status = Status.GSTRING_CURLY_EXPR;
+               }
+               else if (Character.isJavaIdentifierStart((char)c))
+               {
+                  if (accumulator.length() > 0)
+                  {
+                     sections.add(new TemplateSection(SectionType.STRING, accumulator.toString()));
+                     accumulator.setLength(0);
+                  }
+                  status = Status.GSTRING_EXPR;
+                  accumulator.append((char)c);
+               }
+               else
+               {
+                  accumulator.append('$').append((char)c);
+               }
+               break;
+            case GSTRING_CURLY_EXPR:
+               if (c == '}')
+               {
+                  sections.add(new TemplateSection(SectionType.EXPR, accumulator.toString()));
+                  accumulator.setLength(0);
+                  status = Status.TEXT;
+               }
+               else
+               {
+                  accumulator.append((char)c);
+               }
+               break;
+            case GSTRING_EXPR:
+               if (c == '.' || Character.isJavaIdentifierPart((char)c))
+               {
+                  accumulator.append((char)c);
+               }
+               else
+               {
+                  sections.add(new TemplateSection(SectionType.EXPR, accumulator.toString()));
+                  accumulator.setLength(0);
+                  status = Status.TEXT;
+                  accumulator.append((char)c);
+               }
+               break;
+            default:
+               throw new AssertionError();
+         }
+      }
+
+      // Last section
+      if (accumulator.length() > 0)
+      {
+         switch (status)
+         {
+            case TEXT:
+               sections.add(new TemplateSection(SectionType.STRING, accumulator.toString()));
+               accumulator.setLength(0);
+               break;
+            case GSTRING_EXPR:
+               sections.add(new TemplateSection(SectionType.EXPR, accumulator.toString()));
+               accumulator.setLength(0);
+               break;
+            default:
+               throw new AssertionError();
+         }
+      }
+
+      //
+      return Collections.unmodifiableList(sections);
+   }
+}
\ No newline at end of file

Added: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateSection.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateSection.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateSection.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class TemplateSection
+{
+
+   /** . */
+   private final SectionType type;
+
+   /** . */
+   private final List<SectionItem> items;
+
+   public TemplateSection(SectionType type, String text)
+   {
+      if (type == null)
+      {
+         throw new NullPointerException();
+      }
+      if (text == null)
+      {
+         throw new NullPointerException();
+      }
+
+      //
+      // Now we process the line breaks
+      ArrayList<SectionItem> sections = new ArrayList<SectionItem>();
+
+      // on Windows, "\r\n" is a new line
+      text = text.replaceAll("\r\n", "\n");
+
+      //
+      int from = 0;
+      while (true)
+      {
+         int to = text.indexOf('\n', from);
+
+         //
+         if (to != -1)
+         {
+            String chunk = text.substring(from, to);
+            sections.add(new TextItem(chunk));
+            sections.add(new LineBreakItem());
+            from = to + 1;
+         }
+         else
+         {
+            String chunk = text.substring(from);
+            sections.add(new TextItem(chunk));
+            break;
+         }
+      }
+
+      //
+      this.type = type;
+      this.items = Collections.unmodifiableList(sections);
+   }
+
+   public SectionType getType()
+   {
+      return type;
+   }
+
+   public List<SectionItem> getItems()
+   {
+      return items;
+   }
+
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (obj == this)
+      {
+         return true;
+      }
+      if (obj instanceof TemplateSection)
+      {
+         TemplateSection that = (TemplateSection)obj;
+         return type == that.type && items.equals(that.items);
+      }
+      return false;
+   }
+
+   @Override
+   public String toString()
+   {
+      return "TextSection[type=" + type + ",text=" + items + "]";
+   }
+}

Added: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TextItem.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TextItem.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TextItem.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class TextItem extends SectionItem
+{
+
+   /** . */
+   private final String data;
+
+   public TextItem(String data)
+   {
+      if (data == null)
+      {
+         throw new NullPointerException();
+      }
+
+      //
+      this.data = data;
+   }
+
+   public String getData()
+   {
+      return data;
+   }
+
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (obj == this)
+      {
+         return true;
+      }
+      if (obj instanceof TextItem)
+      {
+         TextItem that = (TextItem)obj;
+         return data.equals(that.data);
+      }
+      return false;
+   }
+
+   @Override
+   public String toString()
+   {
+      return "DataText[data=" + data + "]";
+   }
+}

Added: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/WriterGroovyPrinter.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/WriterGroovyPrinter.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/WriterGroovyPrinter.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class WriterGroovyPrinter extends GroovyPrinter
+{
+
+   /** . */
+   private Writer writer;
+
+   public WriterGroovyPrinter(Writer writer)
+   {
+      if (writer == null)
+      {
+         throw new NullPointerException();
+      }
+      this.writer = writer;
+   }
+
+   @Override
+   public void write(char[] cbuf, int off, int len) throws IOException
+   {
+      writer.write(cbuf, off, len);
+   }
+
+   @Override
+   public void close() throws IOException
+   {
+      writer.close();
+   }
+
+   @Override
+   public void flush() throws IOException
+   {
+      writer.flush();
+   }
+}

Deleted: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/text/SimpleTemplateEngine.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/text/SimpleTemplateEngine.java	2009-10-30 10:54:06 UTC (rev 458)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/text/SimpleTemplateEngine.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -1,324 +0,0 @@
-/**
- * Copyright (C) 2009 eXo Platform SAS.
- * 
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- * 
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.exoplatform.groovyscript.text;
-
-import groovy.lang.Binding;
-import groovy.lang.GroovyClassLoader;
-import groovy.lang.GroovyCodeSource;
-import groovy.lang.GroovyShell;
-import groovy.lang.Script;
-import groovy.lang.Writable;
-import groovy.text.Template;
-import groovy.text.TemplateEngine;
-
-import org.codehaus.groovy.control.CompilationFailedException;
-import org.codehaus.groovy.control.CompilerConfiguration;
-import org.codehaus.groovy.runtime.InvokerHelper;
-import org.exoplatform.commons.utils.Printer;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.Map;
-
-/**
- * This simple template engine uses JSP <% %> script and <%= %> expression syntax.  It also lets you use normal groovy expressions in
- * the template text much like the new JSP EL functionality.  The variable 'out' is bound to the writer that the template is being written to.
- * 
- * @author sam
- * @author Christian Stein
- */
-public class SimpleTemplateEngine extends TemplateEngine
-{
-
-   private final boolean verbose;
-
-   public SimpleTemplateEngine()
-   {
-      this(false);
-   }
-
-   public SimpleTemplateEngine(boolean verbose)
-   {
-      this.verbose = verbose;
-   }
-
-   public Template createTemplate(Reader reader) throws CompilationFailedException, IOException
-   {
-      SimpleTemplate template = new SimpleTemplate();
-      GroovyShell shell = new GroovyShell(Thread.currentThread().getContextClassLoader());
-      String script = template.parse(reader);
-      if (verbose)
-      {
-         System.out.println("\n-- script source --");
-         System.out.print(script);
-         System.out.println("\n-- script end --\n");
-      }
-
-      //
-      CompilerConfiguration config = new CompilerConfiguration();
-      config.setScriptBaseClass(ExoScript.class.getName());
-      byte[] bytes = script.getBytes(config.getSourceEncoding());
-      InputStream in = new ByteArrayInputStream(bytes);
-      GroovyCodeSource gcs = new GroovyCodeSource(in, "fic", "/groovy/shell");
-      GroovyClassLoader loader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader(), config);
-      loader.parseClass(gcs, false);
-      template.scriptClass = loader.parseClass(script);
-      return template;
-   }
-
-   public static abstract class ExoScript extends Script
-   {
-
-      private Printer printer;
-
-      protected ExoScript()
-      {
-      }
-
-      protected ExoScript(Binding binding)
-      {
-         super(binding);
-      }
-
-      @Override
-      public void println(Object o)
-      {
-         printer.println(o);
-      }
-
-      @Override
-      public void println()
-      {
-         printer.println();
-      }
-
-      @Override
-      public void print(Object o)
-      {
-         printer.print(o);
-      }
-
-      public void flush()
-      {
-         try
-         {
-            printer.flush();
-         }
-         catch (IOException e)
-         {
-            //TODO: need to check again
-            //      	e.printStackTrace();
-         }
-      }
-   }
-
-   private static class SimpleTemplate implements Template
-   {
-
-      protected Class scriptClass;
-
-      public Writable make()
-      {
-         return make(null);
-      }
-
-      public Writable make(final Map map)
-      {
-         return new Writable()
-         {
-            /**
-             * Write the template document with the set binding applied to the writer.
-             *
-             * @see groovy.lang.Writable#writeTo(java.io.Writer)
-             */
-            public Writer writeTo(Writer writer)
-            {
-               Binding context;
-               if (map == null)
-                  context = new Binding();
-               else
-                  context = new Binding(map);
-
-               //
-               ExoScript script = (ExoScript)InvokerHelper.createScript(scriptClass, context);
-               script.printer = (Printer)writer;
-               script.setProperty("out", script.printer);
-               script.run();
-               script.flush();
-               return writer;
-            }
-
-            /**
-             * Convert the template and binding into a result String.
-             *
-             * @see java.lang.Object#toString()
-             */
-            public String toString()
-            {
-               try
-               {
-                  StringWriter sw = new StringWriter();
-                  writeTo(sw);
-                  return sw.toString();
-               }
-               catch (Exception e)
-               {
-                  return e.toString();
-               }
-            }
-         };
-      }
-
-      /**
-       * Parse the text document looking for <% or <%= and then call out to the appropriate handler, otherwise copy the text directly
-       * into the script while escaping quotes.
-       * 
-       * @param reader
-       * @throws IOException
-       */
-      protected String parse(Reader reader) throws IOException
-      {
-         if (!reader.markSupported())
-         {
-            reader = new BufferedReader(reader);
-         }
-         StringWriter sw = new StringWriter();
-         startScript(sw);
-         int c;
-         while ((c = reader.read()) != -1)
-         {
-            if (c == '<')
-            {
-               reader.mark(1);
-               c = reader.read();
-               if (c != '%')
-               {
-                  sw.write('<');
-                  reader.reset();
-                  continue;
-               }
-               reader.mark(1);
-               c = reader.read();
-               if (c == '=')
-                  groovyExpression(reader, sw);
-               else
-               {
-                  reader.reset();
-                  groovySection(reader, sw);
-               }
-               continue; // at least '<' is consumed ... read next chars.
-            }
-            if (c == '\"')
-               sw.write('\\');
-            /*
-             * Handle raw new line characters.
-             */
-            if (c == '\n' || c == '\r')
-            {
-               if (c == '\r')
-               { // on Windows, "\r\n" is a new line.
-                  reader.mark(1);
-                  c = reader.read();
-                  if (c != '\n')
-                     reader.reset();
-               }
-               sw.write("\\n\");\nout.print(\"");
-               continue;
-            }
-            sw.write(c);
-         }
-         endScript(sw);
-         String result = sw.toString();
-         return result;
-      }
-
-      private void startScript(StringWriter sw)
-      {
-         sw.write("/* Generated by SimpleTemplateEngine */\n");
-         sw.write("out.print(\"");
-      }
-
-      private void endScript(StringWriter sw)
-      {
-         sw.write("\");\n");
-      }
-
-      /**
-       * Closes the currently open write and writes out the following text as a GString expression until it reaches an end %>.
-       * 
-       * @param reader
-       * @param sw
-       * @throws IOException
-       */
-      private void groovyExpression(Reader reader, StringWriter sw) throws IOException
-      {
-         sw.write("\");out.print(\"${");
-         int c;
-         while ((c = reader.read()) != -1)
-         {
-            if (c == '%')
-            {
-               c = reader.read();
-               if (c == '>')
-                  break;
-               sw.write('%');
-            }
-            if (c != '\n' && c != '\r')
-               sw.write(c);
-         }
-         sw.write("}\");\nout.print(\"");
-      }
-
-      /**
-       * Closes the currently open write and writes the following text as normal Groovy script code until it reaches an end %>.
-       * 
-       * @param reader
-       * @param sw
-       * @throws IOException
-       */
-      private void groovySection(Reader reader, StringWriter sw) throws IOException
-      {
-         sw.write("\");");
-         int c;
-         while ((c = reader.read()) != -1)
-         {
-            if (c == '%')
-            {
-               c = reader.read();
-               if (c == '>')
-                  break;
-               sw.write('%');
-            }
-            /* Don't eat EOL chars in sections - as they are valid instruction separators.
-             * See http://jira.codehaus.org/browse/GROOVY-980
-             */
-            // if (c != '\n' && c != '\r') {
-            sw.write(c);
-            //}
-         }
-         sw.write(";\nout.print(\"");
-      }
-   }
-}

Modified: portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/text/TemplateService.java
===================================================================
--- portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/text/TemplateService.java	2009-10-30 10:54:06 UTC (rev 458)
+++ portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/text/TemplateService.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -22,8 +22,10 @@
 import groovy.lang.Writable;
 import groovy.text.Template;
 
+import groovy.text.TemplateEngine;
 import org.exoplatform.commons.utils.IOUtil;
 import org.exoplatform.container.xml.InitParams;
+import org.exoplatform.groovyscript.GroovyTemplateEngine;
 import org.exoplatform.management.annotations.Managed;
 import org.exoplatform.management.annotations.ManagedDescription;
 import org.exoplatform.management.annotations.ManagedName;
@@ -45,7 +47,7 @@
 public class TemplateService
 {
 
-   private SimpleTemplateEngine engine_;
+   private TemplateEngine engine_;
 
    private ExoCache<String, Template> templatesCache_;
 
@@ -56,7 +58,7 @@
    public TemplateService(InitParams params, TemplateStatisticService statisticService, CacheService cservice)
       throws Exception
    {
-      engine_ = new SimpleTemplateEngine();
+      engine_ = new GroovyTemplateEngine();
       this.statisticService = statisticService;
       templatesCache_ = cservice.getCacheInstance(TemplateService.class.getName());
       getTemplatesCache().setLiveTime(10000);

Added: portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateCompiler.java
===================================================================
--- portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateCompiler.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateCompiler.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+import junit.framework.TestCase;
+import org.exoplatform.groovyscript.TemplateCompiler;
+
+import java.io.IOException;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class TestTemplateCompiler extends TestCase
+{
+
+   /** . */
+   private final TemplateCompiler compiler = new TemplateCompiler();
+
+   public void testFoo() throws IOException
+   {
+//      assertEquals("", compiler.compile(""));
+//      assertEquals("out.print(\"a\");", compiler.compile("a"));
+//      assertEquals("out.print(\"a\n\");\nout.print(\"b\");", compiler.compile("a\nb"));
+//      assertEquals("", compiler.compile("<%%>"));
+//      assertEquals("a", compiler.compile("<%a%>"));
+//      assertEquals("a\nb", compiler.compile("<%a\nb%>"));
+   }
+}

Added: portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateParser.java
===================================================================
--- portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateParser.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateParser.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+import junit.framework.TestCase;
+import org.exoplatform.groovyscript.TemplateSection;
+import org.exoplatform.groovyscript.SectionType;
+import org.exoplatform.groovyscript.TemplateParser;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class TestTemplateParser extends TestCase
+{
+
+   /** . */
+   private TemplateParser parser = new TemplateParser();
+
+   public void testEmpty() throws IOException
+   {
+      assertEquals(Collections.<TemplateSection>emptyList(), parser.parse(""));
+   }
+
+   public void testText() throws IOException
+   {
+      assertEquals(Arrays.<TemplateSection>asList(new TemplateSection(SectionType.STRING, "a")), parser.parse("a"));
+   }
+
+   public void testSingleEmptyScriplet() throws IOException
+   {
+      assertEquals(Arrays.<TemplateSection>asList(new TemplateSection(SectionType.SCRIPTLET, "")), parser.parse("<%%>"));
+   }
+
+   public void testSingleEmptyExpression() throws IOException
+   {
+      assertEquals(Arrays.<TemplateSection>asList(new TemplateSection(SectionType.EXPR, "")), parser.parse("<%=%>"));
+   }
+
+   public void testSingleScriplet() throws IOException
+   {
+      assertEquals(Arrays.<TemplateSection>asList(new TemplateSection(SectionType.SCRIPTLET, "a")), parser.parse("<%a%>"));
+   }
+
+   public void testSingleExpression() throws IOException
+   {
+      assertEquals(Arrays.<TemplateSection>asList(new TemplateSection(SectionType.EXPR, "a")), parser.parse("<%=a%>"));
+   }
+
+   public void testPercentScriplet() throws IOException
+   {
+      assertEquals(Arrays.<TemplateSection>asList(new TemplateSection(SectionType.SCRIPTLET, "%")), parser.parse("<%%%>"));
+   }
+
+   public void testPercentExpression() throws IOException
+   {
+      assertEquals(Arrays.<TemplateSection>asList(new TemplateSection(SectionType.EXPR, "%")), parser.parse("<%=%%>"));
+   }
+
+   public void testStartAngleBracketScriplet() throws IOException
+   {
+      assertEquals(Arrays.<TemplateSection>asList(new TemplateSection(SectionType.SCRIPTLET, "<")), parser.parse("<%<%>"));
+   }
+
+   public void testStartAngleBracketExpression() throws IOException
+   {
+      assertEquals(Arrays.<TemplateSection>asList(new TemplateSection(SectionType.EXPR, "<")), parser.parse("<%=<%>"));
+   }
+
+   public void testSimpleScript() throws IOException
+   {
+      assertEquals(Arrays.<TemplateSection>asList(
+         new TemplateSection(SectionType.STRING, "a"),
+         new TemplateSection(SectionType.SCRIPTLET, "b"),
+         new TemplateSection(SectionType.STRING, "c")
+         ), parser.parse("a<%b%>c"));
+   }
+
+   public void testSimpleScript2() throws IOException
+   {
+      assertEquals(Arrays.<TemplateSection>asList(
+         new TemplateSection(SectionType.STRING, "a"),
+         new TemplateSection(SectionType.EXPR, "b"),
+         new TemplateSection(SectionType.STRING, "c")
+         ), parser.parse("a<%=b%>c"));
+   }
+}

Added: portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateRendering.java
===================================================================
--- portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateRendering.java	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateRendering.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+import junit.framework.TestCase;
+import org.exoplatform.commons.utils.CharsetTextEncoder;
+import org.exoplatform.commons.utils.OutputStreamPrinter;
+import org.exoplatform.groovyscript.GroovyTemplate;
+import org.exoplatform.groovyscript.OutputStreamWriterGroovyPrinter;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author <a href="mailto:julien.viet at exoplatform.com">Julien Viet</a>
+ * @version $Revision$
+ */
+public class TestTemplateRendering extends TestCase
+{
+
+   public void testOutputStreamWriter() throws Exception
+   {
+      GroovyTemplate template = new GroovyTemplate("a<%='b'%>c<%out.print('d');%>e");
+      ByteArrayOutputStream  baos = new ByteArrayOutputStream();
+      OutputStreamPrinter writer = new OutputStreamPrinter(CharsetTextEncoder.getUTF8(), baos);
+      OutputStreamWriterGroovyPrinter printer = new OutputStreamWriterGroovyPrinter(writer);
+      template.render(printer);
+      printer.close();
+      assertEquals("abcde", baos.toString("UTF-8"));
+   }
+
+   public void testFoo() throws Exception
+   {
+      GroovyTemplate template = new GroovyTemplate("a");
+//      System.out.println("template = " + template.getGroovyText());
+      String render = template.render();
+      assertEquals("a", render);
+   }
+
+   public void testBar() throws Exception
+   {
+      GroovyTemplate template = new GroovyTemplate("<%='a'%>");
+//      System.out.println("template = " + template.getGroovyText());
+      String render = template.render();
+      assertEquals("a", render);
+   }
+
+   public void testFooBar() throws Exception
+   {
+      GroovyTemplate template = new GroovyTemplate("a<%='b'%>c");
+//      System.out.println("template = " + template.getGroovyText());
+      String render = template.render();
+      assertEquals("abc", render);
+   }
+
+   public void testJuu() throws Exception
+   {
+      GroovyTemplate template = new GroovyTemplate("<% out.print(\"a\"); %>");
+//      System.out.println("template = " + template.getGroovyText());
+      String render = template.render();
+      assertEquals("a", render);
+   }
+
+   public void testLineBreak() throws Exception
+   {
+      GroovyTemplate template = new GroovyTemplate("\n");
+      String render = template.render();
+      assertEquals("\n", render);
+   }
+
+   public void testMultiLine() throws Exception
+   {
+      GroovyTemplate template = new GroovyTemplate(
+         "a\n" +
+         "b\n" +
+         "<%= 'c' %>\n" +
+         "d"
+      );
+      String render = template.render();
+      assertEquals("a\nb\nc\nd", render);
+   }
+
+   public void testIf() throws Exception
+   {
+      GroovyTemplate template = new GroovyTemplate(
+         "a\n" +
+         "<% if (true) {\n %>" +
+         "b\n" +
+         "<% } %>\n"
+      );
+   }
+
+   public void testContextResolution() throws Exception
+   {
+      GroovyTemplate template = new GroovyTemplate("<%= foo %>");
+      Map<String, String> context = new HashMap<String, String>();
+      context.put("foo", "bar");
+      String s = template.render(context);
+      assertEquals("bar", s);
+   }
+
+   public void testGString() throws Exception
+   {
+      GroovyTemplate template = new GroovyTemplate("$foo");
+      Map<String, String> context = new HashMap<String, String>();
+      context.put("foo", "bar");
+      String s = template.render(context);
+      assertEquals("bar", s);
+   }
+
+   public void testGString2() throws Exception
+   {
+      GroovyTemplate template = new GroovyTemplate("$foo\"");
+      Map<String, String> context = new HashMap<String, String>();
+      context.put("foo", "bar");
+      String s = template.render(context);
+      assertEquals("bar\"", s);
+   }
+
+   public void testQuote() throws Exception
+   {
+      GroovyTemplate template = new GroovyTemplate("\"");
+      String s = template.render();
+      assertEquals("\"", s);
+   }
+
+   public void testFooFoo() throws Exception
+   {
+      InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("UIPortalApplication.gtmpl");
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      byte[] buffer = new byte[256];
+      for (int l = in.read(buffer);l != -1;l = in.read(buffer))
+      {
+         baos.write(buffer, 0, l);
+      }
+      String gtmpl = baos.toString("UTF-8");
+      GroovyTemplate template = new GroovyTemplate(gtmpl);
+   }
+}

Added: portal/branches/performance/component/scripting/src/test/resources/UIPortalApplication.gtmpl
===================================================================
--- portal/branches/performance/component/scripting/src/test/resources/UIPortalApplication.gtmpl	                        (rev 0)
+++ portal/branches/performance/component/scripting/src/test/resources/UIPortalApplication.gtmpl	2009-10-30 14:38:36 UTC (rev 459)
@@ -0,0 +1,134 @@
+<!DOCTYPE html 
+    PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+           "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<%
+  def rcontext = _ctx.getRequestContext() ;
+  String docBase =  rcontext.getRequestContextPath() ;
+  String skin = uicomponent.getSkin();
+  def portalSkins = uicomponent.getPortalSkins() ;
+  def portletSkins = uicomponent.getPortletSkins() ;
+  def scriptsPaths = uicomponent.getJavascriptURLs();
+  def lang = uicomponent.getLocale().getLanguage();
+  def title = rcontext.getTitle();
+  def metaInformation = rcontext.getMetaInformation();
+%>
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="$lang" lang="$lang" dir="$dir">
+  <head id="head">
+    <title><%=title%></title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+    <%
+    	if(metaInformation!= null) {
+	    	Iterator<String> keys = metaInformation.keySet().iterator();
+	    	while(keys.hasNext()) {
+	    		String metaName = keys.next();
+	    		String metaContent = metaInformation.get(metaName);
+	  %>
+	   	<meta name="<%=metaName%>" content="<%=metaContent%>" />
+	  <% } } %>
+
+    <link rel="shortcut icon" type="image/x-icon"  href="<%=docBase%>/favicon.ico" />
+    <%for(skinConfig in portalSkins) {
+    def url = skinConfig.createURL();
+    url.setOrientation(orientation);
+    %>
+      <link id="${skinConfig.id}" rel="stylesheet" type="text/css" href="$url" />
+    <%}%>
+    <%for(portletSkin in portletSkins) {
+    def url = portletSkin.createURL();
+    url.setOrientation(orientation);
+    %>
+      <link id="${portletSkin.id}" rel="stylesheet" type="text/css" href= "$url" />
+    <%}%>
+     <script type="text/javascript">
+     // This variable must be used only to initialize other variables otherwise
+     // please use eXo.env.portal.context or eXo.env.portal.context instead
+     // Those 2 last variables cannot be used to initialize variables because
+     // we cannot be sure that they will be initialized before initializing your script
+      var currentContext = '<%=docBase%>' ;
+    </script>
+    <%if(org.exoplatform.commons.utils.PropertyManager.isDevelopping()) {
+        for(path in scriptsPaths) { %>
+          <script type="text/javascript" src="<%=path%>"></script>
+    <%  }
+      } else {
+    %>
+        <script type="text/javascript" src="<%=docBase%>/javascript/merged.js"></script>
+    <%}%>
+    <script type="text/javascript">
+      eXo.env.portal.context = '<%=docBase%>' ;
+      <%if(rcontext.getAccessPath() == 0) {%>
+          eXo.env.portal.accessMode = 'public' ;
+      <%} else {%>
+          eXo.env.portal.accessMode = 'private' ;
+      <%}%>
+      eXo.env.portal.portalName = '<%=rcontext.getPortalOwner()%>' ;
+      eXo.env.server.context = '<%=docBase%>' ;
+      eXo.env.server.portalBaseURL = '<%=rcontext.getURLBuilder().getBaseURL()%>' ;
+      eXo.env.client.skin = '$skin' ;
+      <%
+        String sessionAliveLevel = (portal == null ? null : portal.sessionAlive) ;
+        boolean canKeepState = sessionAliveLevel == null ? false : !sessionAliveLevel.equals(PortalProperties.SESSION_NEVER) ;
+      %>
+
+      eXo.portal.portalMode = <%= uicomponent.getModeState() %>;
+
+      eXo.session.level = '$sessionAliveLevel';
+      eXo.session.canKeepState = $canKeepState;
+      eXo.session.isOpen = $uicomponent.isSessionOpen ;
+      eXo.session.itvTime = ${(rcontext).getRequest().getSession().getMaxInactiveInterval()} ;
+    </script>
+    <script type="text/javascript" src="/eXoResources/javascript/eXo/i18n/I18NMessage.js"></script>
+    <script type="text/javascript" src="/eXoResources/javascript/eXo/i18n/MessageResource_<%=lang%>.js"></script>
+  </head>
+
+  <body style="height: 100%;">
+    <%
+      /*Hide All Popup Menu when click on document*/
+      rcontext.getJavascriptManager().addOnLoadJavascript('eXo.core.DOMUtil.hideElements');
+      //rcontext.getJavascriptManager().addOnResizeJavascript('eXo.core.UIMaskLayer.resizeMaskLayer');
+    %>
+
+	<div class="$uicomponent.skin" id="UIPortalApplication" style="!height: 100%;">
+
+		<div class="AjaxLoadingMask" id="AjaxLoadingMask" style="display: none; margin: auto;">
+      <div class="LoadingContainer">
+        <div class="CenterLoadingContainer">
+          <div class="LoadingText"><%=_ctx.appRes("UIPortalApplication.label.Loading")%></div>
+          <div class="LoadingProgressBar"><span></span></div>
+
+          <div class="UIAction">
+				    <table class="ActionContainer">
+					    <tr>
+					    	<td>
+						      <div onclick="javascript:ajaxAbort();" class="ActionButton LightBlueStyle">
+						        <div class="ButtonLeft">
+						          <div class="ButtonRight">
+						            <div class="ButtonMiddle">
+						              <a href="javascript:void(0);"><%=_ctx.appRes("UIPortalApplication.label.Abort")%></a>
+						            </div>
+						          </div>
+						        </div>
+						      </div>
+						    </td>
+				      </tr>
+				 	  </table>
+					</div>
+
+        </div>
+      </div>
+	  </div>
+
+	  <%uicomponent.renderChildren();%>
+	</div>
+
+
+
+    <script type="text/javascript">
+      <%=rcontext.getJavascriptManager().getJavascript()%>
+        eXo.core.Browser.onLoad();
+      <%=rcontext.getJavascriptManager().getCustomizedOnLoadScript();%>
+      <%if(canKeepState && uicomponent.isSessionOpen) {%> eXo.session.itvInit() ;<%}%>
+    </script>
+  </body>
+</html>

Modified: portal/branches/performance/webui/core/src/main/java/org/exoplatform/webui/application/portlet/PortletApplication.java
===================================================================
--- portal/branches/performance/webui/core/src/main/java/org/exoplatform/webui/application/portlet/PortletApplication.java	2009-10-30 10:54:06 UTC (rev 458)
+++ portal/branches/performance/webui/core/src/main/java/org/exoplatform/webui/application/portlet/PortletApplication.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -19,6 +19,7 @@
 
 package org.exoplatform.webui.application.portlet;
 
+import org.exoplatform.commons.utils.PortalPrinter;
 import org.exoplatform.resolver.ApplicationResourceResolver;
 import org.exoplatform.resolver.PortletResourceResolver;
 import org.exoplatform.services.log.ExoLogger;
@@ -275,12 +276,12 @@
    {
       String attributeName = getApplicationId() + "$PortletRequest";
       PortletRequestContext context = (PortletRequestContext)parentAppRequestContext.getAttribute(attributeName);
-      Writer w = null;
+      PortalPrinter w = null;
       if (res instanceof RenderResponse)
       {
          RenderResponse renderRes = (RenderResponse)res;
          renderRes.setContentType("text/html; charset=UTF-8");
-         w = renderRes.getWriter();
+         w = new PortalPrinter(renderRes.getPortletOutputStream(), true, 0);
       }
       if (context != null)
       {

Modified: portal/branches/performance/webui/core/src/main/java/org/exoplatform/webui/application/portlet/PortletRequestContext.java
===================================================================
--- portal/branches/performance/webui/core/src/main/java/org/exoplatform/webui/application/portlet/PortletRequestContext.java	2009-10-30 10:54:06 UTC (rev 458)
+++ portal/branches/performance/webui/core/src/main/java/org/exoplatform/webui/application/portlet/PortletRequestContext.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -75,7 +75,8 @@
    {
       request_ = req;
       response_ = res;
-      writer_ = HtmlValidator.DEBUG_MODE ? new WriterPrinter(new HtmlValidator(writer)) : new WriterPrinter(writer);
+//      writer_ = HtmlValidator.DEBUG_MODE ? new WriterPrinter(new HtmlValidator(writer)) : new WriterPrinter(writer);
+      writer_ = writer;
       windowId_ = req.getWindowID();
    }
 

Modified: portal/branches/performance/webui/portal/src/main/java/org/exoplatform/portal/webui/application/UIPortletLifecycle.java
===================================================================
--- portal/branches/performance/webui/portal/src/main/java/org/exoplatform/portal/webui/application/UIPortletLifecycle.java	2009-10-30 10:54:06 UTC (rev 458)
+++ portal/branches/performance/webui/portal/src/main/java/org/exoplatform/portal/webui/application/UIPortletLifecycle.java	2009-10-30 14:38:36 UTC (rev 459)
@@ -42,6 +42,7 @@
 import org.gatein.pc.api.invocation.response.PortletInvocationResponse;
 
 import java.io.Serializable;
+import java.nio.charset.Charset;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -175,7 +176,18 @@
                   if (response instanceof FragmentResponse)
                   {
                      FragmentResponse fragmentResponse = (FragmentResponse)response;
-                     markup = Text.create(fragmentResponse.getContent());
+                     switch (fragmentResponse.getType())
+                     {
+                        case FragmentResponse.TYPE_CHARS:
+                           markup = Text.create(fragmentResponse.getContent());
+                           break;
+                        case FragmentResponse.TYPE_BYTES:
+                           markup = Text.create(fragmentResponse.getBytes(), Charset.forName("UTF-8"));
+                           break;
+                        case FragmentResponse.TYPE_EMPTY:
+                           markup = Text.create("");
+                           break;
+                     }
                      portletTitle = fragmentResponse.getTitle();
                      if (fragmentResponse.getProperties() != null
                         && fragmentResponse.getProperties().getTransportHeaders() != null)
@@ -262,6 +274,7 @@
          }
          catch (Throwable ex)
          {
+            ex.printStackTrace();
          }
       }
    }



More information about the gatein-commits mailing list