();
+ viewStack = new Stack();
context.getExternalContext().getSessionMap().put(VIEW_STACK, viewStack);
}
diff --git a/source/java/org/alfresco/web/app/AlfrescoVariableResolver.java b/source/java/org/alfresco/web/app/AlfrescoVariableResolver.java
new file mode 100644
index 0000000000..fa506da653
--- /dev/null
+++ b/source/java/org/alfresco/web/app/AlfrescoVariableResolver.java
@@ -0,0 +1,143 @@
+package org.alfresco.web.app;
+
+import javax.faces.context.FacesContext;
+import javax.faces.el.EvaluationException;
+import javax.faces.el.VariableResolver;
+
+import org.alfresco.config.Config;
+import org.alfresco.config.ConfigService;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.web.jsf.DelegatingVariableResolver;
+
+/**
+ * JSF VariableResolver that first delegates to the Spring JSF variable
+ * resolver. The sole purpose of this variable resolver is to look out
+ * for the Container
variable. If this variable is encountered
+ * the current viewId is examined. If the current viewId matches the
+ * configured dialog or wizard container the appropriate manager object is
+ * returned i.e. DialogManager or WizardManager.
+ *
+ * Configure this resolver in your faces-config.xml
file as follows:
+ *
+ *
+ * <application>
+ * ...
+ * <variable-resolver>org.alfresco.web.app.AlfrescoVariableResolver</variable-resolver>
+ * </application>
+ *
+ * @see org.alfresco.web.bean.dialog.DialogManager
+ * @see org.alfresco.web.bean.wizard.WizardManager
+ * @author gavinc
+ */
+public class AlfrescoVariableResolver extends DelegatingVariableResolver
+{
+ protected String dialogContainer = null;
+ protected String wizardContainer = null;
+
+ private static final String CONTAINER = "Container";
+
+ private static final Log logger = LogFactory.getLog(AlfrescoVariableResolver.class);
+
+ /**
+ * Creates a new VariableResolver.
+ *
+ * @param originalVariableResolver The original variable resolver
+ */
+ public AlfrescoVariableResolver(VariableResolver originalVariableResolver)
+ {
+ super(originalVariableResolver);
+ }
+
+ /**
+ * Resolves the variable with the given name.
+ *
+ * This implementation will first delegate to the Spring variable resolver.
+ * If the variable is not found by the Spring resolver and the variable name
+ * is Container
the current viewId is examined.
+ * If the current viewId matches the configured dialog or wizard container
+ * the appropriate manager object is returned i.e. DialogManager or WizardManager.
+ *
+ * @param context FacesContext
+ * @param name The name of the variable to resolve
+ */
+ public Object resolveVariable(FacesContext context, String name)
+ throws EvaluationException
+ {
+ Object variable = super.resolveVariable(context, name);
+
+ if (variable == null)
+ {
+ // if the variable was not resolved see if the name is "Container"
+ if (name.equals(CONTAINER))
+ {
+ // get the current view id and the configured dialog and wizard
+ // container pages
+ String viewId = context.getViewRoot().getViewId();
+ String dialogContainer = getDialogContainer(context);
+ String wizardContainer = getWizardContainer(context);
+
+ // see if we are currently in a wizard or a dialog
+ if (viewId.equals(dialogContainer))
+ {
+ variable = Application.getDialogManager();
+ }
+ else if (viewId.equals(wizardContainer))
+ {
+ variable = Application.getWizardManager();
+ }
+
+ if (variable != null && logger.isDebugEnabled())
+ {
+ logger.debug("Resolved 'Container' variable to: " + variable);
+ }
+ }
+ }
+
+ return variable;
+ }
+
+ /**
+ * Retrieves the configured dialog container page
+ *
+ * @param context FacesContext
+ * @return The container page
+ */
+ protected String getDialogContainer(FacesContext context)
+ {
+ if (this.dialogContainer == null)
+ {
+ ConfigService configSvc = Application.getConfigService(context);
+ Config globalConfig = configSvc.getGlobalConfig();
+
+ if (globalConfig != null)
+ {
+ this.dialogContainer = globalConfig.getConfigElement("dialog-container").getValue();
+ }
+ }
+
+ return this.dialogContainer;
+ }
+
+ /**
+ * Retrieves the configured wizard container page
+ *
+ * @param context FacesContext
+ * @return The container page
+ */
+ protected String getWizardContainer(FacesContext context)
+ {
+ if (this.wizardContainer == null)
+ {
+ ConfigService configSvc = Application.getConfigService(context);
+ Config globalConfig = configSvc.getGlobalConfig();
+
+ if (globalConfig != null)
+ {
+ this.wizardContainer = globalConfig.getConfigElement("wizard-container").getValue();
+ }
+ }
+
+ return this.wizardContainer;
+ }
+}
diff --git a/source/java/org/alfresco/web/app/portlet/AlfrescoFacesPortlet.java b/source/java/org/alfresco/web/app/portlet/AlfrescoFacesPortlet.java
index afc5984f07..2130a849dd 100644
--- a/source/java/org/alfresco/web/app/portlet/AlfrescoFacesPortlet.java
+++ b/source/java/org/alfresco/web/app/portlet/AlfrescoFacesPortlet.java
@@ -33,6 +33,7 @@ import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.UnavailableException;
+import org.alfresco.config.ConfigService;
import org.alfresco.i18n.I18NUtil;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.service.cmr.security.AuthenticationService;
@@ -43,7 +44,9 @@ import org.alfresco.web.app.servlet.AuthenticationStatus;
import org.alfresco.web.bean.ErrorBean;
import org.alfresco.web.bean.FileUploadBean;
import org.alfresco.web.bean.LoginBean;
+import org.alfresco.web.bean.NavigationBean;
import org.alfresco.web.bean.repository.User;
+import org.alfresco.web.config.ClientConfigElement;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.portlet.PortletFileUpload;
@@ -259,7 +262,18 @@ public class AlfrescoFacesPortlet extends MyFacesGenericPortlet
// perform the forward to the page processed by the Faces servlet
response.setContentType("text/html");
request.getPortletSession().setAttribute(PortletUtil.PORTLET_REQUEST_FLAG, "true");
- nonFacesRequest(request, response, "/jsp/browse/browse.jsp");
+
+ // get the start location as configured by the web-client config
+ ConfigService configService = (ConfigService)ctx.getBean("webClientConfigService");
+ ClientConfigElement configElement = (ClientConfigElement)configService.getGlobalConfig().getConfigElement("client");
+ if (NavigationBean.LOCATION_MYALFRESCO.equals(configElement.getInitialLocation()))
+ {
+ nonFacesRequest(request, response, "/jsp/dashboards/container.jsp");
+ }
+ else
+ {
+ nonFacesRequest(request, response, "/jsp/browse/browse.jsp");
+ }
}
else
{
diff --git a/source/java/org/alfresco/web/app/servlet/BaseServlet.java b/source/java/org/alfresco/web/app/servlet/BaseServlet.java
index 90b4c7c687..42dde0bf53 100644
--- a/source/java/org/alfresco/web/app/servlet/BaseServlet.java
+++ b/source/java/org/alfresco/web/app/servlet/BaseServlet.java
@@ -77,7 +77,6 @@ public abstract class BaseServlet extends HttpServlet
validRedirectJSPs.add("/jsp/forums/forums.jsp");
validRedirectJSPs.add("/jsp/users/users.jsp");
validRedirectJSPs.add("/jsp/trashcan/trash-list.jsp");
- validRedirectJSPs.add("/jsp/dashboards/container.jsp");
}
private static Log logger = LogFactory.getLog(BaseServlet.class);
@@ -156,10 +155,15 @@ public abstract class BaseServlet extends HttpServlet
throws IOException
{
// authentication failed - so end servlet execution and redirect to login page
- // also save the full requested URL so the login page knows where to redirect too later
res.sendRedirect(req.getContextPath() + FACES_SERVLET + Application.getLoginPage(sc));
+
+ // save the full requested URL so the login page knows where to redirect too later
String uri = req.getRequestURI();
- String url = uri + (req.getQueryString() != null ? ("?" + req.getQueryString()) : "");
+ String url = uri;
+ if (req.getQueryString() != null && req.getQueryString().length() != 0)
+ {
+ url += "?" + req.getQueryString();
+ }
if (uri.indexOf(req.getContextPath() + FACES_SERVLET) != -1)
{
// if we find a JSF servlet reference in the URI then we need to check if the rest of the
diff --git a/source/java/org/alfresco/web/bean/CheckinCheckoutBean.java b/source/java/org/alfresco/web/bean/CheckinCheckoutBean.java
index b130c3d788..3359683f70 100644
--- a/source/java/org/alfresco/web/bean/CheckinCheckoutBean.java
+++ b/source/java/org/alfresco/web/bean/CheckinCheckoutBean.java
@@ -40,13 +40,12 @@ import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.version.Version;
import org.alfresco.service.cmr.version.VersionType;
+import org.alfresco.web.app.AlfrescoNavigationHandler;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.context.UIContextService;
import org.alfresco.web.app.servlet.DownloadContentServlet;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.Repository;
-import org.alfresco.web.templating.OutputUtil;
-import org.alfresco.web.templating.TemplatingService;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.component.UIActionLink;
import org.apache.commons.logging.Log;
@@ -376,8 +375,8 @@ public class CheckinCheckoutBean
*/
private Node setupContentDocument(String id)
{
- if (LOGGER.isDebugEnabled())
- LOGGER.debug("Setup for action, setting current document to: " + id);
+ if (logger.isDebugEnabled())
+ logger.debug("Setup for action, setting current document to: " + id);
Node node = null;
@@ -427,14 +426,14 @@ public class CheckinCheckoutBean
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
tx.begin();
- if (LOGGER.isDebugEnabled())
- LOGGER.debug("Trying to checkout content node Id: " + node.getId());
+ if (logger.isDebugEnabled())
+ logger.debug("Trying to checkout content node Id: " + node.getId());
// checkout the node content to create a working copy
- if (LOGGER.isDebugEnabled())
+ if (logger.isDebugEnabled())
{
- LOGGER.debug("Checkout copy location: " + getCopyLocation());
- LOGGER.debug("Selected Space Id: " + this.selectedSpaceId);
+ logger.debug("Checkout copy location: " + getCopyLocation());
+ logger.debug("Selected Space Id: " + this.selectedSpaceId);
}
NodeRef workingCopyRef;
if (getCopyLocation().equals(COPYLOCATION_OTHER) && this.selectedSpaceId != null)
@@ -478,7 +477,7 @@ public class CheckinCheckoutBean
}
else
{
- LOGGER.warn("WARNING: checkoutFile called without a current Document!");
+ logger.warn("WARNING: checkoutFile called without a current Document!");
}
return outcome;
@@ -494,16 +493,22 @@ public class CheckinCheckoutBean
Node node = getWorkingDocument();
if (node != null)
{
+ // reset the underlying node
+ if (this.browseBean.getDocument() != null)
+ {
+ this.browseBean.getDocument().reset();
+ }
+
// clean up and clear action context
clearUpload();
setDocument(null);
setWorkingDocument(null);
-
- outcome = "browse";
+
+ outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME;
}
else
{
- LOGGER.warn("WARNING: checkoutFileOK called without a current WorkingDocument!");
+ logger.warn("WARNING: checkoutFileOK called without a current WorkingDocument!");
}
return outcome;
@@ -524,11 +529,11 @@ public class CheckinCheckoutBean
setDocument(null);
setWorkingDocument(null);
- outcome = "browse";
+ outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME;
}
else
{
- LOGGER.warn("WARNING: editFileOK called without a current Document!");
+ logger.warn("WARNING: editFileOK called without a current Document!");
}
return outcome;
@@ -567,17 +572,12 @@ public class CheckinCheckoutBean
MimetypeMap.MIMETYPE_JAVASCRIPT.equals(mimetype))
{
// make content available to the editing screen
- String contentString = reader.getContentString();
- setDocumentContent(contentString);
- setEditorOutput(contentString);
-
- // navigate to appropriate screen
- FacesContext fc = FacesContext.getCurrentInstance();
- this.navigator.setupDispatchContext(node);
- String s = (MimetypeMap.MIMETYPE_XML.equals(mimetype)
- ? "editXmlInline"
- : "editTextInline");
- fc.getApplication().getNavigationHandler().handleNavigation(fc, null, s);
+ setEditorOutput(reader.getContentString());
+
+ // navigate to appropriate screen
+ FacesContext fc = FacesContext.getCurrentInstance();
+ this.navigator.setupDispatchContext(node);
+ fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "dialog:editTextInline");
}
else
{
@@ -588,7 +588,7 @@ public class CheckinCheckoutBean
// navigate to appropriate screen
FacesContext fc = FacesContext.getCurrentInstance();
this.navigator.setupDispatchContext(node);
- fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "editHtmlInline");
+ fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "dialog:editHtmlInline");
}
}
}
@@ -598,7 +598,7 @@ public class CheckinCheckoutBean
// normal downloadable document
FacesContext fc = FacesContext.getCurrentInstance();
this.navigator.setupDispatchContext(node);
- fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "editFile");
+ fc.getApplication().getNavigationHandler().handleNavigation(fc, null, "dialog:editFile");
}
}
}
@@ -620,31 +620,23 @@ public class CheckinCheckoutBean
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
tx.begin();
- if (LOGGER.isDebugEnabled())
- LOGGER.debug("Trying to update content node Id: " + node.getId());
+ if (logger.isDebugEnabled())
+ logger.debug("Trying to update content node Id: " + node.getId());
// get an updating writer that we can use to modify the content on the current node
ContentWriter writer = this.contentService.getWriter(node.getNodeRef(), ContentModel.PROP_CONTENT, true);
writer.putContent(this.editorOutput);
-
+
// commit the transaction
tx.commit();
-
- if (nodeService.getProperty(node.getNodeRef(),
- TemplatingService.TT_QNAME) != null)
- {
- OutputUtil.regenerate(node.getNodeRef(),
- this.contentService,
- this.nodeService);
- }
// clean up and clear action context
clearUpload();
setDocument(null);
setDocumentContent(null);
setEditorOutput(null);
-
- outcome = "browse";
+
+ outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME;
}
catch (Throwable err)
{
@@ -656,7 +648,7 @@ public class CheckinCheckoutBean
}
else
{
- LOGGER.warn("WARNING: editInlineOK called without a current Document!");
+ logger.warn("WARNING: editInlineOK called without a current Document!");
}
return outcome;
@@ -679,7 +671,7 @@ public class CheckinCheckoutBean
clearUpload();
- outcome = "browse";
+ outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME;
}
catch (Throwable err)
{
@@ -689,7 +681,7 @@ public class CheckinCheckoutBean
}
else
{
- LOGGER.warn("WARNING: undoCheckout called without a current WorkingDocument!");
+ logger.warn("WARNING: undoCheckout called without a current WorkingDocument!");
}
return outcome;
@@ -726,10 +718,10 @@ public class CheckinCheckoutBean
{
throw new IllegalStateException("Node supplied for undo checkout has neither Working Copy or Locked aspect!");
}
-
+
clearUpload();
- outcome = "browse";
+ outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse";
}
catch (Throwable err)
{
@@ -738,7 +730,7 @@ public class CheckinCheckoutBean
}
else
{
- LOGGER.warn("WARNING: undoCheckout called without a current WorkingDocument!");
+ logger.warn("WARNING: undoCheckout called without a current WorkingDocument!");
}
return outcome;
@@ -763,8 +755,8 @@ public class CheckinCheckoutBean
tx = Repository.getUserTransaction(context);
tx.begin();
- if (LOGGER.isDebugEnabled())
- LOGGER.debug("Trying to checkin content node Id: " + node.getId());
+ if (logger.isDebugEnabled())
+ logger.debug("Trying to checkin content node Id: " + node.getId());
// we can either checkin the content from the current working copy node
// which would have been previously updated by the user
@@ -816,7 +808,8 @@ public class CheckinCheckoutBean
setDocument(null);
clearUpload();
- outcome = "browse";
+ outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME +
+ AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse";
}
catch (Throwable err)
{
@@ -828,7 +821,7 @@ public class CheckinCheckoutBean
}
else
{
- LOGGER.warn("WARNING: checkinFileOK called without a current Document!");
+ logger.warn("WARNING: checkinFileOK called without a current Document!");
}
return outcome;
@@ -853,8 +846,8 @@ public class CheckinCheckoutBean
tx = Repository.getUserTransaction(context);
tx.begin();
- if (LOGGER.isDebugEnabled())
- LOGGER.debug("Trying to update content node Id: " + node.getId());
+ if (logger.isDebugEnabled())
+ logger.debug("Trying to update content node Id: " + node.getId());
// get an updating writer that we can use to modify the content on the current node
ContentWriter writer = this.contentService.getWriter(node.getNodeRef(), ContentModel.PROP_CONTENT, true);
@@ -872,7 +865,7 @@ public class CheckinCheckoutBean
setDocument(null);
clearUpload();
- outcome = "browse";
+ outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME;
}
catch (Throwable err)
{
@@ -884,7 +877,7 @@ public class CheckinCheckoutBean
}
else
{
- LOGGER.warn("WARNING: updateFileOK called without a current Document!");
+ logger.warn("WARNING: updateFileOK called without a current Document!");
}
return outcome;
@@ -898,7 +891,7 @@ public class CheckinCheckoutBean
// reset the state
clearUpload();
- return "browse";
+ return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME;
}
/**
@@ -929,7 +922,7 @@ public class CheckinCheckoutBean
// ------------------------------------------------------------------------------
// Private data
- private static final Log LOGGER = LogFactory.getLog(CheckinCheckoutBean.class);
+ private static Log logger = LogFactory.getLog(CheckinCheckoutBean.class);
/** I18N messages */
private static final String MSG_ERROR_CHECKIN = "error_checkin";
diff --git a/source/java/org/alfresco/web/bean/LoginBean.java b/source/java/org/alfresco/web/bean/LoginBean.java
index 17274e42b9..406f26b039 100644
--- a/source/java/org/alfresco/web/bean/LoginBean.java
+++ b/source/java/org/alfresco/web/bean/LoginBean.java
@@ -91,13 +91,21 @@ public class LoginBean
}
/**
- * @param navigator The NavigationBean to set.
+ * @param navigator The NavigationBean to set.
*/
public void setNavigator(NavigationBean navigator)
{
this.navigator = navigator;
}
+ /**
+ * @param preferences The UserPreferencesBean to set
+ */
+ public void setUserPreferencesBean(UserPreferencesBean preferences)
+ {
+ this.preferences = preferences;
+ }
+
/**
* @return true if the default Alfresco authentication process is being used, else false
* if an external authorisation mechanism is present.
@@ -329,7 +337,7 @@ public class LoginBean
else
{
// special case to handle jump to My Alfresco page initially
- String location = Application.getClientConfig(FacesContext.getCurrentInstance()).getInitialLocation();
+ String location = this.preferences.getStartLocation();
if (NavigationBean.LOCATION_MYALFRESCO.equals(location))
{
return "myalfresco";
@@ -451,4 +459,7 @@ public class LoginBean
/** The NavigationBean bean reference */
protected NavigationBean navigator;
+
+ /** The user preferences bean reference */
+ protected UserPreferencesBean preferences;
}
diff --git a/source/java/org/alfresco/web/bean/NavigationBean.java b/source/java/org/alfresco/web/bean/NavigationBean.java
index d426a07732..8f13f9e018 100644
--- a/source/java/org/alfresco/web/bean/NavigationBean.java
+++ b/source/java/org/alfresco/web/bean/NavigationBean.java
@@ -126,6 +126,14 @@ public class NavigationBean
this.contentDiskDriver = contentDiskDriver;
}
+ /**
+ * @param preferences The UserPreferencesBean to set
+ */
+ public void setUserPreferencesBean(UserPreferencesBean preferences)
+ {
+ this.preferences = preferences;
+ }
+
/**
* @return the User object representing the current instance for this user
*/
@@ -252,6 +260,15 @@ public class NavigationBean
}
else if (LOCATION_MYALFRESCO.equals(location))
{
+ // make sure we set a current node ID as some screens expect this
+ if (getCurrentNodeId() == null)
+ {
+ String homeSpaceId = Application.getCurrentUser(context).getHomeSpaceId();
+ NodeRef homeSpaceRef = new NodeRef(Repository.getStoreRef(), homeSpaceId);
+ setCurrentNodeId(homeSpaceRef.getId());
+ }
+
+ // create a breadcrumb handler for this special case location (not a node)
List elements = new ArrayList(1);
elements.add(new IBreadcrumbHandler()
{
@@ -507,13 +524,8 @@ public class NavigationBean
{
if (this.location == null)
{
- // get the initial location from the client config
- String initialLocation = clientConfig.getInitialLocation();
- if (initialLocation == null || initialLocation.length() == 0)
- {
- initialLocation = LOCATION_HOME;
- }
- processToolbarLocation(initialLocation, false);
+ // get the initial location from the user preferences
+ processToolbarLocation(this.preferences.getStartLocation(), false);
}
return this.location;
@@ -798,10 +810,10 @@ public class NavigationBean
private static Logger s_logger = Logger.getLogger(NavigationBean.class);
/** constant values used by the toolbar location modelist control */
- static final String LOCATION_COMPANY = "companyhome";
- static final String LOCATION_HOME = "userhome";
- static final String LOCATION_GUEST = "guesthome";
- static final String LOCATION_MYALFRESCO = "myalfresco";
+ public static final String LOCATION_COMPANY = "companyhome";
+ public static final String LOCATION_HOME = "userhome";
+ public static final String LOCATION_GUEST = "guesthome";
+ public static final String LOCATION_MYALFRESCO = "myalfresco";
private static final String MSG_MYALFRESCO = "my_alfresco";
@@ -828,6 +840,9 @@ public class NavigationBean
/** Client configuration object */
protected ClientConfigElement clientConfig = null;
+ /** The user preferences bean reference */
+ protected UserPreferencesBean preferences;
+
/** Cached path to our CIFS server and top level node DIR */
private String cifsServerPath;
diff --git a/source/java/org/alfresco/web/bean/UserPreferencesBean.java b/source/java/org/alfresco/web/bean/UserPreferencesBean.java
new file mode 100644
index 0000000000..692e3dd7e3
--- /dev/null
+++ b/source/java/org/alfresco/web/bean/UserPreferencesBean.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.web.bean;
+
+import java.util.ResourceBundle;
+
+import javax.faces.context.FacesContext;
+import javax.faces.model.SelectItem;
+
+import org.alfresco.web.app.Application;
+import org.alfresco.web.bean.repository.PreferencesService;
+
+/**
+ * Simple bean backing the user preferences settings.
+ *
+ * @author Kevin Roast
+ */
+public class UserPreferencesBean
+{
+ private static final String PREF_STARTLOCATION = "start-location";
+ private static final String MSG_MYALFRESCO = "my_alfresco";
+ private static final String MSG_MYHOME = "my_home";
+ private static final String MSG_COMPANYHOME = "company_home";
+ private static final String MSG_GUESTHOME = "guest_home";
+
+
+ public String getStartLocation()
+ {
+ String location = (String)PreferencesService.getPreferences().getValue(PREF_STARTLOCATION);
+ if (location == null)
+ {
+ // default to value from client config
+ location = Application.getClientConfig(FacesContext.getCurrentInstance()).getInitialLocation();
+ }
+ return location;
+ }
+
+ public void setStartLocation(String location)
+ {
+ PreferencesService.getPreferences().setValue(PREF_STARTLOCATION, location);
+ }
+
+ public SelectItem[] getStartLocations()
+ {
+ ResourceBundle msg = Application.getBundle(FacesContext.getCurrentInstance());
+ return new SelectItem[] {
+ new SelectItem(NavigationBean.LOCATION_MYALFRESCO, msg.getString(MSG_MYALFRESCO)),
+ new SelectItem(NavigationBean.LOCATION_HOME, msg.getString(MSG_MYHOME)),
+ new SelectItem(NavigationBean.LOCATION_COMPANY, msg.getString(MSG_COMPANYHOME)),
+ new SelectItem(NavigationBean.LOCATION_GUEST, msg.getString(MSG_GUESTHOME))};
+ }
+}
diff --git a/source/java/org/alfresco/web/bean/actions/handlers/ScriptHandler.java b/source/java/org/alfresco/web/bean/actions/handlers/ScriptHandler.java
index 41321fba6e..ef73b9bd9b 100644
--- a/source/java/org/alfresco/web/bean/actions/handlers/ScriptHandler.java
+++ b/source/java/org/alfresco/web/bean/actions/handlers/ScriptHandler.java
@@ -6,7 +6,7 @@ import java.util.Map;
import javax.faces.context.FacesContext;
-import org.alfresco.repo.action.executer.ScriptActionExecutor;
+import org.alfresco.repo.action.executer.ScriptActionExecuter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.servlet.FacesHelper;
@@ -25,7 +25,7 @@ public class ScriptHandler extends BaseActionHandler
public String getJSPPath()
{
- return getJSPPath(ScriptActionExecutor.NAME);
+ return getJSPPath(ScriptActionExecuter.NAME);
}
public void prepareForSave(Map actionProps,
@@ -34,13 +34,13 @@ public class ScriptHandler extends BaseActionHandler
// add the selected script noderef to the action properties
String id = (String)actionProps.get(PROP_SCRIPT);
NodeRef scriptRef = new NodeRef(Repository.getStoreRef(), id);
- repoProps.put(ScriptActionExecutor.PARAM_SCRIPTREF, scriptRef);
+ repoProps.put(ScriptActionExecuter.PARAM_SCRIPTREF, scriptRef);
}
public void prepareForEdit(Map actionProps,
Map repoProps)
{
- NodeRef scriptRef = (NodeRef)repoProps.get(ScriptActionExecutor.PARAM_SCRIPTREF);
+ NodeRef scriptRef = (NodeRef)repoProps.get(ScriptActionExecuter.PARAM_SCRIPTREF);
actionProps.put(PROP_SCRIPT, scriptRef.getId());
}
diff --git a/source/java/org/alfresco/web/bean/clipboard/ClipboardBean.java b/source/java/org/alfresco/web/bean/clipboard/ClipboardBean.java
index 89c9b0c81f..a707d316c7 100644
--- a/source/java/org/alfresco/web/bean/clipboard/ClipboardBean.java
+++ b/source/java/org/alfresco/web/bean/clipboard/ClipboardBean.java
@@ -34,8 +34,6 @@ import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.model.FileExistsException;
import org.alfresco.service.cmr.model.FileFolderService;
-import org.alfresco.service.cmr.model.FileInfo;
-import org.alfresco.service.cmr.model.FileNotFoundException;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.CopyService;
import org.alfresco.service.cmr.repository.InvalidNodeRefException;
@@ -182,12 +180,8 @@ public class ClipboardBean
*/
private void performPasteItems(int index, int action)
{
- UserTransaction tx = null;
try
{
- tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
- tx.begin();
-
if (index == -1)
{
// paste all
@@ -219,16 +213,11 @@ public class ClipboardBean
}
}
- // commit the transaction
- tx.commit();
-
// refresh UI on success
UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans();
}
catch (Throwable err)
{
- // rollback the transaction
- try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
Utils.addErrorMessage(Application.getMessage(
FacesContext.getCurrentInstance(), MSG_ERROR_PASTE) + err.getMessage(), err);
}
@@ -241,7 +230,7 @@ public class ClipboardBean
* @param action the clipboard action to perform (see UIClipboardShelfItem)
*/
private void performClipboardOperation(ClipboardItem item, int action)
- throws FileExistsException, FileNotFoundException
+ throws Throwable
{
NodeRef destRef = new NodeRef(Repository.getStoreRef(), this.navigator.getCurrentNodeId());
@@ -267,8 +256,12 @@ public class ClipboardBean
boolean operationComplete = false;
while (operationComplete == false)
{
+ UserTransaction tx = null;
try
{
+ // attempt each copy/paste in its own transaction
+ tx = Repository.getUserTransaction(FacesContext.getCurrentInstance());
+ tx.begin();
if (item.Mode == ClipboardStatus.COPY)
{
if (action == UIClipboardShelfItem.ACTION_PASTE_LINK)
@@ -399,10 +392,25 @@ public class ClipboardBean
throw fileExistsErr;
}
}
- if (operationComplete == false)
+ catch (Throwable e)
{
- String copyOf = Application.getMessage(FacesContext.getCurrentInstance(), MSG_COPY_OF);
- name = copyOf + ' ' + name;
+ // some other type of exception occured - rollback and exit
+ throw e;
+ }
+ finally
+ {
+ // rollback if the operation didn't complete
+ if (operationComplete == false)
+ {
+ try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
+ String copyOf = Application.getMessage(FacesContext.getCurrentInstance(), MSG_COPY_OF);
+ name = copyOf + ' ' + name;
+ }
+ else
+ {
+ // commit the transaction
+ tx.commit();
+ }
}
}
}
diff --git a/source/java/org/alfresco/web/bean/content/CreateContentWizard.java b/source/java/org/alfresco/web/bean/content/CreateContentWizard.java
index dd11533c0d..881facb299 100644
--- a/source/java/org/alfresco/web/bean/content/CreateContentWizard.java
+++ b/source/java/org/alfresco/web/bean/content/CreateContentWizard.java
@@ -1,23 +1,6 @@
-/*
- * Copyright (C) 2005 Alfresco, Inc.
- *
- * Licensed under the Mozilla Public License version 1.1
- * with a permitted attribution clause. You may obtain a
- * copy of the License at
- *
- * http://www.alfresco.org/legal/license.txt
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific
- * language governing permissions and limitations under the
- * License.
- */
package org.alfresco.web.bean.content;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
@@ -35,17 +18,9 @@ import org.alfresco.web.app.Application;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.data.IDataContainer;
import org.alfresco.web.data.QuickSort;
-import org.alfresco.web.templating.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.alfresco.model.ContentModel;
-import org.alfresco.service.cmr.model.FileInfo;
-import org.alfresco.service.cmr.repository.NodeRef;
-import org.alfresco.service.cmr.repository.ContentWriter;
-import java.io.OutputStreamWriter;
-import org.alfresco.web.app.servlet.FacesHelper;
-
/**
* Bean implementation for the "Create Content Wizard" dialog
*
@@ -53,14 +28,12 @@ import org.alfresco.web.app.servlet.FacesHelper;
*/
public class CreateContentWizard extends BaseContentWizard
{
- protected String content = null;
- protected String templateTypeName;
- protected List createMimeTypes;
-
- private static final Log LOGGER =
- LogFactory.getLog(CreateContentWizard.class);
-
-
+ protected String content = null;
+
+ protected List createMimeTypes;
+
+ private static Log logger = LogFactory.getLog(CreateContentWizard.class);
+
// ------------------------------------------------------------------------------
// Wizard implementation
@@ -68,28 +41,10 @@ public class CreateContentWizard extends BaseContentWizard
protected String finishImpl(FacesContext context, String outcome)
throws Exception
{
- LOGGER.debug("saving file content to " + this.fileName);
- saveContent(null, this.content);
- if (this.templateTypeName != null)
- {
- LOGGER.debug("generating template output for " + this.templateTypeName);
- this.nodeService.setProperty(this.createdNode,
- TemplatingService.TT_QNAME,
- this.templateTypeName);
- TemplatingService ts = TemplatingService.getInstance();
- TemplateType tt = this.getTemplateType();
- OutputUtil.generate(this.createdNode,
- ts.parseXML(this.content),
- tt,
- this.fileName,
- this.getContainerNodeRef(),
- this.fileFolderService,
- this.contentService,
- this.nodeService);
- }
-
- // return the default outcome
- return outcome;
+ saveContent(null, this.content);
+
+ // return the default outcome
+ return outcome;
}
@Override
@@ -99,7 +54,6 @@ public class CreateContentWizard extends BaseContentWizard
this.content = null;
this.inlineEdit = true;
- this.templateTypeName = null;
this.mimeType = MimetypeMap.MIMETYPE_HTML;
}
@@ -162,20 +116,6 @@ public class CreateContentWizard extends BaseContentWizard
{
this.content = content;
}
-
- public List getCreateTemplateTypes()
- {
- Collection ttl = TemplatingService.getInstance().getTemplateTypes();
- List sil = new ArrayList(ttl.size());
- for (TemplateType tt : ttl)
- {
- sil.add(new SelectItem(tt.getName(), tt.getName()));
- }
-
- QuickSort sorter = new QuickSort(sil, "label", true, IDataContainer.SORT_CASEINSENSITIVE);
- sorter.sort();
- return sil;
- }
/**
* @return Returns a list of mime types to allow the user to select from
@@ -213,37 +153,18 @@ public class CreateContentWizard extends BaseContentWizard
}
else
{
- LOGGER.warn("Could not find 'create-mime-types' configuration element");
+ logger.warn("Could not find 'create-mime-types' configuration element");
}
}
else
{
- LOGGER.warn("Could not find 'Content Wizards' configuration section");
+ logger.warn("Could not find 'Content Wizards' configuration section");
}
}
return this.createMimeTypes;
}
-
- public String getTemplateTypeName()
- {
- return this.templateTypeName;
- }
-
- public TemplateType getTemplateType()
- {
- final TemplatingService ts = TemplatingService.getInstance();
- return ts.getTemplateType(this.getTemplateTypeName());
- }
-
- /**
- * @param templateType Sets the currently selected template type
- */
- public void setTemplateTypeName(final String templateTypeName)
- {
- this.templateTypeName = templateTypeName;
- }
/**
* @return Returns the summary data for the wizard.
diff --git a/source/java/org/alfresco/web/bean/content/ViewContentPropertiesDialog.java b/source/java/org/alfresco/web/bean/content/ViewContentPropertiesDialog.java
new file mode 100644
index 0000000000..1b3f75825f
--- /dev/null
+++ b/source/java/org/alfresco/web/bean/content/ViewContentPropertiesDialog.java
@@ -0,0 +1,75 @@
+package org.alfresco.web.bean.content;
+
+import java.util.Map;
+
+import javax.faces.context.FacesContext;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.service.cmr.repository.ContentData;
+import org.alfresco.web.app.Application;
+import org.alfresco.web.bean.dialog.BaseDialogBean;
+import org.alfresco.web.bean.repository.Node;
+
+/**
+ * Bean implementation of the "View Content Properties" dialog.
+ *
+ * @author gavinc
+ */
+public class ViewContentPropertiesDialog extends BaseDialogBean
+{
+ protected static final String TEMP_PROP_MIMETYPE = "mimetype";
+
+ protected Node viewingNode;
+
+ // ------------------------------------------------------------------------------
+ // Dialog implementation
+
+ @Override
+ public void init(Map parameters)
+ {
+ super.init(parameters);
+
+ // setup the editable node
+ this.viewingNode = new Node(this.browseBean.getDocument().getNodeRef());
+
+ // special case for Mimetype - since this is a sub-property of the ContentData object
+ // we must extract it so it can be edited in the client, then we check for it later
+ // and create a new ContentData object to wrap it and it's associated URL
+ ContentData content = (ContentData)this.viewingNode.getProperties().get(ContentModel.PROP_CONTENT);
+ if (content != null)
+ {
+ this.viewingNode.getProperties().put(TEMP_PROP_MIMETYPE, content.getMimetype());
+ }
+
+ // add the specially handled 'size' property
+ this.viewingNode.addPropertyResolver("size", this.browseBean.resolverSize);
+ }
+
+ @Override
+ protected String finishImpl(FacesContext context, String outcome)
+ throws Exception
+ {
+ // nothing to do as the finish button is not shown and the dialog is read only
+
+ return outcome;
+ }
+
+ @Override
+ public String getCancelButtonLabel()
+ {
+ return Application.getMessage(FacesContext.getCurrentInstance(), "close");
+ }
+
+ // ------------------------------------------------------------------------------
+ // Bean getters and setters
+
+ /**
+ * Returns the node being viewed
+ *
+ * @return The node being viewed
+ */
+ public Node getViewingNode()
+ {
+ return this.viewingNode;
+ }
+}
diff --git a/source/java/org/alfresco/web/bean/dashboard/DashboardWizard.java b/source/java/org/alfresco/web/bean/dashboard/DashboardWizard.java
index 615570d480..4ff8d46793 100644
--- a/source/java/org/alfresco/web/bean/dashboard/DashboardWizard.java
+++ b/source/java/org/alfresco/web/bean/dashboard/DashboardWizard.java
@@ -125,6 +125,14 @@ public class DashboardWizard extends BaseWizardBean
// ------------------------------------------------------------------------------
// Dashboard Wizard bean getters
+ /**
+ * @return true to allow the Guest user to configure the dashboard, false otherwise
+ */
+ public boolean getAllowGuestConfig()
+ {
+ return DashboardManager.getDashboardConfig().getAllowGuestConfig();
+ }
+
/**
* @return The currently selected layout ID - used by the Dynamic Description component
*/
diff --git a/source/java/org/alfresco/web/bean/dashboard/GettingStartedBean.java b/source/java/org/alfresco/web/bean/dashboard/GettingStartedBean.java
new file mode 100644
index 0000000000..11cbb1fd6f
--- /dev/null
+++ b/source/java/org/alfresco/web/bean/dashboard/GettingStartedBean.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.web.bean.dashboard;
+
+import javax.faces.context.FacesContext;
+
+import org.alfresco.web.app.Application;
+import org.alfresco.web.bean.NavigationBean;
+
+/**
+ * Backing bean for the Getting Started Dashlet page.
+ *
+ * @author Kevin Roast
+ */
+public class GettingStartedBean
+{
+ private NavigationBean navigationBean;
+
+
+ /**
+ * @param navigationBean The navigationBean to set.
+ */
+ public void setNavigationBean(NavigationBean navigationBean)
+ {
+ this.navigationBean = navigationBean;
+ }
+
+ public String browseHomeSpace()
+ {
+ this.navigationBean.setCurrentNodeId(getHomeSpaceId());
+ return "browse";
+ }
+
+ public String createSpace()
+ {
+ this.navigationBean.setCurrentNodeId(getHomeSpaceId());
+ return "dialog:createSpace";
+ }
+
+ public String createContent()
+ {
+ this.navigationBean.setCurrentNodeId(getHomeSpaceId());
+ return "wizard:createContent";
+ }
+
+ public String addContent()
+ {
+ this.navigationBean.setCurrentNodeId(getHomeSpaceId());
+ return "addContent";
+ }
+
+ private String getHomeSpaceId()
+ {
+ return Application.getCurrentUser(FacesContext.getCurrentInstance()).getHomeSpaceId();
+ }
+}
diff --git a/source/java/org/alfresco/web/bean/dialog/BaseDialogBean.java b/source/java/org/alfresco/web/bean/dialog/BaseDialogBean.java
index 586eb6bd83..535506eb18 100644
--- a/source/java/org/alfresco/web/bean/dialog/BaseDialogBean.java
+++ b/source/java/org/alfresco/web/bean/dialog/BaseDialogBean.java
@@ -59,6 +59,11 @@ public abstract class BaseDialogBean implements IDialogBean
this.isFinished = false;
}
+ public void restored()
+ {
+ // do nothing by default, subclasses can override if necessary
+ }
+
public String cancel()
{
return getDefaultCancelOutcome();
@@ -126,6 +131,16 @@ public abstract class BaseDialogBean implements IDialogBean
return true;
}
+ public String getTitle()
+ {
+ return null;
+ }
+
+ public String getDescription()
+ {
+ return null;
+ }
+
/**
* @param browseBean The BrowseBean to set.
*/
diff --git a/source/java/org/alfresco/web/bean/dialog/DialogManager.java b/source/java/org/alfresco/web/bean/dialog/DialogManager.java
index c47c6d8c62..c7998ab253 100644
--- a/source/java/org/alfresco/web/bean/dialog/DialogManager.java
+++ b/source/java/org/alfresco/web/bean/dialog/DialogManager.java
@@ -20,11 +20,10 @@ import org.alfresco.web.ui.common.component.UIActionLink;
*
* @author gavinc
*/
-public class DialogManager
+public final class DialogManager
{
- protected IDialogBean currentDialog;
- protected DialogConfig currentDialogConfig;
- protected Map currentDialogParams;
+ private DialogState currentDialogState;
+ private Map paramsToApply;
/**
* Action handler used to setup parameters for the dialog being launched
@@ -38,7 +37,7 @@ public class DialogManager
if (component instanceof UIActionLink)
{
// store the parameters
- this.currentDialogParams = ((UIActionLink)component).getParameterMap();
+ this.paramsToApply = ((UIActionLink)component).getParameterMap();
}
}
@@ -49,22 +48,48 @@ public class DialogManager
*/
public void setCurrentDialog(DialogConfig config)
{
- this.currentDialogConfig = config;
-
- String beanName = this.currentDialogConfig.getManagedBean();
- this.currentDialog = (IDialogBean)FacesHelper.getManagedBean(
+ String beanName = config.getManagedBean();
+ IDialogBean dialog = (IDialogBean)FacesHelper.getManagedBean(
FacesContext.getCurrentInstance(), beanName);
- if (this.currentDialog == null)
+ if (dialog == null)
{
throw new AlfrescoRuntimeException("Failed to find managed bean '" + beanName + "'");
}
// initialise the managed bean
- this.currentDialog.init(this.currentDialogParams);
+ dialog.init(this.paramsToApply);
// reset the current parameters so subsequent dialogs don't get them
- this.currentDialogParams = null;
+ this.paramsToApply = null;
+
+ // create the DialogState object
+ this.currentDialogState = new DialogState(config, dialog);
+ }
+
+ /**
+ * Returns the state of the currently active dialog
+ *
+ * @return Current dialog's state
+ */
+ public DialogState getState()
+ {
+ return this.currentDialogState;
+ }
+
+ /**
+ * Restores the dialog represented by the given DialogState object.
+ * NOTE: The dialog's restored() method is also called during this
+ * method.
+ *
+ * @param state The DialogState for the dialog to restore
+ */
+ public void restoreState(DialogState state)
+ {
+ this.currentDialogState = state;
+
+ // retrieve the dialog and call it's restored() method
+ this.currentDialogState.getDialog().restored();
}
/**
@@ -74,7 +99,7 @@ public class DialogManager
*/
public DialogConfig getCurrentDialog()
{
- return this.currentDialogConfig;
+ return this.currentDialogState.getConfig();
}
/**
@@ -84,7 +109,7 @@ public class DialogManager
*/
public IDialogBean getBean()
{
- return this.currentDialog;
+ return this.currentDialogState.getDialog();
}
/**
@@ -94,7 +119,7 @@ public class DialogManager
*/
public String getIcon()
{
- return this.currentDialogConfig.getIcon();
+ return this.currentDialogState.getConfig().getIcon();
}
/**
@@ -105,7 +130,7 @@ public class DialogManager
public String getErrorMessage()
{
return Application.getMessage(FacesContext.getCurrentInstance(),
- this.currentDialogConfig.getErrorMessageId());
+ this.currentDialogState.getConfig().getErrorMessageId());
}
/**
@@ -115,15 +140,23 @@ public class DialogManager
*/
public String getTitle()
{
- String title = this.currentDialogConfig.getTitleId();
+ // try and get the title directly from the dialog
+ String title = this.currentDialogState.getDialog().getTitle();
- if (title != null)
+ if (title == null)
{
- title = Application.getMessage(FacesContext.getCurrentInstance(), title);
- }
- else
- {
- title = this.currentDialogConfig.getTitle();
+ // try and get the title via a message bundle key
+ title = this.currentDialogState.getConfig().getTitleId();
+
+ if (title != null)
+ {
+ title = Application.getMessage(FacesContext.getCurrentInstance(), title);
+ }
+ else
+ {
+ // try and get the title from the configuration
+ title = this.currentDialogState.getConfig().getTitle();
+ }
}
return title;
@@ -136,15 +169,23 @@ public class DialogManager
*/
public String getDescription()
{
- String desc = this.currentDialogConfig.getDescriptionId();
+ // try and get the description directly from the dialog
+ String desc = this.currentDialogState.getDialog().getDescription();
- if (desc != null)
+ if (desc == null)
{
- desc = Application.getMessage(FacesContext.getCurrentInstance(), desc);
- }
- else
- {
- desc = this.currentDialogConfig.getDescription();
+ // try and get the description via a message bundle key
+ desc = this.currentDialogState.getConfig().getDescriptionId();
+
+ if (desc != null)
+ {
+ desc = Application.getMessage(FacesContext.getCurrentInstance(), desc);
+ }
+ else
+ {
+ // try and get the description from the configuration
+ desc = this.currentDialogState.getConfig().getDescription();
+ }
}
return desc;
@@ -158,7 +199,7 @@ public class DialogManager
*/
public String getActions()
{
- return this.currentDialogConfig.getActionsConfigId();
+ return this.currentDialogState.getConfig().getActionsConfigId();
}
/**
@@ -168,7 +209,7 @@ public class DialogManager
*/
public String getPage()
{
- return this.currentDialogConfig.getPage();
+ return this.currentDialogState.getConfig().getPage();
}
/**
@@ -178,7 +219,7 @@ public class DialogManager
*/
public boolean isOKButtonVisible()
{
- return this.currentDialogConfig.isOKButtonVisible();
+ return this.currentDialogState.getConfig().isOKButtonVisible();
}
/**
@@ -191,10 +232,10 @@ public class DialogManager
List buttons = null;
// get a list of buttons to display from the configuration
- List cfgButtons = this.currentDialogConfig.getButtons();
+ List cfgButtons = this.currentDialogState.getConfig().getButtons();
// get a list of buttons added dynamically by the dialog
- List dynButtons = this.currentDialog.getAdditionalButtons();
+ List dynButtons = this.currentDialogState.getDialog().getAdditionalButtons();
if (cfgButtons != null && dynButtons != null)
{
@@ -223,7 +264,7 @@ public class DialogManager
*/
public String getCancelButtonLabel()
{
- return this.currentDialog.getCancelButtonLabel();
+ return this.currentDialogState.getDialog().getCancelButtonLabel();
}
/**
@@ -233,7 +274,7 @@ public class DialogManager
*/
public String getFinishButtonLabel()
{
- return this.currentDialog.getFinishButtonLabel();
+ return this.currentDialogState.getDialog().getFinishButtonLabel();
}
/**
@@ -243,7 +284,7 @@ public class DialogManager
*/
public boolean getFinishButtonDisabled()
{
- return this.currentDialog.getFinishButtonDisabled();
+ return this.currentDialogState.getDialog().getFinishButtonDisabled();
}
/**
@@ -253,7 +294,7 @@ public class DialogManager
*/
public String finish()
{
- return this.currentDialog.finish();
+ return this.currentDialogState.getDialog().finish();
}
/**
@@ -263,6 +304,6 @@ public class DialogManager
*/
public String cancel()
{
- return this.currentDialog.cancel();
+ return this.currentDialogState.getDialog().cancel();
}
}
diff --git a/source/java/org/alfresco/web/bean/dialog/DialogState.java b/source/java/org/alfresco/web/bean/dialog/DialogState.java
new file mode 100644
index 0000000000..aee2a53ab2
--- /dev/null
+++ b/source/java/org/alfresco/web/bean/dialog/DialogState.java
@@ -0,0 +1,53 @@
+package org.alfresco.web.bean.dialog;
+
+import org.alfresco.web.app.AlfrescoNavigationHandler;
+import org.alfresco.web.config.DialogsConfigElement.DialogConfig;
+
+/**
+ * Object responsible for holding the current state of an active dialog.
+ *
+ * @author gavinc
+ */
+public final class DialogState
+{
+ private DialogConfig config;
+ private IDialogBean dialog;
+
+ /**
+ * Default constructor
+ *
+ * @param config The configuration for the dialog
+ * @param dialog The dialog bean instance
+ */
+ public DialogState(DialogConfig config, IDialogBean dialog)
+ {
+ this.config = config;
+ this.dialog = dialog;
+ }
+
+ /**
+ * Returns the configuration for the dialog
+ *
+ * @return The dialog configuration
+ */
+ public DialogConfig getConfig()
+ {
+ return config;
+ }
+
+ /**
+ * Returns the bean representing the dialog instance
+ *
+ * @return The dialog bean instance
+ */
+ public IDialogBean getDialog()
+ {
+ return dialog;
+ }
+
+ @Override
+ public String toString()
+ {
+ return AlfrescoNavigationHandler.DIALOG_PREFIX + this.config.getName();
+ }
+}
diff --git a/source/java/org/alfresco/web/bean/dialog/IDialogBean.java b/source/java/org/alfresco/web/bean/dialog/IDialogBean.java
index fe2e9b59dc..becb29932b 100644
--- a/source/java/org/alfresco/web/bean/dialog/IDialogBean.java
+++ b/source/java/org/alfresco/web/bean/dialog/IDialogBean.java
@@ -19,6 +19,11 @@ public interface IDialogBean
*/
public void init(Map parameters);
+ /**
+ * Called when the dialog is restored after a nested dialog is closed
+ */
+ public void restored();
+
/**
* Method handler called when the cancel button of the dialog is pressed
*
@@ -60,4 +65,22 @@ public interface IDialogBean
* @return true if the button should be disabled
*/
public boolean getFinishButtonDisabled();
+
+ /**
+ * Returns the title to be used for the dialog
+ * If this returns null the DialogManager will
+ * lookup the title via the dialog configuration
+ *
+ * @return The title or null if the title is to be acquired via configuration
+ */
+ public String getTitle();
+
+ /**
+ * Returns the description to be used for the dialog
+ * If this returns null the DialogManager will
+ * lookup the description via the dialog configuration
+ *
+ * @return The title or null if the title is to be acquired via configuration
+ */
+ public String getDescription();
}
diff --git a/source/java/org/alfresco/web/bean/generator/HeaderSeparatorGenerator.java b/source/java/org/alfresco/web/bean/generator/HeaderSeparatorGenerator.java
index 2cb6e31f9b..8b316dcc42 100644
--- a/source/java/org/alfresco/web/bean/generator/HeaderSeparatorGenerator.java
+++ b/source/java/org/alfresco/web/bean/generator/HeaderSeparatorGenerator.java
@@ -12,7 +12,6 @@ import org.alfresco.web.ui.repo.component.property.PropertySheetItem;
*/
public class HeaderSeparatorGenerator extends SeparatorGenerator
{
- @Override
protected String getHtml(UIComponent component, PropertySheetItem item)
{
String html = " " +
diff --git a/source/java/org/alfresco/web/bean/generator/HtmlSeparatorGenerator.java b/source/java/org/alfresco/web/bean/generator/HtmlSeparatorGenerator.java
new file mode 100644
index 0000000000..3e8153750b
--- /dev/null
+++ b/source/java/org/alfresco/web/bean/generator/HtmlSeparatorGenerator.java
@@ -0,0 +1,79 @@
+package org.alfresco.web.bean.generator;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+
+import org.alfresco.web.ui.repo.component.property.PropertySheetItem;
+import org.alfresco.web.ui.repo.component.property.UIPropertySheet;
+
+/**
+ * Generates a component to represent a separator.
+ *
The HTML to be used for the separator is configured via the
+ * setHtml
method.
+ *
+ * @author gavinc
+ */
+public class HtmlSeparatorGenerator extends BaseComponentGenerator
+{
+ protected String html = "default ";
+
+ /**
+ * Returns the HTML configured to be used for this separator
+ *
+ * @return The HTML to display
+ */
+ public String getHtml()
+ {
+ return html;
+ }
+
+ /**
+ * Sets the HTML to display for the separator
+ *
+ * @param html The HTML
+ */
+ public void setHtml(String html)
+ {
+ this.html = html;
+ }
+
+ @SuppressWarnings("unchecked")
+ public UIComponent generate(FacesContext context, String id)
+ {
+ UIComponent component = this.createOutputTextComponent(context, id);
+ component.getAttributes().put("escape", Boolean.FALSE);
+
+ return component;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ protected UIComponent createComponent(FacesContext context, UIPropertySheet propertySheet,
+ PropertySheetItem item)
+ {
+ UIComponent component = this.generate(context, item.getName());
+
+ // set the HTML to use
+ component.getAttributes().put("value", getResolvedHtml(component, item));
+
+ return component;
+ }
+
+ /**
+ * Returns the resolved HTML to use for the separator.
+ *
In the default case we just return the HTML set
+ * via setHtml however subclasses may choose to generate
+ * the resulting HTML using a combination of the HTML set
+ * via setHtml and the given PropertySheetItem.
+ *
+ * @param component The JSF component representing the separator
+ * @param item The separator item
+ * @return The resolved HTML
+ */
+ protected String getResolvedHtml(UIComponent component, PropertySheetItem item)
+ {
+ // In the default case we just return the HTML set via setHtml
+
+ return this.html;
+ }
+}
\ No newline at end of file
diff --git a/source/java/org/alfresco/web/bean/generator/LabelSeparatorGenerator.java b/source/java/org/alfresco/web/bean/generator/LabelSeparatorGenerator.java
new file mode 100644
index 0000000000..7cbaf898c9
--- /dev/null
+++ b/source/java/org/alfresco/web/bean/generator/LabelSeparatorGenerator.java
@@ -0,0 +1,85 @@
+package org.alfresco.web.bean.generator;
+
+import javax.faces.component.UIComponent;
+
+import org.alfresco.web.ui.repo.component.property.PropertySheetItem;
+
+/**
+ * Generates a component to represent a separator that uses the
+ * property sheet display label configuration. The CSS class used
+ * for the HTML representing the label can also be configured via
+ * the setStyleClass
method.
+ *
+ * @author gavinc
+ */
+public class LabelSeparatorGenerator extends HtmlSeparatorGenerator
+{
+ protected String style = "margin-top: 6px; margin-bottom: 6px;";
+ protected String styleClass;
+
+ /**
+ * Returns the CSS class configured to be used for this separator
+ *
+ * @return The CSS class
+ */
+ public String getStyleClass()
+ {
+ return styleClass;
+ }
+
+ /**
+ * Sets the CSS class to use for the separator
+ *
+ * @param styleClass The CSS class
+ */
+ public void setStyleClass(String styleClass)
+ {
+ this.styleClass = styleClass;
+ }
+
+ /**
+ * Returns the CSS style configured to be used for this separator
+ *
+ * @return The CSS style
+ */
+ public String getStyle()
+ {
+ return style;
+ }
+
+ /**
+ * Sets the CSS style to use for the separator
+ *
+ * @param style The CSS style
+ */
+ public void setStyle(String style)
+ {
+ this.style = style;
+ }
+
+ @Override
+ protected String getResolvedHtml(UIComponent component, PropertySheetItem item)
+ {
+ StringBuilder htmlBuilder = new StringBuilder("
0)
+ {
+ htmlBuilder.append(" class=\"");
+ htmlBuilder.append(this.styleClass);
+ htmlBuilder.append("\"");
+ }
+
+ if (this.style != null && this.style.length() > 0)
+ {
+ htmlBuilder.append(" style=\"");
+ htmlBuilder.append(this.style);
+ htmlBuilder.append("\"");
+ }
+
+ // add the display label and close the div
+ htmlBuilder.append("> ");
+ htmlBuilder.append(item.getDisplayLabel());
+ htmlBuilder.append("
");
+
+ return htmlBuilder.toString();
+ }
+}
diff --git a/source/java/org/alfresco/web/bean/generator/SeparatorGenerator.java b/source/java/org/alfresco/web/bean/generator/SeparatorGenerator.java
index 49076c1fa1..2157229577 100644
--- a/source/java/org/alfresco/web/bean/generator/SeparatorGenerator.java
+++ b/source/java/org/alfresco/web/bean/generator/SeparatorGenerator.java
@@ -1,49 +1,16 @@
package org.alfresco.web.bean.generator;
-import javax.faces.component.UIComponent;
-import javax.faces.context.FacesContext;
-
-import org.alfresco.web.ui.repo.component.property.PropertySheetItem;
-import org.alfresco.web.ui.repo.component.property.UIPropertySheet;
-
/**
- * Generates a component to represent a separator.
+ * Generates a component to represent a separator using the HTML
<hr/>
element.
*
* @author gavinc
*/
-public class SeparatorGenerator extends BaseComponentGenerator
+public class SeparatorGenerator extends HtmlSeparatorGenerator
{
- @SuppressWarnings("unchecked")
- public UIComponent generate(FacesContext context, String id)
+ public SeparatorGenerator()
{
- UIComponent component = this.createOutputTextComponent(context, id);
- component.getAttributes().put("escape", Boolean.FALSE);
+ // For the standard separator just show a
element
- return component;
- }
-
- @Override
- @SuppressWarnings("unchecked")
- protected UIComponent createComponent(FacesContext context, UIPropertySheet propertySheet,
- PropertySheetItem item)
- {
- UIComponent component = this.generate(context, item.getName());
-
- // set the HTML to use
- component.getAttributes().put("value", getHtml(component, item));
-
- return component;
- }
-
- /**
- * Returns the HTML to display for the separator
- *
- * @param component The JSF component representing the separator
- * @param item The separator item
- * @return The HTML
- */
- protected String getHtml(UIComponent component, PropertySheetItem item)
- {
- return "
";
+ this.html = "
";
}
}
\ No newline at end of file
diff --git a/source/java/org/alfresco/web/bean/repository/TransientNode.java b/source/java/org/alfresco/web/bean/repository/TransientNode.java
index 50a2c11e32..9f5332fd8b 100644
--- a/source/java/org/alfresco/web/bean/repository/TransientNode.java
+++ b/source/java/org/alfresco/web/bean/repository/TransientNode.java
@@ -1,7 +1,9 @@
package org.alfresco.web.bean.repository;
import java.io.Serializable;
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException;
@@ -10,6 +12,8 @@ import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
+import org.alfresco.service.cmr.repository.AssociationRef;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.GUID;
@@ -54,9 +58,6 @@ public class TransientNode extends Node
// initialise the node
initNode(data);
-
- if (logger.isDebugEnabled())
- logger.debug("Constructed transient node: " + this);
}
/**
@@ -93,11 +94,64 @@ public class TransientNode extends Node
{
if (assocDef.isChild())
{
- this.childAssociations.put(item, data.get(item));
+ // TODO: handle lists of NodeRef's
+ NodeRef child = null;
+ Object obj = data.get(item);
+ if (obj instanceof String)
+ {
+ child = new NodeRef((String)obj);
+ }
+ else if (obj instanceof NodeRef)
+ {
+ child = (NodeRef)obj;
+ }
+ else if (obj instanceof List)
+ {
+ if (logger.isWarnEnabled())
+ logger.warn("0..* child associations are not supported yet");
+ }
+
+ if (child != null)
+ {
+ // create a child association reference, add it to a list and add the list
+ // to the list of child associations for this node
+ List
assocs = new ArrayList(1);
+ ChildAssociationRef childRef = new ChildAssociationRef(assocDef.getName(), this.nodeRef,
+ null, child);
+ assocs.add(childRef);
+
+ this.childAssociations.put(item, assocs);
+ }
}
else
{
- this.associations.put(item, data.get(item));
+ // TODO: handle lists of NodeRef's
+ NodeRef target = null;
+ Object obj = data.get(item);
+ if (obj instanceof String)
+ {
+ target = new NodeRef((String)obj);
+ }
+ else if (obj instanceof NodeRef)
+ {
+ target = (NodeRef)obj;
+ }
+ else if (obj instanceof List)
+ {
+ if (logger.isWarnEnabled())
+ logger.warn("0..* associations are not supported yet");
+ }
+
+ if (target != null)
+ {
+ // create a association reference, add it to a list and add the list
+ // to the list of associations for this node
+ List assocs = new ArrayList(1);
+ AssociationRef assocRef = new AssociationRef(this.nodeRef, assocDef.getName(), target);
+ assocs.add(assocRef);
+
+ this.associations.put(item, assocs);
+ }
}
}
}
@@ -140,7 +194,7 @@ public class TransientNode extends Node
// don't reset anything otherwise we'll lose our data
// with no way of getting it back!!
}
-
+
@Override
public String toString()
{
diff --git a/source/java/org/alfresco/web/bean/users/EmailSpaceUsersDialog.java b/source/java/org/alfresco/web/bean/users/EmailSpaceUsersDialog.java
index 53eb16465f..1bf167d1ae 100644
--- a/source/java/org/alfresco/web/bean/users/EmailSpaceUsersDialog.java
+++ b/source/java/org/alfresco/web/bean/users/EmailSpaceUsersDialog.java
@@ -130,7 +130,7 @@ public class EmailSpaceUsersDialog extends BaseDialogBean implements IContextLis
Set mailedAuthorities = new HashSet(usersGroups.size());
- // walk the list of users/groups to notify
+ // walk the list of users/groups to notify - handle duplicates along the way
for (Map node : usersGroups)
{
String authority = (String)node.get(PROP_USERNAME);
@@ -254,31 +254,47 @@ public class EmailSpaceUsersDialog extends BaseDialogBean implements IContextLis
tx = Repository.getUserTransaction(context, true);
tx.begin();
- // Return all the permissions set against the current node
- // for any authentication instance (user/group).
- // Then combine them into a single list for each authentication found.
+ // Return all the permissions set against the current node for any authentication
+ // instance (user/group), walking the parent space inheritance chain.
+ // Then combine them into a single list for each authentication found.
+ String currentAuthority = Application.getCurrentUser(context).getUserName();
Map> permissionMap = new HashMap>(8, 1.0f);
- Set permissions = permissionService.getAllSetPermissions(getSpace().getNodeRef());
- for (AccessPermission permission : permissions)
+ NodeRef spaceRef = getSpace().getNodeRef();
+ while (spaceRef != null)
{
- // we are only interested in Allow and not groups/owner etc.
- if (permission.getAccessStatus() == AccessStatus.ALLOWED &&
- (permission.getAuthorityType() == AuthorityType.USER ||
- permission.getAuthorityType() == AuthorityType.GROUP ||
- permission.getAuthorityType() == AuthorityType.GUEST ||
- permission.getAuthorityType() == AuthorityType.EVERYONE))
+ Set permissions = permissionService.getAllSetPermissions(spaceRef);
+ for (AccessPermission permission : permissions)
{
- String authority = permission.getAuthority();
-
- List userPermissions = permissionMap.get(authority);
- if (userPermissions == null)
+ // we are only interested in Allow and not Guest/Everyone/owner
+ if (permission.getAccessStatus() == AccessStatus.ALLOWED &&
+ (permission.getAuthorityType() == AuthorityType.USER ||
+ permission.getAuthorityType() == AuthorityType.GROUP))
{
- // create for first time
- userPermissions = new ArrayList(4);
- permissionMap.put(authority, userPermissions);
+ String authority = permission.getAuthority();
+
+ if (currentAuthority.equals(authority) == false)
+ {
+ List userPermissions = permissionMap.get(authority);
+ if (userPermissions == null)
+ {
+ // create for first time
+ userPermissions = new ArrayList(4);
+ permissionMap.put(authority, userPermissions);
+ }
+ // add the permission name for this authority
+ userPermissions.add(permission.getPermission());
+ }
}
- // add the permission name for this authority
- userPermissions.add(permission.getPermission());
+ }
+
+ // walk parent inheritance chain until root or no longer inherits
+ if (permissionService.getInheritParentPermissions(spaceRef))
+ {
+ spaceRef = nodeService.getPrimaryParent(spaceRef).getParentRef();
+ }
+ else
+ {
+ spaceRef = null;
}
}
@@ -316,79 +332,6 @@ public class EmailSpaceUsersDialog extends BaseDialogBean implements IContextLis
}
return this.usersGroups;
}
-
- /**
- * Build a Map representing a user/group with a set of useful property values required
- * by the UIUserGroupPicker UI component.
- *
- * @param authority User/Group authority
- * @param roles Role text for the authority
- *
- * @return Map
- */
- private Map buildAuthorityMap(String authority, String roles)
- {
- Map node = null;
-
- if (AuthorityType.getAuthorityType(authority) == AuthorityType.GUEST ||
- this.personService.personExists(authority))
- {
- NodeRef nodeRef = this.personService.getPerson(authority);
- if (nodeRef != null)
- {
- // create our Node representation
- node = new MapNode(nodeRef);
-
- // set data binding properties
- // this will also force initialisation of the props now during the UserTransaction
- // it is much better for performance to do this now rather than during page bind
- Map props = ((MapNode)node).getProperties();
- props.put(PROP_FULLNAME, ((String)props.get("firstName")) + ' ' + ((String)props.get("lastName")));
- props.put(PROP_ICON, WebResources.IMAGE_PERSON);
- props.put(PROP_ISGROUP, false);
- }
- }
- else if (AuthorityType.getAuthorityType(authority) == AuthorityType.GROUP)
- {
- // need a map (dummy node) to represent props for this Group Authority
- node = new HashMap(8, 1.0f);
- if (authority.startsWith(PermissionService.GROUP_PREFIX) == true)
- {
- node.put(PROP_FULLNAME, authority.substring(PermissionService.GROUP_PREFIX.length()));
- }
- else
- {
- node.put(PROP_FULLNAME, authority);
- }
- node.put(PROP_USERNAME, authority);
- node.put(PROP_ID, authority);
- node.put(PROP_ICON, WebResources.IMAGE_GROUP);
- node.put(PROP_ISGROUP, true);
- node.put(PROP_EXPANDED, false);
- }
- if (node != null)
- {
- // add the common properties
- node.put(PROP_ROLES, roles);
- node.put(PROP_PARENT, null);
-
- if (this.userGroupLookup.get(authority) != null)
- {
- // this authority already exists in the list somewhere else - mark as duplicate
- node.put(PROP_DUPLICATE, true);
- node.put(PROP_SELECTED, false);
- }
- else
- {
- // add to table for the first time, not a duplicate
- this.userGroupLookup.put(authority, node);
- node.put(PROP_DUPLICATE, false);
- node.put(PROP_SELECTED, true);
- }
- }
-
- return node;
- }
/**
* @return TemplateMailHelperBean instance for this wizard
@@ -398,6 +341,29 @@ public class EmailSpaceUsersDialog extends BaseDialogBean implements IContextLis
return this.mailHelper;
}
+ /**
+ * @return true if any authorities are selected, false otherwise
+ */
+ public boolean getFinishButtonDisabled()
+ {
+ boolean disabled = true;
+
+ if (this.usersGroups != null)
+ {
+ for (Map userGroup : this.usersGroups)
+ {
+ if (((Boolean)userGroup.get(PROP_EXPANDED)) == false &&
+ ((Boolean)userGroup.get(PROP_SELECTED)) == true)
+ {
+ disabled = false;
+ break;
+ }
+ }
+ }
+
+ return disabled;
+ }
+
// ------------------------------------------------------------------------------
// Action Event Listeners
@@ -435,16 +401,25 @@ public class EmailSpaceUsersDialog extends BaseDialogBean implements IContextLis
{
// expand the list for this group by adding the immediate child authorities
boolean selected = (Boolean)userGroup.get(PROP_SELECTED);
+ String currentAuthority =
+ Application.getCurrentUser(FacesContext.getCurrentInstance()).getUserName();
Set authorities = authorityService.getContainedAuthorities(
null, pickerEvent.Authority, true);
for (String authority : authorities)
{
- Map node = buildAuthorityMap(authority, (String)userGroup.get(PROP_ROLES));
- if (node != null)
+ if (currentAuthority.equals(authority) == false)
{
- node.put(PROP_PARENT, userGroup);
- node.put(PROP_SELECTED, selected);
- this.usersGroups.add(++index, node);
+ if (AuthorityType.getAuthorityType(authority) == AuthorityType.USER ||
+ AuthorityType.getAuthorityType(authority) == AuthorityType.GROUP)
+ {
+ Map node = buildAuthorityMap(authority, (String)userGroup.get(PROP_ROLES));
+ if (node != null)
+ {
+ node.put(PROP_PARENT, userGroup);
+ node.put(PROP_SELECTED, selected);
+ this.usersGroups.add(++index, node);
+ }
+ }
}
}
}
@@ -494,4 +469,81 @@ public class EmailSpaceUsersDialog extends BaseDialogBean implements IContextLis
}
}
}
+
+
+ // ------------------------------------------------------------------------------
+ // Private helpers
+
+ /**
+ * Build a Map representing a user/group with a set of useful property values required
+ * by the UIUserGroupPicker UI component.
+ *
+ * @param authority User/Group authority
+ * @param roles Role text for the authority
+ *
+ * @return Map
+ */
+ private Map buildAuthorityMap(String authority, String roles)
+ {
+ Map node = null;
+
+ if (AuthorityType.getAuthorityType(authority) == AuthorityType.GUEST ||
+ this.personService.personExists(authority))
+ {
+ NodeRef nodeRef = this.personService.getPerson(authority);
+ if (nodeRef != null)
+ {
+ // create our Node representation
+ node = new MapNode(nodeRef);
+
+ // set data binding properties
+ // this will also force initialisation of the props now during the UserTransaction
+ // it is much better for performance to do this now rather than during page bind
+ Map props = ((MapNode)node).getProperties();
+ props.put(PROP_FULLNAME, ((String)props.get("firstName")) + ' ' + ((String)props.get("lastName")));
+ props.put(PROP_ICON, WebResources.IMAGE_PERSON);
+ props.put(PROP_ISGROUP, false);
+ }
+ }
+ else if (AuthorityType.getAuthorityType(authority) == AuthorityType.GROUP)
+ {
+ // need a map (dummy node) to represent props for this Group Authority
+ node = new HashMap(8, 1.0f);
+ if (authority.startsWith(PermissionService.GROUP_PREFIX) == true)
+ {
+ node.put(PROP_FULLNAME, authority.substring(PermissionService.GROUP_PREFIX.length()));
+ }
+ else
+ {
+ node.put(PROP_FULLNAME, authority);
+ }
+ node.put(PROP_USERNAME, authority);
+ node.put(PROP_ID, authority);
+ node.put(PROP_ICON, WebResources.IMAGE_GROUP);
+ node.put(PROP_ISGROUP, true);
+ }
+ if (node != null)
+ {
+ // add the common properties
+ node.put(PROP_ROLES, roles);
+ node.put(PROP_PARENT, null);
+ node.put(PROP_EXPANDED, false);
+
+ if (this.userGroupLookup.get(authority) != null)
+ {
+ // this authority already exists in the list somewhere else - mark as duplicate
+ node.put(PROP_DUPLICATE, true);
+ node.put(PROP_SELECTED, false);
+ }
+ else
+ {
+ // add to table for the first time, not a duplicate
+ this.userGroupLookup.put(authority, node);
+ node.put(PROP_DUPLICATE, false);
+ node.put(PROP_SELECTED, true);
+ }
+ }
+
+ return node;
+ }
}
diff --git a/source/java/org/alfresco/web/bean/wizard/WizardManager.java b/source/java/org/alfresco/web/bean/wizard/WizardManager.java
index a967648627..c70115e53b 100644
--- a/source/java/org/alfresco/web/bean/wizard/WizardManager.java
+++ b/source/java/org/alfresco/web/bean/wizard/WizardManager.java
@@ -26,16 +26,12 @@ import org.apache.commons.logging.LogFactory;
*
* @author gavinc
*/
-public class WizardManager
+public final class WizardManager
{
private static Log logger = LogFactory.getLog(WizardManager.class);
- protected int currentStep = 1;
- protected PageConfig currentPageCfg;
- protected WizardConfig currentWizardConfig;
- protected IWizardBean currentWizard;
- protected List steps;
- protected Map currentWizardParams;
+ private WizardState currentWizardState;
+ private Map paramsToApply;
/**
* Action handler used to setup parameters for the wizard being launched
@@ -49,7 +45,7 @@ public class WizardManager
if (component instanceof UIActionLink)
{
// store the parameters
- this.currentWizardParams = ((UIActionLink)component).getParameterMap();
+ this.paramsToApply = ((UIActionLink)component).getParameterMap();
}
}
@@ -60,31 +56,53 @@ public class WizardManager
*/
public void setCurrentWizard(WizardConfig config)
{
- this.currentStep = 1;
- this.currentWizardConfig = config;
-
- String beanName = this.currentWizardConfig.getManagedBean();
- this.currentWizard = (IWizardBean)FacesHelper.getManagedBean(
+ String beanName = config.getManagedBean();
+ IWizardBean wizard = (IWizardBean)FacesHelper.getManagedBean(
FacesContext.getCurrentInstance(), beanName);
- if (this.currentWizard == null)
+ if (wizard == null)
{
throw new AlfrescoRuntimeException("Failed to find managed bean '" + beanName + "'");
}
// initialise the managed bean
- this.currentWizard.init(this.currentWizardParams);
+ wizard.init(this.paramsToApply);
// reset the current parameters so subsequent wizards don't get them
- this.currentWizardParams = null;
+ this.paramsToApply = null;
- // get the steps for the wizard
- this.steps = this.currentWizardConfig.getStepsAsList();
+ // create the WizardState object
+ this.currentWizardState = new WizardState(config, wizard);
// setup the first step
determineCurrentPage();
}
+ /**
+ * Returns the state of the currently active wizard
+ *
+ * @return Current wizard's state
+ */
+ public WizardState getState()
+ {
+ return this.currentWizardState;
+ }
+
+ /**
+ * Restores the wizard represented by the given WizardState object.
+ * NOTE: The wizard's restored() method is also called during this
+ * method.
+ *
+ * @param state The WizardState for the wizard to restore
+ */
+ public void restoreState(WizardState state)
+ {
+ this.currentWizardState = state;
+
+ // retrieve the wizard and call it's restored() method
+ this.currentWizardState.getWizard().restored();
+ }
+
/**
* Returns the config for the current wizard
*
@@ -92,7 +110,7 @@ public class WizardManager
*/
public WizardConfig getCurrentWizard()
{
- return this.currentWizardConfig;
+ return this.currentWizardState.getConfig();
}
/**
@@ -102,7 +120,7 @@ public class WizardManager
*/
public IWizardBean getBean()
{
- return this.currentWizard;
+ return this.currentWizardState.getWizard();
}
/**
@@ -112,7 +130,7 @@ public class WizardManager
*/
public String getIcon()
{
- return this.currentWizardConfig.getIcon();
+ return this.currentWizardState.getConfig().getIcon();
}
/**
@@ -123,7 +141,7 @@ public class WizardManager
public String getErrorMessage()
{
return Application.getMessage(FacesContext.getCurrentInstance(),
- this.currentWizardConfig.getErrorMessageId());
+ this.currentWizardState.getConfig().getErrorMessageId());
}
/**
@@ -133,15 +151,23 @@ public class WizardManager
*/
public String getTitle()
{
- String title = this.currentWizardConfig.getTitleId();
+ // try and get the title directly from the wizard
+ String title = this.currentWizardState.getWizard().getTitle();
- if (title != null)
+ if (title == null)
{
- title = Application.getMessage(FacesContext.getCurrentInstance(), title);
- }
- else
- {
- title = this.currentWizardConfig.getTitle();
+ // try and get the title via a message bundle key
+ title = this.currentWizardState.getConfig().getTitleId();
+
+ if (title != null)
+ {
+ title = Application.getMessage(FacesContext.getCurrentInstance(), title);
+ }
+ else
+ {
+ // try and get the title from the configuration
+ title = this.currentWizardState.getConfig().getTitle();
+ }
}
return title;
@@ -154,15 +180,23 @@ public class WizardManager
*/
public String getDescription()
{
- String desc = this.currentWizardConfig.getDescriptionId();
+ // try and get the description directly from the dialog
+ String desc = this.currentWizardState.getWizard().getDescription();
- if (desc != null)
+ if (desc == null)
{
- desc = Application.getMessage(FacesContext.getCurrentInstance(), desc);
- }
- else
- {
- desc = this.currentWizardConfig.getDescription();
+ // try and get the description via a message bundle key
+ desc = this.currentWizardState.getConfig().getDescriptionId();
+
+ if (desc != null)
+ {
+ desc = Application.getMessage(FacesContext.getCurrentInstance(), desc);
+ }
+ else
+ {
+ // try and get the description from the configuration
+ desc = this.currentWizardState.getConfig().getDescription();
+ }
}
return desc;
@@ -175,7 +209,7 @@ public class WizardManager
*/
public int getCurrentStep()
{
- return this.currentStep;
+ return this.currentWizardState.getCurrentStep();
}
/**
@@ -185,7 +219,7 @@ public class WizardManager
*/
public String getCurrentStepAsString()
{
- return Integer.toString(this.currentStep);
+ return Integer.toString(this.currentWizardState.getCurrentStep());
}
/**
@@ -197,7 +231,8 @@ public class WizardManager
*/
public String getCurrentStepName()
{
- return ((StepConfig)this.steps.get(this.currentStep-1)).getName();
+ return ((StepConfig)this.currentWizardState.getSteps().get(
+ this.currentWizardState.getCurrentStep()-1)).getName();
}
/**
@@ -207,12 +242,12 @@ public class WizardManager
*/
public List getStepItems()
{
- List items = new ArrayList(this.steps.size());
+ List items = new ArrayList(this.currentWizardState.getSteps().size());
- for (int x = 0; x < this.steps.size(); x++)
+ for (int x = 0; x < this.currentWizardState.getSteps().size(); x++)
{
String uiStepNumber = Integer.toString(x + 1);
- StepConfig stepCfg = this.steps.get(x);
+ StepConfig stepCfg = this.currentWizardState.getSteps().get(x);
UIListItem item = new UIListItem();
item.setValue(uiStepNumber);
@@ -255,7 +290,7 @@ public class WizardManager
*/
public String getPage()
{
- return this.currentPageCfg.getPath();
+ return this.currentWizardState.getCurrentPageCfg().getPath();
}
/**
@@ -265,7 +300,7 @@ public class WizardManager
*/
public String getStepTitle()
{
- String title = this.currentPageCfg.getTitleId();
+ String title = this.currentWizardState.getCurrentPageCfg().getTitleId();
if (title != null)
{
@@ -273,7 +308,7 @@ public class WizardManager
}
else
{
- title = this.currentPageCfg.getTitle();
+ title = this.currentWizardState.getCurrentPageCfg().getTitle();
}
return title;
@@ -286,7 +321,7 @@ public class WizardManager
*/
public String getStepDescription()
{
- String desc = this.currentPageCfg.getDescriptionId();
+ String desc = this.currentWizardState.getCurrentPageCfg().getDescriptionId();
if (desc != null)
{
@@ -294,7 +329,7 @@ public class WizardManager
}
else
{
- desc = this.currentPageCfg.getDescription();
+ desc = this.currentWizardState.getCurrentPageCfg().getDescription();
}
return desc;
@@ -307,7 +342,7 @@ public class WizardManager
*/
public String getStepInstructions()
{
- String instruction = this.currentPageCfg.getInstructionId();
+ String instruction = this.currentWizardState.getCurrentPageCfg().getInstructionId();
if (instruction != null)
{
@@ -315,7 +350,7 @@ public class WizardManager
}
else
{
- instruction = this.currentPageCfg.getInstruction();
+ instruction = this.currentWizardState.getCurrentPageCfg().getInstruction();
}
return instruction;
@@ -328,7 +363,7 @@ public class WizardManager
*/
public String getNextButtonLabel()
{
- return this.currentWizard.getNextButtonLabel();
+ return this.currentWizardState.getWizard().getNextButtonLabel();
}
/**
@@ -338,13 +373,13 @@ public class WizardManager
*/
public boolean getNextButtonDisabled()
{
- if (this.currentStep == this.steps.size())
+ if (this.currentWizardState.getCurrentStep() == this.currentWizardState.getSteps().size())
{
return true;
}
else
{
- return this.currentWizard.getNextButtonDisabled();
+ return this.currentWizardState.getWizard().getNextButtonDisabled();
}
}
@@ -355,7 +390,7 @@ public class WizardManager
*/
public String getBackButtonLabel()
{
- return this.currentWizard.getBackButtonLabel();
+ return this.currentWizardState.getWizard().getBackButtonLabel();
}
/**
@@ -365,7 +400,7 @@ public class WizardManager
*/
public boolean getBackButtonDisabled()
{
- if (this.currentStep == 1)
+ if (this.currentWizardState.getCurrentStep() == 1)
{
return true;
}
@@ -382,7 +417,7 @@ public class WizardManager
*/
public String getCancelButtonLabel()
{
- return this.currentWizard.getCancelButtonLabel();
+ return this.currentWizardState.getWizard().getCancelButtonLabel();
}
/**
@@ -392,7 +427,7 @@ public class WizardManager
*/
public String getFinishButtonLabel()
{
- return this.currentWizard.getFinishButtonLabel();
+ return this.currentWizardState.getWizard().getFinishButtonLabel();
}
/**
@@ -402,13 +437,13 @@ public class WizardManager
*/
public boolean getFinishButtonDisabled()
{
- if (this.currentStep == this.steps.size())
+ if (this.currentWizardState.getCurrentStep() == this.currentWizardState.getSteps().size())
{
return false;
}
else
{
- return this.currentWizard.getFinishButtonDisabled();
+ return this.currentWizardState.getWizard().getFinishButtonDisabled();
}
}
@@ -419,13 +454,16 @@ public class WizardManager
*/
public void next()
{
- this.currentStep++;
+ // calculate next step number and update wizard state
+ int currentStep = this.currentWizardState.getCurrentStep();
+ currentStep++;
+ this.currentWizardState.setCurrentStep(currentStep);
if (logger.isDebugEnabled())
- logger.debug("next called, current step is now: " + this.currentStep);
+ logger.debug("next called, current step is now: " + this.currentWizardState.getCurrentStep());
// tell the wizard the next button has been pressed
- this.currentWizard.next();
+ this.currentWizardState.getWizard().next();
determineCurrentPage();
}
@@ -437,13 +475,16 @@ public class WizardManager
*/
public void back()
{
- this.currentStep--;
+ // calculate next step number and update wizard state
+ int currentStep = this.currentWizardState.getCurrentStep();
+ currentStep--;
+ this.currentWizardState.setCurrentStep(currentStep);
if (logger.isDebugEnabled())
- logger.debug("back called, current step is now: " + this.currentStep);
+ logger.debug("back called, current step is now: " + this.currentWizardState.getCurrentStep());
// tell the wizard the back button has been pressed
- this.currentWizard.back();
+ this.currentWizardState.getWizard().back();
determineCurrentPage();
}
@@ -455,7 +496,7 @@ public class WizardManager
*/
public String finish()
{
- return this.currentWizard.finish();
+ return this.currentWizardState.getWizard().finish();
}
/**
@@ -465,7 +506,7 @@ public class WizardManager
*/
public String cancel()
{
- return this.currentWizard.cancel();
+ return this.currentWizardState.getWizard().cancel();
}
/**
@@ -473,10 +514,14 @@ public class WizardManager
*/
protected void determineCurrentPage()
{
- this.currentPageCfg = null;
+ // reset the current page config in the state object
+ this.currentWizardState.setCurrentPageCfg(null);
+
+ PageConfig currentPageCfg = null;
// get the config for the current step position
- StepConfig stepCfg = this.steps.get(this.currentStep-1);
+ StepConfig stepCfg = this.currentWizardState.getSteps().get(
+ this.currentWizardState.getCurrentStep()-1);
// is the step conditional?
if (stepCfg.hasConditionalPages())
@@ -497,25 +542,28 @@ public class WizardManager
Object obj = vb.getValue(context);
if (obj instanceof Boolean && ((Boolean)obj).booleanValue())
{
- this.currentPageCfg = pageCfg;
+ currentPageCfg = pageCfg;
break;
}
}
}
// if none of the conditions passed use the default page
- if (this.currentPageCfg == null)
+ if (currentPageCfg == null)
{
- this.currentPageCfg = stepCfg.getDefaultPage();
+ currentPageCfg = stepCfg.getDefaultPage();
}
- if (this.currentPageCfg == null)
+ if (currentPageCfg == null)
{
throw new AlfrescoRuntimeException("Failed to determine page for step '" + stepCfg.getName() +
"'. Make sure a default page is configured.");
}
+ // save the current page config in the state object
+ this.currentWizardState.setCurrentPageCfg(currentPageCfg);
+
if (logger.isDebugEnabled())
- logger.debug("Config for current page: " + this.currentPageCfg);
+ logger.debug("Config for current page: " + this.currentWizardState.getCurrentPageCfg());
}
}
diff --git a/source/java/org/alfresco/web/bean/wizard/WizardState.java b/source/java/org/alfresco/web/bean/wizard/WizardState.java
new file mode 100644
index 0000000000..d006e8f342
--- /dev/null
+++ b/source/java/org/alfresco/web/bean/wizard/WizardState.java
@@ -0,0 +1,113 @@
+package org.alfresco.web.bean.wizard;
+
+import java.util.List;
+
+import org.alfresco.web.app.AlfrescoNavigationHandler;
+import org.alfresco.web.config.WizardsConfigElement.PageConfig;
+import org.alfresco.web.config.WizardsConfigElement.StepConfig;
+import org.alfresco.web.config.WizardsConfigElement.WizardConfig;
+
+/**
+ * Object responsible for holding the current state of an active wizard.
+ *
+ * @author gavinc
+ */
+public final class WizardState
+{
+ private int currentStep = 1;
+ private PageConfig currentPageCfg;
+ private WizardConfig config;
+ private IWizardBean wizard;
+ private List steps;
+
+ /**
+ * Default constructor
+ *
+ * @param config The configuration for the wizard
+ * @param wizard The wizard bean instance
+ */
+ public WizardState(WizardConfig config, IWizardBean wizard)
+ {
+ this.config = config;
+ this.wizard = wizard;
+
+ this.steps = this.config.getStepsAsList();
+ }
+
+ /**
+ * Sets the configuration for the current page of the wizard
+ *
+ * @param currentPageCfg The configuration
+ */
+ public void setCurrentPageCfg(PageConfig currentPageCfg)
+ {
+ this.currentPageCfg = currentPageCfg;
+ }
+
+ /**
+ * Sets the current step the wizard is on
+ *
+ * @param currentStep The current step number
+ */
+ public void setCurrentStep(int currentStep)
+ {
+ this.currentStep = currentStep;
+ }
+
+ /**
+ * Returns the wizard bean instance
+ *
+ * @return The wizard bean instance
+ */
+ public IWizardBean getWizard()
+ {
+ return this.wizard;
+ }
+
+ /**
+ * Returns the configuration for the current wizard
+ *
+ * @return The wizard configuration
+ */
+ public WizardConfig getConfig()
+ {
+ return this.config;
+ }
+
+ /**
+ * Returns the configuration for the current page of the wizard
+ *
+ * @return The current page configuration
+ */
+ public PageConfig getCurrentPageCfg()
+ {
+ return currentPageCfg;
+ }
+
+ /**
+ * The current step the wizard is on
+ *
+ * @return The current wizard step
+ */
+ public int getCurrentStep()
+ {
+ return currentStep;
+ }
+
+ /**
+ * Returns the list of steps the wizard has
+ *
+ * @return List of wizard steps
+ */
+ public List getSteps()
+ {
+ return steps;
+ }
+
+ @Override
+ public String toString()
+ {
+ return AlfrescoNavigationHandler.WIZARD_PREFIX + this.config.getName() +
+ "[" + this.currentStep + "]";
+ }
+}
diff --git a/source/java/org/alfresco/web/bean/workflow/ManageTaskDialog.java b/source/java/org/alfresco/web/bean/workflow/ManageTaskDialog.java
new file mode 100644
index 0000000000..936199c415
--- /dev/null
+++ b/source/java/org/alfresco/web/bean/workflow/ManageTaskDialog.java
@@ -0,0 +1,667 @@
+package org.alfresco.web.bean.workflow;
+
+import java.io.Serializable;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.context.FacesContext;
+import javax.faces.event.ActionEvent;
+import javax.transaction.UserTransaction;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.repo.workflow.WorkflowModel;
+import org.alfresco.service.cmr.dictionary.TypeDefinition;
+import org.alfresco.service.cmr.repository.ChildAssociationRef;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.workflow.WorkflowInstance;
+import org.alfresco.service.cmr.workflow.WorkflowService;
+import org.alfresco.service.cmr.workflow.WorkflowTask;
+import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
+import org.alfresco.service.cmr.workflow.WorkflowTransition;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.service.namespace.RegexQNamePattern;
+import org.alfresco.web.app.AlfrescoNavigationHandler;
+import org.alfresco.web.app.Application;
+import org.alfresco.web.bean.dialog.BaseDialogBean;
+import org.alfresco.web.bean.repository.MapNode;
+import org.alfresco.web.bean.repository.Node;
+import org.alfresco.web.bean.repository.NodePropertyResolver;
+import org.alfresco.web.bean.repository.Repository;
+import org.alfresco.web.bean.repository.TransientNode;
+import org.alfresco.web.config.DialogsConfigElement.DialogButtonConfig;
+import org.alfresco.web.ui.common.Utils;
+import org.alfresco.web.ui.common.component.UIActionLink;
+import org.alfresco.web.ui.common.component.data.UIRichList;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Bean implementation for the "Manage Task" dialog.
+ *
+ * @author gavinc
+ */
+public class ManageTaskDialog extends BaseDialogBean
+{
+ protected WorkflowService workflowService;
+ protected Node taskNode;
+ protected WorkflowTask task;
+ protected WorkflowInstance workflowInstance;
+ protected WorkflowTransition[] transitions;
+ protected NodeRef workflowPackage;
+ protected List resources;
+ protected TaskCompleteResolver completeResolver = new TaskCompleteResolver();
+ protected UIRichList packageItemsRichList;
+ protected List packageItemsToAdd;
+ protected List packageItemsToRemove;
+ protected String[] itemsToAdd;
+ protected boolean isItemBeingAdded = false;
+
+ protected final Log logger = LogFactory.getLog(getClass());
+
+ protected static final String ID_PREFIX = "transition_";
+ protected static final String CLIENT_ID_PREFIX = AlfrescoNavigationHandler.DIALOG_PREFIX + ID_PREFIX;
+
+ // ------------------------------------------------------------------------------
+ // Dialog implementation
+
+ @Override
+ public void init(Map parameters)
+ {
+ super.init(parameters);
+
+ // reset variables
+ this.task = null;
+ this.taskNode = null;
+ this.workflowInstance = null;
+ this.transitions = null;
+ this.workflowPackage = null;
+ this.resources = null;
+ this.itemsToAdd = null;
+ this.packageItemsToAdd = null;
+ this.packageItemsToRemove = null;
+ this.isItemBeingAdded = false;
+ if (this.packageItemsRichList != null)
+ {
+ this.packageItemsRichList.setValue(null);
+ this.packageItemsRichList = null;
+ }
+
+ // get the task details
+ String taskId = this.parameters.get("id");
+ this.task = this.workflowService.getTaskById(taskId);
+
+ if (this.task != null)
+ {
+ // setup a transient node to represent the task we're managing
+ WorkflowTaskDefinition taskDef = this.task.definition;
+ this.taskNode = new TransientNode(taskDef.metadata.getName(),
+ "task_" + System.currentTimeMillis(), this.task.properties);
+
+ // get access to the workflow instance for the task
+ this.workflowInstance = this.task.path.instance;
+
+ // setup the workflow package for the task
+ Serializable obj = this.task.properties.get(WorkflowModel.ASSOC_PACKAGE);
+ // TODO: remove this workaroud where JBPM may return a String and not the NodeRef
+ if (obj instanceof NodeRef)
+ {
+ this.workflowPackage = (NodeRef)obj;
+ }
+ else if (obj instanceof String)
+ {
+ this.workflowPackage = new NodeRef((String)obj);
+ }
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("Task: " + this.task);
+ logger.debug("Trasient node: " + this.taskNode);
+ logger.debug("Workflow package: " + this.workflowPackage );
+ }
+ }
+ }
+
+ @Override
+ public void restored()
+ {
+ // reset the workflow package rich list so everything gets re-evaluated
+ if (this.packageItemsRichList != null)
+ {
+ this.packageItemsRichList.setValue(null);
+ this.packageItemsRichList = null;
+ }
+ }
+
+ @Override
+ protected String finishImpl(FacesContext context, String outcome)
+ throws Exception
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Saving task: " + this.task.id);
+
+ // prepare the edited parameters for saving
+ Map params = WorkflowBean.prepareTaskParams(this.taskNode);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Saving task with parameters: " + params);
+
+ // remove any items the user selected to remove
+ if (this.workflowPackage != null && this.packageItemsToRemove != null &&
+ this.packageItemsToRemove.size() > 0)
+ {
+ for (String removedItem : this.packageItemsToRemove)
+ {
+ this.nodeService.removeChild(this.workflowPackage, new NodeRef(removedItem));
+ }
+ }
+
+ // add any items the user selected to add
+ if (this.workflowPackage != null && this.packageItemsToAdd != null &&
+ this.packageItemsToAdd.size() > 0)
+ {
+ for (String addedItem : this.packageItemsToAdd)
+ {
+ NodeRef addedNodeRef = new NodeRef(addedItem);
+ this.nodeService.addChild(this.workflowPackage, addedNodeRef,
+ ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
+ QName.createValidLocalName((String)this.nodeService.getProperty(
+ addedNodeRef, ContentModel.PROP_NAME))));
+ }
+ }
+
+ // update the task with the updated parameters
+ this.workflowService.updateTask(this.task.id, params, null, null);
+
+ return outcome;
+ }
+
+ @Override
+ public List getAdditionalButtons()
+ {
+ List buttons = null;
+
+ if (this.task != null)
+ {
+ // get the transitions available from this task and
+ // show them in the dialog as additional buttons
+ this.transitions = this.task.path.node.transitions;
+
+ if (this.transitions != null)
+ {
+ buttons = new ArrayList(this.transitions.length);
+
+ for (WorkflowTransition trans : this.transitions)
+ {
+ buttons.add(new DialogButtonConfig(ID_PREFIX + trans.title, trans.title, null,
+ "#{DialogManager.bean.transition}", "false", null));
+ }
+ }
+ }
+
+ return buttons;
+ }
+
+ @Override
+ public String getFinishButtonLabel()
+ {
+ return Application.getMessage(FacesContext.getCurrentInstance(), "save");
+ }
+
+ @Override
+ public boolean getFinishButtonDisabled()
+ {
+ return false;
+ }
+
+ @Override
+ public String getTitle()
+ {
+ String titleStart = Application.getMessage(FacesContext.getCurrentInstance(), "manage_task_title");
+
+ return titleStart + ": " + this.task.title;
+ }
+
+ @Override
+ public String getDescription()
+ {
+ return this.task.description;
+ }
+
+ // ------------------------------------------------------------------------------
+ // Event handlers
+
+ @SuppressWarnings("unused")
+ public String transition()
+ {
+ String outcome = getDefaultFinishOutcome();
+
+ if (logger.isDebugEnabled())
+ logger.debug("Transitioning task: " + this.task.id);
+
+ // to find out which transition button was pressed we need
+ // to look for the button's id in the request parameters,
+ // the first non-null result is the button that was pressed.
+ FacesContext context = FacesContext.getCurrentInstance();
+ Map reqParams = context.getExternalContext().getRequestParameterMap();
+
+ String selectedTransition = null;
+ for (WorkflowTransition trans : this.transitions)
+ {
+ Object result = reqParams.get(CLIENT_ID_PREFIX + trans.title);
+ if (result != null)
+ {
+ // this was the button that was pressed
+ selectedTransition = trans.id;
+ break;
+ }
+ }
+
+ if (selectedTransition != null)
+ {
+ UserTransaction tx = null;
+
+ try
+ {
+ tx = Repository.getUserTransaction(context);
+ tx.begin();
+
+ // prepare the edited parameters for saving
+ Map params = WorkflowBean.prepareTaskParams(this.taskNode);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Transitioning task with parameters: " + params);
+
+ // update the task with the updated parameters
+ this.workflowService.updateTask(this.task.id, params, null, null);
+
+ // signal the selected transition to the workflow task
+ this.workflowService.endTask(this.task.id, selectedTransition);
+
+ // commit the changes
+ tx.commit();
+
+ if (logger.isDebugEnabled())
+ logger.debug("Ended task with transition: " + selectedTransition);
+ }
+ catch (Throwable e)
+ {
+ // rollback the transaction
+ try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
+ Utils.addErrorMessage(formatErrorMessage(e), e);
+ outcome = this.getErrorOutcome(e);
+ }
+ }
+
+ return outcome;
+ }
+
+ /**
+ * Prepares the dialog to allow the user to add an item to the workflow package
+ *
+ * @param event The event
+ */
+ public void prepareForAdd(ActionEvent event)
+ {
+ this.isItemBeingAdded = true;
+ }
+
+ /**
+ * Cancels the adding of an item to the workflow package
+ *
+ * @param event The event
+ */
+ public void cancelAddPackageItems(ActionEvent event)
+ {
+ this.isItemBeingAdded = false;
+ }
+
+ /**
+ * Adds an item to the workflow package
+ *
+ * @param event The event
+ */
+ public void addPackageItems(ActionEvent event)
+ {
+ if (this.itemsToAdd != null)
+ {
+ if (this.packageItemsToAdd == null)
+ {
+ // create the list of items to add if necessary
+ this.packageItemsToAdd = new ArrayList(this.itemsToAdd.length);
+ }
+
+ for (String item : this.itemsToAdd)
+ {
+ // if this item is in the remove list it means it was there originally
+ // and has now been re-added, as a result we don't need to do anything
+ // to the original workflow package, therefore remove from the remove list
+ if (this.packageItemsToRemove != null && this.packageItemsToRemove.contains(item))
+ {
+ this.packageItemsToRemove.remove(item);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Removed item from the removed list: " + item);
+ }
+ else
+ {
+ this.packageItemsToAdd.add(item);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Added item to the added list: " + item);
+ }
+ }
+
+ // reset the rich list so it re-renders
+ this.packageItemsRichList.setValue(null);
+ }
+
+ this.isItemBeingAdded = false;
+ this.itemsToAdd = null;
+ }
+
+ /**
+ * Removes an item from the workflow package
+ *
+ * @param event The event containing a reference to the item to remove
+ */
+ public void removePackageItem(ActionEvent event)
+ {
+ UIActionLink link = (UIActionLink)event.getComponent();
+ Map params = link.getParameterMap();
+ String nodeRef = new NodeRef(Repository.getStoreRef(), params.get("id")).toString();
+
+ if (this.packageItemsToAdd != null && this.packageItemsToAdd.contains(nodeRef))
+ {
+ // remove the item from the added list if it was added in this dialog session
+ this.packageItemsToAdd.remove(nodeRef);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Removed item from the added list: " + nodeRef);
+ }
+ else
+ {
+ // add the node to the list of items to remove
+ if (this.packageItemsToRemove == null)
+ {
+ this.packageItemsToRemove = new ArrayList(1);
+ }
+
+ this.packageItemsToRemove.add(nodeRef);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Added item to the removed list: " + nodeRef);
+ }
+
+ // reset the rich list so it re-renders
+ this.packageItemsRichList.setValue(null);
+ }
+
+ /**
+ * Toggles the complete flag for a workflow package item
+ *
+ * @param event The event containing a reference to the item to toggle the status for
+ */
+ public void togglePackageItemComplete(ActionEvent event)
+ {
+ // TODO: implement this!
+ }
+
+ // ------------------------------------------------------------------------------
+ // Bean Getters and Setters
+
+ /**
+ * Returns a String array of NodeRef's that are being added to the workflow package
+ *
+ * @return String array of NodeRef's
+ */
+ public String[] getItemsToAdd()
+ {
+ return this.itemsToAdd;
+ }
+
+ /**
+ * Sets the NodeRef's to add as items to the workflow package
+ *
+ * @param itemsToAdd NodeRef's to add to the workflow package
+ */
+ public void setItemsToAdd(String[] itemsToAdd)
+ {
+ this.itemsToAdd = itemsToAdd;
+ }
+
+ /**
+ * Determines whether an item is currently being added to the workflow package
+ *
+ * @return true if an item is being added
+ */
+ public boolean isItemBeingAdded()
+ {
+ return this.isItemBeingAdded;
+ }
+
+ /**
+ * Sets the rich list being used for the workflow package items
+ *
+ * @param richList The rich list instance
+ */
+ public void setPackageItemsRichList(UIRichList richList)
+ {
+ this.packageItemsRichList = richList;
+ }
+
+ /**
+ * Returns the rich list being used for the workflow package items
+ *
+ * @return The rich list instance
+ */
+ public UIRichList getPackageItemsRichList()
+ {
+ return this.packageItemsRichList;
+ }
+
+ /**
+ * Returns the Node representing the task
+ *
+ * @return The node
+ */
+ public Node getTaskNode()
+ {
+ return this.taskNode;
+ }
+
+ /**
+ * Returns the WorkflowInstance that the current task belongs to
+ *
+ * @return The workflow instance
+ */
+ public WorkflowInstance getWorkflowInstance()
+ {
+ return this.workflowInstance;
+ }
+
+ /**
+ * Returns the action group the current task uses for the workflow package
+ *
+ * @return action group id
+ */
+ public String getPackageActionGroup()
+ {
+ return (String)this.task.properties.get(
+ WorkflowModel.PROP_PACKAGE_ACTION_GROUP);
+ }
+
+ /**
+ * Returns the action group the current task uses for each workflow package item
+ *
+ * @return action group id
+ */
+ public String getPackageItemActionGroup()
+ {
+ return (String)this.task.properties.get(
+ WorkflowModel.PROP_PACKAGE_ITEM_ACTION_GROUP);
+ }
+
+ /**
+ * Returns a list of resources associated with this task
+ * i.e. the children of the workflow package
+ *
+ * @return The list of nodes
+ */
+ public List getResources()
+ {
+ this.resources = new ArrayList(4);
+
+ if (this.workflowPackage != null)
+ {
+ UserTransaction tx = null;
+ try
+ {
+ FacesContext context = FacesContext.getCurrentInstance();
+ tx = Repository.getUserTransaction(context, true);
+ tx.begin();
+
+ // get existing workflow package items
+ List childRefs = this.nodeService.getChildAssocs(
+ this.workflowPackage, ContentModel.ASSOC_CONTAINS,
+ RegexQNamePattern.MATCH_ALL);
+
+ for (ChildAssociationRef ref: childRefs)
+ {
+ // create our Node representation from the NodeRef
+ NodeRef nodeRef = ref.getChildRef();
+
+ if (this.nodeService.exists(nodeRef))
+ {
+ // find it's type so we can see if it's a node we are interested in
+ QName type = this.nodeService.getType(nodeRef);
+
+ // make sure the type is defined in the data dictionary
+ TypeDefinition typeDef = this.dictionaryService.getType(type);
+
+ if (typeDef != null)
+ {
+ // look for content nodes or links to content
+ // NOTE: folders within workflow packages are ignored for now
+ if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT) ||
+ ContentModel.TYPE_FILELINK.equals(type))
+ {
+ // if the node is not in the removed list then add create the
+ // client side representation and add to the list
+ if (this.packageItemsToRemove == null ||
+ this.packageItemsToRemove.contains(nodeRef.toString()) == false)
+ {
+ createAndAddNode(nodeRef);
+ }
+ }
+ }
+ else
+ {
+ if (logger.isWarnEnabled())
+ logger.warn("Found invalid object in database: id = " + nodeRef + ", type = " + type);
+ }
+ }
+ else
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Ignoring " + nodeRef + " as it has been removed from the repository");
+ }
+ }
+
+ // now iterate through the items to add list and add them to the list of resources
+ if (this.packageItemsToAdd != null)
+ {
+ for (String newItem : this.packageItemsToAdd)
+ {
+ NodeRef nodeRef = new NodeRef(newItem);
+ if (this.nodeService.exists(nodeRef))
+ {
+ // we know the type is correct as this was added as a result of a query
+ // for all content items so just add the item to the resources list
+ createAndAddNode(nodeRef);
+ }
+ else
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Ignoring " + nodeRef + " as it has been removed from the repository");
+ }
+ }
+ }
+
+ // commit the transaction
+ tx.commit();
+ }
+ catch (Throwable err)
+ {
+ Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
+ FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
+ this.resources = Collections.emptyList();
+ try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
+ }
+ }
+ else if (logger.isDebugEnabled())
+ {
+ logger.debug("Failed to find workflow package for task: " + this.task.id);
+ }
+
+ return this.resources;
+ }
+
+ /**
+ * Sets the workflow service to use
+ *
+ * @param workflowService
+ * WorkflowService instance
+ */
+ public void setWorkflowService(WorkflowService workflowService)
+ {
+ this.workflowService = workflowService;
+ }
+
+ // ------------------------------------------------------------------------------
+ // Helper methods
+
+ protected void createAndAddNode(NodeRef nodeRef)
+ {
+ // create our Node representation
+ MapNode node = new MapNode(nodeRef, this.nodeService, true);
+ this.browseBean.setupCommonBindingProperties(node);
+
+ // add property resolvers to show path information
+ node.addPropertyResolver("path", this.browseBean.resolverPath);
+ node.addPropertyResolver("displayPath", this.browseBean.resolverDisplayPath);
+
+ // add a property resolver to indicate whether the item has been completed or not
+// node.addPropertyResolver("completed", this.completeResolver);
+
+ this.resources.add(node);
+ }
+
+ // ------------------------------------------------------------------------------
+ // Inner classes
+
+ /**
+ * Property resolver to determine if the given node has been flagged as complete
+ */
+ protected class TaskCompleteResolver implements NodePropertyResolver
+ {
+ public Object get(Node node)
+ {
+ String result = Application.getMessage(FacesContext.getCurrentInstance(), "no");
+
+ List completedItems = (List)task.properties.get(
+ WorkflowModel.PROP_COMPLETED_ITEMS);
+
+ if (completedItems != null && completedItems.size() > 0 &&
+ completedItems.contains(node.getNodeRef()))
+ {
+ result = Application.getMessage(FacesContext.getCurrentInstance(), "yes");
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/source/java/org/alfresco/web/bean/workflow/ManageWorkItemDialog.java b/source/java/org/alfresco/web/bean/workflow/ManageWorkItemDialog.java
deleted file mode 100644
index 05842b6c22..0000000000
--- a/source/java/org/alfresco/web/bean/workflow/ManageWorkItemDialog.java
+++ /dev/null
@@ -1,476 +0,0 @@
-package org.alfresco.web.bean.workflow;
-
-import java.io.Serializable;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import javax.faces.context.FacesContext;
-import javax.faces.event.ActionEvent;
-import javax.transaction.UserTransaction;
-
-import org.alfresco.model.ContentModel;
-import org.alfresco.repo.workflow.WorkflowModel;
-import org.alfresco.service.cmr.dictionary.TypeDefinition;
-import org.alfresco.service.cmr.repository.ChildAssociationRef;
-import org.alfresco.service.cmr.repository.NodeRef;
-import org.alfresco.service.cmr.workflow.WorkflowService;
-import org.alfresco.service.cmr.workflow.WorkflowTask;
-import org.alfresco.service.cmr.workflow.WorkflowTaskDefinition;
-import org.alfresco.service.cmr.workflow.WorkflowTransition;
-import org.alfresco.service.namespace.QName;
-import org.alfresco.service.namespace.RegexQNamePattern;
-import org.alfresco.web.app.Application;
-import org.alfresco.web.bean.dialog.BaseDialogBean;
-import org.alfresco.web.bean.repository.MapNode;
-import org.alfresco.web.bean.repository.Node;
-import org.alfresco.web.bean.repository.NodePropertyResolver;
-import org.alfresco.web.bean.repository.Repository;
-import org.alfresco.web.bean.repository.TransientNode;
-import org.alfresco.web.config.DialogsConfigElement.DialogButtonConfig;
-import org.alfresco.web.ui.common.Utils;
-import org.alfresco.web.ui.common.component.UIActionLink;
-import org.alfresco.web.ui.common.component.data.UIRichList;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-/**
- * Bean implementation for the "Manage WorkItem" dialog.
- *
- * @author gavinc
- */
-public class ManageWorkItemDialog extends BaseDialogBean
-{
- protected WorkflowService workflowService;
- protected Node workItemNode;
- protected WorkflowTask workItem;
- protected WorkflowTransition[] transitions;
- protected List resources;
- protected WorkItemCompleteResolver completeResolver = new WorkItemCompleteResolver();
- protected UIRichList packageItemsRichList;
-
- protected static final String ID_PREFIX = "transition_";
- protected static final String CLIENT_ID_PREFIX = "dialog:" + ID_PREFIX;
-
- private static final Log logger = LogFactory.getLog(ManageWorkItemDialog.class);
-
- // ------------------------------------------------------------------------------
- // Dialog implementation
-
- @Override
- public void init(Map parameters)
- {
- super.init(parameters);
-
- String taskId = this.parameters.get("id");
- this.workItem = this.workflowService.getTaskById(taskId);
-
- if (this.workItem != null)
- {
- // setup a transient node to represent the work item we're managing
- WorkflowTaskDefinition taskDef = this.workItem.definition;
- this.workItemNode = new TransientNode(taskDef.metadata.getName(),
- "task_" + System.currentTimeMillis(), this.workItem.properties);
- }
- }
-
- @Override
- protected String finishImpl(FacesContext context, String outcome)
- throws Exception
- {
- if (logger.isDebugEnabled())
- logger.debug("Saving work item: " + this.workItemNode.getId());
-
- // prepare the edited parameters for saving
- Map params = WorkflowBean.prepareWorkItemParams(this.workItemNode);
-
- // update the task with the updated parameters
- this.workflowService.updateTask(this.workItem.id, params, null, null);
-
- return outcome;
- }
-
- @Override
- public List getAdditionalButtons()
- {
- List buttons = null;
-
- if (this.workItem != null)
- {
- // get the transitions available from this work item and
- // show them in the dialog as additional buttons
- this.transitions = this.workItem.path.node.transitions;
-
- if (this.transitions != null)
- {
- buttons = new ArrayList(this.transitions.length);
-
- for (WorkflowTransition trans : this.transitions)
- {
- buttons.add(new DialogButtonConfig(ID_PREFIX + trans.title, trans.title, null,
- "#{DialogManager.bean.transition}", "false", null));
- }
- }
- }
-
- return buttons;
- }
-
- @Override
- public String getFinishButtonLabel()
- {
- return Application.getMessage(FacesContext.getCurrentInstance(), "save");
- }
-
- @Override
- public boolean getFinishButtonDisabled()
- {
- return false;
- }
-
- // ------------------------------------------------------------------------------
- // Event handlers
-
- @SuppressWarnings("unused")
- public String transition()
- {
- String outcome = getDefaultFinishOutcome();
-
- if (logger.isDebugEnabled())
- logger.debug("Transitioning work item: " + this.workItemNode.getId());
-
- // to find out which transition button was pressed we need
- // to look for the button's id in the request parameters,
- // the first non-null result is the button that was pressed.
- FacesContext context = FacesContext.getCurrentInstance();
- Map reqParams = context.getExternalContext().getRequestParameterMap();
-
- String selectedTransition = null;
- for (WorkflowTransition trans : this.transitions)
- {
- Object result = reqParams.get(CLIENT_ID_PREFIX + trans.title);
- if (result != null)
- {
- // this was the button that was pressed
- selectedTransition = trans.id;
- break;
- }
- }
-
- if (selectedTransition != null)
- {
- UserTransaction tx = null;
-
- try
- {
- tx = Repository.getUserTransaction(context);
- tx.begin();
-
- // prepare the edited parameters for saving
- Map params = WorkflowBean.prepareWorkItemParams(this.workItemNode);
-
- // update the task with the updated parameters
- this.workflowService.updateTask(this.workItem.id, params, null, null);
-
- // signal the selected transition to the workflow task
- this.workflowService.endTask(this.workItem.id, selectedTransition);
-
- // commit the changes
- tx.commit();
-
- if (logger.isDebugEnabled())
- logger.debug("Ended work item with transition: " + selectedTransition);
- }
- catch (Throwable e)
- {
- // rollback the transaction
- try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
- Utils.addErrorMessage(formatErrorMessage(e), e);
- outcome = this.getErrorOutcome(e);
- }
- }
-
- return outcome;
- }
-
- /**
- * Removes an item from the workflow package
- *
- * @param event The event containing a reference to the item to remove
- */
- public void removePackageItem(ActionEvent event)
- {
- logger.info("remove package item: " + event);
- }
-
- /**
- * Toggles the complete flag for a workflow package item
- *
- * @param event The event containing a reference to the item to toggle the status for
- */
- public void togglePackageItemComplete(ActionEvent event)
- {
- UserTransaction tx = null;
- try
- {
- FacesContext context = FacesContext.getCurrentInstance();
- tx = Repository.getUserTransaction(context);
- tx.begin();
-
- UIActionLink link = (UIActionLink)event.getComponent();
- Map params = link.getParameterMap();
-
- // create the node ref for the item we are toggling
- NodeRef nodeRef = new NodeRef(Repository.getStoreRef(),
- (String)params.get("id"));
-
- // get the existing list of completed items
- List completedItems = (List)this.workItem.properties.get(
- WorkflowModel.PROP_COMPLETED_ITEMS);
-
- if (completedItems == null)
- {
- // if it doesn't exist yet create the list and add the noderef
- completedItems = new ArrayList(1);
- completedItems.add(nodeRef);
- this.workItem.properties.put(WorkflowModel.PROP_COMPLETED_ITEMS,
- (Serializable)completedItems);
- }
- else
- {
- if (completedItems.contains(nodeRef))
- {
- // the item is already in the list remove it
- completedItems.remove(nodeRef);
-
- // NOTE: There is a bug somwehere which causes the list to be
- // returned as a byte array instead of a list if an empty
- // list is persisted, therefore if the list is now empty
- // set the completed items back to null
- if (completedItems.size() == 0)
- {
- this.workItem.properties.put(WorkflowModel.PROP_COMPLETED_ITEMS, null);
- }
- }
- else
- {
- // the noderef is not in the list yet so just add it
- completedItems.add(nodeRef);
- }
- }
-
- // update the task with the updated parameters
- this.workflowService.updateTask(this.workItem.id, this.workItem.properties,
- null, null);
-
- // commit the transaction
- tx.commit();
-
- // reset the rich list if the change was successful
- this.packageItemsRichList.setValue(null);
- }
- catch (Throwable err)
- {
- Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
- FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
- this.resources = Collections.emptyList();
- try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
- }
- }
-
- // ------------------------------------------------------------------------------
- // Bean Getters and Setters
-
- /**
- * Sets the rich list being used for the workflow package items
- *
- * @param richList The rich list instance
- */
- public void setPackageItemsRichList(UIRichList richList)
- {
- this.packageItemsRichList = richList;
- }
-
- /**
- * Returns the rich list being used for the workflow package items
- *
- * @return The rich list instance
- */
- public UIRichList getPackageItemsRichList()
- {
- return this.packageItemsRichList;
- }
-
- /**
- * Returns the Node representing the work item
- *
- * @return The node
- */
- public Node getWorkItemNode()
- {
- return this.workItemNode;
- }
-
- /**
- * Returns the action group the current task uses for the workflow package
- *
- * @return action group id
- */
- public String getPackageActionGroup()
- {
- return (String)this.workItem.properties.get(
- WorkflowModel.PROP_PACKAGE_ACTION_GROUP);
- }
-
- /**
- * Returns the action group the current task uses for each workflow package item
- *
- * @return action group id
- */
- public String getPackageItemActionGroup()
- {
- return (String)this.workItem.properties.get(
- WorkflowModel.PROP_PACKAGE_ITEM_ACTION_GROUP);
- }
-
- /**
- * Returns a list of resources associated with this work item
- * i.e. the children of the workflow package
- *
- * @return The list of nodes
- */
- public List getResources()
- {
- NodeRef workflowPackage = null;
- Serializable obj = this.workItem.properties.get(WorkflowModel.ASSOC_PACKAGE);
- // TODO: remove this workaroud where JBPM may return a String and not the NodeRef
- if (obj instanceof NodeRef)
- {
- workflowPackage = (NodeRef)obj;
- }
- else if (obj instanceof String)
- {
- workflowPackage = new NodeRef((String)obj);
- }
-
- this.resources = new ArrayList(4);
-
- if (workflowPackage != null)
- {
- UserTransaction tx = null;
- try
- {
- FacesContext context = FacesContext.getCurrentInstance();
- tx = Repository.getUserTransaction(context, true);
- tx.begin();
-
- if (logger.isDebugEnabled())
- logger.debug("Found workflow package for work item '" +
- this.workItem.id + "': " + workflowPackage );
-
- List childRefs = this.nodeService.getChildAssocs(workflowPackage,
- ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL);
-
- for (ChildAssociationRef ref: childRefs)
- {
- // create our Node representation from the NodeRef
- NodeRef nodeRef = ref.getChildRef();
-
- if (this.nodeService.exists(nodeRef))
- {
- // find it's type so we can see if it's a node we are interested in
- QName type = this.nodeService.getType(nodeRef);
-
- // make sure the type is defined in the data dictionary
- TypeDefinition typeDef = this.dictionaryService.getType(type);
-
- if (typeDef != null)
- {
- // look for content nodes or links to content
- // NOTE: folders within workflow packages are ignored for now
- if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT) ||
- ContentModel.TYPE_FILELINK.equals(type))
- {
- // create our Node representation
- MapNode node = new MapNode(nodeRef, this.nodeService, true);
- this.browseBean.setupCommonBindingProperties(node);
-
- // add property resolvers to show path information
- node.addPropertyResolver("path", this.browseBean.resolverPath);
- node.addPropertyResolver("displayPath", this.browseBean.resolverDisplayPath);
-
- // add a property resolver to indicate whether the item has been completed or not
- node.addPropertyResolver("completed", this.completeResolver);
-
- this.resources.add(node);
- }
- }
- else
- {
- if (logger.isWarnEnabled())
- logger.warn("Found invalid object in database: id = " + nodeRef + ", type = " + type);
- }
- }
- }
-
- // commit the transaction
- tx.commit();
- }
- catch (Throwable err)
- {
- Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
- FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
- this.resources = Collections.emptyList();
- try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
- }
- }
- else if (logger.isDebugEnabled())
- {
- logger.debug("Failed to find workflow package for work item: " + this.workItem.id);
- }
-
- return this.resources;
- }
-
- /**
- * Sets the workflow service to use
- *
- * @param workflowService
- * WorkflowService instance
- */
- public void setWorkflowService(WorkflowService workflowService)
- {
- this.workflowService = workflowService;
- }
-
- // ------------------------------------------------------------------------------
- // Helper methods
-
-
- // ------------------------------------------------------------------------------
- // Inner classes
-
- /**
- * Property resolver to determine if the given node has been flagged as complete
- */
- protected class WorkItemCompleteResolver implements NodePropertyResolver
- {
- public Object get(Node node)
- {
- String result = Application.getMessage(FacesContext.getCurrentInstance(), "no");
-
- List completedItems = (List)workItem.properties.get(
- WorkflowModel.PROP_COMPLETED_ITEMS);
-
- if (completedItems != null && completedItems.size() > 0 &&
- completedItems.contains(node.getNodeRef()))
- {
- result = Application.getMessage(FacesContext.getCurrentInstance(), "yes");
- }
-
- return result;
- }
- }
-}
diff --git a/source/java/org/alfresco/web/bean/workflow/ReassignTaskDialog.java b/source/java/org/alfresco/web/bean/workflow/ReassignTaskDialog.java
new file mode 100644
index 0000000000..f543730687
--- /dev/null
+++ b/source/java/org/alfresco/web/bean/workflow/ReassignTaskDialog.java
@@ -0,0 +1,199 @@
+package org.alfresco.web.bean.workflow;
+
+import java.io.Serializable;
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ResourceBundle;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.model.SelectItem;
+import javax.transaction.UserTransaction;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.security.PersonService;
+import org.alfresco.service.cmr.workflow.WorkflowService;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.web.app.Application;
+import org.alfresco.web.bean.dialog.BaseDialogBean;
+import org.alfresco.web.bean.repository.Repository;
+import org.alfresco.web.ui.common.SortableSelectItem;
+import org.alfresco.web.ui.common.Utils;
+import org.alfresco.web.ui.common.component.UIGenericPicker;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Bean implementation for the "Reassign Task" dialog
+ *
+ * @author gavinc
+ */
+public class ReassignTaskDialog extends BaseDialogBean
+{
+ protected String taskId;
+
+ protected WorkflowService workflowService;
+ protected PersonService personService;
+
+ private static final Log logger = LogFactory.getLog(ReassignTaskDialog.class);
+
+ // ------------------------------------------------------------------------------
+ // Dialog implementation
+
+ @Override
+ public void init(Map parameters)
+ {
+ super.init(parameters);
+
+ this.taskId = this.parameters.get("task-id");
+ if (this.taskId == null || this.taskId.length() == 0)
+ {
+ throw new IllegalArgumentException("Reassign task dialog called without task id");
+ }
+ }
+
+ @Override
+ protected String finishImpl(FacesContext context, String outcome)
+ throws Exception
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Reassigning task with id: " + this.taskId);
+
+ UIComponent picker = context.getViewRoot().findComponent("dialog:dialog-body:user-picker");
+
+ if (picker != null && picker instanceof UIGenericPicker)
+ {
+ UIGenericPicker userPicker = (UIGenericPicker)picker;
+ String[] user = userPicker.getSelectedResults();
+ if (user != null && user.length > 0)
+ {
+ // create a map to hold the new owner property then update the task
+ String userName = user[0];
+ Map params = new HashMap(1);
+ params.put(ContentModel.PROP_OWNER, userName);
+ this.workflowService.updateTask(this.taskId, params, null, null);
+ }
+ else
+ {
+ if (logger.isWarnEnabled())
+ logger.warn("Failed to find selected user, reassign was unsuccessful");
+ }
+ }
+ else
+ {
+ if (logger.isWarnEnabled())
+ logger.warn("Failed to find user-picker component, reassign was unsuccessful");
+ }
+
+ if (logger.isDebugEnabled())
+ logger.debug("Reassigning task with id: " + this.taskId);
+
+ return outcome;
+ }
+
+ @Override
+ protected String getErrorMessageId()
+ {
+ return "error_reassign_task";
+ }
+
+ // ------------------------------------------------------------------------------
+ // Bean Getters and Setters
+
+ /**
+ * Property accessed by the Generic Picker component.
+ *
+ * @return the array of filter options to show in the users/groups picker
+ */
+ public SelectItem[] getFilters()
+ {
+ ResourceBundle bundle = Application.getBundle(FacesContext.getCurrentInstance());
+ return new SelectItem[] {new SelectItem("0", bundle.getString("users"))};
+ }
+
+ /**
+ * Query callback method executed by the Generic Picker component.
+ * This method is part of the contract to the Generic Picker, it is up to the backing bean
+ * to execute whatever query is appropriate and return the results.
+ *
+ * @param filterIndex Index of the filter drop-down selection
+ * @param contains Text from the contains textbox
+ *
+ * @return An array of SelectItem objects containing the results to display in the picker.
+ */
+ public SelectItem[] pickerCallback(int filterIndex, String contains)
+ {
+ FacesContext context = FacesContext.getCurrentInstance();
+
+ SelectItem[] items;
+
+ UserTransaction tx = null;
+ try
+ {
+ tx = Repository.getUserTransaction(context, true);
+ tx.begin();
+
+ // build xpath to match available User/Person objects
+ NodeRef peopleRef = personService.getPeopleContainer();
+ // NOTE: see SearcherComponentTest
+ String xpath = "*[like(@" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + "firstName, '%" + contains + "%', false)" +
+ " or " + "like(@" + NamespaceService.CONTENT_MODEL_PREFIX + ":" + "lastName, '%" + contains + "%', false)]";
+
+ List nodes = searchService.selectNodes(
+ peopleRef,
+ xpath,
+ null,
+ this.namespaceService,
+ false);
+
+ items = new SelectItem[nodes.size()];
+ for (int index=0; index workflows;
protected WorkflowService workflowService;
protected Node startTaskNode;
+ protected List resources;
+ protected List packageItemsToAdd;
+ protected UIRichList packageItemsRichList;
+ protected String[] itemsToAdd;
+ protected boolean isItemBeingAdded = false;
protected boolean nextButtonDisabled = false;
private static final Log logger = LogFactory.getLog(StartWorkflowWizard.class);
@@ -65,6 +78,43 @@ public class StartWorkflowWizard extends BaseWizardBean
}
this.startTaskNode = null;
+ this.resources = null;
+ this.itemsToAdd = null;
+ this.packageItemsToAdd = new ArrayList();
+ this.isItemBeingAdded = false;
+ if (this.packageItemsRichList != null)
+ {
+ this.packageItemsRichList.setValue(null);
+ this.packageItemsRichList = null;
+ }
+
+ // TODO: Does this need to be in a read-only transaction??
+
+ // add the item the workflow wizard was started on to the list of resources
+ String itemToWorkflowId = this.parameters.get("item-to-workflow");
+ if (itemToWorkflowId != null && itemToWorkflowId.length() > 0)
+ {
+ // create the node ref for the item and determine its type
+ NodeRef itemToWorkflow = new NodeRef(Repository.getStoreRef(), itemToWorkflowId);
+ QName type = this.nodeService.getType(itemToWorkflow);
+
+ if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT) ||
+ this.dictionaryService.isSubClass(type, ContentModel.TYPE_FILELINK))
+ {
+ this.packageItemsToAdd.add(itemToWorkflow.toString());
+ }
+ }
+ }
+
+ @Override
+ public void restored()
+ {
+ // reset the workflow package rich list so everything gets re-evaluated
+ if (this.packageItemsRichList != null)
+ {
+ this.packageItemsRichList.setValue(null);
+ this.packageItemsRichList = null;
+ }
}
@Override
@@ -77,26 +127,23 @@ public class StartWorkflowWizard extends BaseWizardBean
logger.debug("Starting workflow: " + this.selectedWorkflow);
// prepare the parameters from the current state of the property sheet
- Map params = WorkflowBean.prepareWorkItemParams(this.startTaskNode);
+ Map params = WorkflowBean.prepareTaskParams(this.startTaskNode);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Starting workflow with parameters: " + params);
// create a workflow package for the attached items and add them
- String itemToWorkflowId = this.parameters.get("item-to-workflow");
- if (itemToWorkflowId != null && itemToWorkflowId.length() > 0)
+ if (this.packageItemsToAdd.size() > 0)
{
- // create the node ref for the item and determine its type
- NodeRef itemToWorkflow = new NodeRef(Repository.getStoreRef(), itemToWorkflowId);
- QName type = this.nodeService.getType(itemToWorkflow);
+ NodeRef workflowPackage = this.workflowService.createPackage(null);
- NodeRef workflowPackage = null;
- if (this.dictionaryService.isSubClass(type, ContentModel.TYPE_CONTENT) ||
- this.dictionaryService.isSubClass(type, ContentModel.TYPE_FILELINK))
+ for (String addedItem : this.packageItemsToAdd)
{
- // create a workflow package and add the given item to workflow as a child
- workflowPackage = this.workflowService.createPackage(null);
- this.nodeService.addChild(workflowPackage, itemToWorkflow,
+ NodeRef addedNodeRef = new NodeRef(addedItem);
+ this.nodeService.addChild(workflowPackage, addedNodeRef,
ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
QName.createValidLocalName((String)this.nodeService.getProperty(
- itemToWorkflow, ContentModel.PROP_NAME))));
+ addedNodeRef, ContentModel.PROP_NAME))));
}
// add the workflow package to the parameter map
@@ -175,9 +222,131 @@ public class StartWorkflowWizard extends BaseWizardBean
return this.nextButtonDisabled;
}
+ // ------------------------------------------------------------------------------
+ // Event Handlers
+
+ /**
+ * Prepares the dialog to allow the user to add an item to the workflow package
+ *
+ * @param event The event
+ */
+ public void prepareForAdd(ActionEvent event)
+ {
+ this.isItemBeingAdded = true;
+ }
+
+ /**
+ * Cancels the adding of an item to the workflow package
+ *
+ * @param event The event
+ */
+ public void cancelAddPackageItems(ActionEvent event)
+ {
+ this.isItemBeingAdded = false;
+ }
+
+ /**
+ * Adds items to the workflow package
+ *
+ * @param event The event
+ */
+ public void addPackageItems(ActionEvent event)
+ {
+ if (this.itemsToAdd != null)
+ {
+ for (String item : this.itemsToAdd)
+ {
+ this.packageItemsToAdd.add(item);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Added item to the added list: " + item);
+ }
+
+ // reset the rich list so it re-renders
+ this.packageItemsRichList.setValue(null);
+ }
+
+ this.isItemBeingAdded = false;
+ this.itemsToAdd = null;
+ }
+
+ /**
+ * Removes an item from the workflow package
+ *
+ * @param event The event containing a reference to the item to remove
+ */
+ public void removePackageItem(ActionEvent event)
+ {
+ UIActionLink link = (UIActionLink)event.getComponent();
+ Map params = link.getParameterMap();
+ String nodeRef = new NodeRef(Repository.getStoreRef(), params.get("id")).toString();
+
+ if (this.packageItemsToAdd.contains(nodeRef))
+ {
+ // remove the item from the added list if it was added in this dialog session
+ this.packageItemsToAdd.remove(nodeRef);
+
+ if (logger.isDebugEnabled())
+ logger.debug("Removed item from the added list: " + nodeRef);
+ }
+
+ // reset the rich list so it re-renders
+ this.packageItemsRichList.setValue(null);
+ }
+
// ------------------------------------------------------------------------------
// Bean Getters and Setters
+ /**
+ * Returns a String array of NodeRef's that are being added to the workflow package
+ *
+ * @return String array of NodeRef's
+ */
+ public String[] getItemsToAdd()
+ {
+ return this.itemsToAdd;
+ }
+
+ /**
+ * Sets the NodeRef's to add as items to the workflow package
+ *
+ * @param itemsToAdd NodeRef's to add to the workflow package
+ */
+ public void setItemsToAdd(String[] itemsToAdd)
+ {
+ this.itemsToAdd = itemsToAdd;
+ }
+
+ /**
+ * Determines whether an item is currently being added to the workflow package
+ *
+ * @return true if an item is being added
+ */
+ public boolean isItemBeingAdded()
+ {
+ return this.isItemBeingAdded;
+ }
+
+ /**
+ * Sets the rich list being used for the workflow package items
+ *
+ * @param richList The rich list instance
+ */
+ public void setPackageItemsRichList(UIRichList richList)
+ {
+ this.packageItemsRichList = richList;
+ }
+
+ /**
+ * Returns the rich list being used for the workflow package items
+ *
+ * @return The rich list instance
+ */
+ public UIRichList getPackageItemsRichList()
+ {
+ return this.packageItemsRichList;
+ }
+
/**
* Returns the workflow selected by the user
*
@@ -317,6 +486,59 @@ public class StartWorkflowWizard extends BaseWizardBean
return availableWorkflows;
}
+ /**
+ * Returns a list of resources associated with this task
+ * i.e. the children of the workflow package
+ *
+ * @return The list of nodes
+ */
+ public List getResources()
+ {
+ this.resources = new ArrayList(4);
+
+ UserTransaction tx = null;
+ try
+ {
+ FacesContext context = FacesContext.getCurrentInstance();
+ tx = Repository.getUserTransaction(context, true);
+ tx.begin();
+
+ for (String newItem : this.packageItemsToAdd)
+ {
+ NodeRef nodeRef = new NodeRef(newItem);
+ if (this.nodeService.exists(nodeRef))
+ {
+ // create our Node representation
+ MapNode node = new MapNode(nodeRef, this.nodeService, true);
+ this.browseBean.setupCommonBindingProperties(node);
+
+ // add property resolvers to show path information
+ node.addPropertyResolver("path", this.browseBean.resolverPath);
+ node.addPropertyResolver("displayPath", this.browseBean.resolverDisplayPath);
+
+ this.resources.add(node);
+ }
+ else
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("Ignoring " + nodeRef + " as it has been removed from the repository");
+ }
+ }
+
+ // commit the transaction
+ tx.commit();
+ }
+ catch (Throwable err)
+ {
+ Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
+ FacesContext.getCurrentInstance(), Repository.ERROR_GENERIC), err.getMessage()), err);
+ this.resources = Collections.emptyList();
+ try { if (tx != null) {tx.rollback();} } catch (Exception tex) {}
+ }
+
+ return this.resources;
+ }
+
/**
* Sets the workflow service to use
*
diff --git a/source/java/org/alfresco/web/bean/workflow/ViewCompletedTaskDialog.java b/source/java/org/alfresco/web/bean/workflow/ViewCompletedTaskDialog.java
new file mode 100644
index 0000000000..b037ad74ce
--- /dev/null
+++ b/source/java/org/alfresco/web/bean/workflow/ViewCompletedTaskDialog.java
@@ -0,0 +1,48 @@
+package org.alfresco.web.bean.workflow;
+
+import java.util.List;
+
+import javax.faces.context.FacesContext;
+
+import org.alfresco.web.app.Application;
+import org.alfresco.web.config.DialogsConfigElement.DialogButtonConfig;
+
+/**
+ * Bean implementation for the "View Completed Task" dialog.
+ *
+ * @author gavinc
+ */
+public class ViewCompletedTaskDialog extends ManageTaskDialog
+{
+ // ------------------------------------------------------------------------------
+ // Dialog implementation
+
+ @Override
+ protected String finishImpl(FacesContext context, String outcome)
+ throws Exception
+ {
+ // nothing to do as the finish button is not shown and the dialog is read only
+
+ return outcome;
+ }
+
+ @Override
+ public String getCancelButtonLabel()
+ {
+ return Application.getMessage(FacesContext.getCurrentInstance(), "close");
+ }
+
+ @Override
+ public List getAdditionalButtons()
+ {
+ return null;
+ }
+
+ @Override
+ public String getTitle()
+ {
+ String titleStart = Application.getMessage(FacesContext.getCurrentInstance(), "view_completed_task_title");
+
+ return titleStart + ": " + this.task.title;
+ }
+}
diff --git a/source/java/org/alfresco/web/bean/workflow/WorkflowBean.java b/source/java/org/alfresco/web/bean/workflow/WorkflowBean.java
index 5368ca9be6..9800da87b5 100644
--- a/source/java/org/alfresco/web/bean/workflow/WorkflowBean.java
+++ b/source/java/org/alfresco/web/bean/workflow/WorkflowBean.java
@@ -39,8 +39,8 @@ public class WorkflowBean
{
protected NodeService nodeService;
protected WorkflowService workflowService;
- protected List workItems;
- protected List completedWorkItems;
+ protected List tasks;
+ protected List completedTasks;
private static final Log logger = LogFactory.getLog(WorkflowBean.class);
@@ -48,12 +48,12 @@ public class WorkflowBean
// Bean Getters and Setters
/**
- * Returns a list of nodes representing the to do work items the
+ * Returns a list of nodes representing the to do tasks the
* current user has.
*
- * @return List of to do work items
+ * @return List of to do tasks
*/
- public List getWorkItemsToDo()
+ public List getTasksToDo()
{
// get the current username
FacesContext context = FacesContext.getCurrentInstance();
@@ -71,14 +71,14 @@ public class WorkflowBean
userName, WorkflowTaskState.IN_PROGRESS);
// create a list of transient nodes to represent
- this.workItems = new ArrayList(tasks.size());
+ this.tasks = new ArrayList(tasks.size());
for (WorkflowTask task : tasks)
{
- Node node = createWorkItem(task);
- this.workItems.add(node);
+ Node node = createTask(task);
+ this.tasks.add(node);
if (logger.isDebugEnabled())
- logger.debug("Added to do work item: " + node);
+ logger.debug("Added to do task: " + node);
}
// commit the changes
@@ -88,19 +88,19 @@ public class WorkflowBean
{
// rollback the transaction
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
- Utils.addErrorMessage("Failed to get to do work items: " + e.toString(), e);
+ Utils.addErrorMessage("Failed to get to do tasks: " + e.toString(), e);
}
- return this.workItems;
+ return this.tasks;
}
/**
- * Returns a list of nodes representing the completed work items the
+ * Returns a list of nodes representing the completed tasks the
* current user has.
*
- * @return List of completed work items
+ * @return List of completed tasks
*/
- public List getWorkItemsCompleted()
+ public List getTasksCompleted()
{
// get the current username
FacesContext context = FacesContext.getCurrentInstance();
@@ -118,14 +118,14 @@ public class WorkflowBean
userName, WorkflowTaskState.COMPLETED);
// create a list of transient nodes to represent
- this.completedWorkItems = new ArrayList(tasks.size());
+ this.completedTasks = new ArrayList(tasks.size());
for (WorkflowTask task : tasks)
{
- Node node = createWorkItem(task);
- this.completedWorkItems.add(node);
+ Node node = createTask(task);
+ this.completedTasks.add(node);
if (logger.isDebugEnabled())
- logger.debug("Added completed work item: " + node);
+ logger.debug("Added completed task: " + node);
}
// commit the changes
@@ -135,10 +135,10 @@ public class WorkflowBean
{
// rollback the transaction
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
- Utils.addErrorMessage("Failed to get completed work items: " + e.toString(), e);
+ Utils.addErrorMessage("Failed to get completed tasks: " + e.toString(), e);
}
- return this.completedWorkItems;
+ return this.completedTasks;
}
/**
@@ -164,7 +164,7 @@ public class WorkflowBean
// ------------------------------------------------------------------------------
// Helper methods
- public static Map prepareWorkItemParams(Node node)
+ public static Map prepareTaskParams(Node node)
{
Map params = new HashMap();
@@ -199,9 +199,6 @@ public class WorkflowBean
params.put(assocQName, (Serializable)targets);
}
- if (logger.isDebugEnabled())
- logger.debug("Prepared parameters: " + params);
-
return params;
}
@@ -211,7 +208,7 @@ public class WorkflowBean
*
* @param task The task to create a representation of
*/
- protected TransientMapNode createWorkItem(WorkflowTask task)
+ protected TransientMapNode createTask(WorkflowTask task)
{
// get the type of the task
WorkflowTaskDefinition taskDef = task.definition;
diff --git a/source/java/org/alfresco/web/config/ClientConfigElement.java b/source/java/org/alfresco/web/config/ClientConfigElement.java
index 0f6a3e216e..b151b3b0fe 100644
--- a/source/java/org/alfresco/web/config/ClientConfigElement.java
+++ b/source/java/org/alfresco/web/config/ClientConfigElement.java
@@ -40,7 +40,7 @@ public class ClientConfigElement extends ConfigElementAdapter
private String editLinkType = "http";
private String homeSpacePermission = null;
private boolean ajaxEnabled = false;
- private String initialLocation = null;
+ private String initialLocation = "myalfresco";
/**
* Default Constructor
diff --git a/source/java/org/alfresco/web/config/DashboardsConfigElement.java b/source/java/org/alfresco/web/config/DashboardsConfigElement.java
index 83ed1a8039..d5e19db865 100644
--- a/source/java/org/alfresco/web/config/DashboardsConfigElement.java
+++ b/source/java/org/alfresco/web/config/DashboardsConfigElement.java
@@ -37,6 +37,7 @@ public class DashboardsConfigElement extends ConfigElementAdapter
private Map layoutDefs = new LinkedHashMap(4, 1.0f);
private Map dashletDefs = new LinkedHashMap(8, 1.0f);
+ private boolean allowGuestConfig = false;
/**
* Default constructor
@@ -77,9 +78,24 @@ public class DashboardsConfigElement extends ConfigElementAdapter
combinedElement.layoutDefs.putAll(this.layoutDefs);
combinedElement.layoutDefs.putAll(newElement.layoutDefs);
+ if (newElement.allowGuestConfig != combinedElement.allowGuestConfig)
+ {
+ combinedElement.allowGuestConfig = newElement.allowGuestConfig;
+ }
+
return combinedElement;
}
+ /*package*/ void setAllowGuestConfig(boolean allow)
+ {
+ this.allowGuestConfig = allow;
+ }
+
+ public boolean getAllowGuestConfig()
+ {
+ return this.allowGuestConfig;
+ }
+
/*package*/ void addLayoutDefinition(LayoutDefinition def)
{
this.layoutDefs.put(def.Id, def);
diff --git a/source/java/org/alfresco/web/config/DashboardsElementReader.java b/source/java/org/alfresco/web/config/DashboardsElementReader.java
index e532ec8486..e599251f71 100644
--- a/source/java/org/alfresco/web/config/DashboardsElementReader.java
+++ b/source/java/org/alfresco/web/config/DashboardsElementReader.java
@@ -37,6 +37,7 @@ public class DashboardsElementReader implements ConfigElementReader
public static final String ELEMENT_LAYOUT = "layout";
public static final String ELEMENT_DASHLETS = "dashlets";
public static final String ELEMENT_DASHLET = "dashlet";
+ public static final String ELEMENT_GUESTCONFIG = "allow-guest-config";
public static final String ATTR_ID = "id";
public static final String ATTR_COLUMNS = "columns";
public static final String ATTR_COLUMNLENGTH = "column-length";
@@ -85,6 +86,13 @@ public class DashboardsElementReader implements ConfigElementReader
configElement.addDashletDefinition(dashletDef);
}
}
+
+ Element guestConfigElement = element.element(ELEMENT_GUESTCONFIG);
+ if (guestConfigElement != null)
+ {
+ boolean allow = Boolean.parseBoolean(guestConfigElement.getTextTrim());
+ configElement.setAllowGuestConfig(allow);
+ }
}
return configElement;
diff --git a/source/java/org/alfresco/web/ui/repo/component/UIContentSelector.java b/source/java/org/alfresco/web/ui/repo/component/UIContentSelector.java
new file mode 100644
index 0000000000..2aeec8d7a4
--- /dev/null
+++ b/source/java/org/alfresco/web/ui/repo/component/UIContentSelector.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version
+ * 2.1 of the License, or (at your option) any later version.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.web.ui.repo.component;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.faces.component.UIInput;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.el.ValueBinding;
+
+import org.alfresco.model.ContentModel;
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.search.ResultSet;
+import org.alfresco.service.cmr.search.SearchService;
+import org.alfresco.service.namespace.NamespaceService;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.web.app.Application;
+import org.alfresco.web.bean.repository.Repository;
+import org.alfresco.web.ui.common.Utils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Component for selecting content from the repository
+ *
+ * @author gavinc
+ */
+public class UIContentSelector extends UIInput
+{
+ private final static Log logger = LogFactory.getLog(UIContentSelector.class);
+
+ private final static String ACTION_SEPARATOR = ";";
+ private final static String ACTION_SEARCH = "0";
+
+ private final static String FIELD_CONTAINS = "_contains";
+ private final static String FIELD_AVAILABLE = "_available";
+ private final static String MSG_SEARCH = "search";
+
+ protected String availableOptionsSize;
+ protected Boolean disabled;
+ private Boolean multiSelect;
+
+ /** List containing the currently available options */
+ protected List 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)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();
+ 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("");
+ }
+ }
+
+ /**
+ * 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("");
+
+ if (itemsPresent)
+ {
+ for (NodeRef item : this.availableOptions)
+ {
+ out.write("");
+ out.write(Repository.getDisplayPath(nodeService.getPath(item)));
+ out.write("/");
+ out.write(Repository.getNameForNode(nodeService, item));
+ out.write(" ");
+ }
+ }
+
+ out.write(" ");
+ }
+
+ /**
+ * Retrieves the available options for the current association
+ *
+ * @param context Faces Context
+ * @param contains The contains part of the query
+ */
+ protected void getAvailableOptions(FacesContext context, String contains)
+ {
+ // query for all content in the current repository
+ StringBuilder query = new StringBuilder("+TYPE:\"");
+ query.append(ContentModel.TYPE_CONTENT);
+ query.append("\"");
+
+ if (contains != null && contains.length() > 0)
+ {
+ String safeContains = Utils.remove(contains.trim(), "\"");
+ query.append(" AND +@");
+
+ String nameAttr = Repository.escapeQName(QName.createQName(
+ NamespaceService.CONTENT_MODEL_1_0_URI, "name"));
+ query.append(nameAttr);
+
+ query.append(":*" + safeContains + "*");
+ }
+
+ if (logger.isDebugEnabled())
+ logger.debug("Query: " + query.toString());
+
+ ResultSet results = null;
+ try
+ {
+ results = Repository.getServiceRegistry(context).getSearchService().query(
+ Repository.getStoreRef(), SearchService.LANGUAGE_LUCENE, query.toString());
+ this.availableOptions = results.getNodeRefs();
+ }
+ finally
+ {
+ if (results != null)
+ {
+ results.close();
+ }
+ }
+
+ if (logger.isDebugEnabled())
+ logger.debug("Found " + this.availableOptions.size() + " available options");
+ }
+
+ /**
+ * We use a hidden field per picker instance on the page.
+ *
+ * @return hidden field name
+ */
+ private String getHiddenFieldName()
+ {
+ return getClientId(getFacesContext());
+ }
+
+ /**
+ * Generate FORM submit JavaScript for the specified action
+ *
+ * @param context FacesContext
+ * @param action Action string
+ *
+ * @return FORM submit JavaScript
+ */
+ private String generateFormSubmit(FacesContext context, String action)
+ {
+ return Utils.generateFormSubmit(context, this, getHiddenFieldName(), action);
+ }
+}
diff --git a/source/java/org/alfresco/web/ui/repo/component/UIWorkflowSummary.java b/source/java/org/alfresco/web/ui/repo/component/UIWorkflowSummary.java
new file mode 100644
index 0000000000..40676f0844
--- /dev/null
+++ b/source/java/org/alfresco/web/ui/repo/component/UIWorkflowSummary.java
@@ -0,0 +1,163 @@
+package org.alfresco.web.ui.repo.component;
+
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+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.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.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);
+ SimpleDateFormat format = new SimpleDateFormat(bundle.getString("date_pattern"));
+
+ // output surrounding table and style if necessary
+ out.write("");
+
+ // output the title and description
+ out.write("");
+ out.write(bundle.getString("title"));
+ out.write(": ");
+ out.write(wi.definition.title);
+ out.write(" ");
+ out.write(bundle.getString("description"));
+ out.write(": ");
+ out.write(wi.definition.description);
+ out.write(" ");
+ out.write(bundle.getString("initiated_by"));
+ out.write(": ");
+ if (wi.initiator != null)
+ {
+ NodeService nodeService = Repository.getServiceRegistry(
+ context).getNodeService();
+ String userName = (String)nodeService.getProperty(
+ wi.initiator, ContentModel.PROP_USERNAME);
+ out.write(userName);
+ }
+ out.write(" ");
+ out.write(bundle.getString("start_date"));
+ out.write(": ");
+ if (wi.startDate != null)
+ {
+ out.write(format.format(wi.startDate));
+ }
+ out.write(" ");
+ out.write(bundle.getString("due_date"));
+ out.write(": ");
+ if (wi.endDate != null)
+ {
+ out.write(format.format(wi.endDate));
+ }
+ out.write("
");
+ }
+ }
+
+ @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;
+ }
+}
diff --git a/source/java/org/alfresco/web/ui/repo/tag/ContentSelectorTag.java b/source/java/org/alfresco/web/ui/repo/tag/ContentSelectorTag.java
new file mode 100644
index 0000000000..c40549baa3
--- /dev/null
+++ b/source/java/org/alfresco/web/ui/repo/tag/ContentSelectorTag.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.web.ui.repo.tag;
+
+import javax.faces.component.UIComponent;
+
+import org.alfresco.web.ui.common.tag.HtmlComponentTag;
+
+/**
+ * Tag class to allow the content selector component to be added to a JSP page
+ *
+ * @author gavinc
+ */
+public class ContentSelectorTag extends HtmlComponentTag
+{
+ private String availableOptionsSize;
+ private String disabled;
+ private String value;
+ private String multiSelect;
+
+ /**
+ * @see javax.faces.webapp.UIComponentTag#getComponentType()
+ */
+ public String getComponentType()
+ {
+ return "org.alfresco.faces.ContentSelector";
+ }
+
+ /**
+ * @see javax.faces.webapp.UIComponentTag#getRendererType()
+ */
+ public String getRendererType()
+ {
+ return null;
+ }
+
+ /**
+ * @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
+ */
+ protected void setProperties(UIComponent component)
+ {
+ super.setProperties(component);
+
+ setStringStaticProperty(component, "availableOptionsSize", this.availableOptionsSize);
+ setStringProperty(component, "value", this.value);
+ setBooleanProperty(component, "disabled", this.disabled);
+ setBooleanProperty(component, "multiSelect", this.multiSelect);
+ }
+
+ /**
+ * @param value The value to set.
+ */
+ public void setValue(String value)
+ {
+ this.value = value;
+ }
+
+ /**
+ * @param availableOptionsSize Sets the size of the available options size when
+ * multiple items can be selected
+ */
+ public void setAvailableOptionsSize(String availableOptionsSize)
+ {
+ this.availableOptionsSize = availableOptionsSize;
+ }
+
+ /**
+ * Set the multiSelect
+ *
+ * @param mutliSelect the multiSelect
+ */
+ public void setMultiSelect(String multiSelect)
+ {
+ this.multiSelect = multiSelect;
+ }
+
+ /**
+ * Sets whether the component should be rendered in a disabled state
+ *
+ * @param disabled true to render the component in a disabled state
+ */
+ public void setDisabled(String disabled)
+ {
+ this.disabled = disabled;
+ }
+
+ /**
+ * @see javax.faces.webapp.UIComponentTag#release()
+ */
+ public void release()
+ {
+ this.availableOptionsSize = null;
+ this.disabled = null;
+ this.value = null;
+ this.multiSelect = null;
+
+ super.release();
+ }
+}
diff --git a/source/java/org/alfresco/web/ui/repo/tag/WorkflowSummaryTag.java b/source/java/org/alfresco/web/ui/repo/tag/WorkflowSummaryTag.java
new file mode 100644
index 0000000000..b5b159e9fb
--- /dev/null
+++ b/source/java/org/alfresco/web/ui/repo/tag/WorkflowSummaryTag.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.web.ui.repo.tag;
+
+import javax.faces.component.UIComponent;
+
+import org.alfresco.web.ui.common.tag.HtmlComponentTag;
+
+/**
+ * Tag that allows the workflow summary component to be placed on a JSP page
+ *
+ * @author gavinc
+ */
+public class WorkflowSummaryTag extends HtmlComponentTag
+{
+ /**
+ * @see javax.faces.webapp.UIComponentTag#getComponentType()
+ */
+ public String getComponentType()
+ {
+ return "org.alfresco.faces.WorkflowSummary";
+ }
+
+ /**
+ * @see javax.faces.webapp.UIComponentTag#getRendererType()
+ */
+ public String getRendererType()
+ {
+ return null;
+ }
+
+ /**
+ * @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent)
+ */
+ protected void setProperties(UIComponent component)
+ {
+ super.setProperties(component);
+
+ setStringProperty(component, "value", this.value);
+ }
+
+ /**
+ * @see org.alfresco.web.ui.common.tag.HtmlComponentTag#release()
+ */
+ public void release()
+ {
+ super.release();
+ this.value = null;
+ }
+
+ /**
+ * Set the value (binding to the list of user/group data)
+ *
+ * @param value the value
+ */
+ public void setValue(String value)
+ {
+ this.value = value;
+ }
+
+ /** the value (binding to the workflow instance) */
+ private String value;
+}
diff --git a/source/java/org/alfresco/web/ui/repo/tag/property/BaseAssociationEditorTag.java b/source/java/org/alfresco/web/ui/repo/tag/property/BaseAssociationEditorTag.java
index 276852ebfb..2a1382f56d 100644
--- a/source/java/org/alfresco/web/ui/repo/tag/property/BaseAssociationEditorTag.java
+++ b/source/java/org/alfresco/web/ui/repo/tag/property/BaseAssociationEditorTag.java
@@ -34,6 +34,7 @@ public abstract class BaseAssociationEditorTag extends BaseComponentTag
private String selectedItemsMsg;
private String noSelectedItemsMsg;
private String disabled;
+ private String value;
/**
* @see javax.faces.webapp.UIComponentTag#getRendererType()
@@ -56,9 +57,18 @@ public abstract class BaseAssociationEditorTag extends BaseComponentTag
setStringProperty(component, "selectItemsMsg", this.selectItemsMsg);
setStringProperty(component, "selectedItemsMsg", this.selectedItemsMsg);
setStringProperty(component, "noSelectedItemsMsg", this.noSelectedItemsMsg);
+ setStringProperty(component, "value", this.value);
setBooleanProperty(component, "disabled", this.disabled);
}
+ /**
+ * @param value The value to set.
+ */
+ public void setValue(String value)
+ {
+ this.value = value;
+ }
+
/**
* Sets the association name
*
@@ -140,6 +150,7 @@ public abstract class BaseAssociationEditorTag extends BaseComponentTag
this.selectedItemsMsg = null;
this.noSelectedItemsMsg = null;
this.disabled = null;
+ this.value = null;
super.release();
}
diff --git a/source/web/WEB-INF/faces-config-app.xml b/source/web/WEB-INF/faces-config-app.xml
index 3637d56faa..ea4a942c45 100644
--- a/source/web/WEB-INF/faces-config-app.xml
+++ b/source/web/WEB-INF/faces-config-app.xml
@@ -6,7 +6,7 @@
org.alfresco.web.app.AlfrescoNavigationHandler
- org.springframework.web.jsf.DelegatingVariableResolver
+ org.alfresco.web.app.AlfrescoVariableResolver
en
diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml
index fb26e4ff66..8aa2677f2a 100644
--- a/source/web/WEB-INF/faces-config-beans.xml
+++ b/source/web/WEB-INF/faces-config-beans.xml
@@ -31,6 +31,10 @@
browseBean
#{BrowseBean}
+
+ userPreferencesBean
+ #{UserPreferencesBean}
+
@@ -60,6 +64,10 @@
ruleService
#{RuleService}
+
+ userPreferencesBean
+ #{UserPreferencesBean}
+
@@ -583,6 +591,56 @@
+
+
+ The bean that backs up the View Content Properties Dialog
+
+ ViewContentPropertiesDialog
+ org.alfresco.web.bean.content.ViewContentPropertiesDialog
+ session
+
+ nodeService
+ #{NodeService}
+
+
+ fileFolderService
+ #{FileFolderService}
+
+
+ dictionaryService
+ #{DictionaryService}
+
+
+ browseBean
+ #{BrowseBean}
+
+
+
+
+
+ The bean that backs up the Set Content Properties Dialog
+
+ SetContentPropertiesDialog
+ org.alfresco.web.bean.content.SetContentPropertiesDialog
+ session
+
+ nodeService
+ #{NodeService}
+
+
+ fileFolderService
+ #{FileFolderService}
+
+
+ dictionaryService
+ #{DictionaryService}
+
+
+ browseBean
+ #{BrowseBean}
+
+
+
The bean that backs up the Edit Content Properties Dialog
@@ -1386,10 +1444,6 @@
fileFolderService
#{FileFolderService}
-
- searchService
- #{SearchService}
-
navigator
#{NavigationBean}
@@ -1551,8 +1605,8 @@
#{ContentService}
- dictionaryService
- #{DictionaryService}
+ namespaceService
+ #{NamespaceService}
@@ -1657,10 +1711,47 @@
browseBean
#{BrowseBean}
+
+ dictionaryService
+ #{DictionaryService}
+
namespaceService
#{NamespaceService}
+
+
+
+
+ The bean that backs up the Delete Post Dialog
+
+ DeletePostDialog
+ org.alfresco.web.bean.forums.DeletePostDialog
+ session
+
+ nodeService
+ #{NodeService}
+
+
+ fileFolderService
+ #{FileFolderService}
+
+
+ searchService
+ #{SearchService}
+
+
+ navigator
+ #{NavigationBean}
+
+
+ browseBean
+ #{BrowseBean}
+
+
+ dictionaryService
+ #{DictionaryService}
+
namespaceService
#{NamespaceService}
@@ -1765,10 +1856,51 @@
- The bean that backs up the Manage WorkItem Dialog
+ The bean that backs up the Manage Task Dialog
- ManageWorkItemDialog
- org.alfresco.web.bean.workflow.ManageWorkItemDialog
+ ManageTaskDialog
+ org.alfresco.web.bean.workflow.ManageTaskDialog
+ session
+
+ nodeService
+ #{NodeService}
+
+
+ fileFolderService
+ #{FileFolderService}
+
+
+ searchService
+ #{SearchService}
+
+
+ navigator
+ #{NavigationBean}
+
+
+ browseBean
+ #{BrowseBean}
+
+
+ dictionaryService
+ #{DictionaryService}
+
+
+ namespaceService
+ #{NamespaceService}
+
+
+ workflowService
+ #{WorkflowService}
+
+
+
+
+
+ The bean that backs up the View Completed Task Dialog
+
+ ViewCompletedTaskDialog
+ org.alfresco.web.bean.workflow.ViewCompletedTaskDialog
session
nodeService
@@ -1829,8 +1961,8 @@
#{BrowseBean}
- namespaceService
- #{NamespaceService}
+ dictionaryService
+ #{DictionaryService}
namespaceService
@@ -1885,10 +2017,10 @@
- The bean that backs up the Reassign Work Item Dialog
+ The bean that backs up the Reassign Task Dialog
- ReassignWorkItemDialog
- org.alfresco.web.bean.workflow.ReassignWorkItemDialog
+ ReassignTaskDialog
+ org.alfresco.web.bean.workflow.ReassignTaskDialog
session
nodeService
@@ -1976,29 +2108,27 @@
- Bean that manages the Dashboard framework
- DashboardManager
- org.alfresco.web.bean.dashboard.DashboardManager
- session
-
-
-
- The bean that backs up the Dashboard Config Wizard
+ The bean that backs up the Getting Started Dashlet page
- DashboardWizard
- org.alfresco.web.bean.dashboard.DashboardWizard
+ GettingStartedBean
+ org.alfresco.web.bean.dashboard.GettingStartedBean
session
- nodeService
- #{NodeService}
-
-
- dashboardManager
- #{DashboardManager}
+ navigationBean
+ #{NavigationBean}
+
+
+ The bean that backs up the User Preferences page
+
+ UserPreferencesBean
+ org.alfresco.web.bean.UserPreferencesBean
+ session
+
+
@@ -2143,18 +2273,45 @@
SeparatorGenerator
org.alfresco.web.bean.generator.SeparatorGenerator
request
-
-
-
-
- Bean that generates a header separator component
-
- HeaderSeparatorGenerator
- org.alfresco.web.bean.generator.HeaderSeparatorGenerator
- request
+
+
+ Bean that generates a label separator component
+
+ LabelSeparatorGenerator
+ org.alfresco.web.bean.generator.LabelSeparatorGenerator
+ request
+
+
+
+ Bean that generates a label separator component rendered as a heading
+
+ HeaderSeparatorGenerator
+ org.alfresco.web.bean.generator.LabelSeparatorGenerator
+ request
+
+ styleClass
+ wizardSectionHeading mainSubTitle
+
+
+
+
+
@@ -2174,32 +2331,4 @@
-
-
-
-
- Bean that returns information on a node
-
- NodeInfoBean
- org.alfresco.web.bean.ajax.NodeInfoBean
- request
-
- nodeService
- #{NodeService}
-
-
- contentService
- #{ContentService}
-
-
-
-
-
- Bean that returns information on a node
-
- XFormsBean
- org.alfresco.web.bean.ajax.XFormsBean
- session
-
-
diff --git a/source/web/WEB-INF/faces-config-navigation.xml b/source/web/WEB-INF/faces-config-navigation.xml
index 44da3c35b6..60e54eee7a 100644
--- a/source/web/WEB-INF/faces-config-navigation.xml
+++ b/source/web/WEB-INF/faces-config-navigation.xml
@@ -57,6 +57,10 @@
dashboard
/jsp/browse/dashboard.jsp
+
+ addContent
+ /jsp/content/add-content-dialog.jsp
+
@@ -878,9 +882,10 @@
-
/jsp/dialog/container.jsp
+
+
forumsDeleted
/jsp/forums/forums.jsp
@@ -893,6 +898,45 @@
topicDeleted
/jsp/forums/forum.jsp
+
+
+
+
+ checkoutFile
+ /jsp/dialog/checkout-file.jsp
+
+
+ checkinFile
+ /jsp/dialog/checkin-file.jsp
+
+
+ undoCheckoutFile
+ /jsp/dialog/undocheckout-file.jsp
+
+
+ updateFile
+ /jsp/dialog/update-file.jsp
+
+
+ editFile
+ /jsp/dialog/edit-file.jsp
+
+
+ editHtmlInline
+ /jsp/dialog/edit-html-inline.jsp
+
+
+ editTextInline
+ /jsp/dialog/edit-text-inline.jsp
+
+
+ itemDetails
+ /jsp/trashcan/item-details.jsp
+
+
+ recoveryReport
+ /jsp/trashcan/recovery-report.jsp
+
diff --git a/source/web/WEB-INF/faces-config-repo.xml b/source/web/WEB-INF/faces-config-repo.xml
index 9b779c54f9..72eefca71b 100644
--- a/source/web/WEB-INF/faces-config-repo.xml
+++ b/source/web/WEB-INF/faces-config-repo.xml
@@ -54,6 +54,11 @@
org.alfresco.web.ui.repo.component.UISpaceSelector
+
+ org.alfresco.faces.ContentSelector
+ org.alfresco.web.ui.repo.component.UIContentSelector
+
+
org.alfresco.faces.CategorySelector
org.alfresco.web.ui.repo.component.UICategorySelector
@@ -144,6 +149,10 @@
org.alfresco.web.ui.repo.component.UIUserGroupPicker
+
+ org.alfresco.faces.WorkflowSummary
+ org.alfresco.web.ui.repo.component.UIWorkflowSummary
+
diff --git a/source/web/WEB-INF/repo.tld b/source/web/WEB-INF/repo.tld
index 55b9930f2e..ea920aeef3 100644
--- a/source/web/WEB-INF/repo.tld
+++ b/source/web/WEB-INF/repo.tld
@@ -209,11 +209,17 @@
associationEditor
- org.alfresco.web.ui.repo.tag.AssociationEditorTag
+ org.alfresco.web.ui.repo.tag.property.AssociationEditorTag
JSP
- assocationName
+ value
+ true
+ true
+
+
+
+ associationName
true
true
@@ -329,11 +335,17 @@
childAssociationEditor
- org.alfresco.web.ui.repo.tag.ChildAssociationEditorTag
+ org.alfresco.web.ui.repo.tag.property.ChildAssociationEditorTag
JSP
- assocationName
+ value
+ true
+ true
+
+
+
+ associationName
true
true
@@ -721,6 +733,60 @@
+
+ contentSelector
+ org.alfresco.web.ui.repo.tag.ContentSelectorTag
+ JSP
+
+
+ value
+ true
+ true
+
+
+
+ availableOptionsSize
+ false
+ true
+
+
+
+ multiSelect
+ false
+ true
+
+
+
+ id
+ false
+ true
+
+
+
+ binding
+ false
+ true
+
+
+
+ rendered
+ false
+ true
+
+
+
+ style
+ false
+ true
+
+
+
+ styleClass
+ false
+ true
+
+
+
categorySelector
org.alfresco.web.ui.repo.tag.CategorySelectorTag
@@ -1614,4 +1680,50 @@
+
+ workflowSummary
+ org.alfresco.web.ui.repo.tag.WorkflowSummaryTag
+ JSP
+
+
+ Shows summary information of a workflow instance.
+
+
+
+ id
+ false
+ true
+
+
+
+ value
+ true
+ true
+
+
+
+ binding
+ false
+ true
+
+
+
+ rendered
+ false
+ true
+
+
+
+ style
+ false
+ true
+
+
+
+ styleClass
+ false
+ true
+
+
+
diff --git a/source/web/WEB-INF/web.xml b/source/web/WEB-INF/web.xml
index 6ae45b32a1..aeabc86ba8 100644
--- a/source/web/WEB-INF/web.xml
+++ b/source/web/WEB-INF/web.xml
@@ -94,24 +94,14 @@
+
-
- LogFilter
- org.jbpm.webapp.filter.LogFilter
-
JbpmContextFilter
org.jbpm.webapp.filter.JbpmContextFilter
-
-
@@ -138,31 +128,14 @@
+
-
- LogFilter
- /faces/jbpm/*
-
JbpmContextFilter
/faces/jbpm/*
-
- JbpmContextFilter
- /processimage
-
-
- JbpmContextFilter
- /faces/jsp/dashboards/*
-
-
@@ -241,30 +214,6 @@
JBPMDeployProcessServlet
org.alfresco.web.app.servlet.JBPMDeployProcessServlet
-
-
-
-
-
-
-
-
-
-
-
- ProcessImageServlet
- org.jbpm.webapp.servlet.ProcessImageServlet
-
-
-
-
-
Faces Servlet
@@ -316,28 +265,6 @@
/jbpm/deployprocess
-
-
-
-
-
-
-
-
-
- ProcessImageServlet
- /processimage
-
-
-
-
-
-
60
diff --git a/source/web/css/main.css b/source/web/css/main.css
index dc8bd137bd..9e3053357c 100644
--- a/source/web/css/main.css
+++ b/source/web/css/main.css
@@ -528,3 +528,14 @@ a.topToolbarLinkHighlight, a.topToolbarLinkHighlight:link, a.topToolbarLinkHighl
border-style: solid;
border-color: #AAAAAA;
}
+
+.workflowSummary
+{
+ margin-left: 6px;
+}
+
+.workflowSummary td
+{
+ padding-right: 9px;
+ padding-top: 4px;
+}
diff --git a/source/web/images/filetypes/tif.gif b/source/web/images/filetypes/tif.gif
new file mode 100644
index 0000000000..a19a44c3f9
Binary files /dev/null and b/source/web/images/filetypes/tif.gif differ
diff --git a/source/web/images/filetypes/tiff.gif b/source/web/images/filetypes/tiff.gif
new file mode 100644
index 0000000000..a19a44c3f9
Binary files /dev/null and b/source/web/images/filetypes/tiff.gif differ
diff --git a/source/web/images/filetypes32/tif.gif b/source/web/images/filetypes32/tif.gif
new file mode 100644
index 0000000000..1ca54b78ec
Binary files /dev/null and b/source/web/images/filetypes32/tif.gif differ
diff --git a/source/web/images/filetypes32/tiff.gif b/source/web/images/filetypes32/tiff.gif
new file mode 100644
index 0000000000..1ca54b78ec
Binary files /dev/null and b/source/web/images/filetypes32/tiff.gif differ
diff --git a/source/web/images/icons/completed_workflow_task.gif b/source/web/images/icons/completed_workflow_task.gif
new file mode 100644
index 0000000000..65970ff789
Binary files /dev/null and b/source/web/images/icons/completed_workflow_task.gif differ
diff --git a/source/web/images/icons/completed_workflow_task_large.gif b/source/web/images/icons/completed_workflow_task_large.gif
new file mode 100644
index 0000000000..d3014a8d8c
Binary files /dev/null and b/source/web/images/icons/completed_workflow_task_large.gif differ
diff --git a/source/web/images/icons/gettingstarted_browse.gif b/source/web/images/icons/gettingstarted_browse.gif
new file mode 100644
index 0000000000..f1b8f7c6cd
Binary files /dev/null and b/source/web/images/icons/gettingstarted_browse.gif differ
diff --git a/source/web/images/icons/gettingstarted_demonstration.gif b/source/web/images/icons/gettingstarted_demonstration.gif
new file mode 100644
index 0000000000..5a09ca0072
Binary files /dev/null and b/source/web/images/icons/gettingstarted_demonstration.gif differ
diff --git a/source/web/images/icons/gettingstarted_featuretour.gif b/source/web/images/icons/gettingstarted_featuretour.gif
new file mode 100644
index 0000000000..5a09ca0072
Binary files /dev/null and b/source/web/images/icons/gettingstarted_featuretour.gif differ
diff --git a/source/web/images/icons/gettingstarted_onlinehelp.gif b/source/web/images/icons/gettingstarted_onlinehelp.gif
new file mode 100644
index 0000000000..79fe49e316
Binary files /dev/null and b/source/web/images/icons/gettingstarted_onlinehelp.gif differ
diff --git a/source/web/images/icons/manage_workflow_task_large.gif b/source/web/images/icons/manage_workflow_task_large.gif
new file mode 100644
index 0000000000..442c772fb6
Binary files /dev/null and b/source/web/images/icons/manage_workflow_task_large.gif differ
diff --git a/source/web/images/icons/reassign_task.gif b/source/web/images/icons/reassign_task.gif
new file mode 100644
index 0000000000..95f2962dc8
Binary files /dev/null and b/source/web/images/icons/reassign_task.gif differ
diff --git a/source/web/images/icons/reassign_workflow_task_large.gif b/source/web/images/icons/reassign_workflow_task_large.gif
new file mode 100644
index 0000000000..09c30fb95e
Binary files /dev/null and b/source/web/images/icons/reassign_workflow_task_large.gif differ
diff --git a/source/web/images/icons/workflow_task.gif b/source/web/images/icons/workflow_task.gif
new file mode 100644
index 0000000000..6cee9ec039
Binary files /dev/null and b/source/web/images/icons/workflow_task.gif differ
diff --git a/source/web/images/icons/workflow_task_large.gif b/source/web/images/icons/workflow_task_large.gif
new file mode 100644
index 0000000000..bf5bd91084
Binary files /dev/null and b/source/web/images/icons/workflow_task_large.gif differ
diff --git a/source/web/index.jsp b/source/web/index.jsp
index 8916281a16..699051315b 100644
--- a/source/web/index.jsp
+++ b/source/web/index.jsp
@@ -1,21 +1,51 @@
<%--
- Copyright (C) 2005 Alfresco, Inc.
-
- Licensed under the Mozilla Public License version 1.1
- with a permitted attribution clause. You may obtain a
- copy of the License at
-
- http://www.alfresco.org/legal/license.txt
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- either express or implied. See the License for the specific
- language governing permissions and limitations under the
- License.
---%>
-
-<%-- redirect to the web application's start page --%>
-<%
-response.sendRedirect(request.getContextPath() + "/faces/jsp/browse/browse.jsp");
-%>
\ No newline at end of file
+Copyright (C) 2005 Alfresco, Inc.
+
+Licensed under the Mozilla Public License version 1.1
+with a permitted attribution clause. You may obtain a
+copy of the License at
+
+http://www.alfresco.org/legal/license.txt
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+either express or implied. See the License for the specific
+language governing permissions and limitations under the
+License.
+--%>
+
+<%@ page import="org.springframework.web.context.support.WebApplicationContextUtils" %>
+<%@ page import="org.alfresco.config.ConfigService" %>
+<%@ page import="org.alfresco.web.app.servlet.AuthenticationHelper" %>
+<%@ page import="org.alfresco.web.bean.NavigationBean" %>
+<%@ page import="org.alfresco.web.bean.repository.User" %>
+<%@ page import="org.alfresco.web.bean.repository.PreferencesService" %>
+<%@ page import="org.alfresco.web.config.ClientConfigElement" %>
+
+<%-- redirect to the web application's appropriate start page --%>
+<%
+// get the start location as configured by the web-client config
+ConfigService configService = (ConfigService)WebApplicationContextUtils.getRequiredWebApplicationContext(session.getServletContext()).getBean("webClientConfigService");
+ClientConfigElement configElement = (ClientConfigElement)configService.getGlobalConfig().getConfigElement("client");
+String location = configElement.getInitialLocation();
+
+// override with the users preference if they have one
+User user = (User)session.getAttribute(AuthenticationHelper.AUTHENTICATION_USER);
+if (user != null)
+{
+ String preference = (String)PreferencesService.getPreferences(user).getValue("start-location");
+ if (preference != null)
+ {
+ location = preference;
+ }
+}
+if (NavigationBean.LOCATION_MYALFRESCO.equals(location))
+{
+ response.sendRedirect(request.getContextPath() + "/faces/jsp/dashboards/container.jsp");
+}
+else
+{
+ response.sendRedirect(request.getContextPath() + "/faces/jsp/browse/browse.jsp");
+}
+%>
diff --git a/source/web/jsp/admin/admin-console.jsp b/source/web/jsp/admin/admin-console.jsp
index 1afb36f029..ae88d603fc 100644
--- a/source/web/jsp/admin/admin-console.jsp
+++ b/source/web/jsp/admin/admin-console.jsp
@@ -126,6 +126,12 @@
+
+
+
+
+
+
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "ballongrey"); %>
diff --git a/source/web/jsp/content/view-content-properties.jsp b/source/web/jsp/content/view-content-properties.jsp
new file mode 100644
index 0000000000..95e5c607b2
--- /dev/null
+++ b/source/web/jsp/content/view-content-properties.jsp
@@ -0,0 +1,24 @@
+<%--
+ Copyright (C) 2005 Alfresco, Inc.
+
+ Licensed under the Mozilla Public License version 1.1
+ with a permitted attribution clause. You may obtain a
+ copy of the License at
+
+ http://www.alfresco.org/legal/license.txt
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ either express or implied. See the License for the specific
+ language governing permissions and limitations under the
+ License.
+--%>
+<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
+<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
+<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
+<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
+
+
\ No newline at end of file
diff --git a/source/web/jsp/dashboards/container-light.jsp b/source/web/jsp/dashboards/container-light.jsp
new file mode 100644
index 0000000000..d3a97f35a6
--- /dev/null
+++ b/source/web/jsp/dashboards/container-light.jsp
@@ -0,0 +1,54 @@
+<%--
+ Copyright (C) 2005 Alfresco, Inc.
+
+ Licensed under the Mozilla Public License version 1.1
+ with a permitted attribution clause. You may obtain a
+ copy of the License at
+
+ http://www.alfresco.org/legal/license.txt
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ either express or implied. See the License for the specific
+ language governing permissions and limitations under the
+ License.
+--%>
+<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
+<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
+<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
+
+<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %>
+<%@ page isELIgnored="false" %>
+<%@ page import="org.alfresco.web.app.Application" %>
+<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %>
+
+
+
+
+
+ <%-- load a bundle of properties with I18N strings --%>
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/web/jsp/dashboards/container.jsp b/source/web/jsp/dashboards/container.jsp
index adc53b82af..8a1e21eef4 100644
--- a/source/web/jsp/dashboards/container.jsp
+++ b/source/web/jsp/dashboards/container.jsp
@@ -74,7 +74,7 @@
-
+
diff --git a/source/web/jsp/dashboards/dashlets/checkedout-docs.jsp b/source/web/jsp/dashboards/dashlets/checkedout-docs.jsp
new file mode 100644
index 0000000000..ea73ce7215
--- /dev/null
+++ b/source/web/jsp/dashboards/dashlets/checkedout-docs.jsp
@@ -0,0 +1,20 @@
+<%--
+ Copyright (C) 2006 Alfresco, Inc.
+
+ Licensed under the Mozilla Public License version 1.1
+ with a permitted attribution clause. You may obtain a
+ copy of the License at
+
+ http://www.alfresco.org/legal/license.txt
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ either express or implied. See the License for the specific
+ language governing permissions and limitations under the
+ License.
+--%>
+<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
+
+<%-- Note that this template is loaded from the classpath --%>
+
diff --git a/source/web/jsp/dashboards/dashlets/getting-started.jsp b/source/web/jsp/dashboards/dashlets/getting-started.jsp
index f7dd0ffa14..c8b4eee5fc 100644
--- a/source/web/jsp/dashboards/dashlets/getting-started.jsp
+++ b/source/web/jsp/dashboards/dashlets/getting-started.jsp
@@ -24,33 +24,93 @@
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "yellow", "#ffffcc"); %>
-
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "yellow"); %>
diff --git a/source/web/jsp/dashboards/dashlets/my-docs.jsp b/source/web/jsp/dashboards/dashlets/my-docs.jsp
index e79ba1c20a..2908add03f 100644
--- a/source/web/jsp/dashboards/dashlets/my-docs.jsp
+++ b/source/web/jsp/dashboards/dashlets/my-docs.jsp
@@ -14,9 +14,7 @@
language governing permissions and limitations under the
License.
--%>
-<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
-<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
-<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
+<%-- Note that this template is loaded from the classpath --%>
diff --git a/source/web/jsp/dashboards/dashlets/my-images.jsp b/source/web/jsp/dashboards/dashlets/my-images.jsp
new file mode 100644
index 0000000000..a904b9d2b9
--- /dev/null
+++ b/source/web/jsp/dashboards/dashlets/my-images.jsp
@@ -0,0 +1,20 @@
+<%--
+ Copyright (C) 2006 Alfresco, Inc.
+
+ Licensed under the Mozilla Public License version 1.1
+ with a permitted attribution clause. You may obtain a
+ copy of the License at
+
+ http://www.alfresco.org/legal/license.txt
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ either express or implied. See the License for the specific
+ language governing permissions and limitations under the
+ License.
+--%>
+<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
+
+<%-- Note that this template is loaded from the classpath --%>
+
diff --git a/source/web/jsp/dialog/about.jsp b/source/web/jsp/dialog/about.jsp
index dfcf4bb32a..0fb6309acf 100644
--- a/source/web/jsp/dialog/about.jsp
+++ b/source/web/jsp/dialog/about.jsp
@@ -100,9 +100,9 @@
diff --git a/source/web/jsp/dialog/checkout-file.jsp b/source/web/jsp/dialog/checkout-file.jsp
index c1ac8ac394..7a4284cb69 100644
--- a/source/web/jsp/dialog/checkout-file.jsp
+++ b/source/web/jsp/dialog/checkout-file.jsp
@@ -121,7 +121,7 @@
-
+
diff --git a/source/web/jsp/dialog/edit-html-inline.jsp b/source/web/jsp/dialog/edit-html-inline.jsp
index 4430c68a08..a205d7512e 100644
--- a/source/web/jsp/dialog/edit-html-inline.jsp
+++ b/source/web/jsp/dialog/edit-html-inline.jsp
@@ -153,7 +153,7 @@
-
+
diff --git a/source/web/jsp/dialog/edit-text-inline.jsp b/source/web/jsp/dialog/edit-text-inline.jsp
index 137dd3e494..35cfc19545 100644
--- a/source/web/jsp/dialog/edit-text-inline.jsp
+++ b/source/web/jsp/dialog/edit-text-inline.jsp
@@ -126,7 +126,7 @@
-
+
diff --git a/source/web/jsp/dialog/undocheckout-file.jsp b/source/web/jsp/dialog/undocheckout-file.jsp
index a093647aaf..ce5ad2fdab 100644
--- a/source/web/jsp/dialog/undocheckout-file.jsp
+++ b/source/web/jsp/dialog/undocheckout-file.jsp
@@ -115,7 +115,7 @@
-
+
diff --git a/source/web/jsp/users/email-space-users.jsp b/source/web/jsp/users/email-space-users.jsp
index 75994aa0b6..d2005cd847 100644
--- a/source/web/jsp/users/email-space-users.jsp
+++ b/source/web/jsp/users/email-space-users.jsp
@@ -24,22 +24,27 @@
diff --git a/source/web/jsp/users/user-console.jsp b/source/web/jsp/users/user-console.jsp
index 008991349e..6457bc0636 100644
--- a/source/web/jsp/users/user-console.jsp
+++ b/source/web/jsp/users/user-console.jsp
@@ -134,14 +134,25 @@
-
+ <%--
-
- --%>
+
-
+
+
+
+ :
+
+
+ <%-- Start Location drop-down selector --%>
+
+
+
+
+
diff --git a/source/web/jsp/workflow/manage-task-dialog.jsp b/source/web/jsp/workflow/manage-task-dialog.jsp
new file mode 100644
index 0000000000..131268c079
--- /dev/null
+++ b/source/web/jsp/workflow/manage-task-dialog.jsp
@@ -0,0 +1,132 @@
+<%--
+ Copyright (C) 2005 Alfresco, Inc.
+
+ Licensed under the Mozilla Public License version 1.1
+ with a permitted attribution clause. You may obtain a
+ copy of the License at
+
+ http://www.alfresco.org/legal/license.txt
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ either express or implied. See the License for the specific
+ language governing permissions and limitations under the
+ License.
+--%>
+<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
+<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
+<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
+<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
+
+
+
+
+
+
+
+
+
+
+
+
+ <%-- Name column --%>
+
+
+
+
+
+
+
+
+
+
+
+ <%-- Description column --%>
+
+
+
+
+
+
+
+ <%-- Path column --%>
+
+
+
+
+
+
+
+ <%-- Created Date column --%>
+
+
+
+
+
+
+
+
+
+ <%-- Modified Date column --%>
+
+
+
+
+
+
+
+
+
+ <%-- Actions column --%>
+
+
+
+
+
+
+
+ <%-- Completed column --%>
+ <%--
+
+
+
+
+
+
+
+
+ --%>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/web/jsp/workflow/reassign-task-dialog.jsp b/source/web/jsp/workflow/reassign-task-dialog.jsp
new file mode 100644
index 0000000000..0e14e13887
--- /dev/null
+++ b/source/web/jsp/workflow/reassign-task-dialog.jsp
@@ -0,0 +1,40 @@
+<%--
+ Copyright (C) 2005 Alfresco, Inc.
+
+ Licensed under the Mozilla Public License version 1.1
+ with a permitted attribution clause. You may obtain a
+ copy of the License at
+
+ http://www.alfresco.org/legal/license.txt
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ either express or implied. See the License for the specific
+ language governing permissions and limitations under the
+ License.
+--%>
+<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
+<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
+<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
+<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
+<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
+
+<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %>
+<%@ page isELIgnored="false" %>
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/web/jsp/workflow/start-workflow-wizard/workflow-options.jsp b/source/web/jsp/workflow/start-workflow-wizard/workflow-options.jsp
index 969d4ef1bb..4e2b0af400 100644
--- a/source/web/jsp/workflow/start-workflow-wizard/workflow-options.jsp
+++ b/source/web/jsp/workflow/start-workflow-wizard/workflow-options.jsp
@@ -44,7 +44,91 @@
+
+
+
+
+
+
+
+ <%-- Name column --%>
+
+
+
+
+
+
+
+
+
+
+ <%-- Description column --%>
+
+
+
+
+
+
+
+ <%-- Path column --%>
+
+
+
+
+
+
+
+ <%-- Created Date column --%>
+
+
+
+
+
+
+
+
+
+ <%-- Modified Date column --%>
+
+
+
+
+
+
+
+
+
+ <%-- Actions column --%>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/web/jsp/workflow/tasks-completed-dashlet.jsp b/source/web/jsp/workflow/tasks-completed-dashlet.jsp
new file mode 100644
index 0000000000..0efb655524
--- /dev/null
+++ b/source/web/jsp/workflow/tasks-completed-dashlet.jsp
@@ -0,0 +1,72 @@
+<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
+<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
+<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
+<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
+
+
+
+ <%-- Primary column for details view mode --%>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <%-- Task id column --%>
+
+
+
+
+
+
+
+ <%-- Source column --%>
+
+
+
+
+
+
+
+ <%-- Completed date column --%>
+
+
+
+
+
+
+
+
+
+ <%-- Outcome column --%>
+
+
+
+
+
+
+
+ <%-- Actions column --%>
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/web/jsp/workflow/tasks-todo-dashlet.jsp b/source/web/jsp/workflow/tasks-todo-dashlet.jsp
new file mode 100644
index 0000000000..ee386f5ca5
--- /dev/null
+++ b/source/web/jsp/workflow/tasks-todo-dashlet.jsp
@@ -0,0 +1,80 @@
+<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
+<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
+<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
+<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
+
+
+
+ <%-- Primary column for details view mode --%>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <%-- Task id column --%>
+
+
+
+
+
+
+
+ <%-- Source column --%>
+
+
+
+
+
+
+
+ <%-- Due date column --%>
+
+
+
+
+
+
+
+
+
+ <%-- Status column --%>
+
+
+
+
+
+
+
+ <%-- Priority column --%>
+
+
+
+
+
+
+
+ <%-- Actions column --%>
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/web/jsp/workflow/view-completed-task-dialog.jsp b/source/web/jsp/workflow/view-completed-task-dialog.jsp
new file mode 100644
index 0000000000..6287762b9c
--- /dev/null
+++ b/source/web/jsp/workflow/view-completed-task-dialog.jsp
@@ -0,0 +1,98 @@
+<%--
+ Copyright (C) 2005 Alfresco, Inc.
+
+ Licensed under the Mozilla Public License version 1.1
+ with a permitted attribution clause. You may obtain a
+ copy of the License at
+
+ http://www.alfresco.org/legal/license.txt
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ either express or implied. See the License for the specific
+ language governing permissions and limitations under the
+ License.
+--%>
+<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
+<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
+<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
+<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
+
+
+
+
+
+
+
+
+
+
+
+
+ <%-- Name column --%>
+
+
+
+
+
+
+
+
+
+
+
+ <%-- Description column --%>
+
+
+
+
+
+
+
+ <%-- Path column --%>
+
+
+
+
+
+
+
+ <%-- Created Date column --%>
+
+
+
+
+
+
+
+
+
+ <%-- Modified Date column --%>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+