mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged 5.2.N (5.2.1) to HEAD (5.2)
125783 rmunteanu: Merged 5.1.N (5.1.2) to 5.2.N (5.2.1) 125605 rmunteanu: Merged 5.1.1 (5.1.1) to 5.1.N (5.1.2) 125498 slanglois: MNT-16155 Update source headers - remove svn:eol-style property on Java and JSP source files git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@127809 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,296 +1,296 @@
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.springframework.web.jsf.FacesContextUtils;
|
||||
|
||||
/**
|
||||
* @author Mike Hatfield
|
||||
*/
|
||||
public class UIAjaxTagPicker extends BaseAjaxItemPicker
|
||||
{
|
||||
private static final String MSG_CLICK_TO_SELECT_TAG = "click_to_select_tag";
|
||||
private static final String MSG_ADD = "add";
|
||||
private static final String MSG_ADD_A_TAG = "add_a_tag";
|
||||
private static final String MSG_REMOVE = "remove";
|
||||
|
||||
@Override
|
||||
public String getFamily()
|
||||
{
|
||||
return "org.alfresco.faces.AjaxTagPicker";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getServiceCall()
|
||||
{
|
||||
return "PickerBean.getTagNodes";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultIcon()
|
||||
{
|
||||
return "/images/icons/category_small.gif";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getSingleSelect()
|
||||
{
|
||||
// Tag component is never in single select mode, but the base class needs to know this
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel()
|
||||
{
|
||||
// Tagger label only retrieved from a value binding when null
|
||||
if (this.label == null)
|
||||
{
|
||||
super.getLabel();
|
||||
}
|
||||
return this.label;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void encodeBegin(FacesContext fc) throws IOException
|
||||
{
|
||||
if (isRendered() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ResponseWriter out = fc.getResponseWriter();
|
||||
|
||||
String formClientId = Utils.getParentForm(fc, this).getClientId(fc);
|
||||
Map attrs = this.getAttributes();
|
||||
ResourceBundle msg = Application.getBundle(fc);
|
||||
|
||||
// get values from submitted value or none selected
|
||||
String selectedValues = null;
|
||||
String selectedNames = null;
|
||||
String selectedItems = null;
|
||||
List<NodeRef> submitted = null;
|
||||
|
||||
submitted = (List<NodeRef>)getSubmittedValue();
|
||||
if (submitted == null)
|
||||
{
|
||||
Object objSubmitted = getValue();
|
||||
// special case to submit empty lists on multi-select values
|
||||
if ((objSubmitted != null) && (objSubmitted.toString().equals("empty")))
|
||||
{
|
||||
submitted = null;
|
||||
this.setValue(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
submitted = (List<NodeRef>)getValue();
|
||||
}
|
||||
}
|
||||
|
||||
if (submitted != null)
|
||||
{
|
||||
UserTransaction tx = null;
|
||||
try
|
||||
{
|
||||
tx = Repository.getUserTransaction(fc, true);
|
||||
tx.begin();
|
||||
|
||||
StringBuilder nameBuf = new StringBuilder(128);
|
||||
StringBuilder valueBuf = new StringBuilder(128);
|
||||
StringBuilder itemBuf = new StringBuilder(256);
|
||||
NodeService nodeService = (NodeService)FacesContextUtils.getRequiredWebApplicationContext(
|
||||
fc).getBean("nodeService");
|
||||
for (NodeRef value : submitted)
|
||||
{
|
||||
String name = (String)nodeService.getProperty(value, ContentModel.PROP_NAME);
|
||||
String icon = (String)nodeService.getProperty(value, ApplicationModel.PROP_ICON);
|
||||
if (nameBuf.length() != 0)
|
||||
{
|
||||
nameBuf.append(", ");
|
||||
valueBuf.append(",");
|
||||
itemBuf.append(",");
|
||||
}
|
||||
nameBuf.append(name);
|
||||
valueBuf.append(value.toString());
|
||||
itemBuf.append(getItemJson(value.toString(), name, icon));
|
||||
}
|
||||
selectedNames = nameBuf.toString();
|
||||
selectedValues = valueBuf.toString();
|
||||
selectedItems = "[" + itemBuf.toString() + "]";
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
|
||||
}
|
||||
}
|
||||
|
||||
// generate the Ids for our script object and containing DIV element
|
||||
String divId = getId();
|
||||
String objId = divId + "Obj";
|
||||
|
||||
// generate the script to create and init our script object
|
||||
String contextPath = fc.getExternalContext().getRequestContextPath();
|
||||
out.write("<script type='text/javascript'>");
|
||||
out.write("function init" + divId + "() {");
|
||||
out.write(" window." + objId + " = new AlfTagger('" + divId + "','" + objId + "','" + getServiceCall() +
|
||||
"','" + formClientId + "','" + msg.getString(MSG_ADD) + "','" + msg.getString(MSG_REMOVE) + "');");
|
||||
out.write(" window." + objId + ".setChildNavigation(false);");
|
||||
if (getDefaultIcon() != null)
|
||||
{
|
||||
out.write(" window." + objId + ".setDefaultIcon('" + getDefaultIcon() + "');");
|
||||
}
|
||||
if (selectedItems != null)
|
||||
{
|
||||
out.write(" window." + objId + ".setSelectedItems('" + selectedItems + "');");
|
||||
}
|
||||
out.write("}");
|
||||
out.write("window.addEvent('domready', init" + divId + ");");
|
||||
out.write("</script>");
|
||||
|
||||
// generate the DIV structure for our component as expected by the script object
|
||||
out.write("<div id='" + divId + "' class='picker'>") ;
|
||||
out.write(" <input id='" + getHiddenFieldName() + "' name='" + getHiddenFieldName() + "' type='hidden' value='");
|
||||
if (selectedValues != null)
|
||||
{
|
||||
out.write(selectedValues);
|
||||
}
|
||||
out.write("'>");
|
||||
// current selection displayed as link and message to launch the selector
|
||||
out.write(" <div id='" + divId + "-noitems'");
|
||||
if (attrs.get("style") != null)
|
||||
{
|
||||
out.write(" style=\"");
|
||||
out.write((String)attrs.get("style"));
|
||||
out.write('"');
|
||||
}
|
||||
if (attrs.get("styleClass") != null)
|
||||
{
|
||||
out.write(" class=");
|
||||
out.write((String)attrs.get("styleClass"));
|
||||
}
|
||||
out.write(">");
|
||||
if (isDisabled())
|
||||
{
|
||||
out.write(" <span>");
|
||||
if (selectedNames != null)
|
||||
{
|
||||
out.write(selectedNames);
|
||||
}
|
||||
out.write(" </span>");
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write(" <span class='pickerActionButton'><a href='javascript:" + objId + ".showSelector();'>");
|
||||
if (selectedNames == null)
|
||||
{
|
||||
if ("".equals(getLabel()))
|
||||
{
|
||||
setLabel(msg.getString(MSG_CLICK_TO_SELECT_TAG));
|
||||
}
|
||||
out.write(getLabel());
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write(selectedNames);
|
||||
}
|
||||
out.write(" </a></span>");
|
||||
}
|
||||
out.write(" </div>");
|
||||
// container for item navigation
|
||||
out.write(" <div id='" + divId + "-selector' class='pickerSelector'>");
|
||||
out.write(" <div class='pickerResults'>");
|
||||
out.write(" <div class='pickerResultsHeader'>");
|
||||
out.write(" <div class='pickerNavControls'>");
|
||||
out.write(" <span class='pickerNavUp'>");
|
||||
out.write(" <a id='" + divId + "-nav-up' href='#'><img src='");
|
||||
out.write(contextPath);
|
||||
out.write("/images/icons/arrow_up.gif' border='0' alt='");
|
||||
out.write(msg.getString(MSG_GO_UP));
|
||||
out.write("' title='");
|
||||
out.write(msg.getString(MSG_GO_UP));
|
||||
out.write("'></a>");
|
||||
out.write(" </span>");
|
||||
out.write(" <span class='pickerNavBreadcrumb'>");
|
||||
out.write(" <span id='" + divId + "-nav-txt' class='pickerNavBreadcrumbText'></span></a>");
|
||||
out.write(" </span>");
|
||||
out.write(" <span class='pickerNavAddTag'>");
|
||||
out.write(" <span class='pickerAddTagIcon'></span>");
|
||||
out.write(" <span id='" + divId + "-addTag-linkContainer' class='pickerAddTagLinkContainer'>");
|
||||
out.write(" <a href='#' onclick='window." + objId + ".showAddTagForm(); return false;'>");
|
||||
out.write(msg.getString(MSG_ADD_A_TAG));
|
||||
out.write("</a>");
|
||||
out.write(" </span>");
|
||||
out.write(" <span id='" + divId + "-addTag-formContainer' class='pickerAddTagFormContainer'>");
|
||||
out.write(" <input id='" + divId + "-addTag-box' class='pickerAddTagBox' name='" + divId + "-addTag-box' type='text'>");
|
||||
out.write(" <img id='" + divId + "-addTag-ok' class='pickerAddTagImage' src='");
|
||||
out.write(contextPath);
|
||||
out.write("/images/office/action_successful.gif' alt='");
|
||||
out.write(msg.getString(MSG_ADD));
|
||||
out.write("' title='");
|
||||
out.write(msg.getString(MSG_ADD));
|
||||
out.write("'>");
|
||||
out.write(" <img id='" + divId + "-addTag-cancel' class='pickerAddTagImage' src='");
|
||||
out.write(contextPath);
|
||||
out.write("/images/office/action_failed.gif' alt='");
|
||||
out.write(msg.getString(MSG_CANCEL));
|
||||
out.write("' title='");
|
||||
out.write(msg.getString(MSG_CANCEL));
|
||||
out.write("'>");
|
||||
out.write(" </span>");
|
||||
out.write(" </span>");
|
||||
out.write(" <span id='" + divId + "-nav-add'></span>");
|
||||
out.write(" </div>");
|
||||
out.write(" </div>");
|
||||
// container for item selection
|
||||
out.write(" <div>");
|
||||
out.write(" <div id='" + divId + "-ajax-wait' class='pickerAjaxWait'");
|
||||
String height = getHeight();
|
||||
if (height != null)
|
||||
{
|
||||
out.write(" style='height:" + height + "'");
|
||||
}
|
||||
out.write("></div>");
|
||||
out.write(" <div id='" + divId + "-results-list' class='pickerResultsList'");
|
||||
if (height != null)
|
||||
{
|
||||
out.write(" style='height:" + height + "'");
|
||||
}
|
||||
out.write("></div>");
|
||||
out.write(" </div>");
|
||||
out.write(" </div>");
|
||||
// controls (OK & Cancel buttons etc.)
|
||||
out.write(" <div class='pickerFinishControls'>");
|
||||
out.write(" <div id='" + divId + "-finish' style='float:left' class='pickerButtons'><a href='javascript:" + objId + ".doneClicked();'>");
|
||||
out.write(msg.getString(MSG_OK));
|
||||
out.write("</a></div>");
|
||||
out.write(" <div style='float:right' class='pickerButtons'><a href='javascript:" + objId + ".cancelClicked();'>");
|
||||
out.write(msg.getString(MSG_CANCEL));
|
||||
out.write("</a></div>");
|
||||
out.write(" </div>");
|
||||
out.write(" </div>");
|
||||
// container for the selected items
|
||||
out.write(" <div id='" + divId + "-selected' class='pickerSelectedItems'></div>");
|
||||
out.write("</div>");
|
||||
}
|
||||
|
||||
}
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.transaction.UserTransaction;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.springframework.web.jsf.FacesContextUtils;
|
||||
|
||||
/**
|
||||
* @author Mike Hatfield
|
||||
*/
|
||||
public class UIAjaxTagPicker extends BaseAjaxItemPicker
|
||||
{
|
||||
private static final String MSG_CLICK_TO_SELECT_TAG = "click_to_select_tag";
|
||||
private static final String MSG_ADD = "add";
|
||||
private static final String MSG_ADD_A_TAG = "add_a_tag";
|
||||
private static final String MSG_REMOVE = "remove";
|
||||
|
||||
@Override
|
||||
public String getFamily()
|
||||
{
|
||||
return "org.alfresco.faces.AjaxTagPicker";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getServiceCall()
|
||||
{
|
||||
return "PickerBean.getTagNodes";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDefaultIcon()
|
||||
{
|
||||
return "/images/icons/category_small.gif";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean getSingleSelect()
|
||||
{
|
||||
// Tag component is never in single select mode, but the base class needs to know this
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel()
|
||||
{
|
||||
// Tagger label only retrieved from a value binding when null
|
||||
if (this.label == null)
|
||||
{
|
||||
super.getLabel();
|
||||
}
|
||||
return this.label;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void encodeBegin(FacesContext fc) throws IOException
|
||||
{
|
||||
if (isRendered() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ResponseWriter out = fc.getResponseWriter();
|
||||
|
||||
String formClientId = Utils.getParentForm(fc, this).getClientId(fc);
|
||||
Map attrs = this.getAttributes();
|
||||
ResourceBundle msg = Application.getBundle(fc);
|
||||
|
||||
// get values from submitted value or none selected
|
||||
String selectedValues = null;
|
||||
String selectedNames = null;
|
||||
String selectedItems = null;
|
||||
List<NodeRef> submitted = null;
|
||||
|
||||
submitted = (List<NodeRef>)getSubmittedValue();
|
||||
if (submitted == null)
|
||||
{
|
||||
Object objSubmitted = getValue();
|
||||
// special case to submit empty lists on multi-select values
|
||||
if ((objSubmitted != null) && (objSubmitted.toString().equals("empty")))
|
||||
{
|
||||
submitted = null;
|
||||
this.setValue(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
submitted = (List<NodeRef>)getValue();
|
||||
}
|
||||
}
|
||||
|
||||
if (submitted != null)
|
||||
{
|
||||
UserTransaction tx = null;
|
||||
try
|
||||
{
|
||||
tx = Repository.getUserTransaction(fc, true);
|
||||
tx.begin();
|
||||
|
||||
StringBuilder nameBuf = new StringBuilder(128);
|
||||
StringBuilder valueBuf = new StringBuilder(128);
|
||||
StringBuilder itemBuf = new StringBuilder(256);
|
||||
NodeService nodeService = (NodeService)FacesContextUtils.getRequiredWebApplicationContext(
|
||||
fc).getBean("nodeService");
|
||||
for (NodeRef value : submitted)
|
||||
{
|
||||
String name = (String)nodeService.getProperty(value, ContentModel.PROP_NAME);
|
||||
String icon = (String)nodeService.getProperty(value, ApplicationModel.PROP_ICON);
|
||||
if (nameBuf.length() != 0)
|
||||
{
|
||||
nameBuf.append(", ");
|
||||
valueBuf.append(",");
|
||||
itemBuf.append(",");
|
||||
}
|
||||
nameBuf.append(name);
|
||||
valueBuf.append(value.toString());
|
||||
itemBuf.append(getItemJson(value.toString(), name, icon));
|
||||
}
|
||||
selectedNames = nameBuf.toString();
|
||||
selectedValues = valueBuf.toString();
|
||||
selectedItems = "[" + itemBuf.toString() + "]";
|
||||
|
||||
// commit the transaction
|
||||
tx.commit();
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
|
||||
}
|
||||
}
|
||||
|
||||
// generate the Ids for our script object and containing DIV element
|
||||
String divId = getId();
|
||||
String objId = divId + "Obj";
|
||||
|
||||
// generate the script to create and init our script object
|
||||
String contextPath = fc.getExternalContext().getRequestContextPath();
|
||||
out.write("<script type='text/javascript'>");
|
||||
out.write("function init" + divId + "() {");
|
||||
out.write(" window." + objId + " = new AlfTagger('" + divId + "','" + objId + "','" + getServiceCall() +
|
||||
"','" + formClientId + "','" + msg.getString(MSG_ADD) + "','" + msg.getString(MSG_REMOVE) + "');");
|
||||
out.write(" window." + objId + ".setChildNavigation(false);");
|
||||
if (getDefaultIcon() != null)
|
||||
{
|
||||
out.write(" window." + objId + ".setDefaultIcon('" + getDefaultIcon() + "');");
|
||||
}
|
||||
if (selectedItems != null)
|
||||
{
|
||||
out.write(" window." + objId + ".setSelectedItems('" + selectedItems + "');");
|
||||
}
|
||||
out.write("}");
|
||||
out.write("window.addEvent('domready', init" + divId + ");");
|
||||
out.write("</script>");
|
||||
|
||||
// generate the DIV structure for our component as expected by the script object
|
||||
out.write("<div id='" + divId + "' class='picker'>") ;
|
||||
out.write(" <input id='" + getHiddenFieldName() + "' name='" + getHiddenFieldName() + "' type='hidden' value='");
|
||||
if (selectedValues != null)
|
||||
{
|
||||
out.write(selectedValues);
|
||||
}
|
||||
out.write("'>");
|
||||
// current selection displayed as link and message to launch the selector
|
||||
out.write(" <div id='" + divId + "-noitems'");
|
||||
if (attrs.get("style") != null)
|
||||
{
|
||||
out.write(" style=\"");
|
||||
out.write((String)attrs.get("style"));
|
||||
out.write('"');
|
||||
}
|
||||
if (attrs.get("styleClass") != null)
|
||||
{
|
||||
out.write(" class=");
|
||||
out.write((String)attrs.get("styleClass"));
|
||||
}
|
||||
out.write(">");
|
||||
if (isDisabled())
|
||||
{
|
||||
out.write(" <span>");
|
||||
if (selectedNames != null)
|
||||
{
|
||||
out.write(selectedNames);
|
||||
}
|
||||
out.write(" </span>");
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write(" <span class='pickerActionButton'><a href='javascript:" + objId + ".showSelector();'>");
|
||||
if (selectedNames == null)
|
||||
{
|
||||
if ("".equals(getLabel()))
|
||||
{
|
||||
setLabel(msg.getString(MSG_CLICK_TO_SELECT_TAG));
|
||||
}
|
||||
out.write(getLabel());
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write(selectedNames);
|
||||
}
|
||||
out.write(" </a></span>");
|
||||
}
|
||||
out.write(" </div>");
|
||||
// container for item navigation
|
||||
out.write(" <div id='" + divId + "-selector' class='pickerSelector'>");
|
||||
out.write(" <div class='pickerResults'>");
|
||||
out.write(" <div class='pickerResultsHeader'>");
|
||||
out.write(" <div class='pickerNavControls'>");
|
||||
out.write(" <span class='pickerNavUp'>");
|
||||
out.write(" <a id='" + divId + "-nav-up' href='#'><img src='");
|
||||
out.write(contextPath);
|
||||
out.write("/images/icons/arrow_up.gif' border='0' alt='");
|
||||
out.write(msg.getString(MSG_GO_UP));
|
||||
out.write("' title='");
|
||||
out.write(msg.getString(MSG_GO_UP));
|
||||
out.write("'></a>");
|
||||
out.write(" </span>");
|
||||
out.write(" <span class='pickerNavBreadcrumb'>");
|
||||
out.write(" <span id='" + divId + "-nav-txt' class='pickerNavBreadcrumbText'></span></a>");
|
||||
out.write(" </span>");
|
||||
out.write(" <span class='pickerNavAddTag'>");
|
||||
out.write(" <span class='pickerAddTagIcon'></span>");
|
||||
out.write(" <span id='" + divId + "-addTag-linkContainer' class='pickerAddTagLinkContainer'>");
|
||||
out.write(" <a href='#' onclick='window." + objId + ".showAddTagForm(); return false;'>");
|
||||
out.write(msg.getString(MSG_ADD_A_TAG));
|
||||
out.write("</a>");
|
||||
out.write(" </span>");
|
||||
out.write(" <span id='" + divId + "-addTag-formContainer' class='pickerAddTagFormContainer'>");
|
||||
out.write(" <input id='" + divId + "-addTag-box' class='pickerAddTagBox' name='" + divId + "-addTag-box' type='text'>");
|
||||
out.write(" <img id='" + divId + "-addTag-ok' class='pickerAddTagImage' src='");
|
||||
out.write(contextPath);
|
||||
out.write("/images/office/action_successful.gif' alt='");
|
||||
out.write(msg.getString(MSG_ADD));
|
||||
out.write("' title='");
|
||||
out.write(msg.getString(MSG_ADD));
|
||||
out.write("'>");
|
||||
out.write(" <img id='" + divId + "-addTag-cancel' class='pickerAddTagImage' src='");
|
||||
out.write(contextPath);
|
||||
out.write("/images/office/action_failed.gif' alt='");
|
||||
out.write(msg.getString(MSG_CANCEL));
|
||||
out.write("' title='");
|
||||
out.write(msg.getString(MSG_CANCEL));
|
||||
out.write("'>");
|
||||
out.write(" </span>");
|
||||
out.write(" </span>");
|
||||
out.write(" <span id='" + divId + "-nav-add'></span>");
|
||||
out.write(" </div>");
|
||||
out.write(" </div>");
|
||||
// container for item selection
|
||||
out.write(" <div>");
|
||||
out.write(" <div id='" + divId + "-ajax-wait' class='pickerAjaxWait'");
|
||||
String height = getHeight();
|
||||
if (height != null)
|
||||
{
|
||||
out.write(" style='height:" + height + "'");
|
||||
}
|
||||
out.write("></div>");
|
||||
out.write(" <div id='" + divId + "-results-list' class='pickerResultsList'");
|
||||
if (height != null)
|
||||
{
|
||||
out.write(" style='height:" + height + "'");
|
||||
}
|
||||
out.write("></div>");
|
||||
out.write(" </div>");
|
||||
out.write(" </div>");
|
||||
// controls (OK & Cancel buttons etc.)
|
||||
out.write(" <div class='pickerFinishControls'>");
|
||||
out.write(" <div id='" + divId + "-finish' style='float:left' class='pickerButtons'><a href='javascript:" + objId + ".doneClicked();'>");
|
||||
out.write(msg.getString(MSG_OK));
|
||||
out.write("</a></div>");
|
||||
out.write(" <div style='float:right' class='pickerButtons'><a href='javascript:" + objId + ".cancelClicked();'>");
|
||||
out.write(msg.getString(MSG_CANCEL));
|
||||
out.write("</a></div>");
|
||||
out.write(" </div>");
|
||||
out.write(" </div>");
|
||||
// container for the selected items
|
||||
out.write(" <div id='" + divId + "-selected' class='pickerSelectedItems'></div>");
|
||||
out.write("</div>");
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,229 +1,229 @@
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.component.UIComponent;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.event.AbortProcessingException;
|
||||
import javax.faces.event.ActionEvent;
|
||||
import javax.faces.event.FacesEvent;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.CategoryBrowserBean;
|
||||
import org.alfresco.web.bean.NavigationBean;
|
||||
import org.alfresco.web.bean.search.SearchContext;
|
||||
import org.alfresco.web.bean.ajax.CategoryBrowserPluginBean;
|
||||
import org.alfresco.web.data.IDataContainer;
|
||||
import org.alfresco.web.data.QuickSort;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.springframework.extensions.webscripts.ui.common.component.SelfRenderingComponent;
|
||||
import org.alfresco.web.ui.repo.component.UITree.TreeNode;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class UICategoryBrowser extends SelfRenderingComponent
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(UICategoryBrowser.class);
|
||||
|
||||
public static final String COMPONENT_TYPE = "org.alfresco.faces.CategoryBrowser";
|
||||
|
||||
private static final String AJAX_URL_START = "/ajax/invoke/" + CategoryBrowserPluginBean.BEAN_NAME;
|
||||
|
||||
private static final String SUBCATEGORIES_PARAM = "include-subcategories-checkbox";
|
||||
|
||||
@Override
|
||||
public String getFamily()
|
||||
{
|
||||
return COMPONENT_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
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]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object saveState(FacesContext context)
|
||||
{
|
||||
Object values[] = new Object[2];
|
||||
// standard component attributes are saved by the super class
|
||||
values[0] = super.saveState(context);
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void decode(FacesContext context)
|
||||
{
|
||||
Map requestMap = context.getExternalContext().getRequestParameterMap();
|
||||
String fieldId = getClientId(context);
|
||||
String value = (String) requestMap.get(fieldId);
|
||||
|
||||
if (value != null && value.length() != 0)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Received post back: " + value);
|
||||
|
||||
// work out whether a panel or a node was selected
|
||||
String item = value;
|
||||
|
||||
String subcategoriesStr = (String) requestMap.get(SUBCATEGORIES_PARAM);
|
||||
boolean includeSubcategories = "1".equals(subcategoriesStr);
|
||||
logger.debug("Booléen = " + includeSubcategories);
|
||||
|
||||
// queue an event to be handled later
|
||||
CategoryBrowserEvent event = new CategoryBrowserEvent(this, item, includeSubcategories);
|
||||
this.queueEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.alfresco.extension.web.ui.repo.component.UINavigator#broadcast(javax.faces.event.FacesEvent)
|
||||
*/
|
||||
@Override
|
||||
public void broadcast(FacesEvent event) throws AbortProcessingException
|
||||
{
|
||||
if (event instanceof CategoryBrowserEvent)
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
CategoryBrowserEvent categoryBrowseEvent = (CategoryBrowserEvent) event;
|
||||
NodeRef nodeClicked = new NodeRef(categoryBrowseEvent.getItem());
|
||||
boolean subcategories = categoryBrowseEvent.isIncludeSubcategories();
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Selected category: " + nodeClicked + " subcategories? " + subcategories);
|
||||
|
||||
CategoryBrowserBean categoryBrowserBean = (CategoryBrowserBean) FacesHelper.getManagedBean(context,
|
||||
CategoryBrowserBean.BEAN_NAME);
|
||||
categoryBrowserBean.setCurrentCategory(nodeClicked);
|
||||
categoryBrowserBean.setIncludeSubcategories(subcategories);
|
||||
SearchContext categorySearch = categoryBrowserBean.generateCategorySearchContext();
|
||||
|
||||
NavigationBean nb = (NavigationBean) FacesHelper.getManagedBean(context, NavigationBean.BEAN_NAME);
|
||||
nb.setSearchContext(categorySearch);
|
||||
context.getApplication().getNavigationHandler().handleNavigation(context, null, "category-browse");
|
||||
}
|
||||
else
|
||||
{
|
||||
super.broadcast(event);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.alfresco.web.ui.repo.component.UINavigator#encodeBegin(javax.faces.context.FacesContext)
|
||||
*/
|
||||
@Override
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered())
|
||||
return;
|
||||
|
||||
// TODO: pull width and height from user preferences and/or the main config,
|
||||
// if present override below using the style attribute
|
||||
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
CategoryBrowserPluginBean categoryBrowserPluginBean = (CategoryBrowserPluginBean) FacesHelper.getManagedBean(
|
||||
context, CategoryBrowserPluginBean.BEAN_NAME);
|
||||
CategoryBrowserBean categoryBrowserBean = (CategoryBrowserBean) FacesHelper.getManagedBean(context,
|
||||
CategoryBrowserBean.BEAN_NAME);
|
||||
|
||||
List<TreeNode> rootNodes = null;
|
||||
|
||||
rootNodes = categoryBrowserPluginBean.getCategoryRootNodes();
|
||||
// order the root nodes by the tree label
|
||||
if (rootNodes != null && rootNodes.size() > 1)
|
||||
{
|
||||
QuickSort sorter = new QuickSort(rootNodes, "name", true, IDataContainer.SORT_CASEINSENSITIVE);
|
||||
sorter.sort();
|
||||
}
|
||||
|
||||
// main container div
|
||||
out.write("<div id=\"category-navigator\" class=\"navigator\">");
|
||||
|
||||
// Subcategories parameter
|
||||
String includeSub = Application.getMessage(context, "category_browser_plugin_include_subcategories");
|
||||
out.write("<input type='checkbox' id='" + SUBCATEGORIES_PARAM + "' name='" + SUBCATEGORIES_PARAM + "' value=1 "
|
||||
+ (categoryBrowserBean.isIncludeSubcategories() ? "checked" : "") + "/>");
|
||||
out.write("<label for='" + SUBCATEGORIES_PARAM + "'>" + includeSub + "</label>");
|
||||
|
||||
// generate the javascript method to capture the tree node click events
|
||||
out.write("<script type=\"text/javascript\">");
|
||||
out.write("function treeNodeSelected(nodeRef) {");
|
||||
out.write(Utils.generateFormSubmit(context, this, getClientId(context), "nodeRef", true, null));
|
||||
out.write("}</script>");
|
||||
|
||||
// generate the active panel containing the tree
|
||||
out.write("<div class=\"navigatorPanelBody\">");
|
||||
UITree tree = (UITree) context.getApplication().createComponent(UITree.COMPONENT_TYPE);
|
||||
tree.setId("tree");
|
||||
tree.setRootNodes(rootNodes);
|
||||
tree.setRetrieveChildrenUrl(AJAX_URL_START + ".retrieveChildren?");
|
||||
tree.setNodeCollapsedUrl(AJAX_URL_START + ".nodeCollapsed?");
|
||||
tree.setNodeSelectedCallback("treeNodeSelected");
|
||||
tree.setNodeCollapsedCallback("informOfCollapse");
|
||||
Utils.encodeRecursive(context, tree);
|
||||
out.write("</div>");
|
||||
|
||||
out.write("</div>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeChildren(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered())
|
||||
return;
|
||||
for (Iterator i = this.getChildren().iterator(); i.hasNext();)
|
||||
{
|
||||
UIComponent child = (UIComponent) i.next();
|
||||
Utils.encodeRecursive(context, child);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRendersChildren()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing the clicking of a tree node.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public static class CategoryBrowserEvent extends ActionEvent
|
||||
{
|
||||
private String item;
|
||||
|
||||
private boolean includeSubcategories;
|
||||
|
||||
public CategoryBrowserEvent(UIComponent component, String item, boolean include)
|
||||
{
|
||||
super(component);
|
||||
|
||||
this.item = item;
|
||||
this.includeSubcategories = include;
|
||||
}
|
||||
|
||||
public String getItem()
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
public boolean isIncludeSubcategories()
|
||||
{
|
||||
return includeSubcategories;
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.component.UIComponent;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.event.AbortProcessingException;
|
||||
import javax.faces.event.ActionEvent;
|
||||
import javax.faces.event.FacesEvent;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.bean.CategoryBrowserBean;
|
||||
import org.alfresco.web.bean.NavigationBean;
|
||||
import org.alfresco.web.bean.search.SearchContext;
|
||||
import org.alfresco.web.bean.ajax.CategoryBrowserPluginBean;
|
||||
import org.alfresco.web.data.IDataContainer;
|
||||
import org.alfresco.web.data.QuickSort;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.springframework.extensions.webscripts.ui.common.component.SelfRenderingComponent;
|
||||
import org.alfresco.web.ui.repo.component.UITree.TreeNode;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
public class UICategoryBrowser extends SelfRenderingComponent
|
||||
{
|
||||
private static final Log logger = LogFactory.getLog(UICategoryBrowser.class);
|
||||
|
||||
public static final String COMPONENT_TYPE = "org.alfresco.faces.CategoryBrowser";
|
||||
|
||||
private static final String AJAX_URL_START = "/ajax/invoke/" + CategoryBrowserPluginBean.BEAN_NAME;
|
||||
|
||||
private static final String SUBCATEGORIES_PARAM = "include-subcategories-checkbox";
|
||||
|
||||
@Override
|
||||
public String getFamily()
|
||||
{
|
||||
return COMPONENT_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
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]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object saveState(FacesContext context)
|
||||
{
|
||||
Object values[] = new Object[2];
|
||||
// standard component attributes are saved by the super class
|
||||
values[0] = super.saveState(context);
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void decode(FacesContext context)
|
||||
{
|
||||
Map requestMap = context.getExternalContext().getRequestParameterMap();
|
||||
String fieldId = getClientId(context);
|
||||
String value = (String) requestMap.get(fieldId);
|
||||
|
||||
if (value != null && value.length() != 0)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Received post back: " + value);
|
||||
|
||||
// work out whether a panel or a node was selected
|
||||
String item = value;
|
||||
|
||||
String subcategoriesStr = (String) requestMap.get(SUBCATEGORIES_PARAM);
|
||||
boolean includeSubcategories = "1".equals(subcategoriesStr);
|
||||
logger.debug("Booléen = " + includeSubcategories);
|
||||
|
||||
// queue an event to be handled later
|
||||
CategoryBrowserEvent event = new CategoryBrowserEvent(this, item, includeSubcategories);
|
||||
this.queueEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.alfresco.extension.web.ui.repo.component.UINavigator#broadcast(javax.faces.event.FacesEvent)
|
||||
*/
|
||||
@Override
|
||||
public void broadcast(FacesEvent event) throws AbortProcessingException
|
||||
{
|
||||
if (event instanceof CategoryBrowserEvent)
|
||||
{
|
||||
FacesContext context = FacesContext.getCurrentInstance();
|
||||
CategoryBrowserEvent categoryBrowseEvent = (CategoryBrowserEvent) event;
|
||||
NodeRef nodeClicked = new NodeRef(categoryBrowseEvent.getItem());
|
||||
boolean subcategories = categoryBrowseEvent.isIncludeSubcategories();
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Selected category: " + nodeClicked + " subcategories? " + subcategories);
|
||||
|
||||
CategoryBrowserBean categoryBrowserBean = (CategoryBrowserBean) FacesHelper.getManagedBean(context,
|
||||
CategoryBrowserBean.BEAN_NAME);
|
||||
categoryBrowserBean.setCurrentCategory(nodeClicked);
|
||||
categoryBrowserBean.setIncludeSubcategories(subcategories);
|
||||
SearchContext categorySearch = categoryBrowserBean.generateCategorySearchContext();
|
||||
|
||||
NavigationBean nb = (NavigationBean) FacesHelper.getManagedBean(context, NavigationBean.BEAN_NAME);
|
||||
nb.setSearchContext(categorySearch);
|
||||
context.getApplication().getNavigationHandler().handleNavigation(context, null, "category-browse");
|
||||
}
|
||||
else
|
||||
{
|
||||
super.broadcast(event);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.alfresco.web.ui.repo.component.UINavigator#encodeBegin(javax.faces.context.FacesContext)
|
||||
*/
|
||||
@Override
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered())
|
||||
return;
|
||||
|
||||
// TODO: pull width and height from user preferences and/or the main config,
|
||||
// if present override below using the style attribute
|
||||
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
CategoryBrowserPluginBean categoryBrowserPluginBean = (CategoryBrowserPluginBean) FacesHelper.getManagedBean(
|
||||
context, CategoryBrowserPluginBean.BEAN_NAME);
|
||||
CategoryBrowserBean categoryBrowserBean = (CategoryBrowserBean) FacesHelper.getManagedBean(context,
|
||||
CategoryBrowserBean.BEAN_NAME);
|
||||
|
||||
List<TreeNode> rootNodes = null;
|
||||
|
||||
rootNodes = categoryBrowserPluginBean.getCategoryRootNodes();
|
||||
// order the root nodes by the tree label
|
||||
if (rootNodes != null && rootNodes.size() > 1)
|
||||
{
|
||||
QuickSort sorter = new QuickSort(rootNodes, "name", true, IDataContainer.SORT_CASEINSENSITIVE);
|
||||
sorter.sort();
|
||||
}
|
||||
|
||||
// main container div
|
||||
out.write("<div id=\"category-navigator\" class=\"navigator\">");
|
||||
|
||||
// Subcategories parameter
|
||||
String includeSub = Application.getMessage(context, "category_browser_plugin_include_subcategories");
|
||||
out.write("<input type='checkbox' id='" + SUBCATEGORIES_PARAM + "' name='" + SUBCATEGORIES_PARAM + "' value=1 "
|
||||
+ (categoryBrowserBean.isIncludeSubcategories() ? "checked" : "") + "/>");
|
||||
out.write("<label for='" + SUBCATEGORIES_PARAM + "'>" + includeSub + "</label>");
|
||||
|
||||
// generate the javascript method to capture the tree node click events
|
||||
out.write("<script type=\"text/javascript\">");
|
||||
out.write("function treeNodeSelected(nodeRef) {");
|
||||
out.write(Utils.generateFormSubmit(context, this, getClientId(context), "nodeRef", true, null));
|
||||
out.write("}</script>");
|
||||
|
||||
// generate the active panel containing the tree
|
||||
out.write("<div class=\"navigatorPanelBody\">");
|
||||
UITree tree = (UITree) context.getApplication().createComponent(UITree.COMPONENT_TYPE);
|
||||
tree.setId("tree");
|
||||
tree.setRootNodes(rootNodes);
|
||||
tree.setRetrieveChildrenUrl(AJAX_URL_START + ".retrieveChildren?");
|
||||
tree.setNodeCollapsedUrl(AJAX_URL_START + ".nodeCollapsed?");
|
||||
tree.setNodeSelectedCallback("treeNodeSelected");
|
||||
tree.setNodeCollapsedCallback("informOfCollapse");
|
||||
Utils.encodeRecursive(context, tree);
|
||||
out.write("</div>");
|
||||
|
||||
out.write("</div>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeChildren(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered())
|
||||
return;
|
||||
for (Iterator i = this.getChildren().iterator(); i.hasNext();)
|
||||
{
|
||||
UIComponent child = (UIComponent) i.next();
|
||||
Utils.encodeRecursive(context, child);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRendersChildren()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing the clicking of a tree node.
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public static class CategoryBrowserEvent extends ActionEvent
|
||||
{
|
||||
private String item;
|
||||
|
||||
private boolean includeSubcategories;
|
||||
|
||||
public CategoryBrowserEvent(UIComponent component, String item, boolean include)
|
||||
{
|
||||
super(component);
|
||||
|
||||
this.item = item;
|
||||
this.includeSubcategories = include;
|
||||
}
|
||||
|
||||
public String getItem()
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
public boolean isIncludeSubcategories()
|
||||
{
|
||||
return includeSubcategories;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,402 +1,402 @@
|
||||
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.LimitBy;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.SearchParameters;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.SearchLanguageConversion;
|
||||
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("'/> <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(Utils.encode(Repository.getDisplayPath(nodeService.getPath(item))));
|
||||
out.write("/");
|
||||
out.write(Utils.encode(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 = SearchLanguageConversion.escapeLuceneQuery(contains.trim());
|
||||
query.append(" AND +@");
|
||||
|
||||
String nameAttr = Repository.escapeQName(QName.createQName(
|
||||
NamespaceService.CONTENT_MODEL_1_0_URI, "name"));
|
||||
query.append(nameAttr);
|
||||
|
||||
query.append(":\"*" + safeContains + "*\"");
|
||||
}
|
||||
|
||||
int maxResults = Application.getClientConfig(context).getSelectorsSearchMaxResults();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Query: " + query.toString());
|
||||
logger.debug("Max results size: " + maxResults);
|
||||
}
|
||||
|
||||
// setup search parameters, including limiting the results
|
||||
SearchParameters searchParams = new SearchParameters();
|
||||
searchParams.addStore(Repository.getStoreRef());
|
||||
searchParams.setLanguage(SearchService.LANGUAGE_LUCENE);
|
||||
searchParams.setQuery(query.toString());
|
||||
if (maxResults > 0)
|
||||
{
|
||||
searchParams.setLimit(maxResults);
|
||||
searchParams.setLimitBy(LimitBy.FINAL_SIZE);
|
||||
}
|
||||
|
||||
ResultSet results = null;
|
||||
try
|
||||
{
|
||||
results = Repository.getServiceRegistry(context).getSearchService().query(searchParams);
|
||||
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);
|
||||
}
|
||||
}
|
||||
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.LimitBy;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.SearchParameters;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.SearchLanguageConversion;
|
||||
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("'/> <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(Utils.encode(Repository.getDisplayPath(nodeService.getPath(item))));
|
||||
out.write("/");
|
||||
out.write(Utils.encode(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 = SearchLanguageConversion.escapeLuceneQuery(contains.trim());
|
||||
query.append(" AND +@");
|
||||
|
||||
String nameAttr = Repository.escapeQName(QName.createQName(
|
||||
NamespaceService.CONTENT_MODEL_1_0_URI, "name"));
|
||||
query.append(nameAttr);
|
||||
|
||||
query.append(":\"*" + safeContains + "*\"");
|
||||
}
|
||||
|
||||
int maxResults = Application.getClientConfig(context).getSelectorsSearchMaxResults();
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("Query: " + query.toString());
|
||||
logger.debug("Max results size: " + maxResults);
|
||||
}
|
||||
|
||||
// setup search parameters, including limiting the results
|
||||
SearchParameters searchParams = new SearchParameters();
|
||||
searchParams.addStore(Repository.getStoreRef());
|
||||
searchParams.setLanguage(SearchService.LANGUAGE_LUCENE);
|
||||
searchParams.setQuery(query.toString());
|
||||
if (maxResults > 0)
|
||||
{
|
||||
searchParams.setLimit(maxResults);
|
||||
searchParams.setLimitBy(LimitBy.FINAL_SIZE);
|
||||
}
|
||||
|
||||
ResultSet results = null;
|
||||
try
|
||||
{
|
||||
results = Repository.getServiceRegistry(context).getSearchService().query(searchParams);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@@ -1,295 +1,295 @@
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.component.UICommand;
|
||||
import javax.faces.component.UIComponent;
|
||||
import javax.faces.component.UIOutput;
|
||||
import javax.faces.component.html.HtmlCommandButton;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.el.MethodBinding;
|
||||
import javax.faces.el.ValueBinding;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.config.DialogsConfigElement.DialogButtonConfig;
|
||||
import org.alfresco.web.ui.common.ComponentConstants;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.springframework.extensions.webscripts.ui.common.component.SelfRenderingComponent;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Component that displays the buttons for a dialog.
|
||||
* <p>
|
||||
* The standard <code>OK</code> and <code>Cancel</code> buttons
|
||||
* are always generated. Any additional buttons, either configured
|
||||
* or generated dynamically by the dialog, are generated in between
|
||||
* the standard buttons.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class UIDialogButtons extends SelfRenderingComponent
|
||||
{
|
||||
protected static final String BINDING_EXPRESSION_START = "#{";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(UIDialogButtons.class);
|
||||
|
||||
@Override
|
||||
public String getFamily()
|
||||
{
|
||||
return "org.alfresco.faces.DialogButtons";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
if (this.getChildCount() == 0)
|
||||
{
|
||||
// generate all the required buttons the first time
|
||||
generateButtons(context);
|
||||
}
|
||||
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
out.write("<table cellpadding=\"1\" cellspacing=\"1\" border=\"0\">");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeChildren(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
|
||||
// render the buttons
|
||||
for (Iterator i = getChildren().iterator(); i.hasNext(); /**/)
|
||||
{
|
||||
out.write("<tr><td align=\"center\">");
|
||||
|
||||
UIComponent child = (UIComponent)i.next();
|
||||
Utils.encodeRecursive(context, child);
|
||||
|
||||
out.write("</td></tr>");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeEnd(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
out.write("</table>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRendersChildren()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the buttons for the dialog currently being shown.
|
||||
*
|
||||
* @param context Faces context
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void generateButtons(FacesContext context)
|
||||
{
|
||||
// generate the OK button, if necessary
|
||||
if (Application.getDialogManager().isOKButtonVisible())
|
||||
{
|
||||
UICommand okButton = (UICommand)context.getApplication().
|
||||
createComponent(HtmlCommandButton.COMPONENT_TYPE);
|
||||
okButton.setRendererType(ComponentConstants.JAVAX_FACES_BUTTON);
|
||||
FacesHelper.setupComponentId(context, okButton, "finish-button");
|
||||
|
||||
// create the binding for the finish button label
|
||||
ValueBinding valueBinding = context.getApplication().createValueBinding(
|
||||
"#{DialogManager.finishButtonLabel}");
|
||||
okButton.setValueBinding("value", valueBinding);
|
||||
|
||||
// create the action binding
|
||||
MethodBinding methodBinding = context.getApplication().createMethodBinding(
|
||||
"#{DialogManager.finish}", null);
|
||||
okButton.setAction(methodBinding);
|
||||
|
||||
// create the binding for whether the button is disabled
|
||||
valueBinding = context.getApplication().createValueBinding(
|
||||
"#{DialogManager.finishButtonDisabled}");
|
||||
okButton.setValueBinding("disabled", valueBinding);
|
||||
|
||||
// setup CSS class for button
|
||||
String styleClass = (String)this.getAttributes().get("styleClass");
|
||||
if (styleClass != null)
|
||||
{
|
||||
okButton.getAttributes().put("styleClass", styleClass);
|
||||
}
|
||||
|
||||
// add the OK button
|
||||
this.getChildren().add(okButton);
|
||||
}
|
||||
|
||||
// generate the additional buttons
|
||||
generateAdditionalButtons(context);
|
||||
|
||||
// generate the OK button
|
||||
UICommand cancelButton = (UICommand)context.getApplication().
|
||||
createComponent(HtmlCommandButton.COMPONENT_TYPE);
|
||||
cancelButton.setRendererType(ComponentConstants.JAVAX_FACES_BUTTON);
|
||||
FacesHelper.setupComponentId(context, cancelButton, "cancel-button");
|
||||
|
||||
// create the binding for the cancel button label
|
||||
ValueBinding valueBinding = context.getApplication().createValueBinding(
|
||||
"#{DialogManager.cancelButtonLabel}");
|
||||
cancelButton.setValueBinding("value", valueBinding);
|
||||
|
||||
// create the action binding
|
||||
MethodBinding methodBinding = context.getApplication().createMethodBinding(
|
||||
"#{DialogManager.cancel}", null);
|
||||
cancelButton.setAction(methodBinding);
|
||||
|
||||
// setup CSS class for button
|
||||
String styleClass = (String)this.getAttributes().get("styleClass");
|
||||
if (styleClass != null)
|
||||
{
|
||||
cancelButton.getAttributes().put("styleClass", styleClass);
|
||||
}
|
||||
|
||||
// set the immediate flag to true
|
||||
cancelButton.getAttributes().put("immediate", Boolean.TRUE);
|
||||
|
||||
// add the Cancel button
|
||||
this.getChildren().add(cancelButton);
|
||||
}
|
||||
|
||||
/**
|
||||
* If there are any additional buttons to add as defined by the dialog
|
||||
* configuration and the dialog at runtime they are generated in this
|
||||
* method.
|
||||
*
|
||||
* @param context Faces context
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void generateAdditionalButtons(FacesContext context)
|
||||
{
|
||||
// get potential list of additional buttons
|
||||
List<DialogButtonConfig> buttons = Application.getDialogManager().getAdditionalButtons();
|
||||
|
||||
if (buttons != null && buttons.size() > 0)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Adding " + buttons.size() + " additional buttons: " + buttons);
|
||||
|
||||
// add a spacing row to separate the additional buttons from the OK button
|
||||
addSpacingRow(context);
|
||||
|
||||
for (DialogButtonConfig buttonCfg : buttons)
|
||||
{
|
||||
UICommand button = (UICommand)context.getApplication().
|
||||
createComponent(HtmlCommandButton.COMPONENT_TYPE);
|
||||
button.setRendererType(ComponentConstants.JAVAX_FACES_BUTTON);
|
||||
FacesHelper.setupComponentId(context, button, buttonCfg.getId());
|
||||
|
||||
// setup the value of the button (the label)
|
||||
String label = buttonCfg.getLabel();
|
||||
if (label != null)
|
||||
{
|
||||
// see if the label represents a value binding
|
||||
if (label.startsWith(BINDING_EXPRESSION_START))
|
||||
{
|
||||
ValueBinding binding = context.getApplication().createValueBinding(label);
|
||||
button.setValueBinding("value", binding);
|
||||
}
|
||||
else
|
||||
{
|
||||
button.setValue(label);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: the config checks that a label or a label id
|
||||
// is present so we can assume there is an id
|
||||
// if there isn't a label
|
||||
String labelId = buttonCfg.getLabelId();
|
||||
label = Application.getMessage(context, labelId);
|
||||
button.setValue(label);
|
||||
}
|
||||
|
||||
// setup the action binding, the config checks that an action
|
||||
// is present so no need to check for NullPointer. It also checks
|
||||
// it represents a method binding expression.
|
||||
String action = buttonCfg.getAction();
|
||||
MethodBinding methodBinding = context.getApplication().
|
||||
createMethodBinding(action, null);
|
||||
button.setAction(methodBinding);
|
||||
|
||||
// setup the disabled attribute, check for null and
|
||||
// binding expressions
|
||||
String disabled = buttonCfg.getDisabled();
|
||||
if (disabled != null && disabled.length() > 0)
|
||||
{
|
||||
if (disabled.startsWith(BINDING_EXPRESSION_START))
|
||||
{
|
||||
ValueBinding binding = context.getApplication().
|
||||
createValueBinding(disabled);
|
||||
button.setValueBinding("disabled", binding);
|
||||
}
|
||||
else
|
||||
{
|
||||
button.getAttributes().put("disabled",
|
||||
Boolean.parseBoolean(disabled));
|
||||
}
|
||||
}
|
||||
|
||||
// setup CSS class for the button
|
||||
String styleClass = (String)this.getAttributes().get("styleClass");
|
||||
if (styleClass != null)
|
||||
{
|
||||
button.getAttributes().put("styleClass", styleClass);
|
||||
}
|
||||
|
||||
// setup the onclick handler for the button
|
||||
String onclick = buttonCfg.getOnclick();
|
||||
if (onclick != null && onclick.length() > 0)
|
||||
{
|
||||
button.getAttributes().put("onclick", onclick);
|
||||
}
|
||||
|
||||
// add the button
|
||||
this.getChildren().add(button);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Added button with id of: " + button.getId());
|
||||
}
|
||||
|
||||
// add a spacing row to separate the additional buttons from the Cancel button
|
||||
addSpacingRow(context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an output text component to represent a spacing row.
|
||||
*
|
||||
* @param context Faces context
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void addSpacingRow(FacesContext context)
|
||||
{
|
||||
UIOutput spacingRow = (UIOutput)context.getApplication().createComponent(
|
||||
ComponentConstants.JAVAX_FACES_OUTPUT);
|
||||
spacingRow.setRendererType(ComponentConstants.JAVAX_FACES_TEXT);
|
||||
FacesHelper.setupComponentId(context, spacingRow, null);
|
||||
spacingRow.setValue("<div class=\"wizardButtonSpacing\" />");
|
||||
spacingRow.getAttributes().put("escape", Boolean.FALSE);
|
||||
this.getChildren().add(spacingRow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.component.UICommand;
|
||||
import javax.faces.component.UIComponent;
|
||||
import javax.faces.component.UIOutput;
|
||||
import javax.faces.component.html.HtmlCommandButton;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.el.MethodBinding;
|
||||
import javax.faces.el.ValueBinding;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.app.servlet.FacesHelper;
|
||||
import org.alfresco.web.config.DialogsConfigElement.DialogButtonConfig;
|
||||
import org.alfresco.web.ui.common.ComponentConstants;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.springframework.extensions.webscripts.ui.common.component.SelfRenderingComponent;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Component that displays the buttons for a dialog.
|
||||
* <p>
|
||||
* The standard <code>OK</code> and <code>Cancel</code> buttons
|
||||
* are always generated. Any additional buttons, either configured
|
||||
* or generated dynamically by the dialog, are generated in between
|
||||
* the standard buttons.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class UIDialogButtons extends SelfRenderingComponent
|
||||
{
|
||||
protected static final String BINDING_EXPRESSION_START = "#{";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(UIDialogButtons.class);
|
||||
|
||||
@Override
|
||||
public String getFamily()
|
||||
{
|
||||
return "org.alfresco.faces.DialogButtons";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
if (this.getChildCount() == 0)
|
||||
{
|
||||
// generate all the required buttons the first time
|
||||
generateButtons(context);
|
||||
}
|
||||
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
out.write("<table cellpadding=\"1\" cellspacing=\"1\" border=\"0\">");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeChildren(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
|
||||
// render the buttons
|
||||
for (Iterator i = getChildren().iterator(); i.hasNext(); /**/)
|
||||
{
|
||||
out.write("<tr><td align=\"center\">");
|
||||
|
||||
UIComponent child = (UIComponent)i.next();
|
||||
Utils.encodeRecursive(context, child);
|
||||
|
||||
out.write("</td></tr>");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeEnd(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
out.write("</table>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRendersChildren()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the buttons for the dialog currently being shown.
|
||||
*
|
||||
* @param context Faces context
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void generateButtons(FacesContext context)
|
||||
{
|
||||
// generate the OK button, if necessary
|
||||
if (Application.getDialogManager().isOKButtonVisible())
|
||||
{
|
||||
UICommand okButton = (UICommand)context.getApplication().
|
||||
createComponent(HtmlCommandButton.COMPONENT_TYPE);
|
||||
okButton.setRendererType(ComponentConstants.JAVAX_FACES_BUTTON);
|
||||
FacesHelper.setupComponentId(context, okButton, "finish-button");
|
||||
|
||||
// create the binding for the finish button label
|
||||
ValueBinding valueBinding = context.getApplication().createValueBinding(
|
||||
"#{DialogManager.finishButtonLabel}");
|
||||
okButton.setValueBinding("value", valueBinding);
|
||||
|
||||
// create the action binding
|
||||
MethodBinding methodBinding = context.getApplication().createMethodBinding(
|
||||
"#{DialogManager.finish}", null);
|
||||
okButton.setAction(methodBinding);
|
||||
|
||||
// create the binding for whether the button is disabled
|
||||
valueBinding = context.getApplication().createValueBinding(
|
||||
"#{DialogManager.finishButtonDisabled}");
|
||||
okButton.setValueBinding("disabled", valueBinding);
|
||||
|
||||
// setup CSS class for button
|
||||
String styleClass = (String)this.getAttributes().get("styleClass");
|
||||
if (styleClass != null)
|
||||
{
|
||||
okButton.getAttributes().put("styleClass", styleClass);
|
||||
}
|
||||
|
||||
// add the OK button
|
||||
this.getChildren().add(okButton);
|
||||
}
|
||||
|
||||
// generate the additional buttons
|
||||
generateAdditionalButtons(context);
|
||||
|
||||
// generate the OK button
|
||||
UICommand cancelButton = (UICommand)context.getApplication().
|
||||
createComponent(HtmlCommandButton.COMPONENT_TYPE);
|
||||
cancelButton.setRendererType(ComponentConstants.JAVAX_FACES_BUTTON);
|
||||
FacesHelper.setupComponentId(context, cancelButton, "cancel-button");
|
||||
|
||||
// create the binding for the cancel button label
|
||||
ValueBinding valueBinding = context.getApplication().createValueBinding(
|
||||
"#{DialogManager.cancelButtonLabel}");
|
||||
cancelButton.setValueBinding("value", valueBinding);
|
||||
|
||||
// create the action binding
|
||||
MethodBinding methodBinding = context.getApplication().createMethodBinding(
|
||||
"#{DialogManager.cancel}", null);
|
||||
cancelButton.setAction(methodBinding);
|
||||
|
||||
// setup CSS class for button
|
||||
String styleClass = (String)this.getAttributes().get("styleClass");
|
||||
if (styleClass != null)
|
||||
{
|
||||
cancelButton.getAttributes().put("styleClass", styleClass);
|
||||
}
|
||||
|
||||
// set the immediate flag to true
|
||||
cancelButton.getAttributes().put("immediate", Boolean.TRUE);
|
||||
|
||||
// add the Cancel button
|
||||
this.getChildren().add(cancelButton);
|
||||
}
|
||||
|
||||
/**
|
||||
* If there are any additional buttons to add as defined by the dialog
|
||||
* configuration and the dialog at runtime they are generated in this
|
||||
* method.
|
||||
*
|
||||
* @param context Faces context
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void generateAdditionalButtons(FacesContext context)
|
||||
{
|
||||
// get potential list of additional buttons
|
||||
List<DialogButtonConfig> buttons = Application.getDialogManager().getAdditionalButtons();
|
||||
|
||||
if (buttons != null && buttons.size() > 0)
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Adding " + buttons.size() + " additional buttons: " + buttons);
|
||||
|
||||
// add a spacing row to separate the additional buttons from the OK button
|
||||
addSpacingRow(context);
|
||||
|
||||
for (DialogButtonConfig buttonCfg : buttons)
|
||||
{
|
||||
UICommand button = (UICommand)context.getApplication().
|
||||
createComponent(HtmlCommandButton.COMPONENT_TYPE);
|
||||
button.setRendererType(ComponentConstants.JAVAX_FACES_BUTTON);
|
||||
FacesHelper.setupComponentId(context, button, buttonCfg.getId());
|
||||
|
||||
// setup the value of the button (the label)
|
||||
String label = buttonCfg.getLabel();
|
||||
if (label != null)
|
||||
{
|
||||
// see if the label represents a value binding
|
||||
if (label.startsWith(BINDING_EXPRESSION_START))
|
||||
{
|
||||
ValueBinding binding = context.getApplication().createValueBinding(label);
|
||||
button.setValueBinding("value", binding);
|
||||
}
|
||||
else
|
||||
{
|
||||
button.setValue(label);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: the config checks that a label or a label id
|
||||
// is present so we can assume there is an id
|
||||
// if there isn't a label
|
||||
String labelId = buttonCfg.getLabelId();
|
||||
label = Application.getMessage(context, labelId);
|
||||
button.setValue(label);
|
||||
}
|
||||
|
||||
// setup the action binding, the config checks that an action
|
||||
// is present so no need to check for NullPointer. It also checks
|
||||
// it represents a method binding expression.
|
||||
String action = buttonCfg.getAction();
|
||||
MethodBinding methodBinding = context.getApplication().
|
||||
createMethodBinding(action, null);
|
||||
button.setAction(methodBinding);
|
||||
|
||||
// setup the disabled attribute, check for null and
|
||||
// binding expressions
|
||||
String disabled = buttonCfg.getDisabled();
|
||||
if (disabled != null && disabled.length() > 0)
|
||||
{
|
||||
if (disabled.startsWith(BINDING_EXPRESSION_START))
|
||||
{
|
||||
ValueBinding binding = context.getApplication().
|
||||
createValueBinding(disabled);
|
||||
button.setValueBinding("disabled", binding);
|
||||
}
|
||||
else
|
||||
{
|
||||
button.getAttributes().put("disabled",
|
||||
Boolean.parseBoolean(disabled));
|
||||
}
|
||||
}
|
||||
|
||||
// setup CSS class for the button
|
||||
String styleClass = (String)this.getAttributes().get("styleClass");
|
||||
if (styleClass != null)
|
||||
{
|
||||
button.getAttributes().put("styleClass", styleClass);
|
||||
}
|
||||
|
||||
// setup the onclick handler for the button
|
||||
String onclick = buttonCfg.getOnclick();
|
||||
if (onclick != null && onclick.length() > 0)
|
||||
{
|
||||
button.getAttributes().put("onclick", onclick);
|
||||
}
|
||||
|
||||
// add the button
|
||||
this.getChildren().add(button);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Added button with id of: " + button.getId());
|
||||
}
|
||||
|
||||
// add a spacing row to separate the additional buttons from the Cancel button
|
||||
addSpacingRow(context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an output text component to represent a spacing row.
|
||||
*
|
||||
* @param context Faces context
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void addSpacingRow(FacesContext context)
|
||||
{
|
||||
UIOutput spacingRow = (UIOutput)context.getApplication().createComponent(
|
||||
ComponentConstants.JAVAX_FACES_OUTPUT);
|
||||
spacingRow.setRendererType(ComponentConstants.JAVAX_FACES_TEXT);
|
||||
FacesHelper.setupComponentId(context, spacingRow, null);
|
||||
spacingRow.setValue("<div class=\"wizardButtonSpacing\" />");
|
||||
spacingRow.getAttributes().put("escape", Boolean.FALSE);
|
||||
this.getChildren().add(spacingRow);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@@ -1,76 +1,76 @@
|
||||
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.UISelectItems;
|
||||
import javax.faces.component.UISelectOne;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.model.SelectItem;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.data.IDataContainer;
|
||||
import org.alfresco.web.data.QuickSort;
|
||||
|
||||
/**
|
||||
* Component that holds a list of MIME types configured in the repository.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class UIMimeTypeSelector extends UISelectOne
|
||||
{
|
||||
public static final String COMPONENT_TYPE = "org.alfresco.faces.MimeTypeSelector";
|
||||
public static final String COMPONENT_FAMILY = "javax.faces.SelectOne";
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
// if the component does not have any children yet create the
|
||||
// list of MIME types the user can choose from as a child
|
||||
// SelectItems component.
|
||||
if (getChildren().size() == 0)
|
||||
{
|
||||
UISelectItems items = (UISelectItems)context.getApplication().
|
||||
createComponent("javax.faces.SelectItems");
|
||||
items.setId(this.getId() + "_items");
|
||||
items.setValue(createList());
|
||||
|
||||
// add the child component
|
||||
getChildren().add(items);
|
||||
}
|
||||
|
||||
// do the default processing
|
||||
super.encodeBegin(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the list of SelectItem components to represent the list
|
||||
* of MIME types the user can select from
|
||||
*
|
||||
* @return List of SelectItem components
|
||||
*/
|
||||
protected List<SelectItem> createList()
|
||||
{
|
||||
List<SelectItem> items = new ArrayList<SelectItem>(80);
|
||||
ServiceRegistry registry = Repository.getServiceRegistry(FacesContext.getCurrentInstance());
|
||||
MimetypeService mimetypeService = registry.getMimetypeService();
|
||||
|
||||
// get the mime type display names
|
||||
Map<String, String> mimeTypes = mimetypeService.getDisplaysByMimetype();
|
||||
for (String mimeType : mimeTypes.keySet())
|
||||
{
|
||||
items.add(new SelectItem(mimeType, mimeTypes.get(mimeType)));
|
||||
}
|
||||
|
||||
// make sure the list is sorted by the values
|
||||
QuickSort sorter = new QuickSort(items, "label", true, IDataContainer.SORT_CASEINSENSITIVE);
|
||||
sorter.sort();
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
||||
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.UISelectItems;
|
||||
import javax.faces.component.UISelectOne;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.model.SelectItem;
|
||||
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.data.IDataContainer;
|
||||
import org.alfresco.web.data.QuickSort;
|
||||
|
||||
/**
|
||||
* Component that holds a list of MIME types configured in the repository.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class UIMimeTypeSelector extends UISelectOne
|
||||
{
|
||||
public static final String COMPONENT_TYPE = "org.alfresco.faces.MimeTypeSelector";
|
||||
public static final String COMPONENT_FAMILY = "javax.faces.SelectOne";
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
// if the component does not have any children yet create the
|
||||
// list of MIME types the user can choose from as a child
|
||||
// SelectItems component.
|
||||
if (getChildren().size() == 0)
|
||||
{
|
||||
UISelectItems items = (UISelectItems)context.getApplication().
|
||||
createComponent("javax.faces.SelectItems");
|
||||
items.setId(this.getId() + "_items");
|
||||
items.setValue(createList());
|
||||
|
||||
// add the child component
|
||||
getChildren().add(items);
|
||||
}
|
||||
|
||||
// do the default processing
|
||||
super.encodeBegin(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the list of SelectItem components to represent the list
|
||||
* of MIME types the user can select from
|
||||
*
|
||||
* @return List of SelectItem components
|
||||
*/
|
||||
protected List<SelectItem> createList()
|
||||
{
|
||||
List<SelectItem> items = new ArrayList<SelectItem>(80);
|
||||
ServiceRegistry registry = Repository.getServiceRegistry(FacesContext.getCurrentInstance());
|
||||
MimetypeService mimetypeService = registry.getMimetypeService();
|
||||
|
||||
// get the mime type display names
|
||||
Map<String, String> mimeTypes = mimetypeService.getDisplaysByMimetype();
|
||||
for (String mimeType : mimeTypes.keySet())
|
||||
{
|
||||
items.add(new SelectItem(mimeType, mimeTypes.get(mimeType)));
|
||||
}
|
||||
|
||||
// make sure the list is sorted by the values
|
||||
QuickSort sorter = new QuickSort(items, "label", true, IDataContainer.SORT_CASEINSENSITIVE);
|
||||
sorter.sort();
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
@@ -1,133 +1,133 @@
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.el.ValueBinding;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.springframework.extensions.webscripts.ui.common.component.SelfRenderingComponent;
|
||||
|
||||
/**
|
||||
* JSF component that displays information about a node.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class UINodeInfo extends SelfRenderingComponent
|
||||
{
|
||||
protected final static String NODE_INFO_SCRIPTS_WRITTEN = "_alfNodeInfoScripts";
|
||||
|
||||
protected Object value = null;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Component Impl
|
||||
|
||||
@Override
|
||||
public String getFamily()
|
||||
{
|
||||
return "org.alfresco.faces.NodeInfo";
|
||||
}
|
||||
|
||||
@Override
|
||||
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.value = values[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object saveState(FacesContext context)
|
||||
{
|
||||
Object values[] = new Object[] {
|
||||
super.saveState(context),
|
||||
this.value};
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
// if AJAX is disabled don't render anything
|
||||
if (Application.getClientConfig(context).isNodeSummaryEnabled())
|
||||
{
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
|
||||
outputNodeInfoScripts(context, out);
|
||||
|
||||
// wrap the child components in a <span> that has the onmouseover
|
||||
// event which kicks off the request for node information
|
||||
// we key the node info panel by the noderef string of the current node
|
||||
String noderef = Repository.getStoreRef().toString() + '/' + (String)this.getValue();
|
||||
out.write("<span onclick=\"AlfNodeInfoMgr.toggle('");
|
||||
out.write(noderef);
|
||||
out.write("',this);\">");
|
||||
}
|
||||
}
|
||||
|
||||
protected static void outputNodeInfoScripts(FacesContext context, ResponseWriter out) throws IOException
|
||||
{
|
||||
// write out the JavaScript specific to the NodeInfo component, ensure it's only done once
|
||||
Object present = context.getExternalContext().getRequestMap().get(NODE_INFO_SCRIPTS_WRITTEN);
|
||||
if (present == null)
|
||||
{
|
||||
out.write("<script>var AlfNodeInfoMgr = new Alfresco.PanelManager(" +
|
||||
"\"NodeInfoBean.sendNodeInfo\", \"noderef\");</script>");
|
||||
|
||||
context.getExternalContext().getRequestMap().put(
|
||||
NODE_INFO_SCRIPTS_WRITTEN, Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeEnd(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
// if AJAX is disabled don't render anything
|
||||
if (Application.getClientConfig(context).isNodeSummaryEnabled())
|
||||
{
|
||||
context.getResponseWriter().write("</span>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Strongly typed component property accessors
|
||||
|
||||
/**
|
||||
* Get the value - the value is used in a equals() match against the current value in the
|
||||
* parent ModeList component to set the selected item.
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
public Object getValue()
|
||||
{
|
||||
ValueBinding vb = getValueBinding("value");
|
||||
if (vb != null)
|
||||
{
|
||||
this.value = vb.getValue(getFacesContext());
|
||||
}
|
||||
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value - the value is used in a equals() match against the current value in the
|
||||
* parent ModeList component to set the selected item.
|
||||
*
|
||||
* @param value the value
|
||||
*/
|
||||
public void setValue(Object value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.el.ValueBinding;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.springframework.extensions.webscripts.ui.common.component.SelfRenderingComponent;
|
||||
|
||||
/**
|
||||
* JSF component that displays information about a node.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class UINodeInfo extends SelfRenderingComponent
|
||||
{
|
||||
protected final static String NODE_INFO_SCRIPTS_WRITTEN = "_alfNodeInfoScripts";
|
||||
|
||||
protected Object value = null;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Component Impl
|
||||
|
||||
@Override
|
||||
public String getFamily()
|
||||
{
|
||||
return "org.alfresco.faces.NodeInfo";
|
||||
}
|
||||
|
||||
@Override
|
||||
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.value = values[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object saveState(FacesContext context)
|
||||
{
|
||||
Object values[] = new Object[] {
|
||||
super.saveState(context),
|
||||
this.value};
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
// if AJAX is disabled don't render anything
|
||||
if (Application.getClientConfig(context).isNodeSummaryEnabled())
|
||||
{
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
|
||||
outputNodeInfoScripts(context, out);
|
||||
|
||||
// wrap the child components in a <span> that has the onmouseover
|
||||
// event which kicks off the request for node information
|
||||
// we key the node info panel by the noderef string of the current node
|
||||
String noderef = Repository.getStoreRef().toString() + '/' + (String)this.getValue();
|
||||
out.write("<span onclick=\"AlfNodeInfoMgr.toggle('");
|
||||
out.write(noderef);
|
||||
out.write("',this);\">");
|
||||
}
|
||||
}
|
||||
|
||||
protected static void outputNodeInfoScripts(FacesContext context, ResponseWriter out) throws IOException
|
||||
{
|
||||
// write out the JavaScript specific to the NodeInfo component, ensure it's only done once
|
||||
Object present = context.getExternalContext().getRequestMap().get(NODE_INFO_SCRIPTS_WRITTEN);
|
||||
if (present == null)
|
||||
{
|
||||
out.write("<script>var AlfNodeInfoMgr = new Alfresco.PanelManager(" +
|
||||
"\"NodeInfoBean.sendNodeInfo\", \"noderef\");</script>");
|
||||
|
||||
context.getExternalContext().getRequestMap().put(
|
||||
NODE_INFO_SCRIPTS_WRITTEN, Boolean.TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeEnd(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
// if AJAX is disabled don't render anything
|
||||
if (Application.getClientConfig(context).isNodeSummaryEnabled())
|
||||
{
|
||||
context.getResponseWriter().write("</span>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Strongly typed component property accessors
|
||||
|
||||
/**
|
||||
* Get the value - the value is used in a equals() match against the current value in the
|
||||
* parent ModeList component to set the selected item.
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
public Object getValue()
|
||||
{
|
||||
ValueBinding vb = getValueBinding("value");
|
||||
if (vb != null)
|
||||
{
|
||||
this.value = vb.getValue(getFacesContext());
|
||||
}
|
||||
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value - the value is used in a equals() match against the current value in the
|
||||
* parent ModeList component to set the selected item.
|
||||
*
|
||||
* @param value the value
|
||||
*/
|
||||
public void setValue(Object value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
@@ -1,347 +1,347 @@
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.el.ValueBinding;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowInstance;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.springframework.extensions.webscripts.ui.common.component.SelfRenderingComponent;
|
||||
|
||||
/**
|
||||
* JSF component that displays information about the workflows a node is involved in.
|
||||
* <p>
|
||||
* The node to show workflow information on.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class UINodeWorkflowInfo extends SelfRenderingComponent
|
||||
{
|
||||
protected Node value = null;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Component Impl
|
||||
|
||||
@Override
|
||||
public String getFamily()
|
||||
{
|
||||
return "org.alfresco.faces.NodeWorkflowInfo";
|
||||
}
|
||||
|
||||
@Override
|
||||
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.value = (Node)values[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object saveState(FacesContext context)
|
||||
{
|
||||
Object values[] = new Object[8];
|
||||
// standard component attributes are saved by the super class
|
||||
values[0] = super.saveState(context);
|
||||
values[1] = this.value;
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
// get the node to display the information for
|
||||
Node node = getValue();
|
||||
|
||||
if (node != null)
|
||||
{
|
||||
// get the services we need
|
||||
NodeService nodeService = Repository.getServiceRegistry(context).getNodeService();
|
||||
DictionaryService ddService = Repository.getServiceRegistry(context).getDictionaryService();
|
||||
WorkflowService workflowService = Repository.getServiceRegistry(context).getWorkflowService();
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
ResourceBundle bundle = Application.getBundle(context);
|
||||
|
||||
// render simple workflow info
|
||||
renderSimpleWorkflowInfo(context, node, nodeService, ddService, out, bundle);
|
||||
|
||||
// render advanced workflow info
|
||||
renderAdvancedWorkflowInfo(context, node, nodeService, ddService, workflowService, out, bundle);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeEnd(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Strongly typed component property accessors
|
||||
|
||||
/**
|
||||
* Get the value, this will be a node representing a piece of content or a space
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
public Node getValue()
|
||||
{
|
||||
ValueBinding vb = getValueBinding("value");
|
||||
if (vb != null)
|
||||
{
|
||||
this.value = (Node)vb.getValue(getFacesContext());
|
||||
}
|
||||
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value, either a space or content node.
|
||||
*
|
||||
* @param value the value
|
||||
*/
|
||||
public void setValue(Node value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Helper methods
|
||||
|
||||
/**
|
||||
* Renders the simple workflow details for the given node.
|
||||
*
|
||||
* @param context Faces context
|
||||
* @param node The node
|
||||
* @param nodeService The NodeService instance
|
||||
* @param ddService The Data Dictionary instance
|
||||
* @param out The response writer
|
||||
* @param bundle Message bundle to get strings from
|
||||
*/
|
||||
protected void renderSimpleWorkflowInfo(FacesContext context, Node node,
|
||||
NodeService nodeService, DictionaryService ddService,
|
||||
ResponseWriter out, ResourceBundle bundle)
|
||||
throws IOException
|
||||
{
|
||||
boolean isContent = true;
|
||||
|
||||
QName type = nodeService.getType(node.getNodeRef());
|
||||
if (ddService.isSubClass(type, ContentModel.TYPE_FOLDER))
|
||||
{
|
||||
isContent = false;
|
||||
}
|
||||
|
||||
// Render HTML for simple workflow
|
||||
if (isContent)
|
||||
{
|
||||
// TODO: for now we only support advanced workflow on content so only
|
||||
// render the simple workflow title if the node is a content node
|
||||
out.write("<div class=\"nodeWorkflowInfoTitle\">");
|
||||
out.write(bundle.getString("simple_workflow"));
|
||||
out.write("</div>");
|
||||
}
|
||||
out.write("<div class=\"nodeWorkflowInfoText\">");
|
||||
|
||||
if (node.hasAspect(ApplicationModel.ASPECT_SIMPLE_WORKFLOW))
|
||||
{
|
||||
// get the simple workflow aspect properties
|
||||
Map<String, Object> props = node.getProperties();
|
||||
|
||||
String approveStepName = (String)props.get(
|
||||
ApplicationModel.PROP_APPROVE_STEP.toString());
|
||||
String rejectStepName = (String)props.get(
|
||||
ApplicationModel.PROP_REJECT_STEP.toString());
|
||||
|
||||
Boolean approveMove = (Boolean)props.get(
|
||||
ApplicationModel.PROP_APPROVE_MOVE.toString());
|
||||
Boolean rejectMove = (Boolean)props.get(
|
||||
ApplicationModel.PROP_REJECT_MOVE.toString());
|
||||
|
||||
NodeRef approveFolder = (NodeRef)props.get(
|
||||
ApplicationModel.PROP_APPROVE_FOLDER.toString());
|
||||
NodeRef rejectFolder = (NodeRef)props.get(
|
||||
ApplicationModel.PROP_REJECT_FOLDER.toString());
|
||||
|
||||
String approveFolderName = null;
|
||||
String rejectFolderName = null;
|
||||
|
||||
// get the approve folder name
|
||||
if (approveFolder != null)
|
||||
{
|
||||
Node approveNode = new Node(approveFolder);
|
||||
approveFolderName = approveNode.getName();
|
||||
}
|
||||
|
||||
// get the reject folder name
|
||||
if (rejectFolder != null)
|
||||
{
|
||||
Node rejectNode = new Node(rejectFolder);
|
||||
rejectFolderName = rejectNode.getName();
|
||||
}
|
||||
|
||||
// calculate the approve action string
|
||||
String action = null;
|
||||
if (approveMove.booleanValue())
|
||||
{
|
||||
action = Application.getMessage(FacesContext.getCurrentInstance(), "moved");
|
||||
}
|
||||
else
|
||||
{
|
||||
action = Application.getMessage(FacesContext.getCurrentInstance(), "copied");
|
||||
}
|
||||
|
||||
String actionPattern = null;
|
||||
if (isContent)
|
||||
{
|
||||
actionPattern = Application.getMessage(FacesContext.getCurrentInstance(), "document_action");
|
||||
}
|
||||
else
|
||||
{
|
||||
actionPattern = Application.getMessage(FacesContext.getCurrentInstance(), "space_action");
|
||||
}
|
||||
Object[] params = new Object[] {action, approveFolderName, approveStepName};
|
||||
out.write(Utils.encode(MessageFormat.format(actionPattern, params)));
|
||||
|
||||
// add details of the reject step if there is one
|
||||
if (rejectStepName != null && rejectMove != null && rejectFolderName != null)
|
||||
{
|
||||
if (rejectMove.booleanValue())
|
||||
{
|
||||
action = Application.getMessage(FacesContext.getCurrentInstance(), "moved");
|
||||
}
|
||||
else
|
||||
{
|
||||
action = Application.getMessage(FacesContext.getCurrentInstance(), "copied");
|
||||
}
|
||||
|
||||
out.write(" ");
|
||||
params = new Object[] {action, rejectFolderName, rejectStepName};
|
||||
out.write(Utils.encode(MessageFormat.format(actionPattern, params)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// work out which no workflow message to show depending on the node type
|
||||
if (isContent)
|
||||
{
|
||||
out.write(bundle.getString("doc_not_in_simple_workflow"));
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write(bundle.getString("space_not_in_simple_workflow"));
|
||||
}
|
||||
}
|
||||
out.write("</div>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the advanced workflow details for the given node.
|
||||
*
|
||||
* @param context Faces context
|
||||
* @param node The node
|
||||
* @param nodeService The NodeService instance
|
||||
* @param ddService The Data Dictionary instance
|
||||
* @param workflowService The WorkflowService instance
|
||||
* @param out The response writer
|
||||
* @param bundle Message bundle to get strings from
|
||||
*/
|
||||
protected void renderAdvancedWorkflowInfo(FacesContext context, Node node,
|
||||
NodeService nodeService, DictionaryService ddService, WorkflowService workflowService,
|
||||
ResponseWriter out, ResourceBundle bundle)
|
||||
throws IOException
|
||||
{
|
||||
boolean isContent = true;
|
||||
|
||||
QName type = nodeService.getType(node.getNodeRef());
|
||||
if (ddService.isSubClass(type, ContentModel.TYPE_FOLDER))
|
||||
{
|
||||
isContent = false;
|
||||
}
|
||||
|
||||
// TODO: for now we only support advanced workflow on content so don't render
|
||||
// anything for other types
|
||||
if (isContent)
|
||||
{
|
||||
// Render HTML for advanved workflow
|
||||
out.write("<div class=\"nodeWorkflowInfoTitle\">");
|
||||
out.write(bundle.getString("advanced_workflows"));
|
||||
out.write("</div><div class=\"nodeWorkflowInfoText\">");
|
||||
|
||||
List<WorkflowInstance> workflows = workflowService.getWorkflowsForContent(
|
||||
node.getNodeRef(), true);
|
||||
if (workflows != null && workflows.size() > 0)
|
||||
{
|
||||
// list out all the workflows the document is part of
|
||||
if (isContent)
|
||||
{
|
||||
out.write(bundle.getString("doc_part_of_advanced_workflows"));
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write(bundle.getString("space_part_of_advanced_workflows"));
|
||||
}
|
||||
out.write(":<br/><ul>");
|
||||
for (WorkflowInstance wi : workflows)
|
||||
{
|
||||
out.write("<li>");
|
||||
out.write(wi.definition.title);
|
||||
if (wi.description != null && wi.description.length() > 0)
|
||||
{
|
||||
out.write(" (");
|
||||
out.write(Utils.encode(wi.description));
|
||||
out.write(")");
|
||||
}
|
||||
out.write(" ");
|
||||
if (wi.startDate != null)
|
||||
{
|
||||
out.write(bundle.getString("started_on").toLowerCase());
|
||||
out.write(" ");
|
||||
out.write(Utils.getDateFormat(context).format(wi.startDate));
|
||||
out.write(" ");
|
||||
}
|
||||
if (wi.initiator != null)
|
||||
{
|
||||
out.write(bundle.getString("by"));
|
||||
out.write(" ");
|
||||
out.write(Utils.encode(User.getFullName(nodeService, wi.initiator)));
|
||||
out.write(".");
|
||||
}
|
||||
out.write("</li>");
|
||||
}
|
||||
out.write("</ul>");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isContent)
|
||||
{
|
||||
out.write(bundle.getString("doc_not_in_advanced_workflow"));
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write(bundle.getString("space_not_in_advanced_workflow"));
|
||||
}
|
||||
}
|
||||
out.write("</div>");
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.el.ValueBinding;
|
||||
|
||||
import org.alfresco.model.ApplicationModel;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowInstance;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.springframework.extensions.webscripts.ui.common.component.SelfRenderingComponent;
|
||||
|
||||
/**
|
||||
* JSF component that displays information about the workflows a node is involved in.
|
||||
* <p>
|
||||
* The node to show workflow information on.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class UINodeWorkflowInfo extends SelfRenderingComponent
|
||||
{
|
||||
protected Node value = null;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Component Impl
|
||||
|
||||
@Override
|
||||
public String getFamily()
|
||||
{
|
||||
return "org.alfresco.faces.NodeWorkflowInfo";
|
||||
}
|
||||
|
||||
@Override
|
||||
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.value = (Node)values[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object saveState(FacesContext context)
|
||||
{
|
||||
Object values[] = new Object[8];
|
||||
// standard component attributes are saved by the super class
|
||||
values[0] = super.saveState(context);
|
||||
values[1] = this.value;
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
// get the node to display the information for
|
||||
Node node = getValue();
|
||||
|
||||
if (node != null)
|
||||
{
|
||||
// get the services we need
|
||||
NodeService nodeService = Repository.getServiceRegistry(context).getNodeService();
|
||||
DictionaryService ddService = Repository.getServiceRegistry(context).getDictionaryService();
|
||||
WorkflowService workflowService = Repository.getServiceRegistry(context).getWorkflowService();
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
ResourceBundle bundle = Application.getBundle(context);
|
||||
|
||||
// render simple workflow info
|
||||
renderSimpleWorkflowInfo(context, node, nodeService, ddService, out, bundle);
|
||||
|
||||
// render advanced workflow info
|
||||
renderAdvancedWorkflowInfo(context, node, nodeService, ddService, workflowService, out, bundle);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeEnd(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Strongly typed component property accessors
|
||||
|
||||
/**
|
||||
* Get the value, this will be a node representing a piece of content or a space
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
public Node getValue()
|
||||
{
|
||||
ValueBinding vb = getValueBinding("value");
|
||||
if (vb != null)
|
||||
{
|
||||
this.value = (Node)vb.getValue(getFacesContext());
|
||||
}
|
||||
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value, either a space or content node.
|
||||
*
|
||||
* @param value the value
|
||||
*/
|
||||
public void setValue(Node value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Helper methods
|
||||
|
||||
/**
|
||||
* Renders the simple workflow details for the given node.
|
||||
*
|
||||
* @param context Faces context
|
||||
* @param node The node
|
||||
* @param nodeService The NodeService instance
|
||||
* @param ddService The Data Dictionary instance
|
||||
* @param out The response writer
|
||||
* @param bundle Message bundle to get strings from
|
||||
*/
|
||||
protected void renderSimpleWorkflowInfo(FacesContext context, Node node,
|
||||
NodeService nodeService, DictionaryService ddService,
|
||||
ResponseWriter out, ResourceBundle bundle)
|
||||
throws IOException
|
||||
{
|
||||
boolean isContent = true;
|
||||
|
||||
QName type = nodeService.getType(node.getNodeRef());
|
||||
if (ddService.isSubClass(type, ContentModel.TYPE_FOLDER))
|
||||
{
|
||||
isContent = false;
|
||||
}
|
||||
|
||||
// Render HTML for simple workflow
|
||||
if (isContent)
|
||||
{
|
||||
// TODO: for now we only support advanced workflow on content so only
|
||||
// render the simple workflow title if the node is a content node
|
||||
out.write("<div class=\"nodeWorkflowInfoTitle\">");
|
||||
out.write(bundle.getString("simple_workflow"));
|
||||
out.write("</div>");
|
||||
}
|
||||
out.write("<div class=\"nodeWorkflowInfoText\">");
|
||||
|
||||
if (node.hasAspect(ApplicationModel.ASPECT_SIMPLE_WORKFLOW))
|
||||
{
|
||||
// get the simple workflow aspect properties
|
||||
Map<String, Object> props = node.getProperties();
|
||||
|
||||
String approveStepName = (String)props.get(
|
||||
ApplicationModel.PROP_APPROVE_STEP.toString());
|
||||
String rejectStepName = (String)props.get(
|
||||
ApplicationModel.PROP_REJECT_STEP.toString());
|
||||
|
||||
Boolean approveMove = (Boolean)props.get(
|
||||
ApplicationModel.PROP_APPROVE_MOVE.toString());
|
||||
Boolean rejectMove = (Boolean)props.get(
|
||||
ApplicationModel.PROP_REJECT_MOVE.toString());
|
||||
|
||||
NodeRef approveFolder = (NodeRef)props.get(
|
||||
ApplicationModel.PROP_APPROVE_FOLDER.toString());
|
||||
NodeRef rejectFolder = (NodeRef)props.get(
|
||||
ApplicationModel.PROP_REJECT_FOLDER.toString());
|
||||
|
||||
String approveFolderName = null;
|
||||
String rejectFolderName = null;
|
||||
|
||||
// get the approve folder name
|
||||
if (approveFolder != null)
|
||||
{
|
||||
Node approveNode = new Node(approveFolder);
|
||||
approveFolderName = approveNode.getName();
|
||||
}
|
||||
|
||||
// get the reject folder name
|
||||
if (rejectFolder != null)
|
||||
{
|
||||
Node rejectNode = new Node(rejectFolder);
|
||||
rejectFolderName = rejectNode.getName();
|
||||
}
|
||||
|
||||
// calculate the approve action string
|
||||
String action = null;
|
||||
if (approveMove.booleanValue())
|
||||
{
|
||||
action = Application.getMessage(FacesContext.getCurrentInstance(), "moved");
|
||||
}
|
||||
else
|
||||
{
|
||||
action = Application.getMessage(FacesContext.getCurrentInstance(), "copied");
|
||||
}
|
||||
|
||||
String actionPattern = null;
|
||||
if (isContent)
|
||||
{
|
||||
actionPattern = Application.getMessage(FacesContext.getCurrentInstance(), "document_action");
|
||||
}
|
||||
else
|
||||
{
|
||||
actionPattern = Application.getMessage(FacesContext.getCurrentInstance(), "space_action");
|
||||
}
|
||||
Object[] params = new Object[] {action, approveFolderName, approveStepName};
|
||||
out.write(Utils.encode(MessageFormat.format(actionPattern, params)));
|
||||
|
||||
// add details of the reject step if there is one
|
||||
if (rejectStepName != null && rejectMove != null && rejectFolderName != null)
|
||||
{
|
||||
if (rejectMove.booleanValue())
|
||||
{
|
||||
action = Application.getMessage(FacesContext.getCurrentInstance(), "moved");
|
||||
}
|
||||
else
|
||||
{
|
||||
action = Application.getMessage(FacesContext.getCurrentInstance(), "copied");
|
||||
}
|
||||
|
||||
out.write(" ");
|
||||
params = new Object[] {action, rejectFolderName, rejectStepName};
|
||||
out.write(Utils.encode(MessageFormat.format(actionPattern, params)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// work out which no workflow message to show depending on the node type
|
||||
if (isContent)
|
||||
{
|
||||
out.write(bundle.getString("doc_not_in_simple_workflow"));
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write(bundle.getString("space_not_in_simple_workflow"));
|
||||
}
|
||||
}
|
||||
out.write("</div>");
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the advanced workflow details for the given node.
|
||||
*
|
||||
* @param context Faces context
|
||||
* @param node The node
|
||||
* @param nodeService The NodeService instance
|
||||
* @param ddService The Data Dictionary instance
|
||||
* @param workflowService The WorkflowService instance
|
||||
* @param out The response writer
|
||||
* @param bundle Message bundle to get strings from
|
||||
*/
|
||||
protected void renderAdvancedWorkflowInfo(FacesContext context, Node node,
|
||||
NodeService nodeService, DictionaryService ddService, WorkflowService workflowService,
|
||||
ResponseWriter out, ResourceBundle bundle)
|
||||
throws IOException
|
||||
{
|
||||
boolean isContent = true;
|
||||
|
||||
QName type = nodeService.getType(node.getNodeRef());
|
||||
if (ddService.isSubClass(type, ContentModel.TYPE_FOLDER))
|
||||
{
|
||||
isContent = false;
|
||||
}
|
||||
|
||||
// TODO: for now we only support advanced workflow on content so don't render
|
||||
// anything for other types
|
||||
if (isContent)
|
||||
{
|
||||
// Render HTML for advanved workflow
|
||||
out.write("<div class=\"nodeWorkflowInfoTitle\">");
|
||||
out.write(bundle.getString("advanced_workflows"));
|
||||
out.write("</div><div class=\"nodeWorkflowInfoText\">");
|
||||
|
||||
List<WorkflowInstance> workflows = workflowService.getWorkflowsForContent(
|
||||
node.getNodeRef(), true);
|
||||
if (workflows != null && workflows.size() > 0)
|
||||
{
|
||||
// list out all the workflows the document is part of
|
||||
if (isContent)
|
||||
{
|
||||
out.write(bundle.getString("doc_part_of_advanced_workflows"));
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write(bundle.getString("space_part_of_advanced_workflows"));
|
||||
}
|
||||
out.write(":<br/><ul>");
|
||||
for (WorkflowInstance wi : workflows)
|
||||
{
|
||||
out.write("<li>");
|
||||
out.write(wi.definition.title);
|
||||
if (wi.description != null && wi.description.length() > 0)
|
||||
{
|
||||
out.write(" (");
|
||||
out.write(Utils.encode(wi.description));
|
||||
out.write(")");
|
||||
}
|
||||
out.write(" ");
|
||||
if (wi.startDate != null)
|
||||
{
|
||||
out.write(bundle.getString("started_on").toLowerCase());
|
||||
out.write(" ");
|
||||
out.write(Utils.getDateFormat(context).format(wi.startDate));
|
||||
out.write(" ");
|
||||
}
|
||||
if (wi.initiator != null)
|
||||
{
|
||||
out.write(bundle.getString("by"));
|
||||
out.write(" ");
|
||||
out.write(Utils.encode(User.getFullName(nodeService, wi.initiator)));
|
||||
out.write(".");
|
||||
}
|
||||
out.write("</li>");
|
||||
}
|
||||
out.write("</ul>");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isContent)
|
||||
{
|
||||
out.write(bundle.getString("doc_not_in_advanced_workflow"));
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write(bundle.getString("space_not_in_advanced_workflow"));
|
||||
}
|
||||
}
|
||||
out.write("</div>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,340 +1,340 @@
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.web.scripts.bean.SearchProxy;
|
||||
import org.alfresco.repo.web.scripts.config.OpenSearchConfigElement;
|
||||
import org.alfresco.repo.web.scripts.config.OpenSearchConfigElement.EngineConfig;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.springframework.extensions.config.Config;
|
||||
import org.springframework.extensions.config.ConfigService;
|
||||
import org.springframework.extensions.webscripts.ui.common.component.SelfRenderingComponent;
|
||||
import org.springframework.web.jsf.FacesContextUtils;
|
||||
|
||||
/**
|
||||
* JSF component that provides an OpenSearch client, the engines
|
||||
* searched are configured via the web api config.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class UIOpenSearch extends SelfRenderingComponent
|
||||
{
|
||||
protected final static String SCRIPTS_WRITTEN = "_alfOpenSearchScripts";
|
||||
protected final static String ENGINE_ID_PREFIX = "eng";
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Component Impl
|
||||
|
||||
@Override
|
||||
public String getFamily()
|
||||
{
|
||||
return "org.alfresco.faces.OpenSearch";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
|
||||
List<OpenSearchEngine> engines = getRegisteredEngines(context);
|
||||
if (engines != null && engines.size() == 0)
|
||||
{
|
||||
out.write(Application.getMessage(context, "no_engines_registered"));
|
||||
return;
|
||||
}
|
||||
|
||||
String clientId = this.getId();
|
||||
|
||||
// write out the JavaScript specific to the OpenSearch component,
|
||||
// make sure it's only done once
|
||||
Object present = context.getExternalContext().getRequestMap().get(SCRIPTS_WRITTEN);
|
||||
if (present == null)
|
||||
{
|
||||
out.write("<link rel=\"stylesheet\" href=\"");
|
||||
out.write(context.getExternalContext().getRequestContextPath());
|
||||
out.write("/css/opensearch.css\" type=\"text/css\">");
|
||||
out.write("<script type=\"text/javascript\" src=\"");
|
||||
out.write(context.getExternalContext().getRequestContextPath());
|
||||
out.write("/scripts/ajax/opensearch.js\"></script>");
|
||||
|
||||
context.getExternalContext().getRequestMap().put(SCRIPTS_WRITTEN, Boolean.TRUE);
|
||||
}
|
||||
|
||||
// we use summary info panel pop-ups so need scripts for that object
|
||||
UINodeInfo.outputNodeInfoScripts(context, out);
|
||||
|
||||
// write out the javascript initialisation required
|
||||
out.write("<script type='text/javascript'>\n");
|
||||
out.write("var ");
|
||||
out.write(clientId);
|
||||
out.write(" = new Alfresco.OpenSearchClient('");
|
||||
out.write(clientId);
|
||||
out.write("');\n");
|
||||
// ADB-133: Synchronizing lengths of search fields
|
||||
final Integer searchMinimum = Application.getClientConfig(FacesContext.getCurrentInstance()).getSearchMinimum();
|
||||
// register the engines on the client
|
||||
for (OpenSearchEngine engine : engines)
|
||||
{
|
||||
out.write(clientId);
|
||||
out.write(".registerOpenSearchEngine('");
|
||||
out.write(engine.getId());
|
||||
out.write("', '");
|
||||
out.write(engine.getLabel());
|
||||
out.write("', '");
|
||||
out.write(engine.getUrl());
|
||||
out.write("', ");
|
||||
out.write(searchMinimum.toString());
|
||||
out.write(");\n");
|
||||
}
|
||||
|
||||
// pass in NLS strings
|
||||
out.write(clientId);
|
||||
out.write(".setMsgNoResults(\"");
|
||||
out.write(Application.getMessage(context, "no_results"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write(clientId);
|
||||
out.write(".setMsgOf(\"");
|
||||
out.write(Application.getMessage(context, "of"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write(clientId);
|
||||
out.write(".setMsgFailedGenerateUrl(\"");
|
||||
out.write(Application.getMessage(context, "failed_gen_url"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write(clientId);
|
||||
out.write(".setMsgFailedSearch(\"");
|
||||
out.write(Application.getMessage(context, "failed_search"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write(clientId);
|
||||
out.write(".setMsgFirstPage(\"");
|
||||
out.write(Application.getMessage(context, "first_page"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write(clientId);
|
||||
out.write(".setMsgPreviousPage(\"");
|
||||
out.write(Application.getMessage(context, "prev_page"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write(clientId);
|
||||
out.write(".setMsgNextPage(\"");
|
||||
out.write(Application.getMessage(context, "next_page"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write(clientId);
|
||||
out.write(".setMsgLastPage(\"");
|
||||
out.write(Application.getMessage(context, "last_page"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write(clientId);
|
||||
out.write(".setMsgInvalidTermLength(\"");
|
||||
out.write(Application.getMessage(context, "search_minimum"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write("</script>\n");
|
||||
|
||||
// write out the HTML
|
||||
String styleClass = (String)this.getAttributes().get("styleClass");
|
||||
String style = (String)this.getAttributes().get("style");
|
||||
|
||||
if (styleClass != null || style != null)
|
||||
{
|
||||
out.write("<div");
|
||||
|
||||
if (styleClass != null && styleClass.length() > 0)
|
||||
{
|
||||
out.write(" class='");
|
||||
out.write(styleClass);
|
||||
out.write("'");
|
||||
}
|
||||
|
||||
if (style != null && style.length() > 0)
|
||||
{
|
||||
out.write(" style='");
|
||||
out.write(style);
|
||||
out.write("'");
|
||||
}
|
||||
|
||||
out.write(">\n");
|
||||
}
|
||||
|
||||
out.write("<div class='osPanel'><div class='osControls'>");
|
||||
out.write("<table border='0' cellpadding='2' cellspacing='0'><tr>");
|
||||
out.write("<td><input id='");
|
||||
out.write(clientId);
|
||||
out.write("-search-term' name='");
|
||||
out.write(clientId);
|
||||
out.write("-search-term' type='text' size='30' onkeyup='return ");
|
||||
out.write(clientId);
|
||||
out.write(".handleKeyPress(event);' />");
|
||||
out.write("</td><td><img src='");
|
||||
out.write(context.getExternalContext().getRequestContextPath());
|
||||
out.write("/images/icons/search_icon.gif' style='cursor:pointer' onclick='");
|
||||
out.write(clientId);
|
||||
out.write(".executeQuery()' title='");
|
||||
out.write(Application.getMessage(context, "search"));
|
||||
out.write("' /></td></tr></table>\n");
|
||||
out.write("<table border='0' cellpadding='2' cellspacing='0' style='margin-top: 2px;'><tr><td><img src='");
|
||||
out.write(context.getExternalContext().getRequestContextPath());
|
||||
out.write("/images/icons/expanded.gif' style='cursor:pointer' onclick='");
|
||||
out.write(clientId);
|
||||
out.write(".toggleOptions(this)' class='expanded' title='");
|
||||
out.write(Application.getMessage(context, "toggle_options"));
|
||||
out.write("' /></td><td><img src='");
|
||||
out.write(context.getExternalContext().getRequestContextPath());
|
||||
out.write("/images/icons/opensearch_controls.gif' /></td><td>");
|
||||
out.write(Application.getMessage(context, "options"));
|
||||
out.write("</td></tr></table>\n");
|
||||
|
||||
out.write("<div id='");
|
||||
out.write(clientId);
|
||||
out.write("-os-options' class='osOptions'>");
|
||||
out.write(Application.getMessage(context, "show"));
|
||||
out.write("<input id='");
|
||||
out.write(clientId);
|
||||
out.write("-page-size' name='");
|
||||
out.write(clientId);
|
||||
out.write("-page-size' type='text' value='5' style='width: 25px; margin-left: 5px; margin-right: 5px;' />");
|
||||
out.write(Application.getMessage(context, "items_per_page"));
|
||||
out.write("<div style='margin-top: 6px; margin-bottom: 4px;'>");
|
||||
out.write(Application.getMessage(context, "search_in"));
|
||||
out.write(":</div><table border='0' cellpadding='2' cellspacing='0'>");
|
||||
for (OpenSearchEngine engine : engines)
|
||||
{
|
||||
out.write("<tr><td><input id='");
|
||||
out.write(clientId);
|
||||
out.write("-");
|
||||
out.write(engine.getId());
|
||||
out.write("-engine-enabled' name='");
|
||||
out.write(clientId);
|
||||
out.write("-");
|
||||
out.write(engine.getId());
|
||||
out.write("-engine-enabled' type='checkbox' checked='checked' />");
|
||||
out.write("</td><td>");
|
||||
out.write(Utils.encode(engine.getLabel()));
|
||||
out.write("</td></tr>");
|
||||
}
|
||||
out.write("</table></div></div>\n");
|
||||
|
||||
out.write("<div id='");
|
||||
out.write(clientId);
|
||||
out.write("-os-results'></div>\n</div>\n");
|
||||
|
||||
if (styleClass != null || style != null)
|
||||
{
|
||||
out.write("</div>\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of OpenSearchEngine objects representing the
|
||||
* registered OpenSearch engines.
|
||||
*
|
||||
* @param context Faces context
|
||||
* @return List of registered engines
|
||||
*/
|
||||
private List<OpenSearchEngine> getRegisteredEngines(FacesContext context)
|
||||
{
|
||||
List<OpenSearchEngine> engines = null;
|
||||
|
||||
// get the web api config service object from spring
|
||||
ConfigService cfgSvc = (ConfigService)FacesContextUtils.
|
||||
getRequiredWebApplicationContext(context).getBean("webscripts.config");
|
||||
SearchProxy searchProxy = (SearchProxy)FacesContextUtils.
|
||||
getRequiredWebApplicationContext(context).getBean("webscript.org.alfresco.repository.search.searchproxy.get");
|
||||
if (cfgSvc != null)
|
||||
{
|
||||
// get the OpenSearch configuration
|
||||
Config cfg = cfgSvc.getConfig("OpenSearch");
|
||||
OpenSearchConfigElement osConfig = (OpenSearchConfigElement)cfg.
|
||||
getConfigElement(OpenSearchConfigElement.CONFIG_ELEMENT_ID);
|
||||
if (osConfig != null)
|
||||
{
|
||||
// generate the the list of engines with a unique for each
|
||||
int id = 1;
|
||||
engines = new ArrayList<OpenSearchEngine>();
|
||||
|
||||
Set<EngineConfig> enginesCfg = osConfig.getEngines();
|
||||
for (EngineConfig engineCfg : enginesCfg)
|
||||
{
|
||||
// resolve engine label
|
||||
String label = engineCfg.getLabel();
|
||||
String labelId = engineCfg.getLabelId();
|
||||
if (labelId != null && labelId.length() > 0)
|
||||
{
|
||||
label = Application.getMessage(context, labelId);
|
||||
}
|
||||
|
||||
// locate search engine template url of most appropriate response type
|
||||
String url = searchProxy.createUrl(engineCfg, MimetypeMap.MIMETYPE_ATOM);
|
||||
if (url == null)
|
||||
{
|
||||
url = searchProxy.createUrl(engineCfg, MimetypeMap.MIMETYPE_RSS);
|
||||
}
|
||||
|
||||
if (url != null)
|
||||
{
|
||||
if (url.startsWith("/"))
|
||||
{
|
||||
url = context.getExternalContext().getRequestContextPath() + "/wcservice" + url;
|
||||
}
|
||||
|
||||
// add the engine
|
||||
OpenSearchEngine engine = new OpenSearchEngine(id, label, url);
|
||||
engines.add(engine);
|
||||
|
||||
// increase the id counter
|
||||
id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return engines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner class representing a registered OpenSearch engine.
|
||||
*/
|
||||
private class OpenSearchEngine
|
||||
{
|
||||
private String id;
|
||||
private String label;
|
||||
private String url;
|
||||
|
||||
public OpenSearchEngine(int id, String label, String url)
|
||||
{
|
||||
this.id = ENGINE_ID_PREFIX + Integer.toString(id);
|
||||
this.label = label;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getLabel()
|
||||
{
|
||||
return label;
|
||||
}
|
||||
|
||||
public String getUrl()
|
||||
{
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
|
||||
import org.alfresco.repo.content.MimetypeMap;
|
||||
import org.alfresco.repo.web.scripts.bean.SearchProxy;
|
||||
import org.alfresco.repo.web.scripts.config.OpenSearchConfigElement;
|
||||
import org.alfresco.repo.web.scripts.config.OpenSearchConfigElement.EngineConfig;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.springframework.extensions.config.Config;
|
||||
import org.springframework.extensions.config.ConfigService;
|
||||
import org.springframework.extensions.webscripts.ui.common.component.SelfRenderingComponent;
|
||||
import org.springframework.web.jsf.FacesContextUtils;
|
||||
|
||||
/**
|
||||
* JSF component that provides an OpenSearch client, the engines
|
||||
* searched are configured via the web api config.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class UIOpenSearch extends SelfRenderingComponent
|
||||
{
|
||||
protected final static String SCRIPTS_WRITTEN = "_alfOpenSearchScripts";
|
||||
protected final static String ENGINE_ID_PREFIX = "eng";
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Component Impl
|
||||
|
||||
@Override
|
||||
public String getFamily()
|
||||
{
|
||||
return "org.alfresco.faces.OpenSearch";
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
|
||||
List<OpenSearchEngine> engines = getRegisteredEngines(context);
|
||||
if (engines != null && engines.size() == 0)
|
||||
{
|
||||
out.write(Application.getMessage(context, "no_engines_registered"));
|
||||
return;
|
||||
}
|
||||
|
||||
String clientId = this.getId();
|
||||
|
||||
// write out the JavaScript specific to the OpenSearch component,
|
||||
// make sure it's only done once
|
||||
Object present = context.getExternalContext().getRequestMap().get(SCRIPTS_WRITTEN);
|
||||
if (present == null)
|
||||
{
|
||||
out.write("<link rel=\"stylesheet\" href=\"");
|
||||
out.write(context.getExternalContext().getRequestContextPath());
|
||||
out.write("/css/opensearch.css\" type=\"text/css\">");
|
||||
out.write("<script type=\"text/javascript\" src=\"");
|
||||
out.write(context.getExternalContext().getRequestContextPath());
|
||||
out.write("/scripts/ajax/opensearch.js\"></script>");
|
||||
|
||||
context.getExternalContext().getRequestMap().put(SCRIPTS_WRITTEN, Boolean.TRUE);
|
||||
}
|
||||
|
||||
// we use summary info panel pop-ups so need scripts for that object
|
||||
UINodeInfo.outputNodeInfoScripts(context, out);
|
||||
|
||||
// write out the javascript initialisation required
|
||||
out.write("<script type='text/javascript'>\n");
|
||||
out.write("var ");
|
||||
out.write(clientId);
|
||||
out.write(" = new Alfresco.OpenSearchClient('");
|
||||
out.write(clientId);
|
||||
out.write("');\n");
|
||||
// ADB-133: Synchronizing lengths of search fields
|
||||
final Integer searchMinimum = Application.getClientConfig(FacesContext.getCurrentInstance()).getSearchMinimum();
|
||||
// register the engines on the client
|
||||
for (OpenSearchEngine engine : engines)
|
||||
{
|
||||
out.write(clientId);
|
||||
out.write(".registerOpenSearchEngine('");
|
||||
out.write(engine.getId());
|
||||
out.write("', '");
|
||||
out.write(engine.getLabel());
|
||||
out.write("', '");
|
||||
out.write(engine.getUrl());
|
||||
out.write("', ");
|
||||
out.write(searchMinimum.toString());
|
||||
out.write(");\n");
|
||||
}
|
||||
|
||||
// pass in NLS strings
|
||||
out.write(clientId);
|
||||
out.write(".setMsgNoResults(\"");
|
||||
out.write(Application.getMessage(context, "no_results"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write(clientId);
|
||||
out.write(".setMsgOf(\"");
|
||||
out.write(Application.getMessage(context, "of"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write(clientId);
|
||||
out.write(".setMsgFailedGenerateUrl(\"");
|
||||
out.write(Application.getMessage(context, "failed_gen_url"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write(clientId);
|
||||
out.write(".setMsgFailedSearch(\"");
|
||||
out.write(Application.getMessage(context, "failed_search"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write(clientId);
|
||||
out.write(".setMsgFirstPage(\"");
|
||||
out.write(Application.getMessage(context, "first_page"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write(clientId);
|
||||
out.write(".setMsgPreviousPage(\"");
|
||||
out.write(Application.getMessage(context, "prev_page"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write(clientId);
|
||||
out.write(".setMsgNextPage(\"");
|
||||
out.write(Application.getMessage(context, "next_page"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write(clientId);
|
||||
out.write(".setMsgLastPage(\"");
|
||||
out.write(Application.getMessage(context, "last_page"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write(clientId);
|
||||
out.write(".setMsgInvalidTermLength(\"");
|
||||
out.write(Application.getMessage(context, "search_minimum"));
|
||||
out.write("\");\n");
|
||||
|
||||
out.write("</script>\n");
|
||||
|
||||
// write out the HTML
|
||||
String styleClass = (String)this.getAttributes().get("styleClass");
|
||||
String style = (String)this.getAttributes().get("style");
|
||||
|
||||
if (styleClass != null || style != null)
|
||||
{
|
||||
out.write("<div");
|
||||
|
||||
if (styleClass != null && styleClass.length() > 0)
|
||||
{
|
||||
out.write(" class='");
|
||||
out.write(styleClass);
|
||||
out.write("'");
|
||||
}
|
||||
|
||||
if (style != null && style.length() > 0)
|
||||
{
|
||||
out.write(" style='");
|
||||
out.write(style);
|
||||
out.write("'");
|
||||
}
|
||||
|
||||
out.write(">\n");
|
||||
}
|
||||
|
||||
out.write("<div class='osPanel'><div class='osControls'>");
|
||||
out.write("<table border='0' cellpadding='2' cellspacing='0'><tr>");
|
||||
out.write("<td><input id='");
|
||||
out.write(clientId);
|
||||
out.write("-search-term' name='");
|
||||
out.write(clientId);
|
||||
out.write("-search-term' type='text' size='30' onkeyup='return ");
|
||||
out.write(clientId);
|
||||
out.write(".handleKeyPress(event);' />");
|
||||
out.write("</td><td><img src='");
|
||||
out.write(context.getExternalContext().getRequestContextPath());
|
||||
out.write("/images/icons/search_icon.gif' style='cursor:pointer' onclick='");
|
||||
out.write(clientId);
|
||||
out.write(".executeQuery()' title='");
|
||||
out.write(Application.getMessage(context, "search"));
|
||||
out.write("' /></td></tr></table>\n");
|
||||
out.write("<table border='0' cellpadding='2' cellspacing='0' style='margin-top: 2px;'><tr><td><img src='");
|
||||
out.write(context.getExternalContext().getRequestContextPath());
|
||||
out.write("/images/icons/expanded.gif' style='cursor:pointer' onclick='");
|
||||
out.write(clientId);
|
||||
out.write(".toggleOptions(this)' class='expanded' title='");
|
||||
out.write(Application.getMessage(context, "toggle_options"));
|
||||
out.write("' /></td><td><img src='");
|
||||
out.write(context.getExternalContext().getRequestContextPath());
|
||||
out.write("/images/icons/opensearch_controls.gif' /></td><td>");
|
||||
out.write(Application.getMessage(context, "options"));
|
||||
out.write("</td></tr></table>\n");
|
||||
|
||||
out.write("<div id='");
|
||||
out.write(clientId);
|
||||
out.write("-os-options' class='osOptions'>");
|
||||
out.write(Application.getMessage(context, "show"));
|
||||
out.write("<input id='");
|
||||
out.write(clientId);
|
||||
out.write("-page-size' name='");
|
||||
out.write(clientId);
|
||||
out.write("-page-size' type='text' value='5' style='width: 25px; margin-left: 5px; margin-right: 5px;' />");
|
||||
out.write(Application.getMessage(context, "items_per_page"));
|
||||
out.write("<div style='margin-top: 6px; margin-bottom: 4px;'>");
|
||||
out.write(Application.getMessage(context, "search_in"));
|
||||
out.write(":</div><table border='0' cellpadding='2' cellspacing='0'>");
|
||||
for (OpenSearchEngine engine : engines)
|
||||
{
|
||||
out.write("<tr><td><input id='");
|
||||
out.write(clientId);
|
||||
out.write("-");
|
||||
out.write(engine.getId());
|
||||
out.write("-engine-enabled' name='");
|
||||
out.write(clientId);
|
||||
out.write("-");
|
||||
out.write(engine.getId());
|
||||
out.write("-engine-enabled' type='checkbox' checked='checked' />");
|
||||
out.write("</td><td>");
|
||||
out.write(Utils.encode(engine.getLabel()));
|
||||
out.write("</td></tr>");
|
||||
}
|
||||
out.write("</table></div></div>\n");
|
||||
|
||||
out.write("<div id='");
|
||||
out.write(clientId);
|
||||
out.write("-os-results'></div>\n</div>\n");
|
||||
|
||||
if (styleClass != null || style != null)
|
||||
{
|
||||
out.write("</div>\n");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of OpenSearchEngine objects representing the
|
||||
* registered OpenSearch engines.
|
||||
*
|
||||
* @param context Faces context
|
||||
* @return List of registered engines
|
||||
*/
|
||||
private List<OpenSearchEngine> getRegisteredEngines(FacesContext context)
|
||||
{
|
||||
List<OpenSearchEngine> engines = null;
|
||||
|
||||
// get the web api config service object from spring
|
||||
ConfigService cfgSvc = (ConfigService)FacesContextUtils.
|
||||
getRequiredWebApplicationContext(context).getBean("webscripts.config");
|
||||
SearchProxy searchProxy = (SearchProxy)FacesContextUtils.
|
||||
getRequiredWebApplicationContext(context).getBean("webscript.org.alfresco.repository.search.searchproxy.get");
|
||||
if (cfgSvc != null)
|
||||
{
|
||||
// get the OpenSearch configuration
|
||||
Config cfg = cfgSvc.getConfig("OpenSearch");
|
||||
OpenSearchConfigElement osConfig = (OpenSearchConfigElement)cfg.
|
||||
getConfigElement(OpenSearchConfigElement.CONFIG_ELEMENT_ID);
|
||||
if (osConfig != null)
|
||||
{
|
||||
// generate the the list of engines with a unique for each
|
||||
int id = 1;
|
||||
engines = new ArrayList<OpenSearchEngine>();
|
||||
|
||||
Set<EngineConfig> enginesCfg = osConfig.getEngines();
|
||||
for (EngineConfig engineCfg : enginesCfg)
|
||||
{
|
||||
// resolve engine label
|
||||
String label = engineCfg.getLabel();
|
||||
String labelId = engineCfg.getLabelId();
|
||||
if (labelId != null && labelId.length() > 0)
|
||||
{
|
||||
label = Application.getMessage(context, labelId);
|
||||
}
|
||||
|
||||
// locate search engine template url of most appropriate response type
|
||||
String url = searchProxy.createUrl(engineCfg, MimetypeMap.MIMETYPE_ATOM);
|
||||
if (url == null)
|
||||
{
|
||||
url = searchProxy.createUrl(engineCfg, MimetypeMap.MIMETYPE_RSS);
|
||||
}
|
||||
|
||||
if (url != null)
|
||||
{
|
||||
if (url.startsWith("/"))
|
||||
{
|
||||
url = context.getExternalContext().getRequestContextPath() + "/wcservice" + url;
|
||||
}
|
||||
|
||||
// add the engine
|
||||
OpenSearchEngine engine = new OpenSearchEngine(id, label, url);
|
||||
engines.add(engine);
|
||||
|
||||
// increase the id counter
|
||||
id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return engines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner class representing a registered OpenSearch engine.
|
||||
*/
|
||||
private class OpenSearchEngine
|
||||
{
|
||||
private String id;
|
||||
private String label;
|
||||
private String url;
|
||||
|
||||
public OpenSearchEngine(int id, String label, String url)
|
||||
{
|
||||
this.id = ENGINE_ID_PREFIX + Integer.toString(id);
|
||||
this.label = label;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getLabel()
|
||||
{
|
||||
return label;
|
||||
}
|
||||
|
||||
public String getUrl()
|
||||
{
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,63 +1,63 @@
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.component.UISelectItems;
|
||||
import javax.faces.component.UISelectOne;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.model.SelectItem;
|
||||
|
||||
import org.alfresco.repo.dictionary.constraint.ConstraintRegistry;
|
||||
import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint;
|
||||
import org.alfresco.service.cmr.dictionary.Constraint;
|
||||
import org.alfresco.web.data.IDataContainer;
|
||||
import org.alfresco.web.data.QuickSort;
|
||||
|
||||
/**
|
||||
* Component that holds a list of content stores configured in the repository.
|
||||
*/
|
||||
public class UIStoreSelector extends UISelectOne
|
||||
{
|
||||
public static final String COMPONENT_TYPE = "org.alfresco.faces.StoreSelector";
|
||||
public static final String COMPONENT_FAMILY = "javax.faces.SelectOne";
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (getChildren().size() == 0)
|
||||
{
|
||||
UISelectItems items = (UISelectItems)context.getApplication().
|
||||
createComponent("javax.faces.SelectItems");
|
||||
items.setId(this.getId() + "_items");
|
||||
items.setValue(createList());
|
||||
|
||||
// add the child component
|
||||
getChildren().add(items);
|
||||
}
|
||||
|
||||
// do the default processing
|
||||
super.encodeBegin(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return List of SelectItem components
|
||||
*/
|
||||
protected List<SelectItem> createList()
|
||||
{
|
||||
List<SelectItem> items = new ArrayList<SelectItem>(5);
|
||||
Constraint storesConstraint = ConstraintRegistry.getInstance().getConstraint("defaultStoreSelector");
|
||||
for(String store : ((ListOfValuesConstraint) storesConstraint).getAllowedValues())
|
||||
{
|
||||
items.add(new SelectItem(store, store));
|
||||
}
|
||||
|
||||
// make sure the list is sorted by the values
|
||||
QuickSort sorter = new QuickSort(items, "label", true, IDataContainer.SORT_CASEINSENSITIVE);
|
||||
sorter.sort();
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.faces.component.UISelectItems;
|
||||
import javax.faces.component.UISelectOne;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.model.SelectItem;
|
||||
|
||||
import org.alfresco.repo.dictionary.constraint.ConstraintRegistry;
|
||||
import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint;
|
||||
import org.alfresco.service.cmr.dictionary.Constraint;
|
||||
import org.alfresco.web.data.IDataContainer;
|
||||
import org.alfresco.web.data.QuickSort;
|
||||
|
||||
/**
|
||||
* Component that holds a list of content stores configured in the repository.
|
||||
*/
|
||||
public class UIStoreSelector extends UISelectOne
|
||||
{
|
||||
public static final String COMPONENT_TYPE = "org.alfresco.faces.StoreSelector";
|
||||
public static final String COMPONENT_FAMILY = "javax.faces.SelectOne";
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (getChildren().size() == 0)
|
||||
{
|
||||
UISelectItems items = (UISelectItems)context.getApplication().
|
||||
createComponent("javax.faces.SelectItems");
|
||||
items.setId(this.getId() + "_items");
|
||||
items.setValue(createList());
|
||||
|
||||
// add the child component
|
||||
getChildren().add(items);
|
||||
}
|
||||
|
||||
// do the default processing
|
||||
super.encodeBegin(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return List of SelectItem components
|
||||
*/
|
||||
protected List<SelectItem> createList()
|
||||
{
|
||||
List<SelectItem> items = new ArrayList<SelectItem>(5);
|
||||
Constraint storesConstraint = ConstraintRegistry.getInstance().getConstraint("defaultStoreSelector");
|
||||
for(String store : ((ListOfValuesConstraint) storesConstraint).getAllowedValues())
|
||||
{
|
||||
items.add(new SelectItem(store, store));
|
||||
}
|
||||
|
||||
// make sure the list is sorted by the values
|
||||
QuickSort sorter = new QuickSort(items, "label", true, IDataContainer.SORT_CASEINSENSITIVE);
|
||||
sorter.sort();
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
@@ -1,223 +1,223 @@
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.faces.component.NamingContainer;
|
||||
import javax.faces.component.UICommand;
|
||||
import javax.faces.component.UIComponent;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.event.ActionEvent;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.alfresco.web.ui.common.WebResources;
|
||||
|
||||
/**
|
||||
* Seld rendering component tied to the EmailSpaceUsersDialog bean. Renders a hierarchy of
|
||||
* user/group authorities. Each authority can be (de)selected and groups can be expanded/collapsed
|
||||
* to display and select from the child authorities in the group. Nested groups are supported.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class UIUserGroupPicker extends UICommand
|
||||
{
|
||||
/** action ids */
|
||||
public final static int ACTION_NONE = -1;
|
||||
public final static int ACTION_EXPANDCOLLAPSE = 0;
|
||||
public final static int ACTION_SELECT = 1;
|
||||
|
||||
private static String SELECTED_AUTHORITY = "_check";
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Component implementation
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public UIUserGroupPicker()
|
||||
{
|
||||
setRendererType(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponent#getFamily()
|
||||
*/
|
||||
public String getFamily()
|
||||
{
|
||||
return "org.alfresco.faces.UserGroupPicker";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void decode(FacesContext context)
|
||||
{
|
||||
Map requestMap = context.getExternalContext().getRequestParameterMap();
|
||||
String fieldId = getHiddenFieldName(context);
|
||||
String value = (String)requestMap.get(fieldId);
|
||||
|
||||
if (value != null && value.length() != 0)
|
||||
{
|
||||
// decode the values - we are expecting an action identifier and an authority name
|
||||
int sepIndex = value.indexOf(NamingContainer.SEPARATOR_CHAR);
|
||||
int action = Integer.parseInt(value.substring(0, sepIndex));
|
||||
String authority = value.substring(sepIndex + 1);
|
||||
|
||||
// queue an event
|
||||
PickerEvent event = new PickerEvent(this, action, authority);
|
||||
queueEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (isRendered() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
|
||||
ResourceBundle bundle = Application.getBundle(context);
|
||||
|
||||
String clientId = getClientId(context);
|
||||
|
||||
// start outer table
|
||||
out.write("<table width=100% border=0 cellspacing=0 cellpadding=0 class='userGroupPickerList'>");
|
||||
|
||||
// get the data that represents the users/groups to display
|
||||
List<Map> userGroups = (List<Map>)getValue();
|
||||
if (userGroups != null)
|
||||
{
|
||||
for (Map authority : userGroups)
|
||||
{
|
||||
String authorityId = (String)authority.get("id");
|
||||
|
||||
out.write("<tr><td width=100%><table width=100% border=0 cellspacing=3 cellpadding=0><tr>");
|
||||
|
||||
// walk parent hierarchy to calculate width of this cell
|
||||
int width = 16;
|
||||
Map parent = (Map)authority.get("parent");
|
||||
while (parent != null)
|
||||
{
|
||||
width += 16;
|
||||
parent = (Map)parent.get("parent");
|
||||
}
|
||||
out.write("<td width=");
|
||||
out.write(Integer.toString(width));
|
||||
out.write(" align=right>");
|
||||
|
||||
// output expanded/collapsed icon if authority is a group
|
||||
boolean expanded = false;
|
||||
boolean isGroup = (Boolean)authority.get("isGroup");
|
||||
if (isGroup)
|
||||
{
|
||||
// either output the expanded or collapsed selectable widget
|
||||
expanded = (Boolean)authority.get("expanded");
|
||||
String image = expanded ? WebResources.IMAGE_EXPANDED : WebResources.IMAGE_COLLAPSED;
|
||||
out.write(Utils.buildImageTag(context, image, 11, 11, "",
|
||||
generateFormSubmit(context, ACTION_EXPANDCOLLAPSE, authorityId)));
|
||||
}
|
||||
out.write("</td><td width=16>");
|
||||
|
||||
// output selected checkbox if not expanded and not a duplicate
|
||||
boolean duplicate = (Boolean)authority.get("duplicate");
|
||||
if (duplicate == false && (isGroup == false || expanded == false))
|
||||
{
|
||||
boolean selected = (Boolean)authority.get("selected");
|
||||
out.write("<input type='checkbox' value='' name='");
|
||||
out.write(clientId + NamingContainer.SEPARATOR_CHAR + SELECTED_AUTHORITY);
|
||||
out.write("' onclick=\"");
|
||||
out.write(generateFormSubmit(context, ACTION_SELECT, authorityId));
|
||||
out.write('"');
|
||||
if (selected)
|
||||
{
|
||||
out.write(" CHECKED");
|
||||
}
|
||||
out.write('>');
|
||||
}
|
||||
out.write("</td><td width=16>");
|
||||
|
||||
// output icon
|
||||
out.write(Utils.buildImageTag(context, (String)authority.get("icon"), 16, 16, ""));
|
||||
out.write("</td><td>");
|
||||
|
||||
// output textual information
|
||||
if (duplicate)
|
||||
{
|
||||
out.write("<span style='color:#93a8b2'>");
|
||||
}
|
||||
out.write(Utils.encode((String)authority.get("fullName")));
|
||||
out.write(" (");
|
||||
out.write((String)authority.get("roles"));
|
||||
out.write(")");
|
||||
if (duplicate)
|
||||
{
|
||||
out.write("</span>");
|
||||
}
|
||||
out.write("</td>");
|
||||
|
||||
out.write("</tr></table></td></tr>");
|
||||
}
|
||||
}
|
||||
|
||||
out.write("</table>");
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Private helpers
|
||||
|
||||
/**
|
||||
* We use a hidden field per picker instance on the page.
|
||||
*
|
||||
* @return hidden field name
|
||||
*/
|
||||
private String getHiddenFieldName(FacesContext context)
|
||||
{
|
||||
return getClientId(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate FORM submit JavaScript for the specified action
|
||||
*
|
||||
* @param context FacesContext
|
||||
* @param action Action index
|
||||
* @param authority Authority Id of the action source
|
||||
*
|
||||
* @return FORM submit JavaScript
|
||||
*/
|
||||
private String generateFormSubmit(FacesContext context, int action, String authority)
|
||||
{
|
||||
return Utils.generateFormSubmit(context, this, getHiddenFieldName(context),
|
||||
Integer.toString(action) + NamingContainer.SEPARATOR_CHAR + authority);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Inner classes
|
||||
|
||||
/**
|
||||
* Class representing the an action relevant to the User Group picker component.
|
||||
*/
|
||||
public static class PickerEvent extends ActionEvent
|
||||
{
|
||||
public PickerEvent(UIComponent component, int action, String authority)
|
||||
{
|
||||
super(component);
|
||||
Action = action;
|
||||
Authority = authority;
|
||||
}
|
||||
|
||||
public String Authority;
|
||||
public int Action;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.faces.component.NamingContainer;
|
||||
import javax.faces.component.UICommand;
|
||||
import javax.faces.component.UIComponent;
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.event.ActionEvent;
|
||||
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.alfresco.web.ui.common.WebResources;
|
||||
|
||||
/**
|
||||
* Seld rendering component tied to the EmailSpaceUsersDialog bean. Renders a hierarchy of
|
||||
* user/group authorities. Each authority can be (de)selected and groups can be expanded/collapsed
|
||||
* to display and select from the child authorities in the group. Nested groups are supported.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class UIUserGroupPicker extends UICommand
|
||||
{
|
||||
/** action ids */
|
||||
public final static int ACTION_NONE = -1;
|
||||
public final static int ACTION_EXPANDCOLLAPSE = 0;
|
||||
public final static int ACTION_SELECT = 1;
|
||||
|
||||
private static String SELECTED_AUTHORITY = "_check";
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Component implementation
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public UIUserGroupPicker()
|
||||
{
|
||||
setRendererType(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponent#getFamily()
|
||||
*/
|
||||
public String getFamily()
|
||||
{
|
||||
return "org.alfresco.faces.UserGroupPicker";
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void decode(FacesContext context)
|
||||
{
|
||||
Map requestMap = context.getExternalContext().getRequestParameterMap();
|
||||
String fieldId = getHiddenFieldName(context);
|
||||
String value = (String)requestMap.get(fieldId);
|
||||
|
||||
if (value != null && value.length() != 0)
|
||||
{
|
||||
// decode the values - we are expecting an action identifier and an authority name
|
||||
int sepIndex = value.indexOf(NamingContainer.SEPARATOR_CHAR);
|
||||
int action = Integer.parseInt(value.substring(0, sepIndex));
|
||||
String authority = value.substring(sepIndex + 1);
|
||||
|
||||
// queue an event
|
||||
PickerEvent event = new PickerEvent(this, action, authority);
|
||||
queueEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (isRendered() == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
|
||||
ResourceBundle bundle = Application.getBundle(context);
|
||||
|
||||
String clientId = getClientId(context);
|
||||
|
||||
// start outer table
|
||||
out.write("<table width=100% border=0 cellspacing=0 cellpadding=0 class='userGroupPickerList'>");
|
||||
|
||||
// get the data that represents the users/groups to display
|
||||
List<Map> userGroups = (List<Map>)getValue();
|
||||
if (userGroups != null)
|
||||
{
|
||||
for (Map authority : userGroups)
|
||||
{
|
||||
String authorityId = (String)authority.get("id");
|
||||
|
||||
out.write("<tr><td width=100%><table width=100% border=0 cellspacing=3 cellpadding=0><tr>");
|
||||
|
||||
// walk parent hierarchy to calculate width of this cell
|
||||
int width = 16;
|
||||
Map parent = (Map)authority.get("parent");
|
||||
while (parent != null)
|
||||
{
|
||||
width += 16;
|
||||
parent = (Map)parent.get("parent");
|
||||
}
|
||||
out.write("<td width=");
|
||||
out.write(Integer.toString(width));
|
||||
out.write(" align=right>");
|
||||
|
||||
// output expanded/collapsed icon if authority is a group
|
||||
boolean expanded = false;
|
||||
boolean isGroup = (Boolean)authority.get("isGroup");
|
||||
if (isGroup)
|
||||
{
|
||||
// either output the expanded or collapsed selectable widget
|
||||
expanded = (Boolean)authority.get("expanded");
|
||||
String image = expanded ? WebResources.IMAGE_EXPANDED : WebResources.IMAGE_COLLAPSED;
|
||||
out.write(Utils.buildImageTag(context, image, 11, 11, "",
|
||||
generateFormSubmit(context, ACTION_EXPANDCOLLAPSE, authorityId)));
|
||||
}
|
||||
out.write("</td><td width=16>");
|
||||
|
||||
// output selected checkbox if not expanded and not a duplicate
|
||||
boolean duplicate = (Boolean)authority.get("duplicate");
|
||||
if (duplicate == false && (isGroup == false || expanded == false))
|
||||
{
|
||||
boolean selected = (Boolean)authority.get("selected");
|
||||
out.write("<input type='checkbox' value='' name='");
|
||||
out.write(clientId + NamingContainer.SEPARATOR_CHAR + SELECTED_AUTHORITY);
|
||||
out.write("' onclick=\"");
|
||||
out.write(generateFormSubmit(context, ACTION_SELECT, authorityId));
|
||||
out.write('"');
|
||||
if (selected)
|
||||
{
|
||||
out.write(" CHECKED");
|
||||
}
|
||||
out.write('>');
|
||||
}
|
||||
out.write("</td><td width=16>");
|
||||
|
||||
// output icon
|
||||
out.write(Utils.buildImageTag(context, (String)authority.get("icon"), 16, 16, ""));
|
||||
out.write("</td><td>");
|
||||
|
||||
// output textual information
|
||||
if (duplicate)
|
||||
{
|
||||
out.write("<span style='color:#93a8b2'>");
|
||||
}
|
||||
out.write(Utils.encode((String)authority.get("fullName")));
|
||||
out.write(" (");
|
||||
out.write((String)authority.get("roles"));
|
||||
out.write(")");
|
||||
if (duplicate)
|
||||
{
|
||||
out.write("</span>");
|
||||
}
|
||||
out.write("</td>");
|
||||
|
||||
out.write("</tr></table></td></tr>");
|
||||
}
|
||||
}
|
||||
|
||||
out.write("</table>");
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Private helpers
|
||||
|
||||
/**
|
||||
* We use a hidden field per picker instance on the page.
|
||||
*
|
||||
* @return hidden field name
|
||||
*/
|
||||
private String getHiddenFieldName(FacesContext context)
|
||||
{
|
||||
return getClientId(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate FORM submit JavaScript for the specified action
|
||||
*
|
||||
* @param context FacesContext
|
||||
* @param action Action index
|
||||
* @param authority Authority Id of the action source
|
||||
*
|
||||
* @return FORM submit JavaScript
|
||||
*/
|
||||
private String generateFormSubmit(FacesContext context, int action, String authority)
|
||||
{
|
||||
return Utils.generateFormSubmit(context, this, getHiddenFieldName(context),
|
||||
Integer.toString(action) + NamingContainer.SEPARATOR_CHAR + authority);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Inner classes
|
||||
|
||||
/**
|
||||
* Class representing the an action relevant to the User Group picker component.
|
||||
*/
|
||||
public static class PickerEvent extends ActionEvent
|
||||
{
|
||||
public PickerEvent(UIComponent component, int action, String authority)
|
||||
{
|
||||
super(component);
|
||||
Action = action;
|
||||
Authority = authority;
|
||||
}
|
||||
|
||||
public String Authority;
|
||||
public int Action;
|
||||
}
|
||||
}
|
||||
|
@@ -1,258 +1,258 @@
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.el.ValueBinding;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.workflow.WorkflowModel;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowInstance;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskQuery;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTransition;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
import org.springframework.extensions.webscripts.ui.common.component.SelfRenderingComponent;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* JSF component that displays historic information about a workflow.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class UIWorkflowHistory extends SelfRenderingComponent
|
||||
{
|
||||
protected WorkflowInstance value = null;
|
||||
|
||||
private static final Log logger = LogFactory.getLog(UIWorkflowHistory.class);
|
||||
|
||||
private static final String DEFAULT_TRANSITION_TITLE = "bpm_businessprocessmodel.transition.title";
|
||||
private static final String MSG_DESCRIPTION = "description";
|
||||
private static final String MSG_TASK = "task_type";
|
||||
private static final String MSG_ID = "id";
|
||||
private static final String MSG_CREATED = "created";
|
||||
private static final String MSG_ASSIGNEE = "assignee";
|
||||
private static final String MSG_COMMENT = "comment";
|
||||
private static final String MSG_DATE_COMPLETED = "completed_on";
|
||||
private static final String MSG_OUTCOME = "outcome";
|
||||
private static final String MSG_NO_HISTORY = "no_workflow_history";
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Component Impl
|
||||
|
||||
@Override
|
||||
public String getFamily()
|
||||
{
|
||||
return "org.alfresco.faces.WorkflowHistory";
|
||||
}
|
||||
|
||||
@Override
|
||||
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.value = (WorkflowInstance)values[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object saveState(FacesContext context)
|
||||
{
|
||||
Object values[] = new Object[2];
|
||||
// standard component attributes are saved by the super class
|
||||
values[0] = super.saveState(context);
|
||||
values[1] = this.value;
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
WorkflowInstance wi = getValue();
|
||||
|
||||
if (wi != null)
|
||||
{
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
ResourceBundle bundle = Application.getBundle(context);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Retrieving workflow history for workflow instance: " + wi);
|
||||
|
||||
WorkflowTaskQuery query = new WorkflowTaskQuery();
|
||||
query.setActive(null);
|
||||
query.setProcessId(wi.id);
|
||||
query.setTaskState(WorkflowTaskState.COMPLETED);
|
||||
query.setOrderBy(new WorkflowTaskQuery.OrderBy[] {
|
||||
WorkflowTaskQuery.OrderBy.TaskCreated_Desc,
|
||||
WorkflowTaskQuery.OrderBy.TaskActor_Asc });
|
||||
List<WorkflowTask> tasks = Repository.getServiceRegistry(context).
|
||||
getWorkflowService().queryTasks(query);
|
||||
|
||||
if (tasks.size() == 0)
|
||||
{
|
||||
out.write("<div style='margin-left:18px;margin-top: 6px;'>");
|
||||
out.write(bundle.getString(MSG_NO_HISTORY));
|
||||
out.write("</div>");
|
||||
}
|
||||
else
|
||||
{
|
||||
// output surrounding table and style if necessary
|
||||
out.write("<table cellspacing='2' cellpadding='1' border='0'");
|
||||
if (this.getAttributes().get("style") != null)
|
||||
{
|
||||
out.write(" style=\"");
|
||||
out.write((String)this.getAttributes().get("style"));
|
||||
out.write("\"");
|
||||
}
|
||||
if (this.getAttributes().get("styleClass") != null)
|
||||
{
|
||||
out.write(" class=\"");
|
||||
out.write((String)this.getAttributes().get("styleClass"));
|
||||
out.write("\"");
|
||||
}
|
||||
out.write(">");
|
||||
|
||||
// output a header row
|
||||
out.write("<tr align=left><th>");
|
||||
out.write(bundle.getString(MSG_DESCRIPTION));
|
||||
out.write("</th><th>");
|
||||
out.write(bundle.getString(MSG_TASK));
|
||||
out.write("</th><th>");
|
||||
out.write(bundle.getString(MSG_ID));
|
||||
out.write("</th><th>");
|
||||
out.write(bundle.getString(MSG_CREATED));
|
||||
out.write("</th><th>");
|
||||
out.write(bundle.getString(MSG_ASSIGNEE));
|
||||
out.write("</th><th>");
|
||||
out.write(bundle.getString(MSG_COMMENT));
|
||||
out.write("</th><th>");
|
||||
out.write(bundle.getString(MSG_DATE_COMPLETED));
|
||||
out.write("</th><th>");
|
||||
out.write(bundle.getString(MSG_OUTCOME));
|
||||
out.write("</th></tr>");
|
||||
|
||||
// output a row for each previous completed task
|
||||
for (WorkflowTask task : tasks)
|
||||
{
|
||||
String id = null;
|
||||
Serializable idObject = task.properties.get(WorkflowModel.PROP_TASK_ID);
|
||||
if (idObject instanceof Long)
|
||||
{
|
||||
id = ((Long)idObject).toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
id = idObject.toString();
|
||||
}
|
||||
|
||||
String desc = (String)task.properties.get(WorkflowModel.PROP_DESCRIPTION);
|
||||
Date createdDate = (Date)task.properties.get(ContentModel.PROP_CREATED);
|
||||
String owner = (String)task.properties.get(ContentModel.PROP_OWNER);
|
||||
String comment = (String)task.properties.get(WorkflowModel.PROP_COMMENT);
|
||||
Date completedDate = (Date)task.properties.get(WorkflowModel.PROP_COMPLETION_DATE);
|
||||
String transition = (String)task.properties.get(WorkflowModel.PROP_OUTCOME);
|
||||
String outcome = "";
|
||||
if (transition != null)
|
||||
{
|
||||
WorkflowTransition[] transitions = task.definition.node.transitions;
|
||||
for (WorkflowTransition trans : transitions)
|
||||
{
|
||||
if (trans.id.equals(transition))
|
||||
{
|
||||
outcome = trans.title;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((outcome == null || outcome.equals("")) && transition != null)
|
||||
{
|
||||
// it's possible in Activiti to have tasks without an outcome set,
|
||||
// in this case default to the transition, if there is one.
|
||||
outcome = transition;
|
||||
}
|
||||
//ACE-1154
|
||||
if (outcome.equals(""))
|
||||
{
|
||||
outcome = I18NUtil.getMessage(DEFAULT_TRANSITION_TITLE);
|
||||
}
|
||||
|
||||
out.write("<tr><td>");
|
||||
out.write(desc == null ? "" : Utils.encode(desc));
|
||||
out.write("</td><td>");
|
||||
out.write(Utils.encode(task.title));
|
||||
out.write("</td><td>");
|
||||
out.write(id);
|
||||
out.write("</td><td>");
|
||||
out.write(Utils.getDateTimeFormat(context).format(createdDate));
|
||||
out.write("</td><td>");
|
||||
out.write(owner == null ? "" : owner);
|
||||
out.write("</td><td>");
|
||||
out.write(comment == null ? "" : Utils.encode(comment));
|
||||
out.write("</td><td>");
|
||||
out.write(Utils.getDateTimeFormat(context).format(completedDate));
|
||||
out.write("</td><td>");
|
||||
out.write(outcome);
|
||||
out.write("</td></tr>");
|
||||
}
|
||||
|
||||
// output the end of the table
|
||||
out.write("</table>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeEnd(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRendersChildren()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Strongly typed component property accessors
|
||||
|
||||
/**
|
||||
* Returns the workflow instance this component is showing information on
|
||||
*
|
||||
* @return The workflow instance
|
||||
*/
|
||||
public WorkflowInstance getValue()
|
||||
{
|
||||
ValueBinding vb = getValueBinding("value");
|
||||
if (vb != null)
|
||||
{
|
||||
this.value = (WorkflowInstance)vb.getValue(getFacesContext());
|
||||
}
|
||||
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the workflow instance to show the summary for
|
||||
*
|
||||
* @param value The workflow instance
|
||||
*/
|
||||
public void setValue(WorkflowInstance value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.el.ValueBinding;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.workflow.WorkflowModel;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowInstance;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTask;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskQuery;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTaskState;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowTransition;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.springframework.extensions.surf.util.I18NUtil;
|
||||
import org.springframework.extensions.webscripts.ui.common.component.SelfRenderingComponent;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* JSF component that displays historic information about a workflow.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class UIWorkflowHistory extends SelfRenderingComponent
|
||||
{
|
||||
protected WorkflowInstance value = null;
|
||||
|
||||
private static final Log logger = LogFactory.getLog(UIWorkflowHistory.class);
|
||||
|
||||
private static final String DEFAULT_TRANSITION_TITLE = "bpm_businessprocessmodel.transition.title";
|
||||
private static final String MSG_DESCRIPTION = "description";
|
||||
private static final String MSG_TASK = "task_type";
|
||||
private static final String MSG_ID = "id";
|
||||
private static final String MSG_CREATED = "created";
|
||||
private static final String MSG_ASSIGNEE = "assignee";
|
||||
private static final String MSG_COMMENT = "comment";
|
||||
private static final String MSG_DATE_COMPLETED = "completed_on";
|
||||
private static final String MSG_OUTCOME = "outcome";
|
||||
private static final String MSG_NO_HISTORY = "no_workflow_history";
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Component Impl
|
||||
|
||||
@Override
|
||||
public String getFamily()
|
||||
{
|
||||
return "org.alfresco.faces.WorkflowHistory";
|
||||
}
|
||||
|
||||
@Override
|
||||
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.value = (WorkflowInstance)values[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object saveState(FacesContext context)
|
||||
{
|
||||
Object values[] = new Object[2];
|
||||
// standard component attributes are saved by the super class
|
||||
values[0] = super.saveState(context);
|
||||
values[1] = this.value;
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
WorkflowInstance wi = getValue();
|
||||
|
||||
if (wi != null)
|
||||
{
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
ResourceBundle bundle = Application.getBundle(context);
|
||||
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debug("Retrieving workflow history for workflow instance: " + wi);
|
||||
|
||||
WorkflowTaskQuery query = new WorkflowTaskQuery();
|
||||
query.setActive(null);
|
||||
query.setProcessId(wi.id);
|
||||
query.setTaskState(WorkflowTaskState.COMPLETED);
|
||||
query.setOrderBy(new WorkflowTaskQuery.OrderBy[] {
|
||||
WorkflowTaskQuery.OrderBy.TaskCreated_Desc,
|
||||
WorkflowTaskQuery.OrderBy.TaskActor_Asc });
|
||||
List<WorkflowTask> tasks = Repository.getServiceRegistry(context).
|
||||
getWorkflowService().queryTasks(query);
|
||||
|
||||
if (tasks.size() == 0)
|
||||
{
|
||||
out.write("<div style='margin-left:18px;margin-top: 6px;'>");
|
||||
out.write(bundle.getString(MSG_NO_HISTORY));
|
||||
out.write("</div>");
|
||||
}
|
||||
else
|
||||
{
|
||||
// output surrounding table and style if necessary
|
||||
out.write("<table cellspacing='2' cellpadding='1' border='0'");
|
||||
if (this.getAttributes().get("style") != null)
|
||||
{
|
||||
out.write(" style=\"");
|
||||
out.write((String)this.getAttributes().get("style"));
|
||||
out.write("\"");
|
||||
}
|
||||
if (this.getAttributes().get("styleClass") != null)
|
||||
{
|
||||
out.write(" class=\"");
|
||||
out.write((String)this.getAttributes().get("styleClass"));
|
||||
out.write("\"");
|
||||
}
|
||||
out.write(">");
|
||||
|
||||
// output a header row
|
||||
out.write("<tr align=left><th>");
|
||||
out.write(bundle.getString(MSG_DESCRIPTION));
|
||||
out.write("</th><th>");
|
||||
out.write(bundle.getString(MSG_TASK));
|
||||
out.write("</th><th>");
|
||||
out.write(bundle.getString(MSG_ID));
|
||||
out.write("</th><th>");
|
||||
out.write(bundle.getString(MSG_CREATED));
|
||||
out.write("</th><th>");
|
||||
out.write(bundle.getString(MSG_ASSIGNEE));
|
||||
out.write("</th><th>");
|
||||
out.write(bundle.getString(MSG_COMMENT));
|
||||
out.write("</th><th>");
|
||||
out.write(bundle.getString(MSG_DATE_COMPLETED));
|
||||
out.write("</th><th>");
|
||||
out.write(bundle.getString(MSG_OUTCOME));
|
||||
out.write("</th></tr>");
|
||||
|
||||
// output a row for each previous completed task
|
||||
for (WorkflowTask task : tasks)
|
||||
{
|
||||
String id = null;
|
||||
Serializable idObject = task.properties.get(WorkflowModel.PROP_TASK_ID);
|
||||
if (idObject instanceof Long)
|
||||
{
|
||||
id = ((Long)idObject).toString();
|
||||
}
|
||||
else
|
||||
{
|
||||
id = idObject.toString();
|
||||
}
|
||||
|
||||
String desc = (String)task.properties.get(WorkflowModel.PROP_DESCRIPTION);
|
||||
Date createdDate = (Date)task.properties.get(ContentModel.PROP_CREATED);
|
||||
String owner = (String)task.properties.get(ContentModel.PROP_OWNER);
|
||||
String comment = (String)task.properties.get(WorkflowModel.PROP_COMMENT);
|
||||
Date completedDate = (Date)task.properties.get(WorkflowModel.PROP_COMPLETION_DATE);
|
||||
String transition = (String)task.properties.get(WorkflowModel.PROP_OUTCOME);
|
||||
String outcome = "";
|
||||
if (transition != null)
|
||||
{
|
||||
WorkflowTransition[] transitions = task.definition.node.transitions;
|
||||
for (WorkflowTransition trans : transitions)
|
||||
{
|
||||
if (trans.id.equals(transition))
|
||||
{
|
||||
outcome = trans.title;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((outcome == null || outcome.equals("")) && transition != null)
|
||||
{
|
||||
// it's possible in Activiti to have tasks without an outcome set,
|
||||
// in this case default to the transition, if there is one.
|
||||
outcome = transition;
|
||||
}
|
||||
//ACE-1154
|
||||
if (outcome.equals(""))
|
||||
{
|
||||
outcome = I18NUtil.getMessage(DEFAULT_TRANSITION_TITLE);
|
||||
}
|
||||
|
||||
out.write("<tr><td>");
|
||||
out.write(desc == null ? "" : Utils.encode(desc));
|
||||
out.write("</td><td>");
|
||||
out.write(Utils.encode(task.title));
|
||||
out.write("</td><td>");
|
||||
out.write(id);
|
||||
out.write("</td><td>");
|
||||
out.write(Utils.getDateTimeFormat(context).format(createdDate));
|
||||
out.write("</td><td>");
|
||||
out.write(owner == null ? "" : owner);
|
||||
out.write("</td><td>");
|
||||
out.write(comment == null ? "" : Utils.encode(comment));
|
||||
out.write("</td><td>");
|
||||
out.write(Utils.getDateTimeFormat(context).format(completedDate));
|
||||
out.write("</td><td>");
|
||||
out.write(outcome);
|
||||
out.write("</td></tr>");
|
||||
}
|
||||
|
||||
// output the end of the table
|
||||
out.write("</table>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeEnd(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRendersChildren()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Strongly typed component property accessors
|
||||
|
||||
/**
|
||||
* Returns the workflow instance this component is showing information on
|
||||
*
|
||||
* @return The workflow instance
|
||||
*/
|
||||
public WorkflowInstance getValue()
|
||||
{
|
||||
ValueBinding vb = getValueBinding("value");
|
||||
if (vb != null)
|
||||
{
|
||||
this.value = (WorkflowInstance)vb.getValue(getFacesContext());
|
||||
}
|
||||
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the workflow instance to show the summary for
|
||||
*
|
||||
* @param value The workflow instance
|
||||
*/
|
||||
public void setValue(WorkflowInstance value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
@@ -1,182 +1,182 @@
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.el.ValueBinding;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowInstance;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.springframework.extensions.webscripts.ui.common.component.SelfRenderingComponent;
|
||||
|
||||
/**
|
||||
* JSF component that displays summary information about a workflow.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class UIWorkflowSummary extends SelfRenderingComponent
|
||||
{
|
||||
protected WorkflowInstance value = null;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Component Impl
|
||||
|
||||
@Override
|
||||
public String getFamily()
|
||||
{
|
||||
return "org.alfresco.faces.WorkflowSummary";
|
||||
}
|
||||
|
||||
@Override
|
||||
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.value = (WorkflowInstance)values[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object saveState(FacesContext context)
|
||||
{
|
||||
Object values[] = new Object[8];
|
||||
// standard component attributes are saved by the super class
|
||||
values[0] = super.saveState(context);
|
||||
values[1] = this.value;
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
WorkflowInstance wi = getValue();
|
||||
|
||||
if (wi != null)
|
||||
{
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
ResourceBundle bundle = Application.getBundle(context);
|
||||
|
||||
// output surrounding table and style if necessary
|
||||
out.write("<table");
|
||||
if (this.getAttributes().get("style") != null)
|
||||
{
|
||||
out.write(" style=\"");
|
||||
out.write((String)this.getAttributes().get("style"));
|
||||
out.write("\"");
|
||||
}
|
||||
if (this.getAttributes().get("styleClass") != null)
|
||||
{
|
||||
out.write(" class=\"");
|
||||
out.write((String)this.getAttributes().get("styleClass"));
|
||||
out.write("\"");
|
||||
}
|
||||
out.write(">");
|
||||
|
||||
// output the title and description
|
||||
out.write("<tr><td>");
|
||||
out.write(bundle.getString("title"));
|
||||
out.write(":</td><td>");
|
||||
out.write(wi.definition.title);
|
||||
if (wi.definition.description != null && wi.definition.description.length() > 0)
|
||||
{
|
||||
out.write(" (");
|
||||
out.write(Utils.encode(wi.definition.description));
|
||||
out.write(")");
|
||||
}
|
||||
out.write("</td></tr><tr><td>");
|
||||
out.write(bundle.getString("initiated_by"));
|
||||
out.write(":</td><td>");
|
||||
NodeService nodeService = getNodeService(context);
|
||||
if (wi.initiator != null)
|
||||
{
|
||||
if (nodeService.exists(wi.initiator))
|
||||
{
|
||||
out.write(Utils.encode(User.getFullName(Repository.getServiceRegistry(
|
||||
context).getNodeService(), wi.initiator)));
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write("<");
|
||||
out.write(bundle.getString("unknown"));
|
||||
out.write(">");
|
||||
}
|
||||
}
|
||||
out.write("</td></tr><tr><td>");
|
||||
out.write(bundle.getString("started_on"));
|
||||
out.write(":</td><td>");
|
||||
if (wi.startDate != null)
|
||||
{
|
||||
out.write(Utils.getDateFormat(context).format(wi.startDate));
|
||||
}
|
||||
out.write("</td></tr><tr><td>");
|
||||
out.write(bundle.getString("completed_on"));
|
||||
out.write(":</td><td>");
|
||||
if (wi.endDate != null)
|
||||
{
|
||||
out.write(Utils.getDateFormat(context).format(wi.endDate));
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write("<");
|
||||
out.write(bundle.getString("in_progress"));
|
||||
out.write(">");
|
||||
}
|
||||
out.write("</td></tr></table>");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeEnd(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRendersChildren()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Strongly typed component property accessors
|
||||
|
||||
/**
|
||||
* Returns the workflow instance this component is showing information on
|
||||
*
|
||||
* @return The workflow instance
|
||||
*/
|
||||
public WorkflowInstance getValue()
|
||||
{
|
||||
ValueBinding vb = getValueBinding("value");
|
||||
if (vb != null)
|
||||
{
|
||||
this.value = (WorkflowInstance)vb.getValue(getFacesContext());
|
||||
}
|
||||
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the workflow instance to show the summary for
|
||||
*
|
||||
* @param value The workflow instance
|
||||
*/
|
||||
public void setValue(WorkflowInstance value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private NodeService getNodeService(FacesContext fc)
|
||||
{
|
||||
return Repository.getServiceRegistry(fc).getNodeService();
|
||||
}
|
||||
}
|
||||
package org.alfresco.web.ui.repo.component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.context.ResponseWriter;
|
||||
import javax.faces.el.ValueBinding;
|
||||
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.workflow.WorkflowInstance;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
import org.alfresco.web.ui.common.Utils;
|
||||
import org.springframework.extensions.webscripts.ui.common.component.SelfRenderingComponent;
|
||||
|
||||
/**
|
||||
* JSF component that displays summary information about a workflow.
|
||||
*
|
||||
* @author gavinc
|
||||
*/
|
||||
public class UIWorkflowSummary extends SelfRenderingComponent
|
||||
{
|
||||
protected WorkflowInstance value = null;
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Component Impl
|
||||
|
||||
@Override
|
||||
public String getFamily()
|
||||
{
|
||||
return "org.alfresco.faces.WorkflowSummary";
|
||||
}
|
||||
|
||||
@Override
|
||||
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.value = (WorkflowInstance)values[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object saveState(FacesContext context)
|
||||
{
|
||||
Object values[] = new Object[8];
|
||||
// standard component attributes are saved by the super class
|
||||
values[0] = super.saveState(context);
|
||||
values[1] = this.value;
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void encodeBegin(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
|
||||
WorkflowInstance wi = getValue();
|
||||
|
||||
if (wi != null)
|
||||
{
|
||||
ResponseWriter out = context.getResponseWriter();
|
||||
ResourceBundle bundle = Application.getBundle(context);
|
||||
|
||||
// output surrounding table and style if necessary
|
||||
out.write("<table");
|
||||
if (this.getAttributes().get("style") != null)
|
||||
{
|
||||
out.write(" style=\"");
|
||||
out.write((String)this.getAttributes().get("style"));
|
||||
out.write("\"");
|
||||
}
|
||||
if (this.getAttributes().get("styleClass") != null)
|
||||
{
|
||||
out.write(" class=\"");
|
||||
out.write((String)this.getAttributes().get("styleClass"));
|
||||
out.write("\"");
|
||||
}
|
||||
out.write(">");
|
||||
|
||||
// output the title and description
|
||||
out.write("<tr><td>");
|
||||
out.write(bundle.getString("title"));
|
||||
out.write(":</td><td>");
|
||||
out.write(wi.definition.title);
|
||||
if (wi.definition.description != null && wi.definition.description.length() > 0)
|
||||
{
|
||||
out.write(" (");
|
||||
out.write(Utils.encode(wi.definition.description));
|
||||
out.write(")");
|
||||
}
|
||||
out.write("</td></tr><tr><td>");
|
||||
out.write(bundle.getString("initiated_by"));
|
||||
out.write(":</td><td>");
|
||||
NodeService nodeService = getNodeService(context);
|
||||
if (wi.initiator != null)
|
||||
{
|
||||
if (nodeService.exists(wi.initiator))
|
||||
{
|
||||
out.write(Utils.encode(User.getFullName(Repository.getServiceRegistry(
|
||||
context).getNodeService(), wi.initiator)));
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write("<");
|
||||
out.write(bundle.getString("unknown"));
|
||||
out.write(">");
|
||||
}
|
||||
}
|
||||
out.write("</td></tr><tr><td>");
|
||||
out.write(bundle.getString("started_on"));
|
||||
out.write(":</td><td>");
|
||||
if (wi.startDate != null)
|
||||
{
|
||||
out.write(Utils.getDateFormat(context).format(wi.startDate));
|
||||
}
|
||||
out.write("</td></tr><tr><td>");
|
||||
out.write(bundle.getString("completed_on"));
|
||||
out.write(":</td><td>");
|
||||
if (wi.endDate != null)
|
||||
{
|
||||
out.write(Utils.getDateFormat(context).format(wi.endDate));
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write("<");
|
||||
out.write(bundle.getString("in_progress"));
|
||||
out.write(">");
|
||||
}
|
||||
out.write("</td></tr></table>");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encodeEnd(FacesContext context) throws IOException
|
||||
{
|
||||
if (!isRendered()) return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getRendersChildren()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
// Strongly typed component property accessors
|
||||
|
||||
/**
|
||||
* Returns the workflow instance this component is showing information on
|
||||
*
|
||||
* @return The workflow instance
|
||||
*/
|
||||
public WorkflowInstance getValue()
|
||||
{
|
||||
ValueBinding vb = getValueBinding("value");
|
||||
if (vb != null)
|
||||
{
|
||||
this.value = (WorkflowInstance)vb.getValue(getFacesContext());
|
||||
}
|
||||
|
||||
return this.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the workflow instance to show the summary for
|
||||
*
|
||||
* @param value The workflow instance
|
||||
*/
|
||||
public void setValue(WorkflowInstance value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private NodeService getNodeService(FacesContext fc)
|
||||
{
|
||||
return Repository.getServiceRegistry(fc).getNodeService();
|
||||
}
|
||||
}
|
||||
|
@@ -1,196 +1,196 @@
|
||||
package org.alfresco.web.ui.repo.component.evaluator;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.el.ValueBinding;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.web.action.ActionEvaluator;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.ui.common.component.evaluator.BaseEvaluator;
|
||||
|
||||
/**
|
||||
* Evaluator for executing an ActionEvaluator instance.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class ActionInstanceEvaluator extends BaseEvaluator
|
||||
{
|
||||
private static final String EVALUATOR_CACHE = "_alf_evaluator_cache";
|
||||
|
||||
/**
|
||||
* Evaluate by executing the specified action instance evaluator.
|
||||
*
|
||||
* @return true to allow rendering of child components, false otherwise
|
||||
*/
|
||||
public boolean evaluate()
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
try
|
||||
{
|
||||
final Object obj = this.getValue();
|
||||
if (obj instanceof Node)
|
||||
{
|
||||
result = evaluateCachedResult((Node)obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = this.getEvaluator().evaluate(obj);
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
// return default value on error and report meaningful error
|
||||
StringBuilder builder = new StringBuilder("Error during ActionInstanceEvaluator evaluation of ");
|
||||
builder.append(this.getEvaluator()).append(": ");
|
||||
String msg = err.getMessage();
|
||||
if (msg != null)
|
||||
{
|
||||
builder.append(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
StringWriter strWriter = new StringWriter();
|
||||
PrintWriter writer = new PrintWriter(strWriter);
|
||||
err.printStackTrace(writer);
|
||||
builder.append(strWriter.toString());
|
||||
}
|
||||
|
||||
s_logger.warn(builder.toString());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* To reduce invocations of a particular evaluator for a particular node
|
||||
* save a cache of evaluator result for a node against the current request.
|
||||
* Since the same evaluator may get reused several times for multiple actions, but
|
||||
* in effect execute against the same node instance, this can significantly reduce
|
||||
* the number of invocations required for a particular evaluator.
|
||||
*
|
||||
* @param node Node to evaluate against
|
||||
*
|
||||
* @return evaluator result
|
||||
*/
|
||||
private boolean evaluateCachedResult(Node node)
|
||||
{
|
||||
Boolean result;
|
||||
|
||||
ActionEvaluator evaluator = getEvaluator();
|
||||
String cacheKey = node.getNodeRef().toString() + '_' + evaluator.getClass().getName();
|
||||
Map<String, Boolean> cache = getEvaluatorResultCache();
|
||||
result = cache.get(cacheKey);
|
||||
if (result == null)
|
||||
{
|
||||
result = evaluator.evaluate(node);
|
||||
cache.put(cacheKey, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the evaluator result cache - tied to the current request
|
||||
*/
|
||||
private Map<String, Boolean> getEvaluatorResultCache()
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
Map<String, Boolean> cache = (Map<String, Boolean>)fc.getExternalContext().getRequestMap().get(EVALUATOR_CACHE);
|
||||
if (cache == null)
|
||||
{
|
||||
cache = new HashMap<String, Boolean>(64, 1.0f);
|
||||
fc.getExternalContext().getRequestMap().put(EVALUATOR_CACHE, cache);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
|
||||
*/
|
||||
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.evaluator = (ActionEvaluator)values[1];
|
||||
this.evaluatorClassName = (String)values[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public Object saveState(FacesContext context)
|
||||
{
|
||||
return new Object[] {
|
||||
// standard component attributes are saved by the super class
|
||||
super.saveState(context),
|
||||
this.evaluator,
|
||||
this.evaluatorClassName
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ActionEvaluator to execute
|
||||
*/
|
||||
public ActionEvaluator getEvaluator()
|
||||
{
|
||||
if (this.evaluator == null)
|
||||
{
|
||||
Object objEvaluator;
|
||||
try
|
||||
{
|
||||
Class clazz = Class.forName(getEvaluatorClassName());
|
||||
objEvaluator = clazz.newInstance();
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to construct action evaluator: " + getEvaluatorClassName());
|
||||
}
|
||||
if (objEvaluator instanceof ActionEvaluator == false)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Must implement ActionEvaluator interface: " + getEvaluatorClassName());
|
||||
}
|
||||
this.evaluator = (ActionEvaluator)objEvaluator;
|
||||
}
|
||||
return this.evaluator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param evaluator The ActionEvaluator to execute
|
||||
*/
|
||||
public void setEvaluator(ActionEvaluator evaluator)
|
||||
{
|
||||
this.evaluator = evaluator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the evaluatorClassName
|
||||
*/
|
||||
public String getEvaluatorClassName()
|
||||
{
|
||||
ValueBinding vb = getValueBinding("evaluatorClassName");
|
||||
if (vb != null)
|
||||
{
|
||||
this.evaluatorClassName = (String)vb.getValue(getFacesContext());
|
||||
}
|
||||
return this.evaluatorClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param evaluatorClassName the evaluatorClassName to set
|
||||
*/
|
||||
public void setEvaluatorClassName(String evaluatorClassName)
|
||||
{
|
||||
this.evaluatorClassName = evaluatorClassName;
|
||||
}
|
||||
|
||||
private ActionEvaluator evaluator;
|
||||
private String evaluatorClassName;
|
||||
}
|
||||
package org.alfresco.web.ui.repo.component.evaluator;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
import javax.faces.el.ValueBinding;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.web.action.ActionEvaluator;
|
||||
import org.alfresco.web.bean.repository.Node;
|
||||
import org.alfresco.web.ui.common.component.evaluator.BaseEvaluator;
|
||||
|
||||
/**
|
||||
* Evaluator for executing an ActionEvaluator instance.
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class ActionInstanceEvaluator extends BaseEvaluator
|
||||
{
|
||||
private static final String EVALUATOR_CACHE = "_alf_evaluator_cache";
|
||||
|
||||
/**
|
||||
* Evaluate by executing the specified action instance evaluator.
|
||||
*
|
||||
* @return true to allow rendering of child components, false otherwise
|
||||
*/
|
||||
public boolean evaluate()
|
||||
{
|
||||
boolean result = false;
|
||||
|
||||
try
|
||||
{
|
||||
final Object obj = this.getValue();
|
||||
if (obj instanceof Node)
|
||||
{
|
||||
result = evaluateCachedResult((Node)obj);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = this.getEvaluator().evaluate(obj);
|
||||
}
|
||||
}
|
||||
catch (Exception err)
|
||||
{
|
||||
// return default value on error and report meaningful error
|
||||
StringBuilder builder = new StringBuilder("Error during ActionInstanceEvaluator evaluation of ");
|
||||
builder.append(this.getEvaluator()).append(": ");
|
||||
String msg = err.getMessage();
|
||||
if (msg != null)
|
||||
{
|
||||
builder.append(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
StringWriter strWriter = new StringWriter();
|
||||
PrintWriter writer = new PrintWriter(strWriter);
|
||||
err.printStackTrace(writer);
|
||||
builder.append(strWriter.toString());
|
||||
}
|
||||
|
||||
s_logger.warn(builder.toString());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* To reduce invocations of a particular evaluator for a particular node
|
||||
* save a cache of evaluator result for a node against the current request.
|
||||
* Since the same evaluator may get reused several times for multiple actions, but
|
||||
* in effect execute against the same node instance, this can significantly reduce
|
||||
* the number of invocations required for a particular evaluator.
|
||||
*
|
||||
* @param node Node to evaluate against
|
||||
*
|
||||
* @return evaluator result
|
||||
*/
|
||||
private boolean evaluateCachedResult(Node node)
|
||||
{
|
||||
Boolean result;
|
||||
|
||||
ActionEvaluator evaluator = getEvaluator();
|
||||
String cacheKey = node.getNodeRef().toString() + '_' + evaluator.getClass().getName();
|
||||
Map<String, Boolean> cache = getEvaluatorResultCache();
|
||||
result = cache.get(cacheKey);
|
||||
if (result == null)
|
||||
{
|
||||
result = evaluator.evaluate(node);
|
||||
cache.put(cacheKey, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the evaluator result cache - tied to the current request
|
||||
*/
|
||||
private Map<String, Boolean> getEvaluatorResultCache()
|
||||
{
|
||||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
Map<String, Boolean> cache = (Map<String, Boolean>)fc.getExternalContext().getRequestMap().get(EVALUATOR_CACHE);
|
||||
if (cache == null)
|
||||
{
|
||||
cache = new HashMap<String, Boolean>(64, 1.0f);
|
||||
fc.getExternalContext().getRequestMap().put(EVALUATOR_CACHE, cache);
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
|
||||
*/
|
||||
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.evaluator = (ActionEvaluator)values[1];
|
||||
this.evaluatorClassName = (String)values[2];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
|
||||
*/
|
||||
public Object saveState(FacesContext context)
|
||||
{
|
||||
return new Object[] {
|
||||
// standard component attributes are saved by the super class
|
||||
super.saveState(context),
|
||||
this.evaluator,
|
||||
this.evaluatorClassName
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ActionEvaluator to execute
|
||||
*/
|
||||
public ActionEvaluator getEvaluator()
|
||||
{
|
||||
if (this.evaluator == null)
|
||||
{
|
||||
Object objEvaluator;
|
||||
try
|
||||
{
|
||||
Class clazz = Class.forName(getEvaluatorClassName());
|
||||
objEvaluator = clazz.newInstance();
|
||||
}
|
||||
catch (Throwable err)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Unable to construct action evaluator: " + getEvaluatorClassName());
|
||||
}
|
||||
if (objEvaluator instanceof ActionEvaluator == false)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Must implement ActionEvaluator interface: " + getEvaluatorClassName());
|
||||
}
|
||||
this.evaluator = (ActionEvaluator)objEvaluator;
|
||||
}
|
||||
return this.evaluator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param evaluator The ActionEvaluator to execute
|
||||
*/
|
||||
public void setEvaluator(ActionEvaluator evaluator)
|
||||
{
|
||||
this.evaluator = evaluator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the evaluatorClassName
|
||||
*/
|
||||
public String getEvaluatorClassName()
|
||||
{
|
||||
ValueBinding vb = getValueBinding("evaluatorClassName");
|
||||
if (vb != null)
|
||||
{
|
||||
this.evaluatorClassName = (String)vb.getValue(getFacesContext());
|
||||
}
|
||||
return this.evaluatorClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param evaluatorClassName the evaluatorClassName to set
|
||||
*/
|
||||
public void setEvaluatorClassName(String evaluatorClassName)
|
||||
{
|
||||
this.evaluatorClassName = evaluatorClassName;
|
||||
}
|
||||
|
||||
private ActionEvaluator evaluator;
|
||||
private String evaluatorClassName;
|
||||
}
|
||||
|
@@ -1,88 +1,88 @@
|
||||
package org.alfresco.web.ui.repo.component.template;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.repo.web.scripts.FileTypeImageUtils;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.FileTypeImageSize;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
|
||||
/**
|
||||
* Helper class to generate the default template model.
|
||||
* <p>
|
||||
* See http://www.alfresco.org/mediawiki/index.php/Template_Guide for details
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class DefaultModelHelper
|
||||
{
|
||||
/**
|
||||
* Private Constructor
|
||||
*/
|
||||
private DefaultModelHelper()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the default FreeMarker template model.
|
||||
* <p>
|
||||
* Other root level objects such as the current Space or Document are generally
|
||||
* added by the appropriate bean responsible for provided access to those nodes.
|
||||
* <p>
|
||||
* Uses the default TemplateImageResolver instance to resolve icons - assumes that the client
|
||||
* has a valid FacesContext.
|
||||
* <p>
|
||||
* See http://www.alfresco.org/mediawiki/index.php/Template_Guide for details
|
||||
*
|
||||
* @return Map containing the default model.
|
||||
*/
|
||||
public static Map<String, Object> buildDefaultModel(
|
||||
ServiceRegistry services, User user, NodeRef template)
|
||||
{
|
||||
return buildDefaultModel(services, user, template, imageResolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the default FreeMarker template model.
|
||||
* <p>
|
||||
* Other root level objects such as the current Space or Document are generally
|
||||
* added by the appropriate bean responsible for provided access to those nodes.
|
||||
* <p>
|
||||
* See http://www.alfresco.org/mediawiki/index.php/Template_Guide for details
|
||||
*
|
||||
* @return Map containing the default model.
|
||||
*/
|
||||
public static Map<String, Object> buildDefaultModel(
|
||||
ServiceRegistry services, User user, NodeRef template, TemplateImageResolver resolver)
|
||||
{
|
||||
if (services == null)
|
||||
{
|
||||
throw new IllegalArgumentException("ServiceRegistry is mandatory.");
|
||||
}
|
||||
if (user == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Current User is mandatory.");
|
||||
}
|
||||
|
||||
NodeRef companyRootRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId());
|
||||
NodeRef userRootRef = new NodeRef(Repository.getStoreRef(), user.getHomeSpaceId());
|
||||
|
||||
return services.getTemplateService().buildDefaultModel(
|
||||
user.getPerson(), companyRootRef, userRootRef, template, resolver);
|
||||
}
|
||||
|
||||
/** Template Image resolver helper */
|
||||
public static final TemplateImageResolver imageResolver = new TemplateImageResolver()
|
||||
{
|
||||
public String resolveImagePathForName(String filename, FileTypeImageSize size)
|
||||
{
|
||||
return FileTypeImageUtils.getFileTypeImage(FacesContext.getCurrentInstance(), filename, size);
|
||||
}
|
||||
};
|
||||
}
|
||||
package org.alfresco.web.ui.repo.component.template;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.faces.context.FacesContext;
|
||||
|
||||
import org.alfresco.repo.web.scripts.FileTypeImageUtils;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.cmr.repository.FileTypeImageSize;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||
import org.alfresco.web.app.Application;
|
||||
import org.alfresco.web.bean.repository.Repository;
|
||||
import org.alfresco.web.bean.repository.User;
|
||||
|
||||
/**
|
||||
* Helper class to generate the default template model.
|
||||
* <p>
|
||||
* See http://www.alfresco.org/mediawiki/index.php/Template_Guide for details
|
||||
*
|
||||
* @author Kevin Roast
|
||||
*/
|
||||
public class DefaultModelHelper
|
||||
{
|
||||
/**
|
||||
* Private Constructor
|
||||
*/
|
||||
private DefaultModelHelper()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the default FreeMarker template model.
|
||||
* <p>
|
||||
* Other root level objects such as the current Space or Document are generally
|
||||
* added by the appropriate bean responsible for provided access to those nodes.
|
||||
* <p>
|
||||
* Uses the default TemplateImageResolver instance to resolve icons - assumes that the client
|
||||
* has a valid FacesContext.
|
||||
* <p>
|
||||
* See http://www.alfresco.org/mediawiki/index.php/Template_Guide for details
|
||||
*
|
||||
* @return Map containing the default model.
|
||||
*/
|
||||
public static Map<String, Object> buildDefaultModel(
|
||||
ServiceRegistry services, User user, NodeRef template)
|
||||
{
|
||||
return buildDefaultModel(services, user, template, imageResolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct the default FreeMarker template model.
|
||||
* <p>
|
||||
* Other root level objects such as the current Space or Document are generally
|
||||
* added by the appropriate bean responsible for provided access to those nodes.
|
||||
* <p>
|
||||
* See http://www.alfresco.org/mediawiki/index.php/Template_Guide for details
|
||||
*
|
||||
* @return Map containing the default model.
|
||||
*/
|
||||
public static Map<String, Object> buildDefaultModel(
|
||||
ServiceRegistry services, User user, NodeRef template, TemplateImageResolver resolver)
|
||||
{
|
||||
if (services == null)
|
||||
{
|
||||
throw new IllegalArgumentException("ServiceRegistry is mandatory.");
|
||||
}
|
||||
if (user == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Current User is mandatory.");
|
||||
}
|
||||
|
||||
NodeRef companyRootRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId());
|
||||
NodeRef userRootRef = new NodeRef(Repository.getStoreRef(), user.getHomeSpaceId());
|
||||
|
||||
return services.getTemplateService().buildDefaultModel(
|
||||
user.getPerson(), companyRootRef, userRootRef, template, resolver);
|
||||
}
|
||||
|
||||
/** Template Image resolver helper */
|
||||
public static final TemplateImageResolver imageResolver = new TemplateImageResolver()
|
||||
{
|
||||
public String resolveImagePathForName(String filename, FileTypeImageSize size)
|
||||
{
|
||||
return FileTypeImageUtils.getFileTypeImage(FacesContext.getCurrentInstance(), filename, size);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user