Merged V2.2 to HEAD

10640: Fixed ETWOTWO-688: Node Path.Element strings are returned with numerical ordering suffix
   10641: Fix for ETWOTWO-640: Cannot login through FTP
   10665: Fix to generate legal Faces component IDs (in turn output as HTML element IDs). Fixes ETWOTWO-687 and ALFCOM-1756.
   10666: Fix for ETWOTWO-539.
   10675: Merged V2.1 to V2.2
     10649: Fix for ETWOONE-98 and extra error/debug logging. ... other linkvalidation enable/disable changes
   10711: Merged V2.1 to V2.2
      10615: Fix to keep org.alfresco.repo.workflow.jbpm.* in the session


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@10712 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2008-09-04 01:54:39 +00:00
parent c257497885
commit 78e1f21f14
2 changed files with 94 additions and 33 deletions

View File

@@ -53,15 +53,25 @@ import org.apache.commons.logging.LogFactory;
public final class FacesHelper public final class FacesHelper
{ {
private static Log logger = LogFactory.getLog(FacesHelper.class); private static Log logger = LogFactory.getLog(FacesHelper.class);
private static Pattern FACES_ID_PATTERN = Pattern.compile("[^a-z^A-Z^_]?[^a-z^A-Z^0-9^_^-]");
/**
* Mask for hex encoding
*/
private static final int MASK = (1 << 4) - 1;
/**
* Digits used for hex string encoding
*/
private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
/** /**
* Private constructor * Private constructor
*/ */
private FacesHelper() private FacesHelper()
{ {
} }
/** /**
* Return a valid FacesContext for the specific context, request and response. * Return a valid FacesContext for the specific context, request and response.
* The FacesContext can be constructor for Servlet use. * The FacesContext can be constructor for Servlet use.
@@ -76,7 +86,7 @@ public final class FacesHelper
{ {
return getFacesContextImpl(request, response, context, null); return getFacesContextImpl(request, response, context, null);
} }
/** /**
* Return a valid FacesContext for the specific context, request and response. * Return a valid FacesContext for the specific context, request and response.
* The FacesContext can be constructor for Servlet use. * The FacesContext can be constructor for Servlet use.
@@ -106,7 +116,7 @@ public final class FacesHelper
{ {
return getFacesContextImpl(request, response, context, null); return getFacesContextImpl(request, response, context, null);
} }
/** /**
* Return a valid FacesContext for the specific context, request and response. * Return a valid FacesContext for the specific context, request and response.
* The FacesContext can be constructor for Servlet and Portlet use. * The FacesContext can be constructor for Servlet and Portlet use.
@@ -122,13 +132,13 @@ public final class FacesHelper
FacesContextFactory contextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY); FacesContextFactory contextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY); LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE); Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
// Doesn't set this instance as the current instance of FacesContext.getCurrentInstance // Doesn't set this instance as the current instance of FacesContext.getCurrentInstance
FacesContext facesContext = contextFactory.getFacesContext(context, request, response, lifecycle); FacesContext facesContext = contextFactory.getFacesContext(context, request, response, lifecycle);
// Set using our inner class // Set using our inner class
InnerFacesContext.setFacesContextAsCurrent(facesContext); InnerFacesContext.setFacesContextAsCurrent(facesContext);
// set a new viewRoot, otherwise context.getViewRoot returns null // set a new viewRoot, otherwise context.getViewRoot returns null
if (viewRoot == null) if (viewRoot == null)
{ {
@@ -136,10 +146,10 @@ public final class FacesHelper
} }
UIViewRoot view = facesContext.getApplication().getViewHandler().createView(facesContext, viewRoot); UIViewRoot view = facesContext.getApplication().getViewHandler().createView(facesContext, viewRoot);
facesContext.setViewRoot(view); facesContext.setViewRoot(view);
return facesContext; return facesContext;
} }
/** /**
* Return a JSF managed bean reference. * Return a JSF managed bean reference.
* *
@@ -153,7 +163,7 @@ public final class FacesHelper
ValueBinding vb = fc.getApplication().createValueBinding("#{" + name + "}"); ValueBinding vb = fc.getApplication().createValueBinding("#{" + name + "}");
return vb.getValue(fc); return vb.getValue(fc);
} }
/** /**
* Sets up the id for the given component, if the id is null a unique one * Sets up the id for the given component, if the id is null a unique one
* is generated using the standard Faces algorithm. If an id is present it * is generated using the standard Faces algorithm. If an id is present it
@@ -174,27 +184,23 @@ public final class FacesHelper
// make sure we do not have illegal characters in the id // make sure we do not have illegal characters in the id
id = makeLegalId(id); id = makeLegalId(id);
} }
component.setId(id); component.setId(id);
} }
/** /**
* Makes the given id a legal JSF component id by replacing illegal * Makes the given id a legal JSF component id by replacing illegal characters
* characters with underscores. * with ISO9075 encoding - which itself a subset of valid HTML ID characters.
* *
* @param id The id to make legal * @param id The id to make legal
* @return The legalised id *
* @return the legalised id
*/ */
public static String makeLegalId(String id) public static String makeLegalId(String id)
{ {
if (id != null) return (id != null ? validFacesId(id) : null);
{
id = FACES_ID_PATTERN.matcher(id).replaceAll("_");
}
return id;
} }
/** /**
* Retrieves the named component generator implementation. * Retrieves the named component generator implementation.
* If the named generator is not found the TextFieldGenerator is looked up * If the named generator is not found the TextFieldGenerator is looked up
@@ -207,37 +213,37 @@ public final class FacesHelper
public static IComponentGenerator getComponentGenerator(FacesContext context, String generatorName) public static IComponentGenerator getComponentGenerator(FacesContext context, String generatorName)
{ {
IComponentGenerator generator = lookupComponentGenerator(context, generatorName); IComponentGenerator generator = lookupComponentGenerator(context, generatorName);
if (generator == null) if (generator == null)
{ {
// create a text field if we can't find a component generator (a warning should have already been // create a text field if we can't find a component generator (a warning should have already been
// displayed on the appserver console) // displayed on the appserver console)
logger.warn("Attempting to find default component generator '" + RepoConstants.GENERATOR_TEXT_FIELD + "'"); logger.warn("Attempting to find default component generator '" + RepoConstants.GENERATOR_TEXT_FIELD + "'");
generator = lookupComponentGenerator(context, RepoConstants.GENERATOR_TEXT_FIELD); generator = lookupComponentGenerator(context, RepoConstants.GENERATOR_TEXT_FIELD);
} }
// if we still don't have a component generator we should abort as vital configuration is missing // if we still don't have a component generator we should abort as vital configuration is missing
if (generator == null) if (generator == null)
{ {
throw new AlfrescoRuntimeException("Failed to find a component generator, please ensure the '" + throw new AlfrescoRuntimeException("Failed to find a component generator, please ensure the '" +
RepoConstants.GENERATOR_TEXT_FIELD + "' bean is present in your configuration"); RepoConstants.GENERATOR_TEXT_FIELD + "' bean is present in your configuration");
} }
return generator; return generator;
} }
private static IComponentGenerator lookupComponentGenerator(FacesContext context, String generatorName) private static IComponentGenerator lookupComponentGenerator(FacesContext context, String generatorName)
{ {
IComponentGenerator generator = null; IComponentGenerator generator = null;
Object obj = FacesHelper.getManagedBean(context, generatorName); Object obj = FacesHelper.getManagedBean(context, generatorName);
if (obj != null) if (obj != null)
{ {
if (obj instanceof IComponentGenerator) if (obj instanceof IComponentGenerator)
{ {
generator = (IComponentGenerator)obj; generator = (IComponentGenerator)obj;
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Found component generator for '" + generatorName + "': " + generator); logger.debug("Found component generator for '" + generatorName + "': " + generator);
} }
@@ -250,10 +256,10 @@ public final class FacesHelper
{ {
logger.warn("Failed to find component generator with name of '" + generatorName + "'"); logger.warn("Failed to find component generator with name of '" + generatorName + "'");
} }
return generator; return generator;
} }
/** /**
* We need an inner class to be able to call FacesContext.setCurrentInstance * We need an inner class to be able to call FacesContext.setCurrentInstance
* since it's a protected method * since it's a protected method
@@ -265,4 +271,59 @@ public final class FacesHelper
FacesContext.setCurrentInstance(facesContext); FacesContext.setCurrentInstance(facesContext);
} }
} }
/**
* Helper to ensure only valid and acceptable characters are output as Faces component IDs.
* Based on ISO9075 encoding - which itself a subset of valid HTML ID characters.
*/
private static String validFacesId(String id)
{
int len = id.length();
StringBuilder buf = new StringBuilder(len + (len>>1));
for (int i = 0; i<len; i++)
{
char c = id.charAt(i);
int ci = (int)c;
if (i == 0)
{
if ((ci >= 65 && ci <= 90) || // A-Z
(ci >= 97 && ci <= 122)) // a-z
{
buf.append(c);
}
else
{
encode(c, buf);
}
}
else
{
if ((ci >= 65 && ci <= 90) || // A-Z
(ci >= 97 && ci <= 122) || // a-z
(ci >= 48 && ci <= 57) || // 0-9
ci == 45 || ci == 95) // - and _
{
buf.append(c);
}
else
{
encode(c, buf);
}
}
}
return buf.toString();
}
private static void encode(char c, StringBuilder builder)
{
char[] buf = new char[] { 'x', '0', '0', '0', '0', '_' };
int charPos = 5;
do
{
buf[--charPos] = DIGITS[c & MASK];
c >>>= 4;
}
while (c != 0);
builder.append(buf);
}
} }

View File

@@ -242,7 +242,7 @@ public class UploadContentServlet extends BaseServlet
writer.setEncoding(encoding); writer.setEncoding(encoding);
// Stream the content into the repository // Stream the content into the repository
writer.putContent(req.getInputStream()); writer.putContent(inputStream);
if (logger.isDebugEnabled() == true) if (logger.isDebugEnabled() == true)
{ {