Merged V2.2 to HEAD

10931: Merged V2.1 to V2.2
      9931: Fix for https://issues.alfresco.com/jira/browse/ETWOONE-295
      10094: Further fix for ETWOONE-241: SAXException - XML parser apparently is not thread safe
      10101: Resolve ACT 1282: wcm workflow falling over on Oracle while hitting in clause limit of 1000 expressions.
      10188: https://issues.alfresco.com/jira/browse/ETWOONE-74 (Part 1)
      10447: ETWOONE-328: performance improvement added to rule trigger code
      10455: Fix for ETWOONE-306.
      10292: Fix for ETWOONE-92: If two users update the same contents at the same time, you get InvalidNodeRefException
      10293: Fix for ETWOONE-116: Send email action does not handle invalid email address
      10294: Fix for ETWOONE-164: when a powerpoint 2007 pptx is stored in alfresco ...
      10341: Action Evaluator request level cache


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@10934 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2008-09-19 12:51:08 +00:00
parent 1f74c0282c
commit 997e6537aa
7 changed files with 130 additions and 15 deletions

View File

@@ -1430,6 +1430,7 @@ user_properties=User Properties
first_name=First Name
last_name=Last Name
email=Email
email_format_is_not_valid=Email format is not valid
company_id=Company ID
home_space_location=Home Space Location
home_space_name=Home Space Name

View File

@@ -72,6 +72,10 @@ public abstract class BaseDownloadContentServlet extends BaseServlet
{
private static final long serialVersionUID = -4558907921887235966L;
private static final String POWER_POINT_DOCUMENT_MIMETYPE = "application/vnd.powerpoint";
private static final String POWER_POINT_2007_DOCUMENT_MIMETYPE = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
protected static final String MIMETYPE_OCTET_STREAM = "application/octet-stream";
protected static final String MSG_ERROR_CONTENT_MISSING = "error_content_missing";
@@ -286,6 +290,14 @@ public abstract class BaseDownloadContentServlet extends BaseServlet
}
}
}
// explicitly set the content disposition header if the content is powerpoint
if (!attachment && (mimetype.equals(POWER_POINT_2007_DOCUMENT_MIMETYPE) ||
mimetype.equals(POWER_POINT_DOCUMENT_MIMETYPE)))
{
res.setHeader("Content-Disposition", "attachment");
}
// set mimetype for the content and the character encoding for the stream
res.setContentType(mimetype);
res.setCharacterEncoding(reader.getEncoding());

View File

@@ -258,6 +258,7 @@ public class AVMWorkflowUtil extends WorkflowUtil
final HashMap<QName, Object> props = new HashMap<QName, Object>(1, 1.0f);
props.put(WCMWorkflowModel.PROP_FROM_PATH, fromPath);
query.setProcessCustomProps(props);
query.setActive(true);
final List<WorkflowTask> tasks = workflowService.queryTasks(query);
if (logger.isDebugEnabled())

View File

@@ -65,6 +65,7 @@ import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.component.UIActionLink;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.validator.EmailValidator;
/**
* @author Kevin Roast
@@ -85,6 +86,7 @@ public class NewUserWizard extends AbstractWizardBean
private static final String STEP2_DESCRIPTION_ID = "new_user_step2_desc";
private static final String FINISH_INSTRUCTION_ID = "new_user_finish_instruction";
private static final String ERROR = "error_person";
private static final String MSG_ERROR_MAIL_NOT_VALID = "email_format_is_not_valid";
/** form variables */
private String firstName = null;
@@ -916,6 +918,23 @@ public class NewUserWizard extends AbstractWizardBean
}
}
/**
* Validate Email field data is acceptable
*
* @param context
* @param component
* @param value
* @throws ValidatorException
*/
public void validateEmail(FacesContext context, UIComponent component, Object value) throws ValidatorException
{
EmailValidator emailValidator = EmailValidator.getInstance();
if (!emailValidator.isValid((String) value))
{
String err =Application.getMessage(context, MSG_ERROR_MAIL_NOT_VALID);
throw new ValidatorException(new FacesMessage(err));
}
}
// ------------------------------------------------------------------------------
// Helper methods

View File

@@ -22,20 +22,23 @@
* http://www.alfresco.com/legal/licensing" */
package org.alfresco.web.forms;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.alfresco.model.WCMAppModel;
import org.alfresco.repo.domain.PropertyValue;
import org.alfresco.repo.remote.AVMRemoteInputStream;
import org.alfresco.service.cmr.avm.AVMNodeDescriptor;
import org.alfresco.service.cmr.avm.AVMNotFoundException;
import org.alfresco.service.cmr.remote.AVMRemote;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.*;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import javax.xml.parsers.*;
import java.io.*;
import java.util.Map;
import java.util.HashMap;
/**
* Common implementation of functions called in the context of FormDataRenderers.
@@ -43,15 +46,16 @@ import java.util.HashMap;
* of both the alfresco webapp and the virtualization server.
*
* @author Ariel Backenroth
* @author Arseny Kovalchuk (Fix of the bug reported in https://issues.alfresco.com/jira/browse/ETWOONE-241)
*/
public class FormDataFunctions
{
private static final Log LOGGER = LogFactory.getLog(FormDataFunctions.class);
private static DocumentBuilder documentBuilder;
private final AVMRemote avmRemote;
private ThreadLocal<DocumentBuilderFactory> dbf = new ThreadLocal<DocumentBuilderFactory>();
public FormDataFunctions(final AVMRemote avmRemote)
{
this.avmRemote = avmRemote;
@@ -70,7 +74,7 @@ public class FormDataFunctions
final InputStream istream = this.avmRemote.getFileInputStream(-1, avmPath);
try
{
return XMLUtil.parse(istream);
return parseXML(istream);
}
finally
{
@@ -123,7 +127,8 @@ public class FormDataFunctions
final InputStream istream = this.avmRemote.getFileInputStream(-1, avmPath + '/' + entryName);
try
{
result.put(entryName, XMLUtil.parse(istream));
// result.put(entryName, XMLUtil.parse(istream));
result.put(entryName, parseXML(istream));
}
finally
{
@@ -133,4 +138,33 @@ public class FormDataFunctions
}
return result;
}
/*
* We need an internal method for XML parsing with ThreadLocal DocumentBuilderFactory
* to avoid a multithread access to the parser in XMLUtils.
* Fix of the bug reported in https://issues.alfresco.com/jira/browse/ETWOONE-241 reported.
*/
private Document parseXML(InputStream is) throws IOException, SAXException
{
Document result = null;
try
{
DocumentBuilderFactory localDbf = dbf.get();
if (localDbf == null)
{
localDbf = DocumentBuilderFactory.newInstance();
}
localDbf.setNamespaceAware(true);
localDbf.setValidating(false);
dbf.set(localDbf);
DocumentBuilder builder = localDbf.newDocumentBuilder();
result = builder.parse(is);
}
catch (ParserConfigurationException pce)
{
LOGGER.error(pce);
}
return result;
}
}

View File

@@ -27,6 +27,9 @@ package org.alfresco.web.ui.repo.component.evaluator;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
@@ -42,6 +45,8 @@ import org.alfresco.web.ui.common.component.evaluator.BaseEvaluator;
*/
public class ActionInstanceEvaluator extends BaseEvaluator
{
private static final String EVALUATOR_CACHE = "_alf_evaluator_cache";
/**
* Evaluate by executing the specified action instance evaluator.
*
@@ -56,7 +61,7 @@ public class ActionInstanceEvaluator extends BaseEvaluator
final Object obj = this.getValue();
if (obj instanceof Node)
{
result = this.getEvaluator().evaluate((Node)obj);
result = evaluateCachedResult((Node)obj);
}
else
{
@@ -87,6 +92,49 @@ public class ActionInstanceEvaluator extends BaseEvaluator
return result;
}
/**
* To reduce invocations of a particular evaluator for a particular node
* save a cache of evaluator result for a node against the current request.
* Since the same evaluator may get reused several times for multiple actions, but
* in effect execute against the same node instance, this can significantly reduce
* the number of invocations required for a particular evaluator.
*
* @param node Node to evaluate against
*
* @return evaluator result
*/
private boolean evaluateCachedResult(Node node)
{
Boolean result;
ActionEvaluator evaluator = getEvaluator();
String cacheKey = node.getNodeRef().toString() + '_' + evaluator.getClass().getName();
Map<String, Boolean> cache = getEvaluatorResultCache();
result = cache.get(cacheKey);
if (result == null)
{
result = evaluator.evaluate(node);
cache.put(cacheKey, result);
}
return result;
}
/**
* @return the evaluator result cache - tied to the current request
*/
private Map<String, Boolean> getEvaluatorResultCache()
{
FacesContext fc = FacesContext.getCurrentInstance();
Map<String, Boolean> cache = (Map<String, Boolean>)fc.getExternalContext().getRequestMap().get(EVALUATOR_CACHE);
if (cache == null)
{
cache = new HashMap<String, Boolean>(64, 1.0f);
fc.getExternalContext().getRequestMap().put(EVALUATOR_CACHE, cache);
}
return cache;
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/

View File

@@ -170,7 +170,7 @@
<tr>
<td><h:outputText value="#{msg.email}"/>:</td>
<td>
<h:inputText id="email" value="#{NewUserWizard.email}" size="35" maxlength="1024" onkeyup="updateButtonState();" onchange="updateButtonState();" />&nbsp;*
<h:inputText id="email" value="#{NewUserWizard.email}" validator="#{NewUserWizard.validateEmail}" size="35" maxlength="1024" onkeyup="updateButtonState();" onchange="updateButtonState();" />&nbsp;*
</td>
</tr>
@@ -209,7 +209,7 @@
<tr><td class="wizardButtonSpacing"></td></tr>
<tr>
<td align="center">
<h:commandButton value="#{msg.cancel_button}" action="#{NewUserWizard.cancel}" styleClass="wizardButton" />
<h:commandButton value="#{msg.cancel_button}" action="#{NewUserWizard.cancel}" styleClass="wizardButton" immediate="true" />
</td>
</tr>
</table>