Author: cbrisson
Date: Fri Jul 15 07:13:01 2016
New Revision: 1752784
URL: http://svn.apache.org/viewvc?rev=1752784&view=rev
Log:
ResourceLoaders now use Readers rather than InputStreams. InputStream API has
been deprecated.
Modified:
velocity/engine/trunk/src/changes/changes.xml
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/Template.java
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/io/UnicodeInputStream.java
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/ContentResource.java
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/ClasspathResourceLoader.java
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/DataSourceResourceLoader.java
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/FileResourceLoader.java
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/JarResourceLoader.java
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/ResourceLoader.java
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/StringResourceLoader.java
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/URLResourceLoader.java
velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/misc/ExceptionGeneratingResourceLoader.java
Modified: velocity/engine/trunk/src/changes/changes.xml
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/src/changes/changes.xml?rev=1752784&r1=1752783&r2=1752784&view=diff
==============================================================================
--- velocity/engine/trunk/src/changes/changes.xml (original)
+++ velocity/engine/trunk/src/changes/changes.xml Fri Jul 15 07:13:01 2016
@@ -27,6 +27,12 @@
<body>
<release version="2.0" date="In Subversion">
+ <action type="add" dev="cbrisson" issue="VELOCITY-793">
+ The ResourceLoader API now provides a Reader rather than an
InputStream.
+ The InputStream getter method has been deprecated.
+ Also fixes VELOCITY-599.
+ </action>
+
<action type="fix" dev="cbrisson" issue="VELOCITY-553">
InvalidReferenceHandler events should not be triggered by quiet
references, null values,
or by references testing inside #if / #elseif. Thanks to Renato Steiner
Modified:
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/Template.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/Template.java?rev=1752784&r1=1752783&r2=1752784&view=diff
==============================================================================
---
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/Template.java
(original)
+++
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/Template.java
Fri Jul 15 07:13:01 2016
@@ -23,6 +23,7 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.List;
@@ -97,7 +98,7 @@ public class Template extends Resource
throws ResourceNotFoundException, ParseErrorException
{
data = null;
- InputStream is = null;
+ Reader reader = null;
errorCondition = null;
/*
@@ -105,7 +106,7 @@ public class Template extends Resource
*/
try
{
- is = resourceLoader.getResourceStream(name);
+ reader = resourceLoader.getResourceReader(name, getEncoding());
}
catch( ResourceNotFoundException rnfe )
{
@@ -122,7 +123,7 @@ public class Template extends Resource
* forgets to throw a proper exception
*/
- if (is != null)
+ if (reader != null)
{
/*
* now parse the template
@@ -130,19 +131,11 @@ public class Template extends Resource
try
{
- BufferedReader br = new BufferedReader( new InputStreamReader(
is, encoding ) );
+ BufferedReader br = new BufferedReader( reader );
data = rsvc.parse( br, name);
initDocument();
return true;
}
- catch( UnsupportedEncodingException uce )
- {
- String msg = "Template.process : Unsupported input encoding :
" + encoding
- + " for template " + name;
-
- errorCondition = new ParseErrorException( msg );
- throw errorCondition;
- }
catch ( ParseException pex )
{
/*
@@ -172,7 +165,7 @@ public class Template extends Resource
*/
try
{
- is.close();
+ reader.close();
}
catch(IOException e)
{
Modified:
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/io/UnicodeInputStream.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/io/UnicodeInputStream.java?rev=1752784&r1=1752783&r2=1752784&view=diff
==============================================================================
---
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/io/UnicodeInputStream.java
(original)
+++
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/io/UnicodeInputStream.java
Fri Jul 15 07:13:01 2016
@@ -56,14 +56,12 @@ public class UnicodeInputStream
/**
* BOM Marker for UTF 32, little endian. See
http://www.unicode.org/unicode/faq/utf_bom.html
*
- * TODO: Does Java actually support this?
*/
public static final UnicodeBOM UTF32LE_BOM = new UnicodeBOM("UTF-32LE",
new byte [] { (byte)0xff, (byte)0xfe, (byte)0x00, (byte)0x00 });
/**
* BOM Marker for UTF 32, big endian. See
http://www.unicode.org/unicode/faq/utf_bom.html
*
- * TODO: Does Java actually support this?
*/
public static final UnicodeBOM UTF32BE_BOM = new UnicodeBOM("UTF-32BE",
new byte [] { (byte)0x00, (byte)0x00, (byte)0xfe, (byte)0xff });
@@ -340,6 +338,17 @@ public class UnicodeInputStream
return inputStream.skip(n);
}
+
+ /**
+ * Helper function to compare encodings
+ */
+ public static boolean sameEncoding(String left, String right)
+ {
+ left = left.toUpperCase().replace("-", "");
+ right = right.toUpperCase().replace("-", "");
+ return left.equals(right);
+ }
+
/**
* Helper class to bundle encoding and BOM marker.
*
Modified:
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/ContentResource.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/ContentResource.java?rev=1752784&r1=1752783&r2=1752784&view=diff
==============================================================================
---
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/ContentResource.java
(original)
+++
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/ContentResource.java
Fri Jul 15 07:13:01 2016
@@ -62,9 +62,7 @@ public class ContentResource extends Res
{
StringWriter sw = new StringWriter();
- reader = new BufferedReader(
- new InputStreamReader(resourceLoader.getResourceStream(name),
- encoding));
+ reader = new BufferedReader(resourceLoader.getResourceReader(name,
encoding));
char buf[] = new char[1024];
int len = 0;
Modified:
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/ClasspathResourceLoader.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/ClasspathResourceLoader.java?rev=1752784&r1=1752783&r2=1752784&view=diff
==============================================================================
---
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/ClasspathResourceLoader.java
(original)
+++
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/ClasspathResourceLoader.java
Fri Jul 15 07:13:01 2016
@@ -19,7 +19,10 @@ package org.apache.velocity.runtime.reso
* under the License.
*/
+import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
import org.apache.commons.collections.ExtendedProperties;
import org.apache.commons.lang3.StringUtils;
@@ -97,8 +100,9 @@ public class ClasspathResourceLoader ext
* @return InputStream containing the template
* @throws ResourceNotFoundException if template not found
* in classpath.
+ * @deprecated use {@link #getResourceReader(String, String)}
*/
- public InputStream getResourceStream( String name )
+ public @Deprecated InputStream getResourceStream( String name )
throws ResourceNotFoundException
{
InputStream result = null;
@@ -131,6 +135,64 @@ public class ClasspathResourceLoader ext
}
return result;
+ }
+
+ /**
+ * Get a Reader so that the Runtime can build a
+ * template with it.
+ *
+ * @param name name of template to get
+ * @param encoding asked encoding
+ * @return InputStream containing the template
+ * @throws ResourceNotFoundException if template not found
+ * in classpath.
+ * @since 2.0
+ */
+ public Reader getResourceReader( String name, String encoding )
+ throws ResourceNotFoundException
+ {
+ Reader result = null;
+
+ if (StringUtils.isEmpty(name))
+ {
+ throw new ResourceNotFoundException ("No template name provided");
+ }
+
+ /**
+ * look for resource in thread classloader first (e.g. WEB-INF\lib in
+ * a servlet container) then fall back to the system classloader.
+ */
+
+ InputStream rawStream = null;
+ try
+ {
+ rawStream = ClassUtils.getResourceAsStream( getClass(), name );
+ if (rawStream != null)
+ {
+ result = buildReader(rawStream, encoding);
+ }
+ }
+ catch( Exception fnfe )
+ {
+ if (rawStream != null)
+ {
+ try
+ {
+ rawStream.close();
+ }
+ catch (IOException ioe) {}
+ }
+ throw new ResourceNotFoundException("ClasspathResourceLoader
problem with template: " + name, fnfe );
+ }
+
+ if (result == null)
+ {
+ String msg = "ClasspathResourceLoader Error: cannot find resource
" + name;
+
+ throw new ResourceNotFoundException( msg );
+ }
+
+ return result;
}
/**
Modified:
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/DataSourceResourceLoader.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/DataSourceResourceLoader.java?rev=1752784&r1=1752783&r2=1752784&view=diff
==============================================================================
---
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/DataSourceResourceLoader.java
(original)
+++
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/DataSourceResourceLoader.java
Fri Jul 15 07:13:01 2016
@@ -20,7 +20,9 @@ package org.apache.velocity.runtime.reso
*/
import java.io.BufferedInputStream;
+import java.io.IOException;
import java.io.InputStream;
+import java.io.Reader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -209,8 +211,9 @@ public class DataSourceResourceLoader ex
* @param name name of template
* @return InputStream containing template
* @throws ResourceNotFoundException
+ * @deprecated Use {@link #getResourceReader(String,String)}
*/
- public synchronized InputStream getResourceStream(final String name)
+ public synchronized @Deprecated InputStream getResourceStream(final String
name)
throws ResourceNotFoundException
{
if (org.apache.commons.lang3.StringUtils.isEmpty(name))
@@ -262,6 +265,93 @@ public class DataSourceResourceLoader ex
log.error(msg, ne);
throw new ResourceNotFoundException(msg);
+ }
+ finally
+ {
+ closeResultSet(rs);
+ closeStatement(ps);
+ closeDbConnection(conn);
+ }
+ }
+
+ /**
+ * Get an InputStream so that the Runtime can build a
+ * template with it.
+ *
+ * @param name name of template
+ * @param encoding asked encoding
+ * @return InputStream containing template
+ * @throws ResourceNotFoundException
+ * @since 2.0
+ */
+ public synchronized Reader getResourceReader(final String name, String
encoding)
+ throws ResourceNotFoundException
+ {
+ if (org.apache.commons.lang3.StringUtils.isEmpty(name))
+ {
+ throw new ResourceNotFoundException("DataSourceResourceLoader:
Template name was empty or null");
+ }
+
+ Connection conn = null;
+ ResultSet rs = null;
+ PreparedStatement ps = null;
+ try
+ {
+ conn = openDbConnection();
+ ps = getStatement(conn, templateColumn, tableName, keyColumn,
name);
+ rs = ps.executeQuery();
+
+ if (rs.next())
+ {
+ InputStream rawStream = rs.getBinaryStream(templateColumn);
+ if (rawStream == null)
+ {
+ throw new
ResourceNotFoundException("DataSourceResourceLoader: "
+ + "template column for '"
+ + name + "' is null");
+ }
+ try
+ {
+ return buildReader(rawStream, encoding);
+ }
+ catch (Exception e)
+ {
+ if (rawStream != null)
+ {
+ try
+ {
+ rawStream.close();
+ }
+ catch(IOException ioe) {}
+ }
+ String msg = "Exception while loading Template column for
" + name;
+ log.error(msg, e);
+ throw new VelocityException(msg, e);
+ }
+ }
+ else
+ {
+ throw new ResourceNotFoundException("DataSourceResourceLoader:
"
+ + "could not find resource '"
+ + name + "'");
+
+ }
+ }
+ catch (SQLException sqle)
+ {
+ String msg = "DataSourceResourceLoader: database problem while
getting resource '"
+ + name + "': ";
+
+ log.error(msg, sqle);
+ throw new ResourceNotFoundException(msg);
+ }
+ catch (NamingException ne)
+ {
+ String msg = "DataSourceResourceLoader: database problem while
getting resource '"
+ + name + "': ";
+
+ log.error(msg, ne);
+ throw new ResourceNotFoundException(msg);
}
finally
{
Modified:
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/FileResourceLoader.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/FileResourceLoader.java?rev=1752784&r1=1752783&r2=1752784&view=diff
==============================================================================
---
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/FileResourceLoader.java
(original)
+++
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/FileResourceLoader.java
Fri Jul 15 07:13:01 2016
@@ -25,6 +25,7 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.io.Reader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -63,9 +64,6 @@ public class FileResourceLoader extends
*/
private Map templatePaths = Collections.synchronizedMap(new HashMap());
- /** Shall we inspect unicode files to see what encoding they contain?. */
- private boolean unicode = false;
-
/**
* @see
org.apache.velocity.runtime.resource.loader.ResourceLoader#init(org.apache.commons.collections.ExtendedProperties)
*/
@@ -78,15 +76,7 @@ public class FileResourceLoader extends
paths.addAll( configuration.getVector("path") );
- // unicode files may have a BOM marker at the start, but Java
- // has problems recognizing the UTF-8 bom. Enabling unicode will
- // recognize all unicode boms.
- unicode = configuration.getBoolean("unicode", false);
-
- if (log.isDebugEnabled())
- {
- log.debug("Do unicode file recognition: {}", unicode);
- }
+ // unicode files may have a BOM marker at the start,
if (log.isDebugEnabled())
{
@@ -110,9 +100,10 @@ public class FileResourceLoader extends
* @param templateName name of template to get
* @return InputStream containing the template
* @throws ResourceNotFoundException if template not found
+ * @deprecated Use {@link #getResourceReader(String,String)}
* in the file template path.
*/
- public InputStream getResourceStream(String templateName)
+ public @Deprecated InputStream getResourceStream(String templateName)
throws ResourceNotFoundException
{
/*
@@ -145,14 +136,18 @@ public class FileResourceLoader extends
for (int i = 0; i < size; i++)
{
String path = (String) paths.get(i);
- InputStream inputStream = null;
+ InputStream rawStream = null;
+ UnicodeInputStream inputStream = null;
try
{
- inputStream = findTemplate(path, template);
+ rawStream = findTemplate(path, template);
+ inputStream = new UnicodeInputStream(rawStream, true);
+
}
catch (IOException ioe)
{
+ closeQuiet(rawStream);
String msg = "Exception while loading Template " + template;
log.error(msg, ioe);
throw new VelocityException(msg, ioe);
@@ -179,6 +174,87 @@ public class FileResourceLoader extends
}
/**
+ * Get a Reader so that the Runtime can build a
+ * template with it.
+ *
+ * @param templateName name of template to get
+ * @return Reader containing the template
+ * @throws ResourceNotFoundException if template not found
+ * in the file template path.
+ * @since 2.0
+ */
+ public Reader getResourceReader(String templateName, String encoding)
+ throws ResourceNotFoundException
+ {
+ /*
+ * Make sure we have a valid templateName.
+ */
+ if (org.apache.commons.lang3.StringUtils.isEmpty(templateName))
+ {
+ /*
+ * If we don't get a properly formed templateName then
+ * there's not much we can do. So we'll forget about
+ * trying to search any more paths for the template.
+ */
+ throw new ResourceNotFoundException(
+ "Need to specify a file name or file path!");
+ }
+
+ String template = StringUtils.normalizePath(templateName);
+ if ( template == null || template.length() == 0 )
+ {
+ String msg = "File resource error : argument " + template +
+ " contains .. and may be trying to access " +
+ "content outside of template root. Rejected.";
+
+ log.error("FileResourceLoader : " + msg);
+
+ throw new ResourceNotFoundException ( msg );
+ }
+
+ int size = paths.size();
+ for (int i = 0; i < size; i++)
+ {
+ String path = (String) paths.get(i);
+ InputStream rawStream = null;
+ Reader reader = null;
+
+ try
+ {
+ rawStream = findTemplate(path, template);
+ if (rawStream != null)
+ {
+ reader = buildReader(rawStream, encoding);
+ }
+ }
+ catch (IOException ioe)
+ {
+ closeQuiet(rawStream);
+ String msg = "Exception while loading Template " + template;
+ log.error(msg, ioe);
+ throw new VelocityException(msg, ioe);
+ }
+ if (reader != null)
+ {
+ /*
+ * Store the path that this template came
+ * from so that we can check its modification
+ * time.
+ */
+ templatePaths.put(templateName, path);
+ return reader;
+ }
+ }
+
+ /*
+ * We have now searched all the paths for
+ * templates and we didn't find anything so
+ * throw an exception.
+ */
+ throw new ResourceNotFoundException("FileResourceLoader : cannot find
" + template);
+ }
+
+ /**
* Overrides superclass for better performance.
* @since 1.6
*/
@@ -227,7 +303,7 @@ public class FileResourceLoader extends
{
try
{
- File file = getFile(path,template);
+ File file = getFile(path, template);
if (file.canRead())
{
@@ -235,32 +311,7 @@ public class FileResourceLoader extends
try
{
fis = new FileInputStream(file.getAbsolutePath());
-
- if (unicode)
- {
- UnicodeInputStream uis = null;
-
- try
- {
- uis = new UnicodeInputStream(fis, true);
-
- if (log.isDebugEnabled())
- {
- log.debug("File Encoding for {} is: {}", file,
uis.getEncodingFromStream());
- }
-
- return new BufferedInputStream(uis);
- }
- catch(IOException e)
- {
- closeQuiet(uis);
- throw e;
- }
- }
- else
- {
- return new BufferedInputStream(fis);
- }
+ return fis;
}
catch (IOException e)
{
Modified:
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/JarResourceLoader.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/JarResourceLoader.java?rev=1752784&r1=1752783&r2=1752784&view=diff
==============================================================================
---
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/JarResourceLoader.java
(original)
+++
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/JarResourceLoader.java
Fri Jul 15 07:13:01 2016
@@ -19,13 +19,17 @@ package org.apache.velocity.runtime.reso
* under the License.
*/
+import java.io.IOException;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Map;
import java.util.HashMap;
+import org.apache.velocity.exception.VelocityException;
import org.apache.velocity.util.StringUtils;
import org.apache.velocity.runtime.resource.Resource;
import org.apache.velocity.exception.ResourceNotFoundException;
@@ -137,9 +141,9 @@ public class JarResourceLoader extends R
// Create a new JarHolder
JarHolder temp = new JarHolder( rsvc, path );
// Add it's entries to the entryCollection
- addEntries( temp.getEntries() );
+ addEntries(temp.getEntries());
// Add it to the Jar table
- jarfiles.put( temp.getUrlPath(), temp );
+ jarfiles.put(temp.getUrlPath(), temp);
}
/**
@@ -172,8 +176,9 @@ public class JarResourceLoader extends R
* @return InputStream containing the template
* @throws ResourceNotFoundException if template not found
* in the file template path.
+ * @deprecated Use {@link #getResourceReader(String, String)}
*/
- public InputStream getResourceStream( String source )
+ public @Deprecated InputStream getResourceStream( String source )
throws ResourceNotFoundException
{
InputStream results = null;
@@ -221,6 +226,81 @@ public class JarResourceLoader extends R
}
+ /**
+ * Get a Reader so that the Runtime can build a
+ * template with it.
+ *
+ * @param source name of template to get
+ * @param encoding asked encoding
+ * @return InputStream containing the template
+ * @throws ResourceNotFoundException if template not found
+ * in the file template path.
+ * @since 2.0
+ */
+ public Reader getResourceReader( String source, String encoding )
+ throws ResourceNotFoundException
+ {
+ Reader result = null;
+
+ if (org.apache.commons.lang3.StringUtils.isEmpty(source))
+ {
+ throw new ResourceNotFoundException("Need to have a resource!");
+ }
+
+ String normalizedPath = StringUtils.normalizePath( source );
+
+ if ( normalizedPath == null || normalizedPath.length() == 0 )
+ {
+ String msg = "JAR resource error : argument " + normalizedPath +
+ " contains .. and may be trying to access " +
+ "content outside of template root. Rejected.";
+
+ log.error( "JarResourceLoader : " + msg );
+
+ throw new ResourceNotFoundException ( msg );
+ }
+
+ /*
+ * if a / leads off, then just nip that :)
+ */
+ if ( normalizedPath.startsWith("/") )
+ {
+ normalizedPath = normalizedPath.substring(1);
+ }
+
+ if ( entryDirectory.containsKey( normalizedPath ) )
+ {
+ String jarurl = (String)entryDirectory.get( normalizedPath );
+
+ if ( jarfiles.containsKey( jarurl ) )
+ {
+ JarHolder holder = (JarHolder)jarfiles.get( jarurl );
+ InputStream rawStream = holder.getResource( normalizedPath );
+ try
+ {
+ return buildReader(rawStream, encoding);
+ }
+ catch (Exception e)
+ {
+ if (rawStream != null)
+ {
+ try
+ {
+ rawStream.close();
+ }
+ catch (IOException ioe) {}
+ }
+ String msg = "JAR resource error : Exception while loading
" + source;
+ log.error(msg, e);
+ throw new VelocityException(msg, e);
+ }
+ }
+ }
+
+ throw new ResourceNotFoundException( "JarResourceLoader Error: cannot
find resource " +
+ source );
+
+ }
// TODO: SHOULD BE DELEGATED TO THE JARHOLDER
Modified:
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/ResourceLoader.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/ResourceLoader.java?rev=1752784&r1=1752783&r2=1752784&view=diff
==============================================================================
---
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/ResourceLoader.java
(original)
+++
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/ResourceLoader.java
Fri Jul 15 07:13:01 2016
@@ -20,7 +20,13 @@ package org.apache.velocity.runtime.reso
*/
import java.io.InputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import org.apache.velocity.io.UnicodeInputStream;
+import org.apache.velocity.runtime.RuntimeConstants;
import org.slf4j.Logger;
import org.apache.velocity.runtime.RuntimeServices;
@@ -44,7 +50,7 @@ public abstract class ResourceLoader
* Does this loader want templates produced with it
* cached in the Runtime.
*/
- protected boolean isCachingOn = false;
+ protected boolean isCachingOn = false;
/**
* This property will be passed on to the templates
@@ -65,10 +71,11 @@ public abstract class ResourceLoader
* This initialization is used by all resource
* loaders and must be called to set up common
* properties shared by all resource loaders
+ *
* @param rs
* @param configuration
*/
- public void commonInit( RuntimeServices rs, ExtendedProperties
configuration)
+ public void commonInit(RuntimeServices rs, ExtendedProperties
configuration)
{
this.rsvc = rs;
this.log = rsvc.getLog();
@@ -88,7 +95,7 @@ public abstract class ResourceLoader
catch (Exception e)
{
isCachingOn = false;
- String msg = "Exception parsing cache setting:
"+configuration.getString("cache");
+ String msg = "Exception parsing cache setting: " +
configuration.getString("cache");
log.error(msg, e);
throw new VelocityException(msg, e);
}
@@ -99,7 +106,7 @@ public abstract class ResourceLoader
catch (Exception e)
{
modificationCheckInterval = 0;
- String msg = "Exception parsing modificationCheckInterval setting:
"+configuration.getString("modificationCheckInterval");
+ String msg = "Exception parsing modificationCheckInterval setting:
" + configuration.getString("modificationCheckInterval");
log.error(msg, e);
throw new VelocityException(msg, e);
}
@@ -123,23 +130,41 @@ public abstract class ResourceLoader
/**
* Initialize the template loader with a
* a resources class.
+ *
* @param configuration
*/
- public abstract void init( ExtendedProperties configuration);
+ public abstract void init(ExtendedProperties configuration);
/**
* Get the InputStream that the Runtime will parse
* to create a template.
+ *
* @param source
* @return The input stream for the requested resource.
* @throws ResourceNotFoundException
+ * @deprecated Use {@link #getResourceReader(String, String)}
*/
- public abstract InputStream getResourceStream( String source )
- throws ResourceNotFoundException;
+ public
+ @Deprecated
+ abstract InputStream getResourceStream(String source)
+ throws ResourceNotFoundException;
+
+ /**
+ * Get the Reader that the Runtime will parse
+ * to create a template.
+ *
+ * @param source
+ * @return The reader for the requested resource.
+ * @throws ResourceNotFoundException
+ * @since 2.0
+ */
+ public abstract Reader getResourceReader(String source, String encoding)
+ throws ResourceNotFoundException;
/**
* Given a template, check to see if the source of InputStream
* has been modified.
+ *
* @param resource
* @return True if the resource has been modified.
*/
@@ -150,6 +175,7 @@ public abstract class ResourceLoader
* that was used to create the template. We need the template
* here because we have to extract the name of the template
* in order to locate the InputStream source.
+ *
* @param resource
* @return Time in millis when the resource has been modified.
*/
@@ -157,6 +183,7 @@ public abstract class ResourceLoader
/**
* Return the class name of this resource Loader
+ *
* @return Class name of the resource loader.
*/
public String getClassName()
@@ -169,6 +196,7 @@ public abstract class ResourceLoader
* would like the Runtime to cache templates that
* have been created with InputStreams provided
* by this loader.
+ *
* @param value
*/
public void setCachingOn(boolean value)
@@ -181,6 +209,7 @@ public abstract class ResourceLoader
* template loader wants the Runtime to cache
* templates created with InputStreams provided
* by this loader.
+ *
* @return True if this resource loader caches.
*/
public boolean isCachingOn()
@@ -191,6 +220,7 @@ public abstract class ResourceLoader
/**
* Set the interval at which the InputStream source
* should be checked for modifications.
+ *
* @param modificationCheckInterval
*/
public void setModificationCheckInterval(long modificationCheckInterval)
@@ -201,6 +231,7 @@ public abstract class ResourceLoader
/**
* Get the interval at which the InputStream source
* should be checked for modifications.
+ *
* @return The modification check interval.
*/
public long getModificationCheckInterval()
@@ -211,7 +242,7 @@ public abstract class ResourceLoader
/**
* Check whether any given resource exists. This is not really
* a very efficient test and it can and should be overridden in the
- * subclasses extending ResourceLoader.
+ * subclasses extending ResourceLoader.
*
* @param resourceName The name of a resource.
* @return true if a resource exists and can be accessed.
@@ -219,26 +250,26 @@ public abstract class ResourceLoader
*/
public boolean resourceExists(final String resourceName)
{
- InputStream is = null;
+ Reader reader = null;
try
{
- is = getResourceStream(resourceName);
+ reader = getResourceReader(resourceName, null);
}
catch (ResourceNotFoundException e)
{
if (log.isDebugEnabled())
{
log.debug("Could not load resource '{}' from ResourceLoader
{}",
- resourceName, this.getClass().getName(), e);
+ resourceName, this.getClass().getName(), e);
}
}
finally
{
try
{
- if (is != null)
+ if (reader != null)
{
- is.close();
+ reader.close();
}
}
catch (Exception e)
@@ -246,13 +277,64 @@ public abstract class ResourceLoader
if (log.isErrorEnabled())
{
String msg = "While closing InputStream for resource '" +
- resourceName + "' from ResourceLoader " +
- this.getClass().getName();
+ resourceName + "' from ResourceLoader " +
+ this.getClass().getName();
log.error(msg, e);
throw new VelocityException(msg, e);
}
}
}
- return (is != null);
+ return (reader != null);
+ }
+
+ /**
+ * Builds a Reader given a raw InputStream and an encoding. Should be use
+ * by every subclass that whishes to accept optional BOMs in resources.
+ * This method does *not* close the given input stream whenever an
exception is thrown.
+ *
+ * @param rawStream The raw input stream.
+ * @param encoding The asked encoding.
+ * @return found reader
+ * @throws IOException, UnsupportedEncodingException
+ * @since 2.0
+ */
+ protected Reader buildReader(InputStream rawStream, String encoding)
+ throws IOException, UnsupportedEncodingException
+ {
+ UnicodeInputStream inputStream = new UnicodeInputStream(rawStream);
+ /*
+ * Check encoding
+ */
+ String foundEncoding = inputStream.getEncodingFromStream();
+ if (foundEncoding != null && encoding != null &&
!UnicodeInputStream.sameEncoding(foundEncoding, encoding))
+ {
+ log.warn("Found BOM encoding '{}' differs from asked encoding:
'{}' - using BOM encoding to read resource.", foundEncoding, encoding);
+ encoding = foundEncoding;
+ }
+ if (encoding == null)
+ {
+ if (foundEncoding == null)
+ {
+ encoding = rsvc.getString(RuntimeConstants.INPUT_ENCODING);
+ } else
+ {
+ encoding = foundEncoding;
+ }
+ }
+
+ try
+ {
+ return new InputStreamReader(inputStream, encoding);
+ }
+ catch (UnsupportedEncodingException uee)
+ {
+ try
+ {
+ inputStream.close();
+ }
+ catch (IOException ioe) {}
+ throw uee;
+ }
}
+
}
Modified:
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/StringResourceLoader.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/StringResourceLoader.java?rev=1752784&r1=1752783&r2=1752784&view=diff
==============================================================================
---
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/StringResourceLoader.java
(original)
+++
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/StringResourceLoader.java
Fri Jul 15 07:13:01 2016
@@ -24,7 +24,11 @@ import java.util.HashMap;
import java.util.Map;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.Reader;
import java.io.UnsupportedEncodingException;
+
import org.apache.commons.collections.ExtendedProperties;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.VelocityException;
@@ -344,8 +348,9 @@ public class StringResourceLoader extend
* @return InputStream containing the template.
* @throws ResourceNotFoundException Ff template not found
* in the RepositoryFactory.
+ * @deprecated use {@link #getResourceReader(String,String)}
*/
- public InputStream getResourceStream(final String name)
+ public @Deprecated InputStream getResourceStream(final String name)
throws ResourceNotFoundException
{
if (StringUtils.isEmpty(name))
@@ -373,6 +378,68 @@ public class StringResourceLoader extend
}
}
+ /**
+ * Get a reader so that the Runtime can build a
+ * template with it.
+ *
+ * @param name name of template to get.
+ * @param encoding asked encoding
+ * @return Reader containing the template.
+ * @throws ResourceNotFoundException Ff template not found
+ * in the RepositoryFactory.
+ * @since 2.0
+ */
+ public Reader getResourceReader(String name, String encoding)
+ throws ResourceNotFoundException
+ {
+ if (StringUtils.isEmpty(name))
+ {
+ throw new ResourceNotFoundException("No template name provided");
+ }
+
+ StringResource resource = this.repository.getStringResource(name);
+
+ if(resource == null)
+ {
+ throw new ResourceNotFoundException("Could not locate resource '"
+ name + "'");
+ }
+
+ byte [] byteArray = null;
+ InputStream rawStream = null;
+
+ try
+ {
+ byteArray = resource.getBody().getBytes(resource.getEncoding());
+ rawStream = new ByteArrayInputStream(byteArray);
+ return new InputStreamReader(rawStream, resource.getEncoding());
+ }
+ catch(UnsupportedEncodingException ue)
+ {
+ if (rawStream != null)
+ {
+ try
+ {
+ rawStream.close();
+ }
+ catch (IOException ioe) {}
+ }
+ throw new VelocityException("Could not convert String using
encoding " + resource.getEncoding(), ue);
+ }
+ catch(IOException ioe)
+ {
+ if (rawStream != null)
+ {
+ try
+ {
+ rawStream.close();
+ }
+ catch (IOException e) {}
+ }
+ throw new VelocityException("Exception while loading string
resource", ioe);
+
+ }
+ }
+
/**
* @see
org.apache.velocity.runtime.resource.loader.ResourceLoader#isSourceModified(org.apache.velocity.runtime.resource.Resource)
*/
Modified:
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/URLResourceLoader.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/URLResourceLoader.java?rev=1752784&r1=1752783&r2=1752784&view=diff
==============================================================================
---
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/URLResourceLoader.java
(original)
+++
velocity/engine/trunk/velocity-engine-core/src/main/java/org/apache/velocity/runtime/resource/loader/URLResourceLoader.java
Fri Jul 15 07:13:01 2016
@@ -21,6 +21,8 @@ package org.apache.velocity.runtime.reso
import java.io.InputStream;
import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLConnection;
@@ -94,8 +96,9 @@ public class URLResourceLoader extends R
* @return InputStream containing the template
* @throws ResourceNotFoundException if template not found
* in the file template path.
+ * @deprecated Use {@link #findTemplateReader(source)}
*/
- public synchronized InputStream getResourceStream(String name)
+ public synchronized @Deprecated InputStream getResourceStream(String name)
throws ResourceNotFoundException
{
if (StringUtils.isEmpty(name))
@@ -155,6 +158,86 @@ public class URLResourceLoader extends R
}
/**
+ * Get a Reader so that the Runtime can build a
+ * template with it.
+ *
+ * @param name name of template to fetch bytestream of
+ * @param encoding asked encoding
+ * @return InputStream containing the template
+ * @throws ResourceNotFoundException if template not found
+ * in the file template path.
+ * @since 2.0
+ */
+ public synchronized Reader getResourceReader(String name, String encoding)
+ throws ResourceNotFoundException
+ {
+ if (StringUtils.isEmpty(name))
+ {
+ throw new ResourceNotFoundException("URLResourceLoader : No
template name provided");
+ }
+
+ Reader reader = null;
+ Exception exception = null;
+ for(int i=0; i < roots.length; i++)
+ {
+ InputStream rawStream = null;
+ try
+ {
+ URL u = new URL(roots[i] + name);
+ URLConnection conn = u.openConnection();
+ tryToSetTimeout(conn);
+ rawStream = conn.getInputStream();
+ reader = buildReader(rawStream, encoding);
+
+ if (reader != null)
+ {
+ if (log.isDebugEnabled()) log.debug("URLResourceLoader:
Found '{}' at '{}'", name, roots[i]);
+
+ // save this root for later re-use
+ templateRoots.put(name, roots[i]);
+ break;
+ }
+ }
+ catch(IOException ioe)
+ {
+ if (rawStream != null)
+ {
+ try
+ {
+ rawStream.close();
+ }
+ catch (IOException e) {}
+ }
+ if (log.isDebugEnabled()) log.debug("URLResourceLoader:
Exception when looking for '{}' at '{}'", name, roots[i], ioe);
+
+ // only save the first one for later throwing
+ if (exception == null)
+ {
+ exception = ioe;
+ }
+ }
+ }
+
+ // if we never found the template
+ if (reader == null)
+ {
+ String msg;
+ if (exception == null)
+ {
+ msg = "URLResourceLoader : Resource '" + name + "' not found.";
+ }
+ else
+ {
+ msg = exception.getMessage();
+ }
+ // convert to a general Velocity ResourceNotFoundException
+ throw new ResourceNotFoundException(msg);
+ }
+
+ return reader;
+ }
+
+ /**
* Checks to see if a resource has been deleted, moved or modified.
*
* @param resource Resource The resource to check for modification
Modified:
velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/misc/ExceptionGeneratingResourceLoader.java
URL:
http://svn.apache.org/viewvc/velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/misc/ExceptionGeneratingResourceLoader.java?rev=1752784&r1=1752783&r2=1752784&view=diff
==============================================================================
---
velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/misc/ExceptionGeneratingResourceLoader.java
(original)
+++
velocity/engine/trunk/velocity-engine-core/src/test/java/org/apache/velocity/test/misc/ExceptionGeneratingResourceLoader.java
Fri Jul 15 07:13:01 2016
@@ -20,6 +20,7 @@ package org.apache.velocity.test.misc;
*/
import java.io.InputStream;
+import java.io.Reader;
import org.apache.commons.collections.ExtendedProperties;
import org.apache.velocity.exception.ResourceNotFoundException;
@@ -40,7 +41,12 @@ public class ExceptionGeneratingResource
{
}
- public InputStream getResourceStream(String source) throws
ResourceNotFoundException
+ public @Deprecated InputStream getResourceStream(String source) throws
ResourceNotFoundException
+ {
+ throw new RuntimeException("exception");
+ }
+
+ public Reader getResourceReader(String source, String encoding) throws
ResourceNotFoundException
{
throw new RuntimeException("exception");
}