Merged V2.1 to HEAD

6515: Fix for AWC-1362 (system error page when clicking on space that doesn't exist in navigator)
   6516: Fix for AR-1688 - Vista
   6518: Fix for AWC-1479, AWC-1199 and AWC-426 (javascript insertion into forum posts security related fixes) limit to subset of safe tags for posting
   6519: Fix AR-1690 Web Scripts url.args is missing even though it's documented in WIKI
   6520: Fix for AWC-1271 (component generator config ignored for associations)
   6521: Fix AWC-1492 Some included javascript files in template/webscripts use the wrong app context path i.e. /alfresco when the app is called /alfzip
   6522: Build fix
   6523: - Fix rendering of tasks with no description in office portlets
   6524: Added thread pool for index merging (AR-1633, AR-1579)
   6525: One more fix for rendering of tasks with no description in office portlets
   6527: Renamed axis jar to reflect version number.
   6528: WebServices query cache refactoring


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6741 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2007-09-10 23:44:07 +00:00
parent 6e5ac9d831
commit 794cbf4584
20 changed files with 360 additions and 49 deletions

View File

@@ -478,6 +478,7 @@ navigator_desc=Allows tree based navigation around the repository
shelf=Shelf shelf=Shelf
shelf_desc=Area that includes the clipboard, recent space and shortcuts shelf_desc=Area that includes the clipboard, recent space and shortcuts
reset_navigator=Refresh reset_navigator=Refresh
navigator_node_deleted=The space just selected is no longer in the repository, please Refresh the Navigator before continuing.
# Common Wizard messages # Common Wizard messages
steps=Steps steps=Steps

View File

@@ -99,7 +99,7 @@
</#if> </#if>
</span> </span>
<span class="taskItemDetails"> <span class="taskItemDetails">
<span style="font-weight: bold;">${t.description?html}</span> (${t.type?html}) <span style="font-weight: bold;">${t.description!""?html}</span> (${t.type?html})
<#if hasDue> <#if hasDue>
<br />Due date: ${due?date} <br />Due date: ${due?date}
<#else> <#else>

View File

@@ -66,7 +66,7 @@
</#if> </#if>
</span> </span>
<span class="taskItemDetails"> <span class="taskItemDetails">
<span style="font-weight: bold;">${t.description?html}</span> (${t.type?html}) <span style="font-weight: bold;">${t.description!""?html}</span> (${t.type?html})
<#if hasDue> <#if hasDue>
<br />Due date: ${due?date} <br />Due date: ${due?date}
<#else> <#else>

View File

@@ -11,7 +11,7 @@
<tr> <tr>
<td width="32" valign="top"><img src="${url.context}/images/office/task_item.gif" alt="Task item" /></td> <td width="32" valign="top"><img src="${url.context}/images/office/task_item.gif" alt="Task item" /></td>
<td> <td>
<span style="font-weight: bold;">${task.description?html}</span> <span style="font-weight: bold;">${task.description!""?html}</span>
<br /> <br />
<table style="margin-top: 4px;"> <table style="margin-top: 4px;">
<tr> <tr>

View File

@@ -1,11 +1,11 @@
<link rel="stylesheet" href="${url.context}/css/main.css" TYPE="text/css"> <link rel="stylesheet" href="${url.context}/css/main.css" TYPE="text/css">
<script type="text/javascript" src="/alfresco/scripts/ajax/yahoo/yahoo/yahoo-min.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/yahoo/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/yahoo/connection/connection-min.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/yahoo/connection/connection-min.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/mootools.v1.11.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/mootools.v1.11.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/common.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/common.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/summary-info.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/summary-info.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/doclist.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/doclist.js"></script>
<script type="text/javascript">setContextPath('${url.context}');</script> <script type="text/javascript">setContextPath('${url.context}');</script>
<script> <script>

View File

@@ -1,11 +1,11 @@
<link rel="stylesheet" href="${url.context}/css/main.css" TYPE="text/css"> <link rel="stylesheet" href="${url.context}/css/main.css" TYPE="text/css">
<script type="text/javascript" src="/alfresco/scripts/ajax/yahoo/yahoo/yahoo-min.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/yahoo/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/yahoo/connection/connection-min.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/yahoo/connection/connection-min.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/mootools.v1.11.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/mootools.v1.11.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/common.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/common.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/summary-info.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/summary-info.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/myspaces.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/myspaces.js"></script>
<script type="text/javascript">setContextPath('${url.context}');</script> <script type="text/javascript">setContextPath('${url.context}');</script>
<script> <script>

View File

@@ -1,11 +1,11 @@
<link rel="stylesheet" href="${url.context}/css/main.css" TYPE="text/css"> <link rel="stylesheet" href="${url.context}/css/main.css" TYPE="text/css">
<script type="text/javascript" src="/alfresco/scripts/ajax/yahoo/yahoo/yahoo-min.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/yahoo/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/yahoo/connection/connection-min.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/yahoo/connection/connection-min.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/mootools.v1.11.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/mootools.v1.11.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/common.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/common.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/summary-info.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/summary-info.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/mytasks.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/mytasks.js"></script>
<script type="text/javascript">setContextPath('${url.context}');</script> <script type="text/javascript">setContextPath('${url.context}');</script>
<script> <script>

View File

@@ -1,11 +1,11 @@
<link rel="stylesheet" href="${url.context}/css/main.css" TYPE="text/css"> <link rel="stylesheet" href="${url.context}/css/main.css" TYPE="text/css">
<script type="text/javascript" src="/alfresco/scripts/ajax/yahoo/yahoo/yahoo-min.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/yahoo/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/yahoo/connection/connection-min.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/yahoo/connection/connection-min.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/mootools.v1.11.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/mootools.v1.11.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/common.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/common.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/summary-info.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/summary-info.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/mywebfiles.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/mywebfiles.js"></script>
<script type="text/javascript">setContextPath('${url.context}');</script> <script type="text/javascript">setContextPath('${url.context}');</script>
<script> <script>

View File

@@ -1,11 +1,11 @@
<link rel="stylesheet" href="${url.context}/css/main.css" TYPE="text/css"> <link rel="stylesheet" href="${url.context}/css/main.css" TYPE="text/css">
<script type="text/javascript" src="/alfresco/scripts/ajax/yahoo/yahoo/yahoo-min.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/yahoo/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/yahoo/connection/connection-min.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/yahoo/connection/connection-min.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/mootools.v1.11.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/mootools.v1.11.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/common.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/common.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/summary-info.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/summary-info.js"></script>
<script type="text/javascript" src="/alfresco/scripts/ajax/mywebforms.js"></script> <script type="text/javascript" src="${url.context}/scripts/ajax/mywebforms.js"></script>
<script type="text/javascript">setContextPath('${url.context}');</script> <script type="text/javascript">setContextPath('${url.context}');</script>
<script> <script>

View File

@@ -476,6 +476,113 @@ public class BrowseBean implements IContextListener
return result; return result;
} }
/**
* Page accessed bean method to get the parent container nodes currently being browsed
*
* @return List of parent container Node objects for the current browse location
*/
public List<Node> getParentNodes(NodeRef currNodeRef)
{
// As per AWC-1507 there are two scenarios for navigating to the space details. First
// scenario is to show space details of the current space. Second scenario is to show
// space details of a child space of the current space. For now, added an extra query
// so that existing context remains unaffected for second scenario, although it does
// mean that in first scenario there will be an extra query even though parentContainerNodes
// and containerNodes will contain the same list.
if (this.parentContainerNodes == null)
{
long startTime = 0;
if (logger.isDebugEnabled())
startTime = System.currentTimeMillis();
UserTransaction tx = null;
try
{
FacesContext context = FacesContext.getCurrentInstance();
tx = Repository.getUserTransaction(context, true);
tx.begin();
NodeRef parentRef = nodeService.getPrimaryParent(currNodeRef).getParentRef();
List<FileInfo> children = this.fileFolderService.list(parentRef);
this.parentContainerNodes = new ArrayList<Node>(children.size());
for (FileInfo fileInfo : children)
{
// create our Node representation from the NodeRef
NodeRef nodeRef = fileInfo.getNodeRef();
// find it's type so we can see if it's a node we are interested in
QName type = this.nodeService.getType(nodeRef);
// make sure the type is defined in the data dictionary
TypeDefinition typeDef = this.dictionaryService.getType(type);
if (typeDef != null)
{
MapNode node = null;
// look for Space folder node
if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_FOLDER) == true &&
this.dictionaryService.isSubClass(type, ContentModel.TYPE_SYSTEM_FOLDER) == false)
{
// create our Node representation
node = new MapNode(nodeRef, this.nodeService, fileInfo.getProperties());
node.addPropertyResolver("icon", this.resolverSpaceIcon);
node.addPropertyResolver("smallIcon", this.resolverSmallIcon);
this.parentContainerNodes.add(node);
}
else if (ApplicationModel.TYPE_FOLDERLINK.equals(type))
{
// create our Folder Link Node representation
node = new MapNode(nodeRef, this.nodeService, fileInfo.getProperties());
node.addPropertyResolver("icon", this.resolverSpaceIcon);
node.addPropertyResolver("smallIcon", this.resolverSmallIcon);
this.parentContainerNodes.add(node);
}
}
else
{
if (logger.isEnabledFor(Priority.WARN))
logger.warn("Found invalid object in database: id = " + nodeRef + ", type = " + type);
}
}
// commit the transaction
tx.commit();
}
catch (InvalidNodeRefException refErr)
{
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
FacesContext.getCurrentInstance(), Repository.ERROR_NODEREF), new Object[] {refErr.getNodeRef()}), refErr );
this.parentContainerNodes = Collections.<Node>emptyList();
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
}
catch (Throwable err)
{
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
this.parentContainerNodes = Collections.<Node>emptyList();
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
}
if (logger.isDebugEnabled())
{
long endTime = System.currentTimeMillis();
logger.debug("Time to query and build map parent nodes: " + (endTime - startTime) + "ms");
}
}
List<Node> result = this.parentContainerNodes;
// we clear the member variable during invalidateComponents()
return result;
}
/** /**
* Setup the common properties required at data-binding time. * Setup the common properties required at data-binding time.
@@ -1733,6 +1840,7 @@ public class BrowseBean implements IContextListener
// clear the storage of the last set of nodes // clear the storage of the last set of nodes
this.containerNodes = null; this.containerNodes = null;
this.contentNodes = null; this.contentNodes = null;
this.parentContainerNodes = null;
} }
/** /**
@@ -1880,6 +1988,7 @@ public class BrowseBean implements IContextListener
/** Transient lists of container and content nodes for display */ /** Transient lists of container and content nodes for display */
protected List<Node> containerNodes = null; protected List<Node> containerNodes = null;
protected List<Node> contentNodes = null; protected List<Node> contentNodes = null;
protected List<Node> parentContainerNodes = null;
/** The current space and it's properties - if any */ /** The current space and it's properties - if any */
protected Node actionSpace; protected Node actionSpace;

View File

@@ -177,7 +177,8 @@ public class SpaceDetailsBean extends BaseDetailsBean
String id = params.get("id"); String id = params.get("id");
if (id != null && id.length() != 0) if (id != null && id.length() != 0)
{ {
List<Node> nodes = this.browseBean.getNodes(); NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
List<Node> nodes = this.browseBean.getParentNodes(currNodeRef);
if (nodes.size() > 1) if (nodes.size() > 1)
{ {
// perform a linear search - this is slow but stateless // perform a linear search - this is slow but stateless
@@ -214,7 +215,6 @@ public class SpaceDetailsBean extends BaseDetailsBean
// to the default one. // to the default one.
if (foundNextItem == false) if (foundNextItem == false)
{ {
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
Node currNode = new Node(currNodeRef); Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode); this.navigator.setupDispatchContext(currNode);
} }
@@ -232,7 +232,8 @@ public class SpaceDetailsBean extends BaseDetailsBean
String id = params.get("id"); String id = params.get("id");
if (id != null && id.length() != 0) if (id != null && id.length() != 0)
{ {
List<Node> nodes = this.browseBean.getNodes(); NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
List<Node> nodes = this.browseBean.getParentNodes(currNodeRef);
if (nodes.size() > 1) if (nodes.size() > 1)
{ {
// see above // see above
@@ -266,7 +267,6 @@ public class SpaceDetailsBean extends BaseDetailsBean
// to the default one. // to the default one.
if (foundPreviousItem == false) if (foundPreviousItem == false)
{ {
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
Node currNode = new Node(currNodeRef); Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode); this.navigator.setupDispatchContext(currNode);
} }

View File

@@ -831,7 +831,7 @@ public class ForumsBean implements IContextListener
if (reader != null) if (reader != null)
{ {
content = reader.getContentString(); content = Utils.stripUnsafeHTMLTags(reader.getContentString());
} }
return content; return content;

View File

@@ -171,6 +171,9 @@ public class DeclarativeWebScript extends AbstractWebScript
} }
catch(Throwable e) catch(Throwable e)
{ {
if (logger.isInfoEnabled())
logger.info("Caught exception & redirecting to status template: " + e.getMessage());
// extract status code, if specified // extract status code, if specified
int statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; int statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
if (e instanceof WebScriptException) if (e instanceof WebScriptException)

View File

@@ -524,6 +524,7 @@ public class TestWebScriptServer
String[] parts = arg.split("="); String[] parts = arg.split("=");
req.addParameter(parts[0], (parts.length == 2) ? URLDecoder.decode(parts[1], "UTF-8") : null); req.addParameter(parts[0], (parts.length == 2) ? URLDecoder.decode(parts[1], "UTF-8") : null);
} }
req.setQueryString(URLDecoder.decode(uriArgs, "UTF-8"));
} }
String requestURI = "/alfresco/service" + (iArgIndex == -1 ? uri : uri.substring(0, iArgIndex)); String requestURI = "/alfresco/service" + (iArgIndex == -1 ? uri : uri.substring(0, iArgIndex));
req.setRequestURI(URLDecoder.decode(requestURI, "UTF-8")); req.setRequestURI(URLDecoder.decode(requestURI, "UTF-8"));

View File

@@ -113,6 +113,22 @@ public class URLModel
return getFull(); return getFull();
} }
/**
* Gets the URL arguments (query string)
*
* @return args (query string)
*/
public String getArgs()
{
String args = req.getQueryString();
return (args == null) ? "" : args;
}
public String jsGet_args()
{
return getArgs();
}
/** /**
* Gets the matching service path * Gets the matching service path
* *

View File

@@ -190,6 +190,9 @@ public abstract class WebScriptRuntime
} }
catch(Throwable e) catch(Throwable e)
{ {
if (logger.isInfoEnabled())
logger.info("Caught exception & redirecting to status template: " + e.getMessage());
// extract status code, if specified // extract status code, if specified
int statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; int statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
if (e instanceof WebScriptException) if (e instanceof WebScriptException)

View File

@@ -34,9 +34,11 @@ import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import javax.faces.application.FacesMessage; import javax.faces.application.FacesMessage;
import javax.faces.component.NamingContainer; import javax.faces.component.NamingContainer;
@@ -102,7 +104,45 @@ public final class Utils
private static final Map<String, String> s_fileExtensionMap = new HashMap<String, String>(89, 1.0f); private static final Map<String, String> s_fileExtensionMap = new HashMap<String, String>(89, 1.0f);
private static Log logger = LogFactory.getLog(Utils.class); private static final Log logger = LogFactory.getLog(Utils.class);
private static final Set<String> safeTags = new HashSet<String>();
static
{
safeTags.add("p");
safeTags.add("/p");
safeTags.add("b");
safeTags.add("/b");
safeTags.add("i");
safeTags.add("/i");
safeTags.add("br");
safeTags.add("ul");
safeTags.add("/ul");
safeTags.add("ol");
safeTags.add("/ol");
safeTags.add("li");
safeTags.add("/li");
safeTags.add("h1");
safeTags.add("/h1");
safeTags.add("h2");
safeTags.add("/h2");
safeTags.add("h3");
safeTags.add("/h3");
safeTags.add("h4");
safeTags.add("/h4");
safeTags.add("h5");
safeTags.add("/h5");
safeTags.add("h6");
safeTags.add("/h6");
safeTags.add("span");
safeTags.add("/span");
safeTags.add("a");
safeTags.add("/a");
safeTags.add("img");
safeTags.add("font");
safeTags.add("/font");
}
/** /**
* Private constructor * Private constructor
@@ -256,6 +296,92 @@ public final class Utils
return buf.toString(); return buf.toString();
} }
/**
* Strip unsafe HTML tags from a string - only leaves most basic formatting tags
* and encodes or strips the remaining characters.
*
* @param s HTML string to strip tags from
*
* @return safe string
*/
public static String stripUnsafeHTMLTags(String s)
{
s = s.replace("onclick", "$");
s = s.replace("onmouseover", "$");
s = s.replace("onmouseout", "$");
s = s.replace("onmousemove", "$");
s = s.replace("onfocus", "$");
s = s.replace("onblur", "$");
StringBuilder buf = new StringBuilder(s.length());
char[] chars = s.toCharArray();
for (int i=0; i<chars.length; i++)
{
if (chars[i] == '<')
{
// found a tag?
int endMatchIndex = -1;
int endTagIndex = -1;
if (i < chars.length - 2)
{
for (int x=(i + 1); x<chars.length; x++)
{
if (chars[x] == ' ' && endMatchIndex == -1)
{
// keep track of the match point for comparing tags in the safeTags set
endMatchIndex = x;
}
else if (chars[x] == '>')
{
endTagIndex = x;
break;
}
else if (chars[x] == '<')
{
// found another angle bracket - not a tag def so we can safely output to here
break;
}
}
}
if (endTagIndex != -1)
{
// found end of the tag to match
String tag = s.substring(i + 1, endTagIndex).toLowerCase();
String matchTag = tag;
if (endMatchIndex != -1)
{
matchTag = s.substring(i + 1, endMatchIndex).toLowerCase();
}
if (safeTags.contains(matchTag))
{
// safe tag - append to buffer
buf.append('<').append(tag).append('>');
}
// inc counter to skip past whole tag
i = endTagIndex;
continue;
}
}
String enc = null;
switch (chars[i])
{
case '"': enc = "&quot;"; break;
case '&': enc = "&amp;"; break;
case '<': enc = "&lt;"; break;
case '>': enc = "&gt;"; break;
default:
if (((int)chars[i]) >= 0x80)
{
//encode all non basic latin characters
enc = "&#" + ((int)chars[i]) + ";";
}
break;
}
buf.append(enc == null ? chars[i] : enc);
}
return buf.toString();
}
/** /**
* Replace one string instance with another within the specified string * Replace one string instance with another within the specified string
* *
@@ -337,8 +463,12 @@ public final class Utils
String line = reader.readLine(); String line = reader.readLine();
while (line != null) while (line != null)
{ {
parsedContent.append(line).append("<br/>"); parsedContent.append(line);
line = reader.readLine(); line = reader.readLine();
if (line != null)
{
parsedContent.append("<br>");
}
} }
replaced = parsedContent.toString(); replaced = parsedContent.toString();

View File

@@ -30,6 +30,7 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent; import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext; import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter; import javax.faces.context.ResponseWriter;
@@ -37,9 +38,11 @@ import javax.faces.el.ValueBinding;
import javax.faces.event.AbortProcessingException; import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent; import javax.faces.event.ActionEvent;
import javax.faces.event.FacesEvent; import javax.faces.event.FacesEvent;
import javax.transaction.UserTransaction;
import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
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.BrowseBean; import org.alfresco.web.bean.BrowseBean;
@@ -183,17 +186,44 @@ public class UINavigator extends SelfRenderingComponent
case NODE_SELECTED: case NODE_SELECTED:
{ {
// a node was clicked in the tree // a node was clicked in the tree
boolean nodeExists = true;
NodeRef nodeClicked = new NodeRef(navEvent.getItem()); NodeRef nodeClicked = new NodeRef(navEvent.getItem());
// setup the context to make the node the current node // make sure the node exists still before navigating to it
BrowseBean bb = (BrowseBean)FacesHelper.getManagedBean( UserTransaction tx = null;
context, BrowseBean.BEAN_NAME); try
if (bb != null)
{ {
if (logger.isDebugEnabled()) tx = Repository.getUserTransaction(context, true);
logger.debug("Selected node: " + nodeClicked); tx.begin();
bb.clickSpace(nodeClicked); NodeService nodeSvc = Repository.getServiceRegistry(
context).getNodeService();
nodeExists = nodeSvc.exists(nodeClicked);
tx.commit();
}
catch (Throwable err)
{
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
}
if (nodeExists)
{
// setup the context to make the node the current node
BrowseBean bb = (BrowseBean)FacesHelper.getManagedBean(
context, BrowseBean.BEAN_NAME);
if (bb != null)
{
if (logger.isDebugEnabled())
logger.debug("Selected node: " + nodeClicked);
bb.clickSpace(nodeClicked);
}
}
else
{
String msg = Application.getMessage(context, "navigator_node_deleted");
Utils.addErrorMessage(msg);
} }
break; break;

View File

@@ -121,8 +121,17 @@ public class UIAssociation extends PropertySheetItem
private void generateControl(FacesContext context, UIPropertySheet propSheet, private void generateControl(FacesContext context, UIPropertySheet propSheet,
AssociationDefinition assocDef) AssociationDefinition assocDef)
{ {
// get the custom component generator (if one)
String componentGeneratorName = this.getComponentGenerator();
// use the default component generator if there wasn't an overridden one
if (componentGeneratorName == null)
{
componentGeneratorName = RepoConstants.GENERATOR_ASSOCIATION;
}
UIAssociationEditor control = (UIAssociationEditor)FacesHelper.getComponentGenerator( UIAssociationEditor control = (UIAssociationEditor)FacesHelper.getComponentGenerator(
context, RepoConstants.GENERATOR_ASSOCIATION).generateAndAdd(context, propSheet, this); context, componentGeneratorName).generateAndAdd(context, propSheet, this);
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Created control " + control + "(" + logger.debug("Created control " + control + "(" +

View File

@@ -121,8 +121,17 @@ public class UIChildAssociation extends PropertySheetItem
private void generateControl(FacesContext context, UIPropertySheet propSheet, private void generateControl(FacesContext context, UIPropertySheet propSheet,
AssociationDefinition assocDef) AssociationDefinition assocDef)
{ {
// get the custom component generator (if one)
String componentGeneratorName = this.getComponentGenerator();
// use the default component generator if there wasn't an overridden one
if (componentGeneratorName == null)
{
componentGeneratorName = RepoConstants.GENERATOR_CHILD_ASSOCIATION;
}
UIChildAssociationEditor control = (UIChildAssociationEditor)FacesHelper.getComponentGenerator( UIChildAssociationEditor control = (UIChildAssociationEditor)FacesHelper.getComponentGenerator(
context, RepoConstants.GENERATOR_CHILD_ASSOCIATION).generateAndAdd(context, propSheet, this); context, componentGeneratorName).generateAndAdd(context, propSheet, this);
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Created control " + control + "(" + logger.debug("Created control " + control + "(" +