mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V2.2 to HEAD
11065: Fix for ETWOTWO-504: WCM Tutorial rendition shows corrupted characters only during preview git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@11231 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -46,7 +46,7 @@ import org.xml.sax.SAXException;
|
|||||||
* of both the alfresco webapp and the virtualization server.
|
* of both the alfresco webapp and the virtualization server.
|
||||||
*
|
*
|
||||||
* @author Ariel Backenroth
|
* @author Ariel Backenroth
|
||||||
* @author Arseny Kovalchuk (Fix of the bug reported in https://issues.alfresco.com/jira/browse/ETWOONE-241)
|
* @author Arseny Kovalchuk (Fix for the ETWOONE-241 and ETWOTWO-504 issues)
|
||||||
*/
|
*/
|
||||||
public class FormDataFunctions
|
public class FormDataFunctions
|
||||||
{
|
{
|
||||||
@@ -167,4 +167,92 @@ public class FormDataFunctions
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encodes invalid HTML characters. (Fix for ETWOTWO-504 issue)
|
||||||
|
* This code was adopted from WebDAVHelper.encodeHTML() method with some restrictions.
|
||||||
|
* @see press-relese.xsl for pattern.
|
||||||
|
*
|
||||||
|
* @param text to encode
|
||||||
|
* @return encoded text
|
||||||
|
* @throws IOException
|
||||||
|
* @throws SAXException
|
||||||
|
*/
|
||||||
|
public String encodeQuotes(String text) throws IOException, SAXException
|
||||||
|
{
|
||||||
|
if (text == null)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sb = null; //create on demand
|
||||||
|
String enc;
|
||||||
|
char c;
|
||||||
|
for (int i = 0; i < text.length(); i++)
|
||||||
|
{
|
||||||
|
enc = null;
|
||||||
|
c = text.charAt(i);
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '"': enc = """; break; //"
|
||||||
|
//case '&': enc = "&"; break; //&
|
||||||
|
//case '<': enc = "<"; break; //<
|
||||||
|
//case '>': enc = ">"; break; //>
|
||||||
|
|
||||||
|
//german umlauts
|
||||||
|
case '\u00E4' : enc = "ä"; break;
|
||||||
|
case '\u00C4' : enc = "Ä"; break;
|
||||||
|
case '\u00F6' : enc = "ö"; break;
|
||||||
|
case '\u00D6' : enc = "Ö"; break;
|
||||||
|
case '\u00FC' : enc = "ü"; break;
|
||||||
|
case '\u00DC' : enc = "Ü"; break;
|
||||||
|
case '\u00DF' : enc = "ß"; break;
|
||||||
|
|
||||||
|
//misc
|
||||||
|
//case 0x80: enc = "€"; break; sometimes euro symbol is ascii 128, should we suport it?
|
||||||
|
case '\u20AC': enc = "€"; break;
|
||||||
|
case '\u00AB': enc = "«"; break;
|
||||||
|
case '\u00BB': enc = "»"; break;
|
||||||
|
case '\u00A0': enc = " "; break;
|
||||||
|
|
||||||
|
//case '': enc = "&trade"; break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (((int)c) >= 0x80)
|
||||||
|
{
|
||||||
|
//encode all non basic latin characters
|
||||||
|
enc = "&#" + ((int)c) + ";";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enc != null)
|
||||||
|
{
|
||||||
|
if (sb == null)
|
||||||
|
{
|
||||||
|
String soFar = text.substring(0, i);
|
||||||
|
sb = new StringBuilder(i + 8);
|
||||||
|
sb.append(soFar);
|
||||||
|
}
|
||||||
|
sb.append(enc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (sb != null)
|
||||||
|
{
|
||||||
|
sb.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sb == null)
|
||||||
|
{
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -263,7 +263,9 @@ public class RenderingEngineTemplateImpl
|
|||||||
result = AVMUtil.buildPath(parentAVMPath,
|
result = AVMUtil.buildPath(parentAVMPath,
|
||||||
result,
|
result,
|
||||||
AVMUtil.PathRelation.SANDBOX_RELATIVE);
|
AVMUtil.PathRelation.SANDBOX_RELATIVE);
|
||||||
|
if (LOGGER.isDebugEnabled())
|
||||||
LOGGER.debug("processed pattern " + outputPathPattern + " as " + result);
|
LOGGER.debug("processed pattern " + outputPathPattern + " as " + result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,6 +290,7 @@ public class RenderingEngineTemplateImpl
|
|||||||
AVMUtil.makeAllDirectories(parentAVMPath);
|
AVMUtil.makeAllDirectories(parentAVMPath);
|
||||||
avmService.createFile(parentAVMPath,
|
avmService.createFile(parentAVMPath,
|
||||||
AVMNodeConverter.SplitBase(renditionAvmPath)[1]);
|
AVMNodeConverter.SplitBase(renditionAvmPath)[1]);
|
||||||
|
|
||||||
if (LOGGER.isDebugEnabled())
|
if (LOGGER.isDebugEnabled())
|
||||||
LOGGER.debug("Created file node for file: " + renditionAvmPath);
|
LOGGER.debug("Created file node for file: " + renditionAvmPath);
|
||||||
|
|
||||||
@@ -391,9 +394,12 @@ public class RenderingEngineTemplateImpl
|
|||||||
RenderingEngineTemplateImpl.this.getServiceRegistry().getNodeService();
|
RenderingEngineTemplateImpl.this.getServiceRegistry().getNodeService();
|
||||||
final NodeRef parentNodeRef =
|
final NodeRef parentNodeRef =
|
||||||
nodeService.getPrimaryParent(RenderingEngineTemplateImpl.this.getNodeRef()).getParentRef();
|
nodeService.getPrimaryParent(RenderingEngineTemplateImpl.this.getNodeRef()).getParentRef();
|
||||||
|
if (LOGGER.isDebugEnabled())
|
||||||
|
{
|
||||||
LOGGER.debug("request to resolve resource " + name +
|
LOGGER.debug("request to resolve resource " + name +
|
||||||
" webapp url is " + webappUrl +
|
" webapp url is " + webappUrl +
|
||||||
" and data dictionary workspace is " + parentNodeRef);
|
" and data dictionary workspace is " + parentNodeRef);
|
||||||
|
}
|
||||||
final NodeRef result = nodeService.getChildByName(parentNodeRef, ContentModel.ASSOC_CONTAINS, name);
|
final NodeRef result = nodeService.getChildByName(parentNodeRef, ContentModel.ASSOC_CONTAINS, name);
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
@@ -401,7 +407,9 @@ public class RenderingEngineTemplateImpl
|
|||||||
RenderingEngineTemplateImpl.this.getServiceRegistry().getContentService();
|
RenderingEngineTemplateImpl.this.getServiceRegistry().getContentService();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (LOGGER.isDebugEnabled())
|
||||||
LOGGER.debug("found " + name + " in data dictonary: " + result);
|
LOGGER.debug("found " + name + " in data dictonary: " + result);
|
||||||
|
|
||||||
return contentService.getReader(result, ContentModel.PROP_CONTENT).getContentInputStream();
|
return contentService.getReader(result, ContentModel.PROP_CONTENT).getContentInputStream();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -419,13 +427,17 @@ public class RenderingEngineTemplateImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
final URI uri = new URI(webappUrl + '/' + StringUtils.join(path, '/'));
|
final URI uri = new URI(webappUrl + '/' + StringUtils.join(path, '/'));
|
||||||
|
|
||||||
if (LOGGER.isDebugEnabled())
|
if (LOGGER.isDebugEnabled())
|
||||||
LOGGER.debug("loading " + uri);
|
LOGGER.debug("loading " + uri);
|
||||||
|
|
||||||
return uri.toURL().openStream();
|
return uri.toURL().openStream();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
if (LOGGER.isDebugEnabled())
|
||||||
LOGGER.debug(e);
|
LOGGER.debug(e);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -450,6 +462,38 @@ public class RenderingEngineTemplateImpl
|
|||||||
|
|
||||||
// add methods
|
// add methods
|
||||||
final FormDataFunctions fdf = this.getFormDataFunctions();
|
final FormDataFunctions fdf = this.getFormDataFunctions();
|
||||||
|
|
||||||
|
model.put(QName.createQName(NamespaceService.ALFRESCO_PREFIX,
|
||||||
|
"encodeQuotes",
|
||||||
|
namespacePrefixResolver),
|
||||||
|
new RenderingEngine.TemplateProcessorMethod()
|
||||||
|
{
|
||||||
|
public Object exec(final Object[] arguments)
|
||||||
|
throws IOException,
|
||||||
|
SAXException
|
||||||
|
{
|
||||||
|
if (arguments.length != 1)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("expected 1 argument to encodeQuotes. got " +
|
||||||
|
arguments.length);
|
||||||
|
|
||||||
|
}
|
||||||
|
if (! (arguments[0] instanceof String))
|
||||||
|
{
|
||||||
|
throw new ClassCastException("expected arguments[0] to be a " + String.class.getName() +
|
||||||
|
". got a " + arguments[0].getClass().getName() + ".");
|
||||||
|
}
|
||||||
|
String text = (String)arguments[0];
|
||||||
|
|
||||||
|
if (LOGGER.isDebugEnabled())
|
||||||
|
LOGGER.debug("tpm_encodeQuotes('" + text + "'), parentPath = " + parentPath);
|
||||||
|
|
||||||
|
final String result = fdf.encodeQuotes(text);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
model.put(QName.createQName(NamespaceService.ALFRESCO_PREFIX,
|
model.put(QName.createQName(NamespaceService.ALFRESCO_PREFIX,
|
||||||
"parseXMLDocument",
|
"parseXMLDocument",
|
||||||
namespacePrefixResolver),
|
namespacePrefixResolver),
|
||||||
@@ -474,8 +518,10 @@ public class RenderingEngineTemplateImpl
|
|||||||
path = AVMUtil.buildPath(parentPath,
|
path = AVMUtil.buildPath(parentPath,
|
||||||
path,
|
path,
|
||||||
AVMUtil.PathRelation.WEBAPP_RELATIVE);
|
AVMUtil.PathRelation.WEBAPP_RELATIVE);
|
||||||
LOGGER.debug("tpm_parseXMLDocument('" + path +
|
|
||||||
"'), parentPath = " + parentPath);
|
if (LOGGER.isDebugEnabled())
|
||||||
|
LOGGER.debug("tpm_parseXMLDocument('" + path + "'), parentPath = " + parentPath);
|
||||||
|
|
||||||
final Document d = fdf.parseXMLDocument(path);
|
final Document d = fdf.parseXMLDocument(path);
|
||||||
return d != null ? d.getDocumentElement() : null;
|
return d != null ? d.getDocumentElement() : null;
|
||||||
}
|
}
|
||||||
@@ -511,9 +557,14 @@ public class RenderingEngineTemplateImpl
|
|||||||
path,
|
path,
|
||||||
AVMUtil.PathRelation.WEBAPP_RELATIVE);
|
AVMUtil.PathRelation.WEBAPP_RELATIVE);
|
||||||
final String formName = (String)arguments[0];
|
final String formName = (String)arguments[0];
|
||||||
|
|
||||||
|
if (LOGGER.isDebugEnabled())
|
||||||
LOGGER.debug("tpm_parseXMLDocuments('" + formName + "','" + path +
|
LOGGER.debug("tpm_parseXMLDocuments('" + formName + "','" + path +
|
||||||
"'), parentPath = " + parentPath);
|
"'), parentPath = " + parentPath);
|
||||||
|
|
||||||
final Map<String, Document> resultMap = fdf.parseXMLDocuments(formName, path);
|
final Map<String, Document> resultMap = fdf.parseXMLDocuments(formName, path);
|
||||||
|
|
||||||
|
if (LOGGER.isDebugEnabled())
|
||||||
LOGGER.debug("received " + resultMap.size() +
|
LOGGER.debug("received " + resultMap.size() +
|
||||||
" documents in " + path +
|
" documents in " + path +
|
||||||
" with form name " + formName);
|
" with form name " + formName);
|
||||||
@@ -564,7 +615,10 @@ public class RenderingEngineTemplateImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
final String path = (String)arguments[0];
|
final String path = (String)arguments[0];
|
||||||
|
|
||||||
|
if (LOGGER.isDebugEnabled())
|
||||||
LOGGER.debug("tpm_getAVMPAth('" + path + "'), parentPath = " + parentPath);
|
LOGGER.debug("tpm_getAVMPAth('" + path + "'), parentPath = " + parentPath);
|
||||||
|
|
||||||
return AVMUtil.buildPath(parentPath,
|
return AVMUtil.buildPath(parentPath,
|
||||||
path,
|
path,
|
||||||
AVMUtil.PathRelation.WEBAPP_RELATIVE);
|
AVMUtil.PathRelation.WEBAPP_RELATIVE);
|
||||||
|
@@ -59,7 +59,8 @@ Produces an html rendition of a press release
|
|||||||
<p></p>
|
<p></p>
|
||||||
<xsl:for-each select="/pr:press_release/pr:body">
|
<xsl:for-each select="/pr:press_release/pr:body">
|
||||||
<p>
|
<p>
|
||||||
<xsl:if test="position()=1"><xsl:value-of select="normalize-space(/pr:press_release/pr:location)"/>—<xsl:value-of select="normalize-space(/pr:press_release/pr:launch_date)"/>—</xsl:if><xsl:value-of select="normalize-space(.)" disable-output-escaping="yes"/>
|
<xsl:variable name="body-text"><xsl:value-of select="normalize-space(.)" disable-output-escaping="yes"/></xsl:variable>
|
||||||
|
<xsl:if test="position()=1"><xsl:value-of select="normalize-space(/pr:press_release/pr:location)"/>—<xsl:value-of select="normalize-space(/pr:press_release/pr:launch_date)"/>—</xsl:if><xsl:value-of select="alf:encodeQuotes($body-text)" disable-output-escaping="yes"/>
|
||||||
</p>
|
</p>
|
||||||
</xsl:for-each>
|
</xsl:for-each>
|
||||||
<xsl:for-each select="/pr:press_release/pr:include_company_footer">
|
<xsl:for-each select="/pr:press_release/pr:include_company_footer">
|
||||||
@@ -68,7 +69,8 @@ Produces an html rendition of a press release
|
|||||||
<xsl:variable name="cf" select="alf:parseXMLDocument($cf-id)"/>
|
<xsl:variable name="cf" select="alf:parseXMLDocument($cf-id)"/>
|
||||||
<h2>About <xsl:value-of select="$cf/pr:name"/></h2>
|
<h2>About <xsl:value-of select="$cf/pr:name"/></h2>
|
||||||
<xsl:for-each select="$cf/pr:body">
|
<xsl:for-each select="$cf/pr:body">
|
||||||
<p><xsl:value-of select="." disable-output-escaping="yes"/></p>
|
<xsl:variable name="bd-text"><xsl:value-of select="normalize-space(.)" disable-output-escaping="yes"/></xsl:variable>
|
||||||
|
<p><xsl:value-of select="alf:encodeQuotes($bd-text)" disable-output-escaping="yes"/></p>
|
||||||
</xsl:for-each>
|
</xsl:for-each>
|
||||||
</xsl:for-each>
|
</xsl:for-each>
|
||||||
<xsl:if test="/pr:press_release/pr:include_media_contacts='true'">
|
<xsl:if test="/pr:press_release/pr:include_media_contacts='true'">
|
||||||
|
Reference in New Issue
Block a user