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_desc=Area that includes the clipboard, recent space and shortcuts
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
steps=Steps

View File

@@ -99,7 +99,7 @@
</#if>
</span>
<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>
<br />Due date: ${due?date}
<#else>

View File

@@ -66,7 +66,7 @@
</#if>
</span>
<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>
<br />Due date: ${due?date}
<#else>

View File

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

View File

@@ -1,11 +1,11 @@
<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="/alfresco/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="/alfresco/scripts/ajax/common.js"></script>
<script type="text/javascript" src="/alfresco/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/yahoo/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/yahoo/connection/connection-min.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/mootools.v1.11.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/common.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/summary-info.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/doclist.js"></script>
<script type="text/javascript">setContextPath('${url.context}');</script>
<script>

View File

@@ -1,11 +1,11 @@
<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="/alfresco/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="/alfresco/scripts/ajax/common.js"></script>
<script type="text/javascript" src="/alfresco/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/yahoo/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/yahoo/connection/connection-min.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/mootools.v1.11.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/common.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/summary-info.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/myspaces.js"></script>
<script type="text/javascript">setContextPath('${url.context}');</script>
<script>

View File

@@ -1,11 +1,11 @@
<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="/alfresco/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="/alfresco/scripts/ajax/common.js"></script>
<script type="text/javascript" src="/alfresco/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/yahoo/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/yahoo/connection/connection-min.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/mootools.v1.11.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/common.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/summary-info.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/mytasks.js"></script>
<script type="text/javascript">setContextPath('${url.context}');</script>
<script>

View File

@@ -1,11 +1,11 @@
<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="/alfresco/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="/alfresco/scripts/ajax/common.js"></script>
<script type="text/javascript" src="/alfresco/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/yahoo/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/yahoo/connection/connection-min.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/mootools.v1.11.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/common.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/summary-info.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/mywebfiles.js"></script>
<script type="text/javascript">setContextPath('${url.context}');</script>
<script>

View File

@@ -1,11 +1,11 @@
<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="/alfresco/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="/alfresco/scripts/ajax/common.js"></script>
<script type="text/javascript" src="/alfresco/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/yahoo/yahoo/yahoo-min.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/yahoo/connection/connection-min.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/mootools.v1.11.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/common.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/summary-info.js"></script>
<script type="text/javascript" src="${url.context}/scripts/ajax/mywebforms.js"></script>
<script type="text/javascript">setContextPath('${url.context}');</script>
<script>

View File

@@ -476,6 +476,113 @@ public class BrowseBean implements IContextListener
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.
@@ -1733,6 +1840,7 @@ public class BrowseBean implements IContextListener
// clear the storage of the last set of nodes
this.containerNodes = 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 */
protected List<Node> containerNodes = null;
protected List<Node> contentNodes = null;
protected List<Node> parentContainerNodes = null;
/** The current space and it's properties - if any */
protected Node actionSpace;

View File

@@ -177,7 +177,8 @@ public class SpaceDetailsBean extends BaseDetailsBean
String id = params.get("id");
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)
{
// perform a linear search - this is slow but stateless
@@ -214,7 +215,6 @@ public class SpaceDetailsBean extends BaseDetailsBean
// to the default one.
if (foundNextItem == false)
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
}
@@ -232,7 +232,8 @@ public class SpaceDetailsBean extends BaseDetailsBean
String id = params.get("id");
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)
{
// see above
@@ -266,7 +267,6 @@ public class SpaceDetailsBean extends BaseDetailsBean
// to the default one.
if (foundPreviousItem == false)
{
NodeRef currNodeRef = new NodeRef(Repository.getStoreRef(), id);
Node currNode = new Node(currNodeRef);
this.navigator.setupDispatchContext(currNode);
}

View File

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

View File

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

View File

@@ -524,6 +524,7 @@ public class TestWebScriptServer
String[] parts = arg.split("=");
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));
req.setRequestURI(URLDecoder.decode(requestURI, "UTF-8"));

View File

@@ -113,6 +113,22 @@ public class URLModel
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
*

View File

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

View File

@@ -34,9 +34,11 @@ import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.faces.application.FacesMessage;
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 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
@@ -256,6 +296,92 @@ public final class Utils
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
*
@@ -337,8 +463,12 @@ public final class Utils
String line = reader.readLine();
while (line != null)
{
parsedContent.append(line).append("<br/>");
parsedContent.append(line);
line = reader.readLine();
if (line != null)
{
parsedContent.append("<br>");
}
}
replaced = parsedContent.toString();

View File

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

View File

@@ -121,8 +121,17 @@ public class UIAssociation extends PropertySheetItem
private void generateControl(FacesContext context, UIPropertySheet propSheet,
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(
context, RepoConstants.GENERATOR_ASSOCIATION).generateAndAdd(context, propSheet, this);
context, componentGeneratorName).generateAndAdd(context, propSheet, this);
if (logger.isDebugEnabled())
logger.debug("Created control " + control + "(" +

View File

@@ -121,8 +121,17 @@ public class UIChildAssociation extends PropertySheetItem
private void generateControl(FacesContext context, UIPropertySheet propSheet,
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(
context, RepoConstants.GENERATOR_CHILD_ASSOCIATION).generateAndAdd(context, propSheet, this);
context, componentGeneratorName).generateAndAdd(context, propSheet, this);
if (logger.isDebugEnabled())
logger.debug("Created control " + control + "(" +