You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by mi...@apache.org on 2004/06/11 21:45:40 UTC

cvs commit: jakarta-tapestry/framework/src/org/apache/tapestry/html HTMLWriter.java

mindbridge    2004/06/11 12:45:40

  Modified:    framework/src/org/apache/tapestry/util/text
                        ICharacterMatcher.java WhitespaceMatcher.java
                        CompoundMatcher.java AsciiCharacterMatcher.java
               framework/src/org/apache/tapestry/wml WMLWriter.java
               framework/src/org/apache/tapestry AbstractMarkupWriter.java
               framework/src/org/apache/tapestry/html HTMLWriter.java
  Added:       framework/src/org/apache/tapestry/util/text
                        DefaultCharacterTranslatorSource.java
                        MLCharacterTranslator.java
                        AsciiCharacterTranslator.java
                        ICharacterTranslatorSource.java
                        ICharacterTranslator.java
               framework/src/org/apache/tapestry/wml
                        WMLCharacterTranslatorSource.java
  Log:
  Changing the MarkupWriters to quote different sets of characters
  depending on the encoding used.
  TODO: Add the ability to define a character translator using an extension
  
  Revision  Changes    Path
  1.2       +2 -2      jakarta-tapestry/framework/src/org/apache/tapestry/util/text/ICharacterMatcher.java
  
  Index: ICharacterMatcher.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/util/text/ICharacterMatcher.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ICharacterMatcher.java	6 Jun 2004 08:49:28 -0000	1.1
  +++ ICharacterMatcher.java	11 Jun 2004 19:45:40 -0000	1.2
  @@ -21,7 +21,7 @@
    * @version $Id$
    * @since 3.1
    */
  -interface ICharacterMatcher 
  +public interface ICharacterMatcher 
   {
       /**
        * Determine whether the given character matches the implemented rule
  
  
  
  1.2       +2 -2      jakarta-tapestry/framework/src/org/apache/tapestry/util/text/WhitespaceMatcher.java
  
  Index: WhitespaceMatcher.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/util/text/WhitespaceMatcher.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- WhitespaceMatcher.java	6 Jun 2004 08:49:28 -0000	1.1
  +++ WhitespaceMatcher.java	11 Jun 2004 19:45:40 -0000	1.2
  @@ -21,7 +21,7 @@
    * @version $Id$
    * @since 3.1
    */
  -class WhitespaceMatcher implements ICharacterMatcher 
  +public class WhitespaceMatcher implements ICharacterMatcher 
   {
       private boolean _matchEndLines;
       
  
  
  
  1.2       +2 -2      jakarta-tapestry/framework/src/org/apache/tapestry/util/text/CompoundMatcher.java
  
  Index: CompoundMatcher.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/util/text/CompoundMatcher.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- CompoundMatcher.java	6 Jun 2004 08:49:28 -0000	1.1
  +++ CompoundMatcher.java	11 Jun 2004 19:45:40 -0000	1.2
  @@ -22,7 +22,7 @@
    * @version $Id$
    * @since 3.1
    */
  -class CompoundMatcher implements ICharacterMatcher
  +public class CompoundMatcher implements ICharacterMatcher
   {
       private ICharacterMatcher[] _matchers;
       
  
  
  
  1.2       +2 -2      jakarta-tapestry/framework/src/org/apache/tapestry/util/text/AsciiCharacterMatcher.java
  
  Index: AsciiCharacterMatcher.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/util/text/AsciiCharacterMatcher.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- AsciiCharacterMatcher.java	6 Jun 2004 08:49:28 -0000	1.1
  +++ AsciiCharacterMatcher.java	11 Jun 2004 19:45:40 -0000	1.2
  @@ -21,7 +21,7 @@
    * @version $Id$
    * @since 3.1
    */
  -class AsciiCharacterMatcher implements ICharacterMatcher 
  +public class AsciiCharacterMatcher implements ICharacterMatcher 
   {
       private boolean[] _charMap;
       
  
  
  
  1.1                  jakarta-tapestry/framework/src/org/apache/tapestry/util/text/DefaultCharacterTranslatorSource.java
  
  Index: DefaultCharacterTranslatorSource.java
  ===================================================================
  //Copyright 2004 The Apache Software Foundation
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  package org.apache.tapestry.util.text;
  
  import java.util.HashMap;
  import java.util.Map;
  
  /**
   * The default implementation of a character translator source.
   * Returns a standard HTML translator that encodes everything that is non-safe
   * or an HTML translator that encodes only non-safe ASCII symbols 
   * if the encoding is a unicode one. 
   * 
   * @author mb
   * @version $Id: DefaultCharacterTranslatorSource.java,v 1.1 2004/06/11 19:45:40 mindbridge Exp $
   * @since 3.1
   */
  public class DefaultCharacterTranslatorSource implements ICharacterTranslatorSource
  {
  	private static final ICharacterTranslator DEFAULT_TRANSLATOR = new MLCharacterTranslator();
  	private static final ICharacterTranslator UNICODE_TRANSLATOR = new MLCharacterTranslator(false);
  
  	private final static Map _translators;
  	
  	static {
  		_translators = new HashMap();
  		_translators.put("UTF-8", UNICODE_TRANSLATOR);
  		_translators.put("UTF-7", UNICODE_TRANSLATOR);
  		_translators.put("UTF-16", UNICODE_TRANSLATOR);
  		_translators.put("UTF-16BE", UNICODE_TRANSLATOR);
  		_translators.put("UTF-16LE", UNICODE_TRANSLATOR);
  	}
  	
  	/**
  	 * Returns a translator that encodes all non-safe characters into their HTML equivalents.
  	 * 
  	 * @see org.apache.tapestry.util.text.ICharacterTranslatorSource#getDefaultTranslator()
  	 */
  	public ICharacterTranslator getDefaultTranslator() {
  		return DEFAULT_TRANSLATOR;
  	}
  
  	/**
  	 * If the encoding is a Unicode one, returns a translator that encodes only the 
  	 * non-safe ASCII characters and leaves the others untouched.
  	 * Otherwise, returns the default translator.
  	 * 
  	 * @see org.apache.tapestry.util.text.ICharacterTranslatorSource#getTranslator(java.lang.String)
  	 */
  	public ICharacterTranslator getTranslator(String encoding) {
  		ICharacterTranslator translator = (ICharacterTranslator) _translators.get(encoding.toUpperCase());
  		if (translator != null)
  			return translator;
  		return getDefaultTranslator();
  	}
  	
  }
  
  
  
  1.1                  jakarta-tapestry/framework/src/org/apache/tapestry/util/text/MLCharacterTranslator.java
  
  Index: MLCharacterTranslator.java
  ===================================================================
  //Copyright 2004 The Apache Software Foundation
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  package org.apache.tapestry.util.text;
  
  /**
   * An object that encodes a character according to rules of the HTML specification, 
   * so that it will be properly parsed by a browser irrespectively of the character
   * encoding used in the HTML output.
   * 
   * @author mb
   * @version $Id: MLCharacterTranslator.java,v 1.1 2004/06/11 19:45:40 mindbridge Exp $
   * @since 3.1
   */
  public class MLCharacterTranslator implements ICharacterTranslator
  {
      private static final String SAFE_CHARACTERS =
          "01234567890"
              + "abcdefghijklmnopqrstuvwxyz"
              + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
              + "\t\n\r !#$%'()*+,-./:;=?@[\\]^_`{|}~";
  
      private static final String[][] ENTITIES = {
      	{ "\"", """ }, 
  		{ "<", "&lt;" },
  		{ ">", "&gt;" },
  		{ "&", "&amp;" }
      };
      
      private static final ICharacterMatcher SAFE_MATCHER = new AsciiCharacterMatcher(SAFE_CHARACTERS);
      private static final ICharacterTranslator ENTITY_TRANSLATOR = new AsciiCharacterTranslator(ENTITIES);
      
      private boolean _encodeNonAscii;
      private ICharacterMatcher _safeMatcher;
      private ICharacterTranslator _entityTranslator;
  	
      public MLCharacterTranslator()
      {
      	this(true);
      }
      
      public MLCharacterTranslator(boolean encodeNonAscii)
      {
      	this(encodeNonAscii, SAFE_MATCHER, ENTITY_TRANSLATOR);
      }
      
      public MLCharacterTranslator(boolean encodeNonAscii, ICharacterMatcher safeMatcher, ICharacterTranslator entityTranslator)
      {
      	_encodeNonAscii = encodeNonAscii;
      	_safeMatcher = safeMatcher;
      	_entityTranslator = entityTranslator;
      }
  
      public MLCharacterTranslator(boolean encodeNonAscii, String safeCharacters, String[][] entities)
      {
      	_encodeNonAscii = encodeNonAscii;
      	_safeMatcher = new AsciiCharacterMatcher(safeCharacters);
      	_entityTranslator = new AsciiCharacterTranslator(entities);
      }
      
  	/**
  	 * @see org.apache.tapestry.util.text.IMarkupCharacterTranslator#translateAttribute(char)
  	 */
  	public String translate(char ch) {
  		if (ch >= 128 && !_encodeNonAscii)
  			return null;
  		
  		if (_safeMatcher.matches(ch))
  			return null;
  
  		String entity = _entityTranslator.translate(ch);
  		if (entity != null)
  			return entity;
  		
  		// needs to use a NumberFormat here to be fully compliant, 
  		// but this is accepted fine by the browsers
  		return "&#" + (int) ch + ";";
  	}
  }
  
  
  
  1.1                  jakarta-tapestry/framework/src/org/apache/tapestry/util/text/AsciiCharacterTranslator.java
  
  Index: AsciiCharacterTranslator.java
  ===================================================================
  //Copyright 2004 The Apache Software Foundation
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  package org.apache.tapestry.util.text;
  
  /**
   * An object that translates selected ASCII characters into equivalent strings.
   * 
   * @author mb
   * @version $Id: AsciiCharacterTranslator.java,v 1.1 2004/06/11 19:45:40 mindbridge Exp $
   * @since 3.1
   */
  public class AsciiCharacterTranslator implements ICharacterTranslator
  {
  	private String[] _charMap;
  	
  	/**
  	 * Creates and initializes a new translator that translates the provided 
  	 * ASCII characters into strings. All other characters will be translated to null.
  	 * 
  	 * @param characterMap an array of pairs of strings. 
  	 *        Each pair consists of a key that must be a single ASCII character, 
  	 *        and a value that is its equivalent string. 
  	 */
  	public AsciiCharacterTranslator(String[][] characterMap)
  	{
  		_charMap = new String[128];
  		
  		int pairCount = characterMap.length;
  		for (int i = 0; i < pairCount; i++) {
  			String[] pair = characterMap[i];
  			if (pair.length != 2)
  				continue;
  			String key = pair[0];
  			String value = pair[1];
  			if (key.length() != 1)
  				continue;
  			char ch = key.charAt(0);
  			if (ch >= 128)
  				continue;
  			
  			_charMap[ch] = value;
  		}
  	}
  	
  	/**
  	 * @see org.apache.tapestry.util.text.ICharacterTranslator#translate(char)
  	 */
  	public String translate(char ch) {
  		if (ch >= 128)
  			return null;
  		return _charMap[ch];
  	}
  }
  
  
  
  1.1                  jakarta-tapestry/framework/src/org/apache/tapestry/util/text/ICharacterTranslatorSource.java
  
  Index: ICharacterTranslatorSource.java
  ===================================================================
  //Copyright 2004 The Apache Software Foundation
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  package org.apache.tapestry.util.text;
  
  /**
   * A factory for creating character translators depending on the encoding
   * 
   * @author mb
   * @version $Id: ICharacterTranslatorSource.java,v 1.1 2004/06/11 19:45:40 mindbridge Exp $
   * @since 3.1
   */
  public interface ICharacterTranslatorSource 
  {
  	ICharacterTranslator getDefaultTranslator();
  	ICharacterTranslator getTranslator(String encoding);
  }
  
  
  
  1.1                  jakarta-tapestry/framework/src/org/apache/tapestry/util/text/ICharacterTranslator.java
  
  Index: ICharacterTranslator.java
  ===================================================================
  //Copyright 2004 The Apache Software Foundation
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  package org.apache.tapestry.util.text;
  
  /**
   * An interface for translating a character into a string.
   * 
   * @author mb
   * @version $Id: ICharacterTranslator.java,v 1.1 2004/06/11 19:45:40 mindbridge Exp $
   * @since 3.1
   */
  public interface ICharacterTranslator 
  {
  	/**
  	 * Translates the provided character into a string 
  	 * 
  	 * @param ch the character to be translated
  	 * @return null if the character is not to be translated,
  	 * an empty string if the character is to be ignored, 
  	 * or another string to represent the character translation
  	 */
  	String translate(char ch);
  }
  
  
  
  1.7       +8 -25     jakarta-tapestry/framework/src/org/apache/tapestry/wml/WMLWriter.java
  
  Index: WMLWriter.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/wml/WMLWriter.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- WMLWriter.java	19 Feb 2004 17:37:46 -0000	1.6
  +++ WMLWriter.java	11 Jun 2004 19:45:40 -0000	1.7
  @@ -18,6 +18,7 @@
   
   import org.apache.tapestry.AbstractMarkupWriter;
   import org.apache.tapestry.IMarkupWriter;
  +import org.apache.tapestry.util.text.ICharacterTranslatorSource;
   
   /**
    *  This class is used to create WML output.
  @@ -43,27 +44,9 @@
   
   public class WMLWriter extends AbstractMarkupWriter
   {
  -
  -    private static final String[] entities = new String[64];
  -    private static final boolean[] safe = new boolean[128];
  -    private static final String SAFE_CHARACTERS =
  -        "01234567890"
  -            + "abcdefghijklmnopqrstuvwxyz"
  -            + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  -            + "\t\n\r !\"#%'()*+,-./:;=?@[\\]^_`{|}~";
  -
  -    static {
  -        entities['"'] = "&quot;";
  -        entities['<'] = "&lt;";
  -        entities['>'] = "&gt;";
  -        entities['&'] = "&amp;";
  -        entities['$'] = "$$";
  -
  -        int length = SAFE_CHARACTERS.length();
  -        for (int i = 0; i < length; i++)
  -            safe[SAFE_CHARACTERS.charAt(i)] = true;
  -    }
  -
  +    private static final ICharacterTranslatorSource TRANSLATOR_SOURCE = 
  +    	new WMLCharacterTranslatorSource();
  +    
       /**
        *  Creates a response writer for content type "text/vnd.wap.wml".
        * 
  @@ -88,7 +71,7 @@
   
       public WMLWriter(String contentType, OutputStream stream)
       {
  -        super(safe, entities, contentType, stream);
  +        super(TRANSLATOR_SOURCE, contentType, stream);
       }
   
       /**
  @@ -101,12 +84,12 @@
        **/
       public WMLWriter(String mimeType, String encoding, OutputStream stream)
       {
  -        super(safe, entities, mimeType, encoding, stream);
  +        super(TRANSLATOR_SOURCE, mimeType, encoding, stream);
       }
   
       protected WMLWriter(String contentType)
       {
  -        super(safe, entities, contentType);
  +        super(TRANSLATOR_SOURCE, contentType);
       }
   
       public IMarkupWriter getNestedWriter()
  
  
  
  1.1                  jakarta-tapestry/framework/src/org/apache/tapestry/wml/WMLCharacterTranslatorSource.java
  
  Index: WMLCharacterTranslatorSource.java
  ===================================================================
  //Copyright 2004 The Apache Software Foundation
  //
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  package org.apache.tapestry.wml;
  
  import org.apache.tapestry.util.text.AsciiCharacterMatcher;
  import org.apache.tapestry.util.text.AsciiCharacterTranslator;
  import org.apache.tapestry.util.text.ICharacterMatcher;
  import org.apache.tapestry.util.text.ICharacterTranslator;
  import org.apache.tapestry.util.text.ICharacterTranslatorSource;
  import org.apache.tapestry.util.text.MLCharacterTranslator;
  
  /**
   * The WML implementation of a character translator source.
   * Returns a WML translator that encodes everything that is non-safe.
   * 
   * Some code borrowed from WMLWriter (by David Solis)
   * 
   * @author mb
   * @version $Id: WMLCharacterTranslatorSource.java,v 1.1 2004/06/11 19:45:40 mindbridge Exp $
   * @since 3.1
   */
  public class WMLCharacterTranslatorSource implements ICharacterTranslatorSource
  {
      private static final String SAFE_CHARACTERS =
          "01234567890"
              + "abcdefghijklmnopqrstuvwxyz"
              + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
              + "\t\n\r !\"#%'()*+,-./:;=?@[\\]^_`{|}~";
  
      private static final String[][] ENTITIES = {
          	{ "\"", "&quot;" }, 
      		{ "<", "&lt;" },
      		{ ">", "&gt;" },
      		{ "&", "&amp;" },
      		{ "$", "$$" }
          };
  
      private static final ICharacterMatcher SAFE_MATCHER = new AsciiCharacterMatcher(SAFE_CHARACTERS);
      private static final ICharacterTranslator ENTITY_TRANSLATOR = new AsciiCharacterTranslator(ENTITIES);
  
      private static final ICharacterTranslator WML_TRANSLATOR = new MLCharacterTranslator(true, SAFE_MATCHER, ENTITY_TRANSLATOR);
  
  	/**
  	 * @see org.apache.tapestry.util.text.ICharacterTranslatorSource#getDefaultTranslator()
  	 */
  	public ICharacterTranslator getDefaultTranslator() {
  		return WML_TRANSLATOR;
  	}
  
  	/**
  	 * @see org.apache.tapestry.util.text.ICharacterTranslatorSource#getTranslator(java.lang.String)
  	 */
  	public ICharacterTranslator getTranslator(String encoding) {
  		return getDefaultTranslator();
  	}
  }
  
  
  
  1.14      +42 -67    jakarta-tapestry/framework/src/org/apache/tapestry/AbstractMarkupWriter.java
  
  Index: AbstractMarkupWriter.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/AbstractMarkupWriter.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- AbstractMarkupWriter.java	19 Feb 2004 17:37:36 -0000	1.13
  +++ AbstractMarkupWriter.java	11 Jun 2004 19:45:40 -0000	1.14
  @@ -23,6 +23,8 @@
   import java.util.Stack;
   
   import org.apache.tapestry.util.ContentType;
  +import org.apache.tapestry.util.text.ICharacterTranslator;
  +import org.apache.tapestry.util.text.ICharacterTranslatorSource;
   
   /**
    * Abstract base class implementing the {@link IMarkupWriter} interface.
  @@ -117,9 +119,6 @@
   
       private char[] _buffer;
   
  -    private String[] _entities;
  -    private boolean[] _safe;
  -
       /**
        *  Implemented in concrete subclasses to provide an indication of which
        *  characters are 'safe' to insert directly into the response.  The index
  @@ -128,6 +127,8 @@
        *
        **/
   
  +    private ICharacterTranslator _translator;
  +    
       private String _contentType;
   
       /**
  @@ -163,21 +164,21 @@
        **/
   
       protected AbstractMarkupWriter(
  -        boolean safe[],
  -        String[] entities,
  +        ICharacterTranslatorSource translatorSource,
           String contentType,
           String encoding,
           OutputStream stream)
       {
  -        if (entities == null || safe == null || contentType == null || encoding == null)
  +        if (translatorSource == null || contentType == null || encoding == null)
               throw new IllegalArgumentException(
                   Tapestry.getMessage("AbstractMarkupWriter.missing-constructor-parameters"));
   
  -        _entities = entities;
  -        _safe = safe;
  -
  -        _contentType = generateFullContentType(contentType, encoding);
  -
  +        ContentType contentTypeObject = generateFullContentType(contentType, encoding);
  +        _contentType = contentTypeObject.unparse();
  +        
  +        encoding = contentTypeObject.getParameter("charset");
  +        _translator = translatorSource.getTranslator(encoding);
  +        
           setOutputStream(stream, encoding);
       }
   
  @@ -198,12 +199,11 @@
        **/
   
       protected AbstractMarkupWriter(
  -        boolean safe[],
  -        String[] entities,
  +    	ICharacterTranslatorSource translatorSource,
           String contentType,
           OutputStream stream)
       {
  -        this(safe, entities, contentType);
  +        this(translatorSource, contentType);
   
           ContentType contentTypeObject = new ContentType(contentType);
           String encoding = contentTypeObject.getParameter("charset");
  @@ -223,12 +223,11 @@
        **/
   
       protected AbstractMarkupWriter(
  -        boolean safe[],
  -        String[] entities,
  +    	ICharacterTranslatorSource translatorSource,
           String contentType,
           PrintWriter writer)
       {
  -        this(safe, entities, contentType);
  +        this(translatorSource, contentType);
   
           // When the markup writer is closed, the underlying writer
           // is NOT closed.
  @@ -243,15 +242,17 @@
        * 
        **/
   
  -    protected AbstractMarkupWriter(boolean safe[], String[] entities, String contentType)
  +    protected AbstractMarkupWriter(ICharacterTranslatorSource translatorSource, String contentType)
       {
  -        if (entities == null || safe == null || contentType == null)
  +        if (translatorSource == null || contentType == null)
               throw new IllegalArgumentException(
                   Tapestry.getMessage("AbstractMarkupWriter.missing-constructor-parameters"));
   
  -        _entities = entities;
  -        _safe = safe;
  -        _contentType = generateFullContentType(contentType, DEFAULT_ENCODING);
  +        ContentType contentTypeObject = generateFullContentType(contentType, DEFAULT_ENCODING);
  +        _contentType = contentTypeObject.unparse();
  +        
  +        String encoding = contentTypeObject.getParameter("charset");
  +        _translator = translatorSource.getTranslator(encoding);
       }
   
       /**
  @@ -261,12 +262,12 @@
        * @param encoding The value of the charset parameter of the content type if it is not already present.
        * @return The content type containing a charset parameter, e.g. text/html;charset=utf-8 
        */
  -    private String generateFullContentType(String contentType, String encoding)
  +    private ContentType generateFullContentType(String contentType, String encoding)
       {
           ContentType contentTypeObject = new ContentType(contentType);
           if (contentTypeObject.getParameter("charset") == null)
               contentTypeObject.setParameter("charset", encoding);
  -        return contentTypeObject.unparse();
  +        return contentTypeObject;
       }
   
       protected void setWriter(PrintWriter writer)
  @@ -649,27 +650,12 @@
           if (_openTag)
               closeTag();
   
  -        if (value < _safe.length && _safe[value])
  -        {
  -            _writer.print(value);
  -            return;
  -        }
  -
  -        String entity = null;
  -
  -        if (value < _entities.length)
  -            entity = _entities[value];
  -
  -        if (entity != null)
  -        {
  -            _writer.print(entity);
  -            return;
  -        }
  -
  -        // Not a well-known entity.  Print it's numeric equivalent.  Note:  this omits
  -        // the leading '0', but most browsers (IE 5.0) don't seem to mind.  Is this a bug?
  -
  -        _writer.print("&#" + (int) value + ";");
  +        String translation = _translator.translate(value);
  +        
  +        if (translation == null)
  +        	_writer.print(value);
  +        else
  +        	_writer.print(translation);
       }
   
       /**
  @@ -799,15 +785,16 @@
           {
               char ch = data[offset + i];
   
  -            // Ignore safe characters.  In an attribute, quotes
  -            // are not ok and are escaped.
  +            // Ignore safe characters.  Outside an attribute, quotes
  +            // are ok and are not escaped.
   
  -            boolean isSafe = (ch < _safe.length && _safe[ch]);
  -
  -            if (isAttribute && ch == '"')
  -                isSafe = false;
  -
  -            if (isSafe)
  +            String translation;
  +            if (ch == '"' && !isAttribute)
  +            	translation = null;
  +            else
  +            	translation = _translator.translate(ch);
  +            
  +            if (translation == null)
               {
                   safelength++;
                   continue;
  @@ -818,19 +805,7 @@
               if (safelength > 0)
                   _writer.write(data, start, safelength);
   
  -            String entity = null;
  -
  -            // Look for a known entity.
  -
  -            if (ch < _entities.length)
  -                entity = _entities[ch];
  -
  -            // Failing that, emit a numeric entity.
  -
  -            if (entity == null)
  -                entity = "&#" + (int) ch + ";";
  -
  -            _writer.print(entity);
  +            _writer.print(translation);
   
               start = offset + i + 1;
               safelength = 0;
  
  
  
  1.7       +10 -26    jakarta-tapestry/framework/src/org/apache/tapestry/html/HTMLWriter.java
  
  Index: HTMLWriter.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/html/HTMLWriter.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- HTMLWriter.java	19 Feb 2004 17:37:44 -0000	1.6
  +++ HTMLWriter.java	11 Jun 2004 19:45:40 -0000	1.7
  @@ -19,6 +19,8 @@
   
   import org.apache.tapestry.AbstractMarkupWriter;
   import org.apache.tapestry.IMarkupWriter;
  +import org.apache.tapestry.util.text.DefaultCharacterTranslatorSource;
  +import org.apache.tapestry.util.text.ICharacterTranslatorSource;
   
   /**
    *  This class is used to create HTML output.
  @@ -36,27 +38,9 @@
   
   public class HTMLWriter extends AbstractMarkupWriter
   {
  -
  -    private static final String[] entities = new String[64];
  -    private static final boolean[] safe = new boolean[128];
  -
  -    private static final String SAFE_CHARACTERS =
  -        "01234567890"
  -            + "abcdefghijklmnopqrstuvwxyz"
  -            + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  -            + "\t\n\r !\"#$%'()*+,-./:;=?@[\\]^_`{|}~";
  -
  -    static {
  -        entities['"'] = "&quot;";
  -        entities['<'] = "&lt;";
  -        entities['>'] = "&gt;";
  -        entities['&'] = "&amp;";
  -
  -        int length = SAFE_CHARACTERS.length();
  -        for (int i = 0; i < length; i++)
  -            safe[SAFE_CHARACTERS.charAt(i)] = true;
  -    }
  -
  +	private static final ICharacterTranslatorSource TRANSLATOR_SOURCE = 
  +		new DefaultCharacterTranslatorSource();
  +	
   	/**
   	 *  Creates a new markup writer around the {@link PrintWriter}.
   	 *  The writer will not be closed when the markup writer closes.
  @@ -69,22 +53,22 @@
   	
   	public HTMLWriter(PrintWriter writer)
   	{
  -		super(safe, entities, "text/html", writer);
  +		super(TRANSLATOR_SOURCE, "text/html", writer);
   	}
   
       public HTMLWriter(String contentType, OutputStream outputStream)
       {
  -        super(safe, entities, contentType, outputStream);
  +        super(TRANSLATOR_SOURCE, contentType, outputStream);
       }
   
       public HTMLWriter(String contentType, String encoding, OutputStream outputStream)
       {
  -        super(safe, entities, contentType, encoding, outputStream);
  +        super(TRANSLATOR_SOURCE, contentType, encoding, outputStream);
       }
   
       protected HTMLWriter(String contentType)
       {
  -        super(safe, entities, contentType);
  +        super(TRANSLATOR_SOURCE, contentType);
       }
   
       /**
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org