Changeset 1694


Ignore:
Timestamp:
2010-08-23 20:39:24 (3 years ago)
Author:
mpo
Message:

closes #356, #107 (completes started work in #335 and r1688)
Adding tests and code to properly use the retrieved encoding and mime-type from external sources or let them be overriden by using @mode and @encoding.
The plain_Cp1251.txt file should be kept in Cp1252 encoding to work.
Also removing more Byte-Order-Marks that got added by eager text editor tools.

Location:
trunk
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/modules/kauri-template/kauri-template-service-impl/src/main/java/org/kauriproject/template/service/impl/RestletSource.java

    r1329 r1694  
    8484        return representation.getMediaType().toString(); 
    8585    } 
     86     
     87    public String getEncoding() { 
     88        return representation.getCharacterSet().getName(); 
     89    } 
    8690 
    8791    public Validity getValidity() { 
  • trunk/universe/kauri-template/src/main/java/org/kauriproject/template/InsertBlock.java

    r1688 r1694  
    1616package org.kauriproject.template; 
    1717 
    18 import java.io.BufferedReader; 
    19 import java.io.ByteArrayInputStream; 
     18import java.io.Closeable; 
    2019import java.io.FileNotFoundException; 
    2120import java.io.IOException; 
    2221import java.io.InputStream; 
    2322import java.io.InputStreamReader; 
     23import java.io.Reader; 
     24import java.io.StringReader; 
     25import java.io.UnsupportedEncodingException; 
     26import java.util.regex.Matcher; 
     27import java.util.regex.Pattern; 
    2428 
    2529import javax.xml.parsers.SAXParser; 
    2630 
    27 import org.apache.commons.logging.Log; 
    28 import org.apache.commons.logging.LogFactory; 
    2931import org.kauriproject.template.el.ELFacade; 
    3032import org.kauriproject.template.el.Expression; 
     
    4850    public static final String VALUE = "value"; 
    4951    public static final String MODE  = "mode"; 
     52    public static final String ENCODING  = "encoding"; 
    5053 
    5154    // EL 
     
    7275        private Expression sourceExpr, valueExpr; 
    7376        private String mode; 
     77        private String encoding; 
    7478 
    7579        public StartStep(Locator locator) { 
     
    8791            } 
    8892            mode = attributes.getValue(MODE); 
     93            encoding = attributes.getValue(ENCODING); 
    8994        } 
    9095 
     
    9499            Source source = null; 
    95100            String valueStr = null; 
    96             String usedMode = "undefined"; 
     101            ParseType parseType = null; 
     102            InsertBlockInput input = null; 
    97103 
    98104            try { 
    99                 // resolve and parse 
    100                 ParseType parseType = null; 
    101                  
    102                 if(sourceLocation != null) 
     105 
     106                // find content to insert 
     107                if(sourceLocation != null) 
    103108                    source = context.getSourceResolver().resolve(sourceLocation, context.getBaseUri()); 
    104109                else{ 
     
    106111                }    
    107112 
     113                // decide on mode 
    108114                if (mode != null) { 
    109115                    parseType = ParseType.fromMode(mode);  // this is silent about unknown modes 
    110116                } 
     117                if (parseType == null && source!=null) {  
     118                    parseType = ParseType.fromMediaType(source.getMediaType()); 
     119                } 
    111120                if (parseType == null) {  
    112                     parseType = ParseType.fromMediaType(source.getMediaType()); // this could NPE when source == null 
     121                    parseType = ParseType.TXT; // default to txt mode to be sure to include something 
    113122                } 
    114  
    115                 usedMode = parseType.name(); 
    116                 parseType.doInsert(source, valueStr, result, parser); // this could NPE when parseType was still not found 
     123                 
     124                //actually insert 
     125                input = InsertBlockInput.newInput(source, valueStr, encoding); 
     126                parseType.doInsert(input, result, parser); // this could NPE when parseType was still not found 
    117127 
    118128            } catch (FileNotFoundException ex) { 
    119                 throw new TemplateException("Error inserting " + usedMode + "(mode) from " + (sourceLocation != null ? sourceLocation : valueStr) + ": " + ex); 
     129                throw new TemplateException("Error inserting " + parseType.name() + "(mode) from " + (sourceLocation != null ? sourceLocation : valueStr) + ": " + ex); 
    120130            } catch (Exception ex) { 
    121                 throw new TemplateException("Error parsing " + usedMode + "(mode) from " + (sourceLocation != null ? sourceLocation : valueStr) + ": " + ex); 
     131                throw new TemplateException("Error parsing " + parseType.name() + "(mode) from " + (sourceLocation != null ? sourceLocation : valueStr) + ": " + ex); 
    122132            } finally { 
    123133                if (source != null) { 
    124134                    source.release(); 
    125135                } 
     136                IOUtils.closeQuietly(input); 
    126137            } 
    127138 
     
    153164    } 
    154165     
    155     void doInsert(Source src, String value, TemplateResult result, SAXParser parser) throws IOException, SAXException{ 
    156         this.strategy.doInsert(src, value, result, parser); 
     166    void doInsert(InsertBlockInput input, TemplateResult result, SAXParser parser) throws IOException, SAXException{ 
     167        this.strategy.doInsert(input, result, parser); 
    157168    } 
    158169     
     
    178189} 
    179190 
     191class InsertBlockInput implements Closeable { 
     192     
     193    private final Reader reader; 
     194     
     195    InsertBlockInput(final InputStream is, final String encoding) throws UnsupportedEncodingException { 
     196        this( encoding == null ? new InputStreamReader(is) :  new InputStreamReader(is, encoding)); 
     197    } 
     198     
     199    InsertBlockInput(final Reader reader) { 
     200        this.reader = reader; 
     201    } 
     202     
     203    static InsertBlockInput newInput(final Source source, final String valueStr, String encoding) throws UnsupportedEncodingException, IOException { 
     204        if (source == null ){ 
     205            // we read from the string, no encoding to be followed 
     206            final Reader input = new StringReader(valueStr); 
     207            return new InsertBlockInput(input); 
     208        }  
     209        //else  
     210        if (encoding == null) //if nothing specified, let source charset decide 
     211            encoding = source.getEncoding(); 
     212         
     213        final InputStream input = source.getInputStream(); 
     214        return new InsertBlockInput(input, encoding); 
     215    } 
     216     
     217    InputSource getInputSource() { 
     218        return new InputSource(reader); 
     219    } 
     220 
     221    public Reader getReader() { 
     222        return reader; 
     223    } 
     224     
     225    public void close() { 
     226        IOUtils.closeQuietly(reader); 
     227    } 
     228} 
     229 
    180230interface InsertStrategy { 
    181     void doInsert(Source src, String value, TemplateResult result, SAXParser parser) throws IOException, SAXException; 
     231    void doInsert(InsertBlockInput input, TemplateResult result, SAXParser parser) throws IOException, SAXException; 
    182232} 
    183233 
    184234class XMLInsertStrategy implements InsertStrategy { 
    185     public void doInsert(final Source source, final String valueStr, final TemplateResult result, final SAXParser parser) throws IOException, SAXException { 
    186         InputStream input = null; 
    187         try { 
    188             input = (source != null ? source.getInputStream() :  new ByteArrayInputStream(valueStr.getBytes())); 
    189    
    190             // default to XML: parse with saxparser 
    191             XmlConsumer consumer = new EmbedXmlFilter(result); 
    192             XMLReader xmlReader = parser.getXMLReader(); 
    193             xmlReader.setContentHandler(consumer); 
    194             xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", consumer); 
    195             xmlReader.parse(new InputSource(input)); 
    196         } finally { 
    197             IOUtils.closeQuietly(input); 
    198         } 
     235    public void doInsert(InsertBlockInput input, final TemplateResult result, final SAXParser parser) throws IOException, SAXException { 
     236        // default to XML: parse with saxparser 
     237        XmlConsumer consumer = new EmbedXmlFilter(result); 
     238        XMLReader xmlReader = parser.getXMLReader(); 
     239        xmlReader.setContentHandler(consumer); 
     240        xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", consumer); 
     241        xmlReader.parse(input.getInputSource()); 
    199242    } 
    200243} 
    201244 
    202245class TextInsertStrategy implements InsertStrategy { 
    203     public void doInsert(final Source source, final String valueStr, final TemplateResult result, SAXParser parser) throws IOException, SAXException { 
    204         InputStream input = null; 
    205         try { 
    206             input = (source != null ? source.getInputStream() :  new ByteArrayInputStream(valueStr.getBytes())); 
     246    public void doInsert(InsertBlockInput input, final TemplateResult result, SAXParser parser) throws IOException, SAXException { 
    207247         
    208             //TODO check encoding used to read the text! -- possibly allow encoding to be specified or read from inputstream?  
    209             BufferedReader reader = new BufferedReader(new InputStreamReader(input)); 
    210             String line = reader.readLine(); 
    211             while (line != null) { 
    212                 result.characters(line.toCharArray(), 0, line.length()); 
    213                 line = reader.readLine(); 
    214             } 
    215         } finally { 
    216             IOUtils.closeQuietly(input); 
     248        //TODO check encoding used to read the text! -- possibly allow encoding to be specified or read from inputstream? 
     249         
     250        Reader reader = input.getReader(); 
     251        char[] buf = new char[1024]; 
     252        int read = -1; 
     253        while ( (read = reader.read(buf)) > 0) { 
     254            result.characters(buf, 0, read); 
    217255        } 
    218256    } 
     
    220258 
    221259class HTMLInsertStrategy implements InsertStrategy { 
    222     public void doInsert(final Source source, final String valueStr, final TemplateResult result, SAXParser parser) throws SAXException, IOException { 
    223         InputStream input = null; 
    224         try { 
    225             input = (source != null ? source.getInputStream() :  new ByteArrayInputStream(valueStr.getBytes())); 
    226                
    227             //TODO check proper namespace-handling and correctly marking html to xhtml spaced elements 
    228             // will be important for post-processing 
    229             NekoHtmlParser neko = new NekoHtmlParser(); 
    230             neko.parse(new InputSource(input), new HtmlBodyContentsFilter(result)); 
     260    public void doInsert(InsertBlockInput input, final TemplateResult result, SAXParser parser) throws SAXException, IOException { 
     261           
     262        //TODO check proper namespace-handling and correctly marking html to xhtml spaced elements 
     263        // will be important for post-processing 
     264        NekoHtmlParser neko = new NekoHtmlParser(); 
     265        neko.parse(input.getInputSource(), new HtmlBodyContentsFilter(result)); 
    231266             
    232         } finally { 
    233             IOUtils.closeQuietly(input); 
    234         } 
    235267    } 
    236268} 
  • trunk/universe/kauri-template/src/main/java/org/kauriproject/template/source/ClasspathSource.java

    r1329 r1694  
    1616package org.kauriproject.template.source; 
    1717 
     18import java.io.IOException; 
     19import java.io.InputStream; 
     20import java.io.InputStreamReader; 
     21import java.io.OutputStream; 
     22import java.io.Reader; 
     23import java.io.Writer; 
     24import java.net.URI; 
     25import java.net.URISyntaxException; 
     26import java.net.URL; 
     27import java.net.URLConnection; 
     28 
     29import org.apache.commons.lang.builder.EqualsBuilder; 
    1830import org.apache.commons.lang.builder.HashCodeBuilder; 
    19 import org.apache.commons.lang.builder.EqualsBuilder; 
    2031import org.apache.commons.lang.builder.ToStringBuilder; 
    2132import org.kauriproject.util.io.IOUtils; 
    22  
    23 import java.net.URL; 
    24 import java.net.URI; 
    25 import java.net.URISyntaxException; 
    26 import java.net.URLConnection; 
    27 import java.io.*; 
    2833 
    2934public class ClasspathSource implements Source { 
     
    104109        return mediaType; 
    105110    } 
     111     
     112    public String getEncoding() { 
     113        return System.getProperty("file.encoding"); // just the default encoding. Note for HTML and XML a better effort could be done baed on the content. 
     114    } 
    106115 
    107116    public void release() { 
  • trunk/universe/kauri-template/src/main/java/org/kauriproject/template/source/ClasspathSourceResolver.java

    r900 r1694  
    4242        if (baseLocation.endsWith("/")) 
    4343            return baseLocation + sourceLocation; 
    44         else { 
    45             int end = baseLocation.lastIndexOf('/'); 
    46             if (end < 0) { 
    47                 return sourceLocation; 
    48             } 
    49             return baseLocation.substring(0, ++end) + sourceLocation; 
     44        //else  
     45        int end = baseLocation.lastIndexOf('/'); 
     46        if (end < 0) { 
     47            return sourceLocation; 
    5048        } 
     49        return baseLocation.substring(0, ++end) + sourceLocation; 
    5150    } 
    5251 
  • trunk/universe/kauri-template/src/main/java/org/kauriproject/template/source/Source.java

    r1329 r1694  
    4646 
    4747    String getMediaType(); 
     48     
     49    String getEncoding(); 
    4850 
    4951    Validity getValidity(); 
  • trunk/universe/kauri-template/src/test/resources/org/kauriproject/template/insert_text.xml

    r1688 r1694  
    77    <h3>test insert text from url</h3> 
    88    <t:insert src="plain.txt"/><!-- silently taking text mode from media-type? --> 
     9    <br /> 
     10    <t:insert src="plain_Cp1252.txt" encoding="Cp1252"/> 
    911  </body> 
    1012</html> 
  • trunk/universe/kauri-template/src/test/resources/org/kauriproject/template/insert_text_result.xml

    r1690 r1694  
    1111    </h3> 
    1212    There is no song, just a delusion of silence. We dance and the music dies. 
     13    <br> 
     14    </br> 
     15    This file must be encoded in Cp1252. To test it contains the chars €(euro) é(e-acute) ©(copyright) 
    1316  </body> 
    1417</html> 
  • trunk/universe/kauri-template/src/test/resources/org/kauriproject/template/plain.html

    r1688 r1694  
    1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
     1<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
    22<html> 
    33  <head> 
  • trunk/universe/kauri-template/src/test/resources/org/kauriproject/template/plain.xml

    r523 r1694  
    1 <?xml version="1.0" encoding="UTF-8"?> 
     1<?xml version="1.0" encoding="UTF-8"?> 
    22<root> 
    33  <h1>Hello Kauri</h1> 
Note: See TracChangeset for help on using the changeset viewer.