- Resources can now be added and removed to and from workflow packages

- Added simple search based content selector component to support this

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@3628 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gavin Cornwell
2006-08-29 19:39:28 +00:00
parent 93de1bdfba
commit 7878ecd144
9 changed files with 853 additions and 106 deletions

View File

@@ -971,6 +971,7 @@ error_reassign_workitem=Unable to reassign the work item due to system error:
part_of_workflow=Part of Workflow part_of_workflow=Part of Workflow
initiated_by=Initiated by initiated_by=Initiated by
start_date=Start date start_date=Start date
add_resource=Add Resource
# Admin Console messages # Admin Console messages
title_admin_console=Administration Console title_admin_console=Administration Console

View File

@@ -111,9 +111,9 @@
</action> </action>
<action id="add_package_item"> <action id="add_package_item">
<label-id>add</label-id> <label-id>add_resource</label-id>
<image>/images/icons/add_item.gif</image> <image>/images/icons/add_item.gif</image>
<action>null</action> <action-listener>#{DialogManager.bean.prepareForAdd}</action-listener>
</action> </action>
<action id="remove_package_item"> <action id="remove_package_item">

View File

@@ -21,6 +21,7 @@ import org.alfresco.service.cmr.workflow.WorkflowService;
import org.alfresco.service.cmr.workflow.WorkflowTask; import org.alfresco.service.cmr.workflow.WorkflowTask;
import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition; import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
import org.alfresco.service.cmr.workflow.WorkflowTransition; import org.alfresco.service.cmr.workflow.WorkflowTransition;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.web.app.Application; import org.alfresco.web.app.Application;
@@ -49,9 +50,14 @@ public class ManageWorkItemDialog extends BaseDialogBean
protected WorkflowTask workItem; protected WorkflowTask workItem;
protected WorkflowInstance workflowInstance; protected WorkflowInstance workflowInstance;
protected WorkflowTransition[] transitions; protected WorkflowTransition[] transitions;
protected NodeRef workflowPackage;
protected List<Node> resources; protected List<Node> resources;
protected WorkItemCompleteResolver completeResolver = new WorkItemCompleteResolver(); protected WorkItemCompleteResolver completeResolver = new WorkItemCompleteResolver();
protected UIRichList packageItemsRichList; protected UIRichList packageItemsRichList;
protected List<String> packageItemsToAdd;
protected List<String> packageItemsToRemove;
protected String[] itemsToAdd;
protected boolean isItemBeingAdded = false;
protected static final String ID_PREFIX = "transition_"; protected static final String ID_PREFIX = "transition_";
protected static final String CLIENT_ID_PREFIX = "dialog:" + ID_PREFIX; protected static final String CLIENT_ID_PREFIX = "dialog:" + ID_PREFIX;
@@ -66,6 +72,23 @@ public class ManageWorkItemDialog extends BaseDialogBean
{ {
super.init(parameters); super.init(parameters);
// reset variables
this.workItem = null;
this.workItemNode = null;
this.workflowInstance = null;
this.transitions = null;
this.workflowPackage = null;
this.resources = null;
this.itemsToAdd = null;
this.packageItemsToAdd = null;
this.packageItemsToRemove = null;
this.isItemBeingAdded = false;
if (this.packageItemsRichList != null)
{
this.packageItemsRichList.setValue(null);
}
// get the task details
String taskId = this.parameters.get("id"); String taskId = this.parameters.get("id");
this.workItem = this.workflowService.getTaskById(taskId); this.workItem = this.workflowService.getTaskById(taskId);
@@ -78,6 +101,22 @@ public class ManageWorkItemDialog extends BaseDialogBean
// get access to the workflow instance for the work item // get access to the workflow instance for the work item
this.workflowInstance = this.workItem.path.instance; this.workflowInstance = this.workItem.path.instance;
// setup the workflow package for the task
Serializable obj = this.workItem.properties.get(WorkflowModel.ASSOC_PACKAGE);
// TODO: remove this workaroud where JBPM may return a String and not the NodeRef
if (obj instanceof NodeRef)
{
this.workflowPackage = (NodeRef)obj;
}
else if (obj instanceof String)
{
this.workflowPackage = new NodeRef((String)obj);
}
if (logger.isDebugEnabled())
logger.debug("Found workflow package for work item '" +
this.workItem.id + "': " + this.workflowPackage );
} }
} }
@@ -86,11 +125,35 @@ public class ManageWorkItemDialog extends BaseDialogBean
throws Exception throws Exception
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Saving work item: " + this.workItemNode.getId()); logger.debug("Saving task: " + this.workItem.id);
// prepare the edited parameters for saving // prepare the edited parameters for saving
Map<QName, Serializable> params = WorkflowBean.prepareWorkItemParams(this.workItemNode); Map<QName, Serializable> params = WorkflowBean.prepareWorkItemParams(this.workItemNode);
// remove any items the user selected to remove
if (this.workflowPackage != null && this.packageItemsToRemove != null &&
this.packageItemsToRemove.size() > 0)
{
for (String removedItem : this.packageItemsToRemove)
{
this.nodeService.removeChild(this.workflowPackage, new NodeRef(removedItem));
}
}
// add any items the user selected to add
if (this.workflowPackage != null && this.packageItemsToAdd != null &&
this.packageItemsToAdd.size() > 0)
{
for (String addedItem : this.packageItemsToAdd)
{
NodeRef addedNodeRef = new NodeRef(addedItem);
this.nodeService.addChild(this.workflowPackage, addedNodeRef,
ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
QName.createValidLocalName((String)this.nodeService.getProperty(
addedNodeRef, ContentModel.PROP_NAME))));
}
}
// update the task with the updated parameters // update the task with the updated parameters
this.workflowService.updateTask(this.workItem.id, params, null, null); this.workflowService.updateTask(this.workItem.id, params, null, null);
@@ -200,6 +263,70 @@ public class ManageWorkItemDialog extends BaseDialogBean
return outcome; return outcome;
} }
/**
* Prepares the dialog to allow the user to add an item to the workflow package
*
* @param event The event
*/
public void prepareForAdd(ActionEvent event)
{
this.isItemBeingAdded = true;
}
/**
* Cancels the adding of an item to the workflow package
*
* @param event The event
*/
public void cancelAddPackageItems(ActionEvent event)
{
this.isItemBeingAdded = false;
}
/**
* Adds an item to the workflow package
*
* @param event The event
*/
public void addPackageItems(ActionEvent event)
{
if (this.itemsToAdd != null)
{
if (this.packageItemsToAdd == null)
{
// create the list of items to add if necessary
this.packageItemsToAdd = new ArrayList<String>(this.itemsToAdd.length);
}
for (String item : this.itemsToAdd)
{
// if this item is in the remove list it means it was there originally
// and has now been re-added, as a result we don't need to do anything
// to the original workflow package, therefore remove from the remove list
if (this.packageItemsToRemove != null && this.packageItemsToRemove.contains(item))
{
this.packageItemsToRemove.remove(item);
if (logger.isDebugEnabled())
logger.debug("Removed item from the removed list: " + item);
}
else
{
this.packageItemsToAdd.add(item);
if (logger.isDebugEnabled())
logger.debug("Added item to the added list: " + item);
}
}
// reset the rich list so it re-renders
this.packageItemsRichList.setValue(null);
}
this.isItemBeingAdded = false;
this.itemsToAdd = null;
}
/** /**
* Removes an item from the workflow package * Removes an item from the workflow package
* *
@@ -207,7 +334,34 @@ public class ManageWorkItemDialog extends BaseDialogBean
*/ */
public void removePackageItem(ActionEvent event) public void removePackageItem(ActionEvent event)
{ {
logger.info("remove package item: " + event); UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
String nodeRef = new NodeRef(Repository.getStoreRef(), params.get("id")).toString();
if (this.packageItemsToAdd != null && this.packageItemsToAdd.contains(nodeRef))
{
// remove the item from the added list if it was added in this dialog session
this.packageItemsToAdd.remove(nodeRef);
if (logger.isDebugEnabled())
logger.debug("Removed item from the added list: " + nodeRef);
}
else
{
// add the node to the list of items to remove
if (this.packageItemsToRemove == null)
{
this.packageItemsToRemove = new ArrayList<String>(1);
}
this.packageItemsToRemove.add(nodeRef);
if (logger.isDebugEnabled())
logger.debug("Added item to the removed list: " + nodeRef);
}
// reset the rich list so it re-renders
this.packageItemsRichList.setValue(null);
} }
/** /**
@@ -217,77 +371,42 @@ public class ManageWorkItemDialog extends BaseDialogBean
*/ */
public void togglePackageItemComplete(ActionEvent event) public void togglePackageItemComplete(ActionEvent event)
{ {
UserTransaction tx = null; // TODO: implement this!
try
{
FacesContext context = FacesContext.getCurrentInstance();
tx = Repository.getUserTransaction(context);
tx.begin();
UIActionLink link = (UIActionLink)event.getComponent();
Map<String, String> params = link.getParameterMap();
// create the node ref for the item we are toggling
NodeRef nodeRef = new NodeRef(Repository.getStoreRef(),
(String)params.get("id"));
// get the existing list of completed items
List<NodeRef> completedItems = (List<NodeRef>)this.workItem.properties.get(
WorkflowModel.PROP_COMPLETED_ITEMS);
if (completedItems == null)
{
// if it doesn't exist yet create the list and add the noderef
completedItems = new ArrayList<NodeRef>(1);
completedItems.add(nodeRef);
this.workItem.properties.put(WorkflowModel.PROP_COMPLETED_ITEMS,
(Serializable)completedItems);
}
else
{
if (completedItems.contains(nodeRef))
{
// the item is already in the list remove it
completedItems.remove(nodeRef);
// NOTE: There is a bug somwehere which causes the list to be
// returned as a byte array instead of a list if an empty
// list is persisted, therefore if the list is now empty
// set the completed items back to null
if (completedItems.size() == 0)
{
this.workItem.properties.put(WorkflowModel.PROP_COMPLETED_ITEMS, null);
}
}
else
{
// the noderef is not in the list yet so just add it
completedItems.add(nodeRef);
}
}
// update the task with the updated parameters
this.workflowService.updateTask(this.workItem.id, this.workItem.properties,
null, null);
// commit the transaction
tx.commit();
// reset the rich list if the change was successful
this.packageItemsRichList.setValue(null);
}
catch (Throwable err)
{
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
this.resources = Collections.<Node>emptyList();
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
}
} }
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
// Bean Getters and Setters // Bean Getters and Setters
/**
* Returns a String array of NodeRef's that are being added to the workflow package
*
* @return String array of NodeRef's
*/
public String[] getItemsToAdd()
{
return this.itemsToAdd;
}
/**
* Sets the NodeRef's to add as items to the workflow package
*
* @param itemsToAdd NodeRef's to add to the workflow package
*/
public void setItemsToAdd(String[] itemsToAdd)
{
this.itemsToAdd = itemsToAdd;
}
/**
* Determines whether an item is currently being added to the workflow package
*
* @return true if an item is being added
*/
public boolean isItemBeingAdded()
{
return this.isItemBeingAdded;
}
/** /**
* Sets the rich list being used for the workflow package items * Sets the rich list being used for the workflow package items
* *
@@ -358,21 +477,9 @@ public class ManageWorkItemDialog extends BaseDialogBean
*/ */
public List<Node> getResources() public List<Node> getResources()
{ {
NodeRef workflowPackage = null;
Serializable obj = this.workItem.properties.get(WorkflowModel.ASSOC_PACKAGE);
// TODO: remove this workaroud where JBPM may return a String and not the NodeRef
if (obj instanceof NodeRef)
{
workflowPackage = (NodeRef)obj;
}
else if (obj instanceof String)
{
workflowPackage = new NodeRef((String)obj);
}
this.resources = new ArrayList<Node>(4); this.resources = new ArrayList<Node>(4);
if (workflowPackage != null) if (this.workflowPackage != null)
{ {
UserTransaction tx = null; UserTransaction tx = null;
try try
@@ -381,12 +488,10 @@ public class ManageWorkItemDialog extends BaseDialogBean
tx = Repository.getUserTransaction(context, true); tx = Repository.getUserTransaction(context, true);
tx.begin(); tx.begin();
if (logger.isDebugEnabled()) // get existing workflow package items
logger.debug("Found workflow package for work item '" + List<ChildAssociationRef> childRefs = this.nodeService.getChildAssocs(
this.workItem.id + "': " + workflowPackage ); this.workflowPackage, ContentModel.ASSOC_CONTAINS,
RegexQNamePattern.MATCH_ALL);
List<ChildAssociationRef> childRefs = this.nodeService.getChildAssocs(workflowPackage,
ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
for (ChildAssociationRef ref: childRefs) for (ChildAssociationRef ref: childRefs)
{ {
@@ -408,18 +513,13 @@ public class ManageWorkItemDialog extends BaseDialogBean
if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT) || if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT) ||
ContentModel.TYPE_FILELINK.equals(type)) ContentModel.TYPE_FILELINK.equals(type))
{ {
// create our Node representation // if the node is not in the removed list then add create the
MapNode node = new MapNode(nodeRef, this.nodeService, true); // client side representation and add to the list
this.browseBean.setupCommonBindingProperties(node); if (this.packageItemsToRemove == null ||
this.packageItemsToRemove.contains(nodeRef.toString()) == false)
// add property resolvers to show path information {
node.addPropertyResolver("path", this.browseBean.resolverPath); createAndAddNode(nodeRef);
node.addPropertyResolver("displayPath", this.browseBean.resolverDisplayPath); }
// add a property resolver to indicate whether the item has been completed or not
node.addPropertyResolver("completed", this.completeResolver);
this.resources.add(node);
} }
} }
else else
@@ -428,6 +528,31 @@ public class ManageWorkItemDialog extends BaseDialogBean
logger.warn("Found invalid object in database: id = " + nodeRef + ", type = " + type); logger.warn("Found invalid object in database: id = " + nodeRef + ", type = " + type);
} }
} }
else
{
if (logger.isDebugEnabled())
logger.debug("Ignoring " + nodeRef + " as it has been removed from the repository");
}
}
// now iterate through the items to add list and add them to the list of resources
if (this.packageItemsToAdd != null)
{
for (String newItem : this.packageItemsToAdd)
{
NodeRef nodeRef = new NodeRef(newItem);
if (this.nodeService.exists(nodeRef))
{
// we know the type is correct as this was added as a result of a query
// for all content items so just add the item to the resources list
createAndAddNode(nodeRef);
}
else
{
if (logger.isDebugEnabled())
logger.debug("Ignoring " + nodeRef + " as it has been removed from the repository");
}
}
} }
// commit the transaction // commit the transaction
@@ -463,6 +588,21 @@ public class ManageWorkItemDialog extends BaseDialogBean
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
// Helper methods // Helper methods
protected void createAndAddNode(NodeRef nodeRef)
{
// create our Node representation
MapNode node = new MapNode(nodeRef, this.nodeService, true);
this.browseBean.setupCommonBindingProperties(node);
// add property resolvers to show path information
node.addPropertyResolver("path", this.browseBean.resolverPath);
node.addPropertyResolver("displayPath", this.browseBean.resolverDisplayPath);
// add a property resolver to indicate whether the item has been completed or not
// node.addPropertyResolver("completed", this.completeResolver);
this.resources.add(node);
}
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
// Inner classes // Inner classes

View File

@@ -0,0 +1,401 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the GNU Lesser General Public License as
* published by the Free Software Foundation; either version
* 2.1 of the License, or (at your option) any later version.
* You may obtain a copy of the License at
*
* http://www.gnu.org/licenses/lgpl.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.repo.component;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.el.ValueBinding;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.Utils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Component for selecting content from the repository
*
* @author gavinc
*/
public class UIContentSelector extends UIInput
{
private final static Log logger = LogFactory.getLog(UIContentSelector.class);
private final static String ACTION_SEPARATOR = ";";
private final static String ACTION_SEARCH = "0";
private final static String FIELD_CONTAINS = "_contains";
private final static String FIELD_AVAILABLE = "_available";
private final static String MSG_SEARCH = "search";
protected String availableOptionsSize;
protected Boolean disabled;
private Boolean multiSelect;
/** List containing the currently available options */
protected List<NodeRef> availableOptions;
// ------------------------------------------------------------------------------
// Component implementation
/**
* @see javax.faces.component.UIComponent#getFamily()
*/
public String getFamily()
{
return "org.alfresco.faces.ContentSelector";
}
/**
* Default constructor
*/
public UIContentSelector()
{
setRendererType(null);
}
/**
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
*/
@SuppressWarnings("unchecked")
public void restoreState(FacesContext context, Object state)
{
Object values[] = (Object[])state;
// standard component attributes are restored by the super class
super.restoreState(context, values[0]);
this.availableOptions = (List<NodeRef>)values[1];
this.availableOptionsSize = (String)values[2];
this.disabled = (Boolean)values[3];
this.multiSelect = (Boolean)values[4];
}
/**
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
*/
public Object saveState(FacesContext context)
{
Object values[] = new Object[10];
// standard component attributes are saved by the super class
values[0] = super.saveState(context);
values[1] = this.availableOptions;
values[2] = this.availableOptionsSize;
values[3] = this.disabled;
values[4] = this.multiSelect;
return (values);
}
/**
* @see javax.faces.component.UIComponent#decode(javax.faces.context.FacesContext)
*/
public void decode(FacesContext context)
{
Map requestMap = context.getExternalContext().getRequestParameterMap();
Map valuesMap = context.getExternalContext().getRequestParameterValuesMap();
String fieldId = getHiddenFieldName();
String value = (String)requestMap.get(fieldId);
if (value != null && value.equals(ACTION_SEARCH))
{
// user has issued a search action, fill the list with options
String contains = (String)requestMap.get(fieldId + FIELD_CONTAINS);
this.availableOptions = new ArrayList<NodeRef>();
getAvailableOptions(FacesContext.getCurrentInstance(), contains);
}
else
{
// set the submitted value (if there is one)
String[] addedItems = (String[])valuesMap.get(fieldId + FIELD_AVAILABLE);
this.setSubmittedValue(addedItems);
}
}
/**
* @see javax.faces.component.UIComponent#encodeBegin(javax.faces.context.FacesContext)
*/
public void encodeBegin(FacesContext context) throws IOException
{
if (isRendered() == false)
{
return;
}
ResponseWriter out = context.getResponseWriter();
// get the child associations currently on the node and any that have been added
NodeService nodeService = Repository.getServiceRegistry(context).getNodeService();
if (isDisabled())
{
// TODO: if the component is disabled just show the current value as text
}
else
{
// start outer table
out.write("<table border='0' cellspacing='4' cellpadding='0' class='");
if (this.getAttributes().get("styleClass") != null)
{
out.write((String)this.getAttributes().get("styleClass"));
}
else
{
out.write("selector");
}
out.write("'");
if (this.getAttributes().get("style") != null)
{
out.write(" style='");
out.write((String)this.getAttributes().get("style"));
out.write("'");
}
out.write(">");
// show the search field
out.write("<tr><td colspan='2'><input type='text' maxlength='1024' size='32' name='");
out.write(getClientId(context) + FIELD_CONTAINS);
out.write("'/>&nbsp;&nbsp;<input type='submit' value='");
out.write(Application.getMessage(context, MSG_SEARCH));
out.write("' onclick=\"");
out.write(generateFormSubmit(context, ACTION_SEARCH));
out.write("\"/></td></tr>");
// show available options i.e. all content in repository
renderAvailableOptions(context, out, nodeService);
// close table
out.write("</table>");
}
}
/**
* Determines whether the component should be rendered in a disabled state
*
* @return Returns whether the component is disabled
*/
public boolean isDisabled()
{
if (this.disabled == null)
{
ValueBinding vb = getValueBinding("disabled");
if (vb != null)
{
this.disabled = (Boolean)vb.getValue(getFacesContext());
}
}
if (this.disabled == null)
{
this.disabled = Boolean.FALSE;
}
return this.disabled;
}
/**
* Determines whether the component should be rendered in a disabled state
*
* @param disabled true to disable the component
*/
public void setDisabled(boolean disabled)
{
this.disabled = disabled;
}
/**
* Returns the size of the select control when multiple items
* can be selected
*
* @return The size of the select control
*/
public String getAvailableOptionsSize()
{
if (this.availableOptionsSize == null)
{
this.availableOptionsSize = "6";
}
return this.availableOptionsSize;
}
/**
* Sets the size of the select control used when multiple items can
* be selected
*
* @param availableOptionsSize The size
*/
public void setAvailableOptionsSize(String availableOptionsSize)
{
this.availableOptionsSize = availableOptionsSize;
}
/**
* @return true if multi select should be enabled.
*/
public boolean getMultiSelect()
{
ValueBinding vb = getValueBinding("multiSelect");
if (vb != null)
{
this.multiSelect = (Boolean)vb.getValue(getFacesContext());
}
return multiSelect != null ? multiSelect.booleanValue() : true;
}
/**
* @param multiSelect Flag to determine whether multi select is enabled
*/
public void setMultiSelect(boolean multiSelect)
{
this.multiSelect = Boolean.valueOf(multiSelect);
}
/**
* Renders the list of available options
*
* @param context FacesContext
* @param out Writer to write output to
* @param nodeService The NodeService
* @throws IOException
*/
protected void renderAvailableOptions(FacesContext context, ResponseWriter out, NodeService nodeService)
throws IOException
{
boolean itemsPresent = (this.availableOptions != null && this.availableOptions.size() > 0);
out.write("<tr><td colspan='2'><select ");
if (itemsPresent == false)
{
// rather than having a very slim select box set the width if there are no results
out.write("style='width:240px;' ");
}
out.write("name='");
out.write(getClientId(context) + FIELD_AVAILABLE);
out.write("' size='");
if (getMultiSelect())
{
out.write(getAvailableOptionsSize());
out.write("' multiple");
}
else
{
out.write("1'");
}
out.write(">");
if (itemsPresent)
{
for (NodeRef item : this.availableOptions)
{
out.write("<option value='");
out.write(item.toString());
out.write("'>");
out.write(Repository.getDisplayPath(nodeService.getPath(item)));
out.write("/");
out.write(Repository.getNameForNode(nodeService, item));
out.write("</option>");
}
}
out.write("</select></td></tr>");
}
/**
* Retrieves the available options for the current association
*
* @param context Faces Context
* @param contains The contains part of the query
*/
protected void getAvailableOptions(FacesContext context, String contains)
{
// query for all content in the current repository
StringBuilder query = new StringBuilder("+TYPE:\"");
query.append(ContentModel.TYPE_CONTENT);
query.append("\"");
if (contains != null && contains.length() > 0)
{
String safeContains = Utils.remove(contains.trim(), "\"");
query.append(" AND +@");
String nameAttr = Repository.escapeQName(QName.createQName(
NamespaceService.CONTENT_MODEL_1_0_URI, "name"));
query.append(nameAttr);
query.append(":*" + safeContains + "*");
}
if (logger.isDebugEnabled())
logger.debug("Query: " + query.toString());
ResultSet results = null;
try
{
results = Repository.getServiceRegistry(context).getSearchService().query(
Repository.getStoreRef(), SearchService.LANGUAGE_LUCENE, query.toString());
this.availableOptions = results.getNodeRefs();
}
finally
{
if (results != null)
{
results.close();
}
}
if (logger.isDebugEnabled())
logger.debug("Found " + this.availableOptions.size() + " available options");
}
/**
* We use a hidden field per picker instance on the page.
*
* @return hidden field name
*/
private String getHiddenFieldName()
{
return getClientId(getFacesContext());
}
/**
* Generate FORM submit JavaScript for the specified action
*
* @param context FacesContext
* @param action Action string
*
* @return FORM submit JavaScript
*/
private String generateFormSubmit(FacesContext context, String action)
{
return Utils.generateFormSubmit(context, this, getHiddenFieldName(), action);
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
package org.alfresco.web.ui.repo.tag;
import javax.faces.component.UIComponent;
import org.alfresco.web.ui.common.tag.HtmlComponentTag;
/**
* Tag class to allow the content selector component to be added to a JSP page
*
* @author gavinc
*/
public class ContentSelectorTag extends HtmlComponentTag
{
private String availableOptionsSize;
private String disabled;
private String value;
private String multiSelect;
/**
* @see javax.faces.webapp.UIComponentTag#getComponentType()
*/
public String getComponentType()
{
return "org.alfresco.faces.ContentSelector";
}
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
*/
public String getRendererType()
{
return null;
}
/**
* @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
*/
protected void setProperties(UIComponent component)
{
super.setProperties(component);
setStringStaticProperty(component, "availableOptionsSize", this.availableOptionsSize);
setStringProperty(component, "value", this.value);
setBooleanProperty(component, "disabled", this.disabled);
setBooleanProperty(component, "multiSelect", this.multiSelect);
}
/**
* @param value The value to set.
*/
public void setValue(String value)
{
this.value = value;
}
/**
* @param availableOptionsSize Sets the size of the available options size when
* multiple items can be selected
*/
public void setAvailableOptionsSize(String availableOptionsSize)
{
this.availableOptionsSize = availableOptionsSize;
}
/**
* Set the multiSelect
*
* @param mutliSelect the multiSelect
*/
public void setMultiSelect(String multiSelect)
{
this.multiSelect = multiSelect;
}
/**
* Sets whether the component should be rendered in a disabled state
*
* @param disabled true to render the component in a disabled state
*/
public void setDisabled(String disabled)
{
this.disabled = disabled;
}
/**
* @see javax.faces.webapp.UIComponentTag#release()
*/
public void release()
{
this.availableOptionsSize = null;
this.disabled = null;
this.value = null;
this.multiSelect = null;
super.release();
}
}

View File

@@ -34,6 +34,7 @@ public abstract class BaseAssociationEditorTag extends BaseComponentTag
private String selectedItemsMsg; private String selectedItemsMsg;
private String noSelectedItemsMsg; private String noSelectedItemsMsg;
private String disabled; private String disabled;
private String value;
/** /**
* @see javax.faces.webapp.UIComponentTag#getRendererType() * @see javax.faces.webapp.UIComponentTag#getRendererType()
@@ -56,9 +57,18 @@ public abstract class BaseAssociationEditorTag extends BaseComponentTag
setStringProperty(component, "selectItemsMsg", this.selectItemsMsg); setStringProperty(component, "selectItemsMsg", this.selectItemsMsg);
setStringProperty(component, "selectedItemsMsg", this.selectedItemsMsg); setStringProperty(component, "selectedItemsMsg", this.selectedItemsMsg);
setStringProperty(component, "noSelectedItemsMsg", this.noSelectedItemsMsg); setStringProperty(component, "noSelectedItemsMsg", this.noSelectedItemsMsg);
setStringProperty(component, "value", this.value);
setBooleanProperty(component, "disabled", this.disabled); setBooleanProperty(component, "disabled", this.disabled);
} }
/**
* @param value The value to set.
*/
public void setValue(String value)
{
this.value = value;
}
/** /**
* Sets the association name * Sets the association name
* *
@@ -140,6 +150,7 @@ public abstract class BaseAssociationEditorTag extends BaseComponentTag
this.selectedItemsMsg = null; this.selectedItemsMsg = null;
this.noSelectedItemsMsg = null; this.noSelectedItemsMsg = null;
this.disabled = null; this.disabled = null;
this.value = null;
super.release(); super.release();
} }

View File

@@ -54,6 +54,11 @@
<component-class>org.alfresco.web.ui.repo.component.UISpaceSelector</component-class> <component-class>org.alfresco.web.ui.repo.component.UISpaceSelector</component-class>
</component> </component>
<component>
<component-type>org.alfresco.faces.ContentSelector</component-type>
<component-class>org.alfresco.web.ui.repo.component.UIContentSelector</component-class>
</component>
<component> <component>
<component-type>org.alfresco.faces.CategorySelector</component-type> <component-type>org.alfresco.faces.CategorySelector</component-type>
<component-class>org.alfresco.web.ui.repo.component.UICategorySelector</component-class> <component-class>org.alfresco.web.ui.repo.component.UICategorySelector</component-class>

View File

@@ -209,11 +209,17 @@
<tag> <tag>
<name>associationEditor</name> <name>associationEditor</name>
<tag-class>org.alfresco.web.ui.repo.tag.AssociationEditorTag</tag-class> <tag-class>org.alfresco.web.ui.repo.tag.property.AssociationEditorTag</tag-class>
<body-content>JSP</body-content> <body-content>JSP</body-content>
<attribute> <attribute>
<name>assocationName</name> <name>value</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>associationName</name>
<required>true</required> <required>true</required>
<rtexprvalue>true</rtexprvalue> <rtexprvalue>true</rtexprvalue>
</attribute> </attribute>
@@ -329,11 +335,17 @@
<tag> <tag>
<name>childAssociationEditor</name> <name>childAssociationEditor</name>
<tag-class>org.alfresco.web.ui.repo.tag.ChildAssociationEditorTag</tag-class> <tag-class>org.alfresco.web.ui.repo.tag.property.ChildAssociationEditorTag</tag-class>
<body-content>JSP</body-content> <body-content>JSP</body-content>
<attribute> <attribute>
<name>assocationName</name> <name>value</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>associationName</name>
<required>true</required> <required>true</required>
<rtexprvalue>true</rtexprvalue> <rtexprvalue>true</rtexprvalue>
</attribute> </attribute>
@@ -721,6 +733,60 @@
</attribute> </attribute>
</tag> </tag>
<tag>
<name>contentSelector</name>
<tag-class>org.alfresco.web.ui.repo.tag.ContentSelectorTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>value</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>availableOptionsSize</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>multiSelect</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>id</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>binding</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>rendered</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>style</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>styleClass</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag> <tag>
<name>categorySelector</name> <name>categorySelector</name>
<tag-class>org.alfresco.web.ui.repo.tag.CategorySelectorTag</tag-class> <tag-class>org.alfresco.web.ui.repo.tag.CategorySelectorTag</tag-class>

View File

@@ -106,8 +106,18 @@
</a:column> </a:column>
--%> --%>
</a:richList> </a:richList>
<h:panelGrid columns="1" styleClass="paddingRow">
<r:actions context="#{DialogManager.bean.workItemNode}" value="#{DialogManager.bean.packageActionGroup}" />
</h:panelGrid>
<%-- Put the package actions here --%> <h:panelGrid columns="1" rendered="#{DialogManager.bean.itemBeingAdded}" styleClass="selector" style="margin-top: 6px;">
<r:contentSelector value="#{DialogManager.bean.itemsToAdd}" styleClass="" />
<h:panelGrid columns="2">
<h:commandButton value="#{msg.add_to_list_button}" actionListener="#{DialogManager.bean.addPackageItems}" />
<h:commandButton value="#{msg.cancel}" actionListener="#{DialogManager.bean.cancelAddPackageItems}" />
</h:panelGrid>
</h:panelGrid>
</a:panel> </a:panel>