First cut of dialog/wizard framework

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2577 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Gavin Cornwell
2006-03-27 10:40:39 +00:00
parent cb69c74d73
commit 9be6273144
25 changed files with 1628 additions and 169 deletions

View File

@@ -7,6 +7,8 @@
<constructor-arg> <constructor-arg>
<list> <list>
<value>classpath:alfresco/web-client-config.xml</value> <value>classpath:alfresco/web-client-config.xml</value>
<value>classpath:alfresco/web-client-config-dialogs.xml</value>
<value>classpath:alfresco/web-client-config-wizards.xml</value>
<value>classpath:alfresco/web-client-config-properties.xml</value> <value>classpath:alfresco/web-client-config-properties.xml</value>
<value>classpath:alfresco/web-client-config-navigation.xml</value> <value>classpath:alfresco/web-client-config-navigation.xml</value>
<value>classpath:alfresco/web-client-config-actions.xml</value> <value>classpath:alfresco/web-client-config-actions.xml</value>

View File

@@ -329,8 +329,8 @@
</permissions> </permissions>
<label-id>new_space</label-id> <label-id>new_space</label-id>
<image>/images/icons/create_space.gif</image> <image>/images/icons/create_space.gif</image>
<action>createSpace</action> <action>dialog:createSpace</action>
<action-listener>#{NewSpaceDialog.startWizard}</action-listener> <!-- <action-listener>#{NewSpaceDialog.startWizard}</action-listener> -->
</action> </action>
<!-- Create Advanced Space Wizard --> <!-- Create Advanced Space Wizard -->

View File

@@ -0,0 +1,13 @@
<alfresco-config>
<config evalutor="string-compare" condition="Dialogs">
<dialog-container>/jsp/dialog/container.jsp</dialog-container>
<dialogs>
<dialog name="createSpace" page="/jsp/spaces/create-space-details.jsp" managed-bean="CreateSpaceDialog"
actions-config-id="space-actions" icon="/images/icons/create_space_large.gif"
title-id="new_space" description-id="newspace_description" />
</dialogs>
</config>
</alfresco-config>

View File

@@ -0,0 +1,10 @@
<alfresco-config>
<config evalutor="string-compare" condition="Wizards">
<wizard-container>/jsp/dialog/container.jsp</wizard-container>
<wizards>
</wizards>
</config>
</alfresco-config>

View File

@@ -13,6 +13,8 @@
<element-reader element-name="advanced-search" class="org.alfresco.web.config.AdvancedSearchElementReader" /> <element-reader element-name="advanced-search" class="org.alfresco.web.config.AdvancedSearchElementReader" />
<element-reader element-name="views" class="org.alfresco.web.config.ViewsElementReader" /> <element-reader element-name="views" class="org.alfresco.web.config.ViewsElementReader" />
<element-reader element-name="actions" class="org.alfresco.web.config.ActionsElementReader" /> <element-reader element-name="actions" class="org.alfresco.web.config.ActionsElementReader" />
<element-reader element-name="dialogs" class="org.alfresco.web.config.DialogsElementReader"/>
<element-reader element-name="wizards" class="org.alfresco.web.config.WizardsElementReader"/>
</element-readers> </element-readers>
</plug-ins> </plug-ins>

View File

@@ -26,23 +26,37 @@ import javax.faces.context.FacesContext;
import org.alfresco.config.Config; import org.alfresco.config.Config;
import org.alfresco.config.ConfigService; import org.alfresco.config.ConfigService;
import org.alfresco.web.app.context.UIContextService;
import org.alfresco.web.bean.NavigationBean; import org.alfresco.web.bean.NavigationBean;
import org.alfresco.web.bean.dialog.DialogManager;
import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.wizard.WizardManager;
import org.alfresco.web.config.DialogsConfigElement;
import org.alfresco.web.config.NavigationConfigElement; import org.alfresco.web.config.NavigationConfigElement;
import org.alfresco.web.config.NavigationElementReader; import org.alfresco.web.config.NavigationElementReader;
import org.alfresco.web.config.NavigationResult; import org.alfresco.web.config.NavigationResult;
import org.alfresco.web.config.DialogsConfigElement.DialogConfig;
import org.alfresco.web.config.WizardsConfigElement.WizardConfig;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.web.jsf.FacesContextUtils;
/** /**
* @author gavinc * @author gavinc
*/ */
public class AlfrescoNavigationHandler extends NavigationHandler public class AlfrescoNavigationHandler extends NavigationHandler
{ {
public final static String DIALOG_SEPARATOR = ":"; public final static String OUTCOME_SEPARATOR = ":";
public final static String DIALOG_PREXIX = "dialog" + DIALOG_SEPARATOR; public final static String DIALOG_PREXIX = "dialog" + OUTCOME_SEPARATOR;
public final static String WIZARD_PREFIX = "wizard" + OUTCOME_SEPARATOR;
public final static String CLOSE_DIALOG_OUTCOME = DIALOG_PREXIX + "close"; public final static String CLOSE_DIALOG_OUTCOME = DIALOG_PREXIX + "close";
public final static String CLOSE_WIZARD_OUTCOME = WIZARD_PREFIX + "close";
protected final static String CONFIG_NAV_BEAN = "NavigationBean";
protected final static String CONFIG_DIALOGS = "Dialogs";
protected final static String CONFIG_WIZARDS = "Wizards";
protected String dialogContainer = null;
protected String wizardContainer = null;
private final static Log logger = LogFactory.getLog(AlfrescoNavigationHandler.class); private final static Log logger = LogFactory.getLog(AlfrescoNavigationHandler.class);
private final static String VIEW_STACK = "_alfViewStack"; private final static String VIEW_STACK = "_alfViewStack";
@@ -69,186 +83,530 @@ public class AlfrescoNavigationHandler extends NavigationHandler
public void handleNavigation(FacesContext context, String fromAction, String outcome) public void handleNavigation(FacesContext context, String fromAction, String outcome)
{ {
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{
logger.debug("handleNavigation (fromAction=" + fromAction + ", outcome=" + outcome + ")"); logger.debug("handleNavigation (fromAction=" + fromAction + ", outcome=" + outcome + ")");
logger.debug("Current view id: " + context.getViewRoot().getViewId());
}
boolean isDialog = isDialog(outcome);
if (isDialog || isWizard(outcome))
{
boolean dialogWizardClosing = isDialogOrWizardClosing(outcome);
outcome = stripPrefix(outcome);
if (dialogWizardClosing)
{
handleDialogOrWizardClose(context, fromAction, outcome);
}
else
{
if (isDialog)
{
handleDialogOpen(context, fromAction, outcome);
}
else
{
handleWizardOpen(context, fromAction, outcome);
}
if (logger.isDebugEnabled())
logger.debug("view stack: " + getViewStack(context));
}
}
else
{
handleDispatch(context, fromAction, outcome);
}
}
/**
* Determines whether the given outcome is dialog related
*
* @param outcome The outcome to test
* @return true if outcome is dialog related i.e. starts with dialog:
*/
protected boolean isDialog(String outcome)
{
boolean dialog = false;
boolean useOriginalNavHandler = true;
boolean closingDialog = false;
String viewId = context.getViewRoot().getViewId();
if (logger.isDebugEnabled())
logger.debug("Current view id: " + viewId);
// determine if we are dealing with a dialog
if (outcome != null && outcome.startsWith(DIALOG_PREXIX)) if (outcome != null && outcome.startsWith(DIALOG_PREXIX))
{ {
// determine whether it's being closed or opened dialog = true;
closingDialog = outcome.startsWith(CLOSE_DIALOG_OUTCOME); }
// remove the dialog prefix return dialog;
outcome = outcome.substring(DIALOG_PREXIX.length()); }
if (closingDialog) /**
* Determines whether the given outcome is wizard related
*
* @param outcome The outcome to test
* @return true if outcome is wizard related
* i.e. starts with create-wizard: or edit-wizard:
*/
protected boolean isWizard(String outcome)
{
boolean wizard = false;
if (outcome != null && outcome.startsWith(WIZARD_PREFIX))
{
wizard = true;
}
return wizard;
}
/**
* Determines whether the given outcome represents a dialog or wizard closing
*
* @param outcome The outcome to test
* @return true if the outcome represents a closing dialog or wizard
*/
protected boolean isDialogOrWizardClosing(String outcome)
{
boolean closing = false;
if (outcome != null &&
(outcome.startsWith(CLOSE_DIALOG_OUTCOME) ||
outcome.startsWith(CLOSE_WIZARD_OUTCOME)))
{
closing = true;
}
return closing;
}
/**
* Removes the dialog or wizard prefix from the given outcome
*
* @param outcome The outcome to remove the prefix from
* @return The remaining outcome
*/
protected String stripPrefix(String outcome)
{
String newOutcome = outcome;
if (outcome != null)
{
int idx = outcome.indexOf(OUTCOME_SEPARATOR);
if (idx != -1)
{ {
// if we are closing the dialog take the view off the newOutcome = outcome.substring(idx+1);
// top of the stack then decide whether to use the view }
// or any overridden outcome that may be present }
if (getViewStack(context).empty() == false)
return newOutcome;
}
/**
* Returns the overridden outcome.
* Used by dialogs and wizards to go to a particular page after it closes
* rather than back to the page it was launched from.
*
* @param outcome The current outcome
* @return The overridden outcome or null if there isn't an override
*/
protected String getOutcomeOverride(String outcome)
{
String override = null;
if (outcome != null)
{
int idx = outcome.indexOf(OUTCOME_SEPARATOR);
if (idx != -1)
{
override = outcome.substring(idx+1);
}
}
return override;
}
/**
* Returns the dialog configuration object for the given dialog name.
* If there is a node in the dispatch context a lookup is performed using
* the node. If this doesn't return any config or there is no dispatch
* context node a 'global' dialog lookup is performed.
*
*
* @param name The name of dialog being launched
* @param dispatchContext The node being acted upon
* @return The DialogConfig for the dialog or null if no config could be found
*/
protected DialogConfig getDialogConfig(FacesContext context, String name, Node dispatchContext)
{
DialogConfig dialogConfig = null;
ConfigService configSvc = Application.getConfigService(context);
if (dispatchContext != null)
{
Config config = configSvc.getConfig(dispatchContext);
if (config != null)
{
DialogsConfigElement dialogsCfg = (DialogsConfigElement)config.getConfigElement(
DialogsConfigElement.CONFIG_ELEMENT_ID);
if (dialogsCfg != null)
{ {
String newViewId = (String)getViewStack(context).pop(); dialogConfig = dialogsCfg.getDialog(name);
}
}
}
// if we didn't find a dialog via the dispatch look it up in the 'global' dialogs config
if (dialogConfig == null)
{
Config config = configSvc.getConfig(CONFIG_DIALOGS);
if (config != null)
{
DialogsConfigElement dialogsCfg = (DialogsConfigElement)config.getConfigElement(
DialogsConfigElement.CONFIG_ELEMENT_ID);
if (dialogsCfg != null)
{
dialogConfig = dialogsCfg.getDialog(name);
}
}
}
return dialogConfig;
}
/**
* Returns the wizard configuration object for the given wizard name.
* If there is a node in the dispatch context a lookup is performed using
* the node otherwise a 'global' wizard lookup is performed.
*
* @param name The name of wizard being launched
* @param dispatchContext The node being acted upon
* @return The WizardConfig for the wizard or null if no config could be found
*/
protected WizardConfig getWizardConfig(FacesContext context, String name, Node dispatchContext)
{
return null;
}
/**
* 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 dialogsConfig = configSvc.getConfig(CONFIG_DIALOGS);
if (dialogsConfig != null)
{
this.dialogContainer = dialogsConfig.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 wizardsConfig = configSvc.getConfig(CONFIG_WIZARDS);
if (wizardsConfig != null)
{
this.wizardContainer = wizardsConfig.getConfigElement("wizard-container").getValue();
}
}
return this.wizardContainer;
}
/**
* Returns the node currently in the dispatch context
*
* @return The node currently in the dispatch context or null if
* the dispatch context is empty
*/
protected Node getDispatchContextNode(FacesContext context)
{
Node dispatchNode = null;
NavigationBean navBean = (NavigationBean)context.getExternalContext().
getSessionMap().get(CONFIG_NAV_BEAN);
if (navBean != null)
{
dispatchNode = navBean.getDispatchContextNode();
}
return dispatchNode;
}
/**
* Processes any dispatching that may need to occur
*
* @param node The node in the current dispatch context
* @param viewId The current view id
* @param outcome The outcome
*/
protected void handleDispatch(FacesContext context, String fromAction, String outcome)
{
Node dispatchNode = getDispatchContextNode(context);
if (dispatchNode != null)
{
if (logger.isDebugEnabled())
logger.debug("Found node with type '" + dispatchNode.getType().toString() +
"' in dispatch context");
// get the current view id
String viewId = context.getViewRoot().getViewId();
// is there an overiddent outcome? // see if there is any navigation config for the node type
int idx = outcome.indexOf(DIALOG_SEPARATOR); ConfigService configSvc = Application.getConfigService(context);
if (idx == -1) Config nodeConfig = configSvc.getConfig(dispatchNode);
{ NavigationConfigElement navigationCfg = (NavigationConfigElement)nodeConfig.
// there isn't an overidden outcome so go back to the previous view getConfigElement(NavigationElementReader.ELEMENT_NAVIGATION);
if (logger.isDebugEnabled())
logger.debug("Closing dialog, going back to view id: " + newViewId); if (navigationCfg != null)
{
// see if there is config for the current view state
NavigationResult navResult = navigationCfg.getOverride(viewId, outcome);
if (navResult != null)
{
if (logger.isDebugEnabled())
logger.debug("Found navigation config: " + navResult);
goToView(context, newViewId); if (navResult.isOutcome())
{
navigate(context, fromAction, navResult.getResult());
} }
else else
{ {
// there is an overidden outcome so extract it String newViewId = navResult.getResult();
outcome = outcome.substring(idx+1, outcome.length());
// we also need to empty the dialog stack if we have been given if (newViewId.equals(viewId) == false)
// an overidden outcome as we could be going anywhere in the app {
getViewStack(context).clear(); if (logger.isDebugEnabled())
logger.debug("Dispatching to new view id: " + newViewId);
if (logger.isDebugEnabled()) goToView(context, newViewId);
logger.debug("Closing dialog with an overridden outcome of '" + outcome + "'"); }
else
this.origHandler.handleNavigation(context, fromAction, outcome); {
if (logger.isDebugEnabled())
logger.debug("New view id is the same as the current one so setting outcome to null");
navigate(context, fromAction, null);
}
} }
} }
else else
{ {
// we are trying to close a dialog when one hasn't been opened! if (logger.isDebugEnabled())
// log a warning and return a null outcome to stay on the same page logger.debug("No override configuration found for current view or outcome");
if (logger.isWarnEnabled())
{
logger.warn("Attempting to close a dialog with an empty view stack, returning null outcome");
}
this.origHandler.handleNavigation(context, fromAction, null); navigate(context, fromAction, outcome);
} }
} }
else else
{ {
// if we are opening a dialog push the current view id
// on to the stack, but only if it is different than the
// current view at the top (you can't launch a dialog from
// the same page 2 times in a row!)
// TODO: This wouldn't happen if we could be sure a dialog is
// ALWAYS exited properly, look into a way of ensuring
// dialogs get closed if a user navigates away from the page,
// would a PhaseListener help in any way??
if (getViewStack(context).empty() ||
viewId.equals(getViewStack(context).peek()) == false)
{
getViewStack(context).push(viewId);
if (logger.isDebugEnabled())
logger.debug("Pushed current view to stack: " + viewId);
}
else
{
if (getViewStack(context).empty() == false && logger.isDebugEnabled())
{
logger.debug("current view is already top the view stack!");
}
}
}
if (logger.isDebugEnabled())
logger.debug("view stack: " + getViewStack(context));
}
if (closingDialog == false)
{
NavigationBean navBean = (NavigationBean)context.getExternalContext().
getSessionMap().get("NavigationBean");
// only continue if we have some dispatching context
if (navBean != null && navBean.getDispatchContextNode() != null)
{
Node node = navBean.getDispatchContextNode();
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Found node with type '" + node.getType().toString() +
"' in dispatch context");
// see if there is any navigation config for the node type
ConfigService configSvc = Application.getConfigService(context);
Config nodeConfig = configSvc.getConfig(node);
NavigationConfigElement navigationCfg = (NavigationConfigElement)nodeConfig.
getConfigElement(NavigationElementReader.ELEMENT_NAVIGATION);
if (navigationCfg != null)
{
// see if there is config for the current view state
NavigationResult navResult = navigationCfg.getOverride(viewId, outcome);
if (navResult != null)
{
if (logger.isDebugEnabled())
logger.debug("Found navigation config: " + navResult);
if (navResult.isOutcome())
{
outcome = navResult.getResult();
}
else
{
String newViewId = navResult.getResult();
if (newViewId.equals(viewId) == false)
{
useOriginalNavHandler = false;
if (logger.isDebugEnabled())
logger.debug("Dispatching to new view id: " + newViewId);
goToView(context, newViewId);
}
else
{
if (logger.isDebugEnabled())
logger.debug("New view id is the same as the current one so setting outcome to null");
outcome = null;
}
}
}
else if (logger.isDebugEnabled())
{
logger.debug("No override configuration found for current view or outcome");
}
}
else if (logger.isDebugEnabled())
{
logger.debug("No navigation configuration found for node"); logger.debug("No navigation configuration found for node");
}
// reset the dispatch context navigate(context, fromAction, outcome);
navBean.resetDispatchContext();
}
else if (logger.isDebugEnabled())
{
logger.debug("No dispatch context found");
} }
// do the appropriate navigation handling // reset the dispatch context
if (useOriginalNavHandler) ((NavigationBean)context.getExternalContext().getSessionMap().
{ get(CONFIG_NAV_BEAN)).resetDispatchContext();
if (logger.isDebugEnabled()) }
logger.debug("Passing outcome '" + outcome + "' to original navigation handler"); else
{
if (logger.isDebugEnabled())
logger.debug("No dispatch context found");
this.origHandler.handleNavigation(context, fromAction, outcome); // pass off to the original handler
navigate(context, fromAction, outcome);
}
}
/**
* Opens a dialog
*
* @param context FacesContext
* @param fromAction The fromAction
* @param name The name of the dialog to open
*/
protected void handleDialogOpen(FacesContext context, String fromAction, String name)
{
if (logger.isDebugEnabled())
logger.debug("Opening dialog '" + name + "'");
// firstly add the current view to the stack so we know where to go back to
addCurrentViewToStack(context);
DialogConfig config = getDialogConfig(context, name, getDispatchContextNode(context));
if (config != null)
{
if (logger.isDebugEnabled())
logger.debug("Found config for dialog '" + name + "': " + config);
// set the dialog manager up with the retrieved config
DialogManager dialogManager = Application.getDialogManager();
dialogManager.setCurrentDialog(config);
// retrieve the container page and navigate to it
goToView(context, getDialogContainer(context));
}
else
{
// send the dialog name as the outcome to the original handler
handleDispatch(context, fromAction, name);
}
}
/**
* Opens a wizard
*
* @param context FacesContext
* @param fromAction The fromAction
* @param name The name of the wizard to open
*/
protected void handleWizardOpen(FacesContext context, String fromAction, String name)
{
if (logger.isDebugEnabled())
logger.debug("Opening wizard '" + name + "'");
// firstly add the current view to the stack so we know where to go back to
addCurrentViewToStack(context);
WizardConfig wizard = getWizardConfig(context, name, getDispatchContextNode(context));
if (wizard != null)
{
if (logger.isDebugEnabled())
logger.debug("Found config for wizard '" + name + "': " + wizard);
// set the wizard manager up with the retrieved config
WizardManager wizardManager = Application.getWizardManager();
wizardManager.setCurrentWizard(wizard);
// retrieve the container page and navigate to it
goToView(context, getWizardContainer(context));
}
else
{
// send the dialog name as the outcome to the original handler
handleDispatch(context, fromAction, name);
}
}
/**
* Closes the current dialog or wizard
*/
protected void handleDialogOrWizardClose(FacesContext context, String fromAction, String outcome)
{
// if we are closing the dialog take the view off the
// top of the stack then decide whether to use the view
// or any overridden outcome that may be present
if (getViewStack(context).empty() == false)
{
String newViewId = (String)getViewStack(context).pop();
// is there an overidden outcome?
String overriddenOutcome = getOutcomeOverride(outcome);
if (overriddenOutcome == null)
{
// there isn't an overidden outcome so go back to the previous view
if (logger.isDebugEnabled())
logger.debug("Closing dialog, going back to view id: " + newViewId);
goToView(context, newViewId);
}
else
{
// we also need to empty the dialog stack if we have been given
// an overidden outcome as we could be going anywhere in the app
getViewStack(context).clear();
if (logger.isDebugEnabled())
logger.debug("Closing dialog with an overridden outcome of '" + overriddenOutcome + "'");
navigate(context, fromAction, overriddenOutcome);
} }
} }
else
{
// we are trying to close a dialog when one hasn't been opened!
// log a warning and return a null outcome to stay on the same page
if (logger.isWarnEnabled())
{
logger.warn("Attempting to close a dialog with an empty view stack, returning null outcome");
}
navigate(context, fromAction, null);
}
}
/**
* Adds the current view to the stack (if required).
* If the current view is already the top of the stack it is not added again
* to stop the stack from growing and growing.
*
* @param context FacesContext
*/
protected void addCurrentViewToStack(FacesContext context)
{
// if we are opening a dialog push the current view id
// on to the stack, but only if it is different than the
// current view at the top (you can't launch a dialog from
// the same page 2 times in a row!)
// TODO: This wouldn't happen if we could be sure a dialog is
// ALWAYS exited properly, look into a way of ensuring
// dialogs get closed if a user navigates away from the page,
// would a PhaseListener help in any way??
String viewId = context.getViewRoot().getViewId();
if (getViewStack(context).empty() ||
viewId.equals(getViewStack(context).peek()) == false)
{
getViewStack(context).push(viewId);
if (logger.isDebugEnabled())
logger.debug("Pushed current view to stack: " + viewId);
}
else
{
if (getViewStack(context).empty() == false && logger.isDebugEnabled())
{
logger.debug("current view is already top the view stack!");
}
}
}
/**
* Navigates to the appropriate page using the original navigation handler
*
* @param context FacesContext
* @param fromAction The fromAction
* @param outcome The outcome
*/
private void navigate(FacesContext context, String fromAction, String outcome)
{
if (logger.isDebugEnabled())
logger.debug("Passing outcome '" + outcome + "' to original navigation handler");
this.origHandler.handleNavigation(context, fromAction, outcome);
} }
/** /**
@@ -274,13 +632,13 @@ public class AlfrescoNavigationHandler extends NavigationHandler
* the users session, will never be null * the users session, will never be null
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Stack getViewStack(FacesContext context) private Stack<String> getViewStack(FacesContext context)
{ {
Stack viewStack = (Stack)context.getExternalContext().getSessionMap().get(VIEW_STACK); Stack<String> viewStack = (Stack)context.getExternalContext().getSessionMap().get(VIEW_STACK);
if (viewStack == null) if (viewStack == null)
{ {
viewStack = new Stack(); viewStack = new Stack<String>();
context.getExternalContext().getSessionMap().put(VIEW_STACK, viewStack); context.getExternalContext().getSessionMap().put(VIEW_STACK, viewStack);
} }

View File

@@ -36,8 +36,11 @@ import org.alfresco.config.ConfigService;
import org.alfresco.repo.importer.ImporterBootstrap; import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.web.app.servlet.AuthenticationHelper; import org.alfresco.web.app.servlet.AuthenticationHelper;
import org.alfresco.web.app.servlet.FacesHelper;
import org.alfresco.web.bean.ErrorBean; import org.alfresco.web.bean.ErrorBean;
import org.alfresco.web.bean.dialog.DialogManager;
import org.alfresco.web.bean.repository.User; import org.alfresco.web.bean.repository.User;
import org.alfresco.web.bean.wizard.WizardManager;
import org.alfresco.web.config.ClientConfigElement; import org.alfresco.web.config.ClientConfigElement;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.WebApplicationContext;
@@ -164,6 +167,26 @@ public class Application
} }
} }
/**
* Retrieves the DialogManager managed bean
*
* @return DialogManager bean
*/
public static DialogManager getDialogManager()
{
return (DialogManager)FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "DialogManager");
}
/**
* Retrieves the WizardManager managed bean
*
* @return WizardManager bean
*/
public static WizardManager getWizardManager()
{
return (WizardManager)FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "WizardManager");
}
/** /**
* Retrieves the configured error page for the application * Retrieves the configured error page for the application
* *

View File

@@ -1197,7 +1197,7 @@ public class BrowseBean implements IContextListener
// setting the outcome will show the browse view again // setting the outcome will show the browse view again
outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME +
AlfrescoNavigationHandler.DIALOG_SEPARATOR + "browse"; AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse";
} }
catch (Throwable err) catch (Throwable err)
{ {
@@ -1237,7 +1237,7 @@ public class BrowseBean implements IContextListener
// setting the outcome will show the browse view again // setting the outcome will show the browse view again
outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME +
AlfrescoNavigationHandler.DIALOG_SEPARATOR + "browse"; AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse";
} }
catch (Throwable err) catch (Throwable err)
{ {

View File

@@ -737,7 +737,7 @@ public class ForumsBean implements IContextListener
{ {
// return an overidden outcome which closes the dialog with an outcome // return an overidden outcome which closes the dialog with an outcome
outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME +
AlfrescoNavigationHandler.DIALOG_SEPARATOR + outcomeOverride; AlfrescoNavigationHandler.OUTCOME_SEPARATOR + outcomeOverride;
} }
return outcome; return outcome;
@@ -788,7 +788,7 @@ public class ForumsBean implements IContextListener
{ {
// return an overidden outcome which closes the dialog with an outcome // return an overidden outcome which closes the dialog with an outcome
outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME +
AlfrescoNavigationHandler.DIALOG_SEPARATOR + outcomeOverride; AlfrescoNavigationHandler.OUTCOME_SEPARATOR + outcomeOverride;
} }
return outcome; return outcome;
@@ -823,7 +823,7 @@ public class ForumsBean implements IContextListener
if (outcome != null) if (outcome != null)
{ {
outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + outcome = AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME +
AlfrescoNavigationHandler.DIALOG_SEPARATOR + outcomeOverride; AlfrescoNavigationHandler.OUTCOME_SEPARATOR + outcomeOverride;
} }
return outcome; return outcome;

View File

@@ -0,0 +1,39 @@
package org.alfresco.web.bean.dialog;
import javax.faces.context.FacesContext;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.context.UIContextService;
/**
* Base class for all dialog beans providing common functionality
*
* @author gavinc
*/
public abstract class BaseDialogBean implements IDialogBean
{
protected static final String DIALOG_CLOSE = "dialog:close";
public abstract String finish();
public void init()
{
// tell any beans to update themselves so the UI gets refreshed
UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans();
}
public String cancel()
{
return DIALOG_CLOSE;
}
public boolean getFinishButtonDisabled()
{
return true;
}
public String getFinishButtonLabel()
{
return Application.getMessage(FacesContext.getCurrentInstance(), "ok");
}
}

View File

@@ -0,0 +1,153 @@
package org.alfresco.web.bean.dialog;
import javax.faces.context.FacesContext;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.servlet.FacesHelper;
import org.alfresco.web.config.DialogsConfigElement.DialogConfig;
/**
* Bean that manages the dialog framework
*
* @author gavinc
*/
public class DialogManager
{
protected DialogConfig currentDialogConfig;
protected IDialogBean currentDialog;
/**
* Sets the current dialog
*
* @param config The configuration for the dialog to set
*/
public void setCurrentDialog(DialogConfig config)
{
this.currentDialogConfig = config;
String beanName = this.currentDialogConfig.getManagedBean();
this.currentDialog = (IDialogBean)FacesHelper.getManagedBean(
FacesContext.getCurrentInstance(), beanName);
if (this.currentDialog == null)
{
throw new AlfrescoRuntimeException("Failed to find managed bean '" + beanName + "'");
}
// initialise the managed bean
this.currentDialog.init();
}
/**
* Returns the current dialog bean being managed
*
* @return The current managed bean
*/
public IDialogBean getBean()
{
return this.currentDialog;
}
/**
* Returns the icon to use for the current dialog
*
* @return The icon
*/
public String getIcon()
{
return this.currentDialogConfig.getIcon();
}
/**
* Returns the resolved title to use for the dialog
*
* @return The title
*/
public String getTitle()
{
String title = this.currentDialogConfig.getTitleId();
if (title != null)
{
title = Application.getMessage(FacesContext.getCurrentInstance(), title);
}
else
{
title = this.currentDialogConfig.getTitle();
}
return title;
}
/**
* Returns the resolved description to use for the dialog
*
* @return The description
*/
public String getDescription()
{
String desc = this.currentDialogConfig.getDescriptionId();
if (desc != null)
{
desc = Application.getMessage(FacesContext.getCurrentInstance(), desc);
}
else
{
desc = this.currentDialogConfig.getDescription();
}
return desc;
}
/**
* Returns the page the dialog will use
*
* @return The page
*/
public String getPage()
{
return this.currentDialogConfig.getPage();
}
/**
* Returns the label to use for the finish button
*
* @return The finish button label
*/
public String getFinishButtonLabel()
{
return this.currentDialog.getFinishButtonLabel();
}
/**
* Determines whether the finish button on the dialog should be disabled
*
* @return true if the button should be disabled
*/
public boolean getFinishButtonDisabled()
{
return this.currentDialog.getFinishButtonDisabled();
}
/**
* Method handler called when the finish button of the dialog is pressed
*
* @return The outcome
*/
public String finish()
{
return this.currentDialog.finish();
}
/**
* Method handler called when the cancel button of the dialog is pressed
*
* @return The outcome
*/
public String cancel()
{
return this.currentDialog.cancel();
}
}

View File

@@ -0,0 +1,42 @@
package org.alfresco.web.bean.dialog;
/**
* Interface that defines the contract for a dialog backing bean
*
* @author gavinc
*/
public interface IDialogBean
{
/**
* Initialises the dialog bean
*/
public void init();
/**
* Method handler called when the finish button of the dialog is pressed
*
* @return The outcome to return (normally dialog:close)
*/
public String finish();
/**
* Method handler called when the cancel button of the dialog is pressed
*
* @return The outcome to return (normally dialog:close)
*/
public String cancel();
/**
* Returns the label to use for the finish button
*
* @return The finish button label
*/
public String getFinishButtonLabel();
/**
* Determines whether the finish button on the dialog should be disabled
*
* @return true if the button should be disabled
*/
public boolean getFinishButtonDisabled();
}

View File

@@ -0,0 +1,328 @@
package org.alfresco.web.bean.dialog;
import java.io.Serializable;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.transaction.UserTransaction;
import org.alfresco.config.Config;
import org.alfresco.config.ConfigElement;
import org.alfresco.model.ContentModel;
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.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
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.BrowseBean;
import org.alfresco.web.bean.NavigationBean;
import org.alfresco.web.bean.repository.Repository;
import org.alfresco.web.ui.common.Utils;
import org.alfresco.web.ui.common.component.UIListItem;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Dialog bean to create a space
*
* @author gavinc
*/
public class SpaceDialog extends BaseDialogBean
{
protected static final String ERROR = "error_space";
private static final String SPACE_ICON_DEFAULT = "space-icon-default";
// private static final String DEFAULT_SPACE_TYPE_ICON = "/images/icons/space.gif";
private static final String ICONS_LOOKUP_KEY = " icons";
protected NodeService nodeService;
protected FileFolderService fileFolderService;
protected NamespaceService namespaceService;
protected SearchService searchService;
protected NavigationBean navigator;
protected BrowseBean browseBean;
protected String spaceType;
protected String icon;
protected String name;
protected String description;
private static Log logger = LogFactory.getLog(SpaceDialog.class);
/**
* @param nodeService The nodeService to set.
*/
public void setNodeService(NodeService nodeService)
{
this.nodeService = nodeService;
}
/**
* @param fileFolderService used to manipulate folder/folder model nodes
*/
public void setFileFolderService(FileFolderService fileFolderService)
{
this.fileFolderService = fileFolderService;
}
/**
* @param searchService the service used to find nodes
*/
public void setSearchService(SearchService searchService)
{
this.searchService = searchService;
}
/**
* @param namespaceService The NamespaceService
*/
public void setNamespaceService(NamespaceService namespaceService)
{
this.namespaceService = namespaceService;
}
/**
* @param navigator The NavigationBean to set.
*/
public void setNavigator(NavigationBean navigator)
{
this.navigator = navigator;
}
/**
* @param browseBean The BrowseBean to set.
*/
public void setBrowseBean(BrowseBean browseBean)
{
this.browseBean = browseBean;
}
/**
* @return Returns the description.
*/
public String getDescription()
{
return description;
}
/**
* @param description The description to set.
*/
public void setDescription(String description)
{
this.description = description;
}
/**
* @return Returns the icon.
*/
public String getIcon()
{
return icon;
}
/**
* @param icon The icon to set.
*/
public void setIcon(String icon)
{
this.icon = icon;
}
/**
* @return Returns the name.
*/
public String getName()
{
return name;
}
/**
* @param name The name to set.
*/
public void setName(String name)
{
this.name = name;
}
/**
* @return Returns the spaceType.
*/
public String getSpaceType()
{
return spaceType;
}
/**
* @param spaceType The spaceType to set.
*/
public void setSpaceType(String spaceType)
{
this.spaceType = spaceType;
}
/**
* Returns a list of icons to allow the user to select from.
* The list can change according to the type of space being created.
*
* @return A list of icons
*/
@SuppressWarnings("unchecked")
public List<UIListItem> getIcons()
{
// NOTE: we can't cache this list as it depends on the space type
// which the user can change during the advanced space wizard
List<UIListItem> icons = null;
QName type = QName.createQName(this.spaceType);
String typePrefixForm = type.toPrefixString(this.namespaceService);
Config config = Application.getConfigService(FacesContext.getCurrentInstance()).
getConfig(typePrefixForm + ICONS_LOOKUP_KEY);
if (config != null)
{
ConfigElement iconsCfg = config.getConfigElement("icons");
if (iconsCfg != null)
{
boolean first = true;
for (ConfigElement icon : iconsCfg.getChildren())
{
String iconName = icon.getAttribute("name");
String iconPath = icon.getAttribute("path");
if (iconName != null && iconPath != null)
{
if (first)
{
// if this is the first icon create the list and make
// the first icon in the list the default
icons = new ArrayList<UIListItem>(iconsCfg.getChildCount());
if (this.icon == null)
{
// set the default if it is not already
this.icon = iconName;
}
first = false;
}
UIListItem item = new UIListItem();
item.setValue(iconName);
item.getAttributes().put("image", iconPath);
icons.add(item);
}
}
}
}
// if we didn't find any icons display one default choice
if (icons == null)
{
icons = new ArrayList<UIListItem>(1);
this.icon = SPACE_ICON_DEFAULT;
UIListItem item = new UIListItem();
item.setValue("space-icon-default");
item.getAttributes().put("image", "/images/icons/space-icon-default.gif");
icons.add(item);
}
return icons;
}
/**
* Initialises the wizard
*/
public void init()
{
super.init();
// reset all variables
this.spaceType = ContentModel.TYPE_FOLDER.toString();
this.icon = null;
this.name = null;
this.description = "";
}
@Override
public String finish()
{
String outcome = DIALOG_CLOSE;
UserTransaction tx = null;
try
{
FacesContext context = FacesContext.getCurrentInstance();
tx = Repository.getUserTransaction(context);
tx.begin();
// create the space (just create a folder for now)
NodeRef parentNodeRef;
String nodeId = this.navigator.getCurrentNodeId();
if (nodeId == null)
{
parentNodeRef = this.nodeService.getRootNode(Repository.getStoreRef());
}
else
{
parentNodeRef = new NodeRef(Repository.getStoreRef(), nodeId);
}
FileInfo fileInfo = fileFolderService.create(
parentNodeRef,
this.name,
Repository.resolveToQName(this.spaceType));
NodeRef nodeRef = fileInfo.getNodeRef();
if (logger.isDebugEnabled())
logger.debug("Created folder node with name: " + this.name);
// apply the uifacets aspect - icon, title and description props
Map<QName, Serializable> uiFacetsProps = new HashMap<QName, Serializable>(5);
uiFacetsProps.put(ContentModel.PROP_ICON, this.icon);
uiFacetsProps.put(ContentModel.PROP_TITLE, this.name);
uiFacetsProps.put(ContentModel.PROP_DESCRIPTION, this.description);
this.nodeService.addAspect(nodeRef, ContentModel.ASPECT_UIFACETS, uiFacetsProps);
if (logger.isDebugEnabled())
logger.debug("Added uifacets aspect with properties: " + uiFacetsProps);
// commit the transaction
tx.commit();
}
catch (FileExistsException e)
{
// rollback the transaction
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
// print status message
String statusMsg = MessageFormat.format(
Application.getMessage(
FacesContext.getCurrentInstance(), "error_exists"),
e.getExisting().getName());
Utils.addErrorMessage(statusMsg);
// no outcome
outcome = null;
}
catch (Throwable e)
{
// rollback the transaction
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
FacesContext.getCurrentInstance(), ERROR), e.getMessage()), e);
outcome = null;
}
return outcome;
}
}

View File

@@ -0,0 +1,60 @@
package org.alfresco.web.bean.wizard;
import javax.faces.context.FacesContext;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.context.UIContextService;
/**
* Base class for all wizard beans providing common functionality
*
* @author gavinc
*/
public abstract class BaseWizardBean implements IWizardBean
{
protected static final String WIZARD_CLOSE = "wizard:close";
public abstract String finish();
public void init()
{
// tell any beans to update themselves so the UI gets refreshed
UIContextService.getInstance(FacesContext.getCurrentInstance()).notifyBeans();
}
public boolean getNextButtonDisabled()
{
return true;
}
public boolean getBackButtonDisabled()
{
return true;
}
public boolean getFinishButtonDisabled()
{
return true;
}
public String getNextButtonLabel()
{
return Application.getMessage(FacesContext.getCurrentInstance(), "next_button");
}
public String getBackButtonLabel()
{
return Application.getMessage(FacesContext.getCurrentInstance(), "back_button");
}
public String getFinishButtonLabel()
{
return Application.getMessage(FacesContext.getCurrentInstance(), "finish_button");
}
public String cancel()
{
return WIZARD_CLOSE;
}
}

View File

@@ -0,0 +1,53 @@
package org.alfresco.web.bean.wizard;
import org.alfresco.web.bean.dialog.IDialogBean;
/**
* Interface that defines the contract for a wizard backing bean
*
* @author gavinc
*/
public interface IWizardBean extends IDialogBean
{
/**
* Method handler called when the next button of the wizard is pressed
*
* @return The outcome to return
*/
// public String next();
/**
* Method handler called when the back button of the wizard is pressed
*
* @return The outcome to return
*/
// public String back();
/**
* Determines whether the next button on the wizard should be disabled
*
* @return true if the button should be disabled
*/
public boolean getNextButtonDisabled();
/**
* Determines whether the back button on the wizard should be disabled
*
* @return true if the button should be disabled
*/
public boolean getBackButtonDisabled();
/**
* Returns the label to use for the next button
*
* @return The next button label
*/
public String getNextButtonLabel();
/**
* Returns the label to use for the back button
*
* @return The back button label
*/
public String getBackButtonLabel();
}

View File

@@ -173,7 +173,7 @@ public class NewDiscussionWizard extends NewTopicWizard
// to the browse screen, this also makes sure we don't end up in the forum that // to the browse screen, this also makes sure we don't end up in the forum that
// just got deleted! // just got deleted!
return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME +
AlfrescoNavigationHandler.DIALOG_SEPARATOR + "browse"; AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "browse";
} }

View File

@@ -154,7 +154,7 @@ public class NewTopicWizard extends NewSpaceWizard
// outcome of 'showTopic' // outcome of 'showTopic'
this.browseBean.clickSpace(this.createdNode); this.browseBean.clickSpace(this.createdNode);
outcome = outcome + AlfrescoNavigationHandler.DIALOG_SEPARATOR + "showTopic"; outcome = outcome + AlfrescoNavigationHandler.OUTCOME_SEPARATOR + "showTopic";
} }
} }

View File

@@ -0,0 +1,50 @@
package org.alfresco.web.bean.wizard;
import javax.faces.context.FacesContext;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.web.app.servlet.FacesHelper;
import org.alfresco.web.config.WizardsConfigElement.WizardConfig;
/**
* Bean that manages the wizard framework
*
* @author gavinc
*/
public class WizardManager
{
protected WizardConfig currentWizardConfig;
protected IWizardBean currentWizard;
/**
* Sets the current wizard
*
* @param config The configuration for the wizard to set
*/
public void setCurrentWizard(WizardConfig config)
{
this.currentWizardConfig = config;
String beanName = this.currentWizardConfig.getManagedBean();
this.currentWizard = (IWizardBean)FacesHelper.getManagedBean(
FacesContext.getCurrentInstance(), beanName);
if (this.currentWizard == null)
{
throw new AlfrescoRuntimeException("Failed to find managed bean '" + beanName + "'");
}
// initialise the managed bean
this.currentWizard.init();
}
/**
* Returns the current wizard bean being managed
*
* @return The current managed bean
*/
public IWizardBean getBean()
{
return this.currentWizard;
}
}

View File

@@ -124,13 +124,14 @@ public class DialogsConfigElement extends ConfigElementAdapter
protected String name; protected String name;
protected String page; protected String page;
protected String managedBean; protected String managedBean;
protected String icon;
protected String title; protected String title;
protected String titleId; protected String titleId;
protected String description; protected String description;
protected String descriptionId; protected String descriptionId;
public DialogConfig(String name, String page, String bean, public DialogConfig(String name, String page, String bean,
String title, String titleId, String icon, String title, String titleId,
String description, String descriptionId) String description, String descriptionId)
{ {
// check the mandatory parameters are present // check the mandatory parameters are present
@@ -141,6 +142,7 @@ public class DialogsConfigElement extends ConfigElementAdapter
this.name = name; this.name = name;
this.page = page; this.page = page;
this.managedBean = bean; this.managedBean = bean;
this.icon = icon;
this.title = title; this.title = title;
this.titleId = titleId; this.titleId = titleId;
this.description = description; this.description = description;
@@ -172,6 +174,11 @@ public class DialogsConfigElement extends ConfigElementAdapter
return this.page; return this.page;
} }
public String getIcon()
{
return this.icon;
}
public String getTitle() public String getTitle()
{ {
return this.title; return this.title;
@@ -192,6 +199,7 @@ public class DialogsConfigElement extends ConfigElementAdapter
buffer.append(" (name=").append(this.name); buffer.append(" (name=").append(this.name);
buffer.append(" page=").append(this.page); buffer.append(" page=").append(this.page);
buffer.append(" managed-bean=").append(this.managedBean); buffer.append(" managed-bean=").append(this.managedBean);
buffer.append(" icon=").append(this.icon);
buffer.append(" title=").append(this.title); buffer.append(" title=").append(this.title);
buffer.append(" titleId=").append(this.titleId); buffer.append(" titleId=").append(this.titleId);
buffer.append(" description=").append(this.description); buffer.append(" description=").append(this.description);

View File

@@ -35,6 +35,7 @@ public class DialogsElementReader implements ConfigElementReader
public static final String ATTR_NAME = "name"; public static final String ATTR_NAME = "name";
public static final String ATTR_PAGE = "page"; public static final String ATTR_PAGE = "page";
public static final String ATTR_MANAGED_BEAN = "managed-bean"; public static final String ATTR_MANAGED_BEAN = "managed-bean";
public static final String ATTR_ICON = "icon";
public static final String ATTR_TITLE = "title"; public static final String ATTR_TITLE = "title";
public static final String ATTR_TITLE_ID = "title-id"; public static final String ATTR_TITLE_ID = "title-id";
public static final String ATTR_DESCRIPTION = "description"; public static final String ATTR_DESCRIPTION = "description";
@@ -68,13 +69,14 @@ public class DialogsElementReader implements ConfigElementReader
String name = item.attributeValue(ATTR_NAME); String name = item.attributeValue(ATTR_NAME);
String page = item.attributeValue(ATTR_PAGE); String page = item.attributeValue(ATTR_PAGE);
String bean = item.attributeValue(ATTR_MANAGED_BEAN); String bean = item.attributeValue(ATTR_MANAGED_BEAN);
String icon = item.attributeValue(ATTR_ICON);
String title = item.attributeValue(ATTR_TITLE); String title = item.attributeValue(ATTR_TITLE);
String titleId = item.attributeValue(ATTR_TITLE_ID); String titleId = item.attributeValue(ATTR_TITLE_ID);
String description = item.attributeValue(ATTR_DESCRIPTION); String description = item.attributeValue(ATTR_DESCRIPTION);
String descriptionId = item.attributeValue(ATTR_DESCRIPTION_ID); String descriptionId = item.attributeValue(ATTR_DESCRIPTION_ID);
DialogsConfigElement.DialogConfig cfg = new DialogsConfigElement.DialogConfig( DialogsConfigElement.DialogConfig cfg = new DialogsConfigElement.DialogConfig(
name, page, bean, title, titleId, description, descriptionId); name, page, bean, icon, title, titleId, description, descriptionId);
configElement.addDialog(cfg); configElement.addDialog(cfg);
} }

View File

@@ -158,9 +158,10 @@ public class WizardsConfigElement extends ConfigElementAdapter
{ {
protected String name; protected String name;
protected String managedBean; protected String managedBean;
protected String icon;
protected Map<String, StepConfig> steps = new LinkedHashMap<String, StepConfig>(4); protected Map<String, StepConfig> steps = new LinkedHashMap<String, StepConfig>(4);
public WizardConfig(String name, String bean, public WizardConfig(String name, String bean, String icon,
String title, String titleId, String title, String titleId,
String description, String descriptionId) String description, String descriptionId)
{ {
@@ -171,6 +172,7 @@ public class WizardsConfigElement extends ConfigElementAdapter
this.name = name; this.name = name;
this.managedBean = bean; this.managedBean = bean;
this.icon = icon;
} }
public String getName() public String getName()
@@ -183,6 +185,11 @@ public class WizardsConfigElement extends ConfigElementAdapter
return this.managedBean; return this.managedBean;
} }
public String getIcon()
{
return this.icon;
}
public void addStep(StepConfig step) public void addStep(StepConfig step)
{ {
this.steps.put(step.getName(), step); this.steps.put(step.getName(), step);
@@ -224,6 +231,7 @@ public class WizardsConfigElement extends ConfigElementAdapter
StringBuilder buffer = new StringBuilder(super.toString()); StringBuilder buffer = new StringBuilder(super.toString());
buffer.append(" (name=").append(this.name); buffer.append(" (name=").append(this.name);
buffer.append(" managed-bean=").append(this.managedBean); buffer.append(" managed-bean=").append(this.managedBean);
buffer.append(" icon=").append(this.icon);
buffer.append(" title=").append(this.title); buffer.append(" title=").append(this.title);
buffer.append(" titleId=").append(this.titleId); buffer.append(" titleId=").append(this.titleId);
buffer.append(" description=").append(this.description); buffer.append(" description=").append(this.description);

View File

@@ -41,6 +41,7 @@ public class WizardsElementReader implements ConfigElementReader
public static final String ATTR_NAME = "name"; public static final String ATTR_NAME = "name";
public static final String ATTR_MANAGED_BEAN = "managed-bean"; public static final String ATTR_MANAGED_BEAN = "managed-bean";
public static final String ATTR_ICON = "icon";
public static final String ATTR_TITLE = "title"; public static final String ATTR_TITLE = "title";
public static final String ATTR_TITLE_ID = "title-id"; public static final String ATTR_TITLE_ID = "title-id";
public static final String ATTR_DESCRIPTION = "description"; public static final String ATTR_DESCRIPTION = "description";
@@ -77,6 +78,7 @@ public class WizardsElementReader implements ConfigElementReader
String name = wizard.attributeValue(ATTR_NAME); String name = wizard.attributeValue(ATTR_NAME);
String bean = wizard.attributeValue(ATTR_MANAGED_BEAN); String bean = wizard.attributeValue(ATTR_MANAGED_BEAN);
String icon = wizard.attributeValue(ATTR_ICON);
String title = wizard.attributeValue(ATTR_TITLE); String title = wizard.attributeValue(ATTR_TITLE);
String titleId = wizard.attributeValue(ATTR_TITLE_ID); String titleId = wizard.attributeValue(ATTR_TITLE_ID);
String description = wizard.attributeValue(ATTR_DESCRIPTION); String description = wizard.attributeValue(ATTR_DESCRIPTION);
@@ -84,7 +86,7 @@ public class WizardsElementReader implements ConfigElementReader
// create the wizard config object // create the wizard config object
WizardsConfigElement.WizardConfig wizardCfg = new WizardsConfigElement.WizardConfig( WizardsConfigElement.WizardConfig wizardCfg = new WizardsConfigElement.WizardConfig(
name, bean, title, titleId, description, descriptionId); name, bean, icon, title, titleId, description, descriptionId);
Iterator<Element> steps = wizard.elementIterator(ELEMENT_STEP); Iterator<Element> steps = wizard.elementIterator(ELEMENT_STEP);
while (steps.hasNext()) while (steps.hasNext())

View File

@@ -95,6 +95,53 @@
</managed-property> </managed-property>
</managed-bean> </managed-bean>
<managed-bean>
<description>Bean that manages the dialog framework</description>
<managed-bean-name>DialogManager</managed-bean-name>
<managed-bean-class>org.alfresco.web.bean.dialog.DialogManager</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<description>Bean that manages the wizard framework</description>
<managed-bean-name>WizardManager</managed-bean-name>
<managed-bean-class>org.alfresco.web.bean.wizard.WizardManager</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<description>
The bean that backs up the Create Space Dialog
</description>
<managed-bean-name>CreateSpaceDialog</managed-bean-name>
<managed-bean-class>org.alfresco.web.bean.dialog.SpaceDialog</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>nodeService</property-name>
<value>#{NodeService}</value>
</managed-property>
<managed-property>
<property-name>fileFolderService</property-name>
<value>#{FileFolderService}</value>
</managed-property>
<managed-property>
<property-name>searchService</property-name>
<value>#{SearchService}</value>
</managed-property>
<managed-property>
<property-name>navigator</property-name>
<value>#{NavigationBean}</value>
</managed-property>
<managed-property>
<property-name>browseBean</property-name>
<value>#{BrowseBean}</value>
</managed-property>
<managed-property>
<property-name>namespaceService</property-name>
<value>#{NamespaceService}</value>
</managed-property>
</managed-bean>
<managed-bean> <managed-bean>
<description> <description>
The bean that holds a users Clipboard state. The bean that holds a users Clipboard state.

View File

@@ -0,0 +1,149 @@
<%--
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" %>
<%-- ***************************************************************************** --%>
<%-- TODO: Find a way to dynamically drive the container title for automated tests --%>
<%-- ***************************************************************************** --%>
<r:page title="Dialog Container">
<f:view>
<%-- load a bundle of properties with I18N strings --%>
<f:loadBundle basename="alfresco.messages.webclient" var="msg"/>
<h:form acceptCharset="UTF-8" id="dialog">
<%-- Main outer table --%>
<table cellspacing="0" cellpadding="2">
<%-- Title bar --%>
<tr>
<td colspan="2">
<%@ include file="../parts/titlebar.jsp" %>
</td>
</tr>
<%-- Main area --%>
<tr valign="top">
<%-- Shelf --%>
<td>
<%@ include file="../parts/shelf.jsp" %>
</td>
<%-- Work Area --%>
<td width="100%">
<table cellspacing="0" cellpadding="0" width="100%">
<%-- Breadcrumb --%>
<%@ include file="../parts/breadcrumb.jsp" %>
<%-- Status and Actions --%>
<tr>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_4.gif)" width="4"></td>
<td bgcolor="#EEEEEE">
<%-- Status and Actions inner contents table --%>
<%-- Generally this consists of an icon, textual summary and actions for the current object --%>
<table cellspacing="4" cellpadding="0" width="100%">
<tr>
<td width="32">
<h:graphicImage id="wizard-logo" url="#{DialogManager.icon}" />
</td>
<td>
<div class="mainTitle"><h:outputText value="#{DialogManager.title}" /></div>
<div class="mainSubText"><h:outputText value="#{DialogManager.description}" /></div>
</td>
</tr>
</table>
</td>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_6.gif)" width="4"></td>
</tr>
<%-- separator row with gradient shadow --%>
<tr>
<td><img src="<%=request.getContextPath()%>/images/parts/statuspanel_7.gif" width="4" height="9"></td>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_8.gif)"></td>
<td><img src="<%=request.getContextPath()%>/images/parts/statuspanel_9.gif" width="4" height="9"></td>
</tr>
<%-- Details --%>
<tr valign=top>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_4.gif)" width="4"></td>
<td>
<table cellspacing="0" cellpadding="3" border="0" width="100%">
<tr>
<td width="100%" valign="top">
<f:subview id="dialog-body">
<jsp:include page="<%=Application.getDialogManager().getPage() %>" />
</f:subview>
</td>
<td valign="top">
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %>
<table cellpadding="1" cellspacing="1" border="0">
<tr>
<td align="center">
<h:commandButton id="finish-button" styleClass="wizardButton"
value="#{DialogManager.finishButtonLabel}"
action="#{DialogManager.finish}"
disabled="#{DialogManager.finishButtonDisabled}" />
</td>
</tr>
<tr>
<td align="center">
<h:commandButton id="cancel-button" styleClass="wizardButton"
value="#{msg.cancel}"
action="#{DialogManager.cancel}" />
</td>
</tr>
</table>
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %>
</td>
</tr>
</table>
</td>
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_6.gif)" width="4"></td>
</tr>
<%-- separator row with bottom panel graphics --%>
<tr>
<td><img src="<%=request.getContextPath()%>/images/parts/whitepanel_7.gif" width="4" height="4"></td>
<td width="100%" align="center" style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_8.gif)"></td>
<td><img src="<%=request.getContextPath()%>/images/parts/whitepanel_9.gif" width="4" height="4"></td>
</tr>
</table>
</td>
</tr>
</table>
</h:form>
</f:view>
</r:page>

View File

@@ -0,0 +1,110 @@
<%--
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 import="org.alfresco.web.app.Application" %>
<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %>
<script language="JavaScript1.2">
window.onload = pageLoaded;
function pageLoaded()
{
document.getElementById("dialog:dialog-body:name").focus();
checkButtonState();
}
function checkButtonState()
{
if (document.getElementById("dialog:dialog-body:name").value.length == 0 )
{
document.getElementById("dialog:finish-button").disabled = true;
}
else
{
document.getElementById("dialog:finish-button").disabled = false;
}
}
</script>
<%-- Create Space Dialog Fragment --%>
<a:errors message="#{msg.error_create_space_dialog}" styleClass="errorMessage" />
<f:verbatim>
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %>
<table cellpadding="2" cellspacing="2" border="0" width="100%">
<tr>
<td colspan="2" class="wizardSectionHeading"></f:verbatim>
<h:outputText value="#{msg.space_props}" />
<f:verbatim></td>
</tr>
<tr>
<td></f:verbatim>
<h:outputText value="#{msg.name}:" /><f:verbatim>
</td>
<td></f:verbatim>
<h:inputText id="name" value="#{DialogManager.bean.name}" size="35" maxlength="1024"
onkeyup="javascript:checkButtonState();" onchange="javascript:checkButtonState();"/><f:verbatim>&nbsp;*
</td>
</tr>
<tr>
<td></f:verbatim>
<h:outputText value="#{msg.description}:" /><f:verbatim>
</td>
<td></f:verbatim>
<h:inputText value="#{DialogManager.bean.description}" size="35" maxlength="1024" />
<f:verbatim></td>
</tr>
<tr><td class="paddingRow"></td></tr>
<tr>
<td colspan="2" class="wizardSectionHeading">
&nbsp;</f:verbatim>
<h:outputText value="#{msg.other_options}" />
<f:verbatim></td>
</tr>
<tr>
<td></f:verbatim>
<h:outputText value="#{msg.choose_space_icon}:" /><f:verbatim>
</td>
<td>
<table border="0" cellpadding="0" cellspacing="0"><tr><td>
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %>
</f:verbatim>
<a:imagePickerRadio columns="6" spacing="4" value="#{DialogManager.bean.icon}" >
<a:listItems value="#{DialogManager.bean.icons}" />
</a:imagePickerRadio>
<f:verbatim>
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %>
</td></tr></table>
</td>
</tr>
<tr><td class="paddingRow"></td></tr>
<tr>
<td colspan="2"></f:verbatim>
<h:outputText value="#{msg.create_space_finish}" />
<f:verbatim></td>
</tr>
</table>
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %></f:verbatim>