Merged V3.2 to HEAD

18862: Merged DEV_TEMPORARY to V3.2 
      18699: ETHREEOH-4171: HTTP 500 when filling in a WCM webform (ACT-15969)

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18863 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gavin Cornwell
2010-02-25 22:04:55 +00:00
parent b3cb4d3953
commit 6221cbde08

View File

@@ -33,6 +33,7 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.faces.context.ExternalContext; import javax.faces.context.ExternalContext;
@@ -42,10 +43,12 @@ import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.repo.avm.AVMNodeConverter;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.springframework.extensions.surf.util.Pair; import org.springframework.extensions.surf.util.Pair;
import org.alfresco.web.app.Application; import org.alfresco.web.app.Application;
import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.app.servlet.FacesHelper;
import org.alfresco.web.bean.NavigationBean; import org.alfresco.web.bean.NavigationBean;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.bean.wcm.AVMBrowseBean; import org.alfresco.web.bean.wcm.AVMBrowseBean;
import org.alfresco.web.bean.wcm.AVMNode; import org.alfresco.web.bean.wcm.AVMNode;
import org.alfresco.web.bean.wcm.AVMUtil; import org.alfresco.web.bean.wcm.AVMUtil;
@@ -80,9 +83,6 @@ import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget; import org.w3c.dom.events.EventTarget;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.web.bean.repository.Repository;
/** /**
* Bean for interacting with the chiba processor from the ui using ajax requests. * Bean for interacting with the chiba processor from the ui using ajax requests.
@@ -122,6 +122,7 @@ public class XFormsBean implements Serializable
*/ */
class XFormsSession implements FormProcessor.Session class XFormsSession implements FormProcessor.Session
{ {
private static final long serialVersionUID = 1L;
private final Document formInstanceData; private final Document formInstanceData;
private final String formInstanceDataName; private final String formInstanceDataName;
private final Form form; private final Form form;
@@ -179,8 +180,10 @@ public class XFormsBean implements Serializable
private transient Schema2XFormsProperties schema2XFormsProperties; private transient Schema2XFormsProperties schema2XFormsProperties;
private AVMBrowseBean avmBrowseBean; private AVMBrowseBean avmBrowseBean;
private NavigationBean navigator; private NavigationBean navigator;
// lock for XFormSession.eventLog
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
private Lock writeLock = rwLock.writeLock();
private Lock readLock = rwLock.readLock();
public static String BEAN_NAME = "XFormsBean"; public static String BEAN_NAME = "XFormsBean";
@@ -229,6 +232,9 @@ public class XFormsBean implements Serializable
final ServletContext servletContext = (ServletContext) final ServletContext servletContext = (ServletContext)
externalContext.getContext(); externalContext.getContext();
writeLock.lock();
try
{
final ChibaBean chibaBean = new ChibaBean(); final ChibaBean chibaBean = new ChibaBean();
chibaBean.setConfig(servletContext.getRealPath("/WEB-INF/chiba.xml")); chibaBean.setConfig(servletContext.getRealPath("/WEB-INF/chiba.xml"));
Pair<Document, XSModel> chibaPair = this.getXFormsDocument(); Pair<Document, XSModel> chibaPair = this.getXFormsDocument();
@@ -244,16 +250,8 @@ public class XFormsBean implements Serializable
if (XFormsBean.LOGGER.isDebugEnabled()) if (XFormsBean.LOGGER.isDebugEnabled())
XFormsBean.LOGGER.debug("received event " + xmle.getType() + ": " + xmle); XFormsBean.LOGGER.debug("received event " + xmle.getType() + ": " + xmle);
try
{
lock.writeLock().lock();
XFormsBean.this.xformsSession.eventLog.add(xmle); XFormsBean.this.xformsSession.eventLog.add(xmle);
} }
finally
{
lock.writeLock().unlock();
}
}
}; };
// interaction events my occur during init so we have to register before // interaction events my occur during init so we have to register before
@@ -291,6 +289,11 @@ public class XFormsBean implements Serializable
et.addEventListener(ChibaEventNames.SWITCH_TOGGLED, el, true); et.addEventListener(ChibaEventNames.SWITCH_TOGGLED, el, true);
this.xformsSession.chibaBean = chibaBean; this.xformsSession.chibaBean = chibaBean;
} }
finally
{
writeLock.unlock();
}
}
/** /**
* Initializes the chiba process with the xform and registers any necessary * Initializes the chiba process with the xform and registers any necessary
@@ -323,24 +326,30 @@ public class XFormsBean implements Serializable
* Writes the xform out to the http servlet response. This allows * Writes the xform out to the http servlet response. This allows
* us to use the browser to parse the xform using XMLHttpRequest. * us to use the browser to parse the xform using XMLHttpRequest.
*/ */
public synchronized void getXForm() public void getXForm() throws IOException, XFormsException
throws IOException,
XFormsException
{ {
if (LOGGER.isDebugEnabled()) if (LOGGER.isDebugEnabled())
LOGGER.debug(this + ".getXForm()"); LOGGER.debug(this + ".getXForm()");
final FacesContext context = FacesContext.getCurrentInstance(); final FacesContext context = FacesContext.getCurrentInstance();
final ResponseWriter out = context.getResponseWriter(); final ResponseWriter out = context.getResponseWriter();
readLock.lock();
try
{
final ChibaBean chibaBean = this.xformsSession.chibaBean; final ChibaBean chibaBean = this.xformsSession.chibaBean;
final Node xformsDocument = chibaBean.getXMLContainer(); final Node xformsDocument = chibaBean.getXMLContainer();
XMLUtil.print(xformsDocument, out); XMLUtil.print(xformsDocument, out);
} }
finally
{
readLock.unlock();
}
}
/** /**
* sets the value of a control in the processor. * sets the value of a control in the processor.
*/ */
public synchronized void setXFormsValue() public void setXFormsValue() throws XFormsException, IOException
throws XFormsException, IOException
{ {
final FacesContext context = FacesContext.getCurrentInstance(); final FacesContext context = FacesContext.getCurrentInstance();
final Map requestParameters = context.getExternalContext().getRequestParameterMap(); final Map requestParameters = context.getExternalContext().getRequestParameterMap();
@@ -349,7 +358,13 @@ public class XFormsBean implements Serializable
if (LOGGER.isDebugEnabled()) if (LOGGER.isDebugEnabled())
LOGGER.debug(this + ".setXFormsValue(" + id + ", " + value + ")"); LOGGER.debug(this + ".setXFormsValue(" + id + ", " + value + ")");
readLock.lock();
final ChibaBean chibaBean = this.xformsSession.chibaBean; final ChibaBean chibaBean = this.xformsSession.chibaBean;
readLock.unlock();
writeLock.lock();
try
{
if (chibaBean.getContainer().lookup(id) instanceof Upload) if (chibaBean.getContainer().lookup(id) instanceof Upload)
{ {
chibaBean.updateControlValue(id, null, value, value.getBytes("UTF-8")); chibaBean.updateControlValue(id, null, value, value.getBytes("UTF-8"));
@@ -358,23 +373,30 @@ public class XFormsBean implements Serializable
{ {
chibaBean.updateControlValue(id, value); chibaBean.updateControlValue(id, value);
} }
final ResponseWriter out = context.getResponseWriter(); final ResponseWriter out = context.getResponseWriter();
XMLUtil.print(this.getEventLog(), out); XMLUtil.print(this.getEventLog(), out);
out.close(); out.close();
} }
finally
{
writeLock.unlock();
}
}
/** /**
* sets the value of a control in the processor. * sets the value of a control in the processor.
*/ */
public void setRepeatIndeces() public void setRepeatIndeces() throws XFormsException, IOException
throws XFormsException, IOException
{ {
final FacesContext context = FacesContext.getCurrentInstance(); final FacesContext context = FacesContext.getCurrentInstance();
final Map requestParameters = context.getExternalContext().getRequestParameterMap(); final Map requestParameters = context.getExternalContext().getRequestParameterMap();
final String repeatIds = (String)requestParameters.get("repeatIds"); final String repeatIds = (String)requestParameters.get("repeatIds");
if (LOGGER.isDebugEnabled()) if (LOGGER.isDebugEnabled())
LOGGER.debug(this + ".setRepeatIndeces(" + repeatIds + ")"); LOGGER.debug(this + ".setRepeatIndeces(" + repeatIds + ")");
writeLock.lock();
try
{
for (String id : repeatIds.split(",")) for (String id : repeatIds.split(","))
{ {
final int index = Integer.parseInt((String)requestParameters.get(id)); final int index = Integer.parseInt((String)requestParameters.get(id));
@@ -387,12 +409,16 @@ public class XFormsBean implements Serializable
XMLUtil.print(this.getEventLog(), out); XMLUtil.print(this.getEventLog(), out);
out.close(); out.close();
} }
finally
{
writeLock.unlock();
}
}
/** /**
* fires an action associated with a trigger. * fires an action associated with a trigger.
*/ */
public synchronized void fireAction() public void fireAction() throws XFormsException, IOException
throws XFormsException, IOException
{ {
final FacesContext context = FacesContext.getCurrentInstance(); final FacesContext context = FacesContext.getCurrentInstance();
final Map requestParameters = context.getExternalContext().getRequestParameterMap(); final Map requestParameters = context.getExternalContext().getRequestParameterMap();
@@ -400,6 +426,10 @@ public class XFormsBean implements Serializable
if (LOGGER.isDebugEnabled()) if (LOGGER.isDebugEnabled())
LOGGER.debug(this + ".fireAction(" + id + ")"); LOGGER.debug(this + ".fireAction(" + id + ")");
writeLock.lock();
try
{
final ChibaBean chibaBean = this.xformsSession.chibaBean; final ChibaBean chibaBean = this.xformsSession.chibaBean;
chibaBean.dispatch(id, DOMEventNames.ACTIVATE); chibaBean.dispatch(id, DOMEventNames.ACTIVATE);
@@ -407,6 +437,11 @@ public class XFormsBean implements Serializable
XMLUtil.print(this.getEventLog(), out); XMLUtil.print(this.getEventLog(), out);
out.close(); out.close();
} }
finally
{
writeLock.unlock();
}
}
/** /**
* handles submits and sets the instance data. * handles submits and sets the instance data.
@@ -454,8 +489,7 @@ public class XFormsBean implements Serializable
/** /**
* Swaps model nodes to implement reordering within repeats. * Swaps model nodes to implement reordering within repeats.
*/ */
public synchronized void swapRepeatItems() public void swapRepeatItems() throws Exception
throws Exception
{ {
final FacesContext context = FacesContext.getCurrentInstance(); final FacesContext context = FacesContext.getCurrentInstance();
final Map requestParameters = context.getExternalContext().getRequestParameterMap(); final Map requestParameters = context.getExternalContext().getRequestParameterMap();
@@ -464,6 +498,10 @@ public class XFormsBean implements Serializable
final String toItemId = (String)requestParameters.get("toItemId"); final String toItemId = (String)requestParameters.get("toItemId");
if (LOGGER.isDebugEnabled()) if (LOGGER.isDebugEnabled())
LOGGER.debug(this + ".swapRepeatItems(" + fromItemId + ", " + toItemId + ")"); LOGGER.debug(this + ".swapRepeatItems(" + fromItemId + ", " + toItemId + ")");
readLock.lock();
try
{
final ChibaBean chibaBean = this.xformsSession.chibaBean; final ChibaBean chibaBean = this.xformsSession.chibaBean;
final RepeatItem from = (RepeatItem)chibaBean.getContainer().lookup(fromItemId); final RepeatItem from = (RepeatItem)chibaBean.getContainer().lookup(fromItemId);
if (from == null) if (from == null)
@@ -475,12 +513,24 @@ public class XFormsBean implements Serializable
{ {
throw new NullPointerException("unable to find destination repeat item " + toItemId); throw new NullPointerException("unable to find destination repeat item " + toItemId);
} }
readLock.unlock();
writeLock.lock();
this.swapRepeatItems(from, to); this.swapRepeatItems(from, to);
final ResponseWriter out = context.getResponseWriter(); final ResponseWriter out = context.getResponseWriter();
XMLUtil.print(this.getEventLog(), out); XMLUtil.print(this.getEventLog(), out);
out.close(); out.close();
} }
catch (NullPointerException e)
{
readLock.unlock();
throw e;
}
finally
{
writeLock.unlock();
}
}
private void swapRepeatItems(final RepeatItem from, private void swapRepeatItems(final RepeatItem from,
final RepeatItem to) final RepeatItem to)
@@ -644,10 +694,6 @@ public class XFormsBean implements Serializable
final Element eventsElement = result.createElement("events"); final Element eventsElement = result.createElement("events");
result.appendChild(eventsElement); result.appendChild(eventsElement);
try
{
lock.readLock().lock();
for (XMLEvent xfe : this.xformsSession.eventLog) for (XMLEvent xfe : this.xformsSession.eventLog)
{ {
final String type = xfe.getType(); final String type = xfe.getType();
@@ -712,21 +758,7 @@ public class XFormsBean implements Serializable
} }
} }
} }
}
finally
{
lock.readLock().unlock();
}
try
{
lock.writeLock().lock();
this.xformsSession.eventLog.clear(); this.xformsSession.eventLog.clear();
}
finally
{
lock.writeLock().unlock();
}
if (LOGGER.isDebugEnabled()) if (LOGGER.isDebugEnabled())
{ {