diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index 576205e82c..f64bb23275 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -807,9 +807,20 @@ create_website_step1_desc=Enter the information about the web project. website_dnsname=DNS name validation_invalid_dns_name=Invalid website DNS name, a minimum of 2 alpha-numeric characters are accepted. website_forms=Form Templates +website_selected_forms=Selected Web Content Forms +website_save_scripts=Save Scripts +website_save_scripts_info=Use the following scripts when saving changes +website_pre_script=Pre-script +website_post_script=Post-script +website_workflow=Workflow +website_workflow_info=Use the following workflow +form_template_details=Form Details +form_template_details_desc=Edit the details of this Form Template +form_template_conf_workflow=Configure Workflow +form_template_select_templates=Select Templates create_website_step2_title=Step Two - Form Templates create_website_step2_desc=Setup the forms you want to use in this project. -website_select_form=Select Form +website_select_form=Select Form Templates to use website_invite=Invite Users create_website_step3_title=Step Three - Invite Users create_website_step3_desc=Select users and their roles. diff --git a/config/alfresco/web-client-config-dialogs.xml b/config/alfresco/web-client-config-dialogs.xml index d48f1610bc..18fb1b95d6 100644 --- a/config/alfresco/web-client-config-dialogs.xml +++ b/config/alfresco/web-client-config-dialogs.xml @@ -145,6 +145,10 @@ + + diff --git a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java index 6bfc7c86ab..f978f0a0d8 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java @@ -16,12 +16,10 @@ */ package org.alfresco.web.bean.wcm; -import java.io.Serializable; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.ResourceBundle; @@ -33,7 +31,6 @@ import javax.transaction.UserTransaction; import org.alfresco.model.ContentModel; import org.alfresco.repo.avm.AVMNodeConverter; -import org.alfresco.repo.avm.actions.StartAVMWorkflowAction; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.action.ActionService; import org.alfresco.service.cmr.avm.AVMNodeDescriptor; diff --git a/source/java/org/alfresco/web/bean/wcm/CreateFolderDialog.java b/source/java/org/alfresco/web/bean/wcm/CreateFolderDialog.java index 884abf7322..9818fe20d0 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateFolderDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateFolderDialog.java @@ -40,7 +40,6 @@ public class CreateFolderDialog extends BaseDialogBean protected AVMService avmService; protected AVMBrowseBean avmBrowseBean; - protected NodeService nodeService; private String name; private String description; @@ -73,14 +72,6 @@ public class CreateFolderDialog extends BaseDialogBean this.avmService = avmService; } - /** - * @param nodeService The NodeService to set. - */ - public void setNodeService(NodeService nodeService) - { - this.nodeService = nodeService; - } - /** * @return Returns the description. */ diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java index 9e813f1af3..8a73357fda 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java @@ -18,14 +18,16 @@ package org.alfresco.web.bean.wcm; import java.io.Serializable; import java.util.ArrayList; -import java.util.Collections; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.ResourceBundle; -import javax.faces.component.UISelectItem; import javax.faces.context.FacesContext; +import javax.faces.event.ActionEvent; +import javax.faces.model.DataModel; +import javax.faces.model.ListDataModel; import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; @@ -46,7 +48,10 @@ import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.wizard.BaseWizardBean; import org.alfresco.web.bean.wizard.InviteUsersWizard.UserGroupRole; +import org.alfresco.web.forms.Form; +import org.alfresco.web.forms.FormsService; import org.alfresco.web.ui.common.component.UIListItem; +import org.alfresco.web.ui.common.component.UISelectList; import org.alfresco.web.ui.wcm.WebResources; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -56,6 +61,7 @@ import org.apache.commons.logging.LogFactory; */ public class CreateWebsiteWizard extends BaseWizardBean { + private static final String COMPONENT_FORMLIST = "form-list"; private static final String MSG_DESCRIPTION = "description"; private static final String MSG_NAME = "name"; private static final String MSG_USERROLES = "create_website_summary_users"; @@ -74,6 +80,18 @@ public class CreateWebsiteWizard extends BaseWizardBean protected AVMService avmService; protected PermissionService permissionService; + /** datamodel for table of selected forms */ + private DataModel formsDataModel = null; + + /** transient list of form UIListItem objects */ + private List formsList = null; + + /** list of forms wrapper objects */ + private List forms = null; + + /** Current form action dialog context */ + private FormWrapper actionForm = null; + // ------------------------------------------------------------------------------ // Wizard implementation @@ -89,6 +107,8 @@ public class CreateWebsiteWizard extends BaseWizardBean this.dnsName = null; this.title = null; this.description = null; + this.formsDataModel = null; + this.forms = new ArrayList(); // init the dependant bean we are using for the invite users pages InviteWebsiteUsersWizard wiz = getInviteUsersWizard(); @@ -216,6 +236,23 @@ public class CreateWebsiteWizard extends BaseWizardBean this.name = name; } + public DataModel getFormsDataModel() + { + if (this.formsDataModel == null) + { + this.formsDataModel = new ListDataModel(); + } + + this.formsDataModel.setWrappedData(this.forms); + + return this.formsDataModel; + } + + public void setFormsDataModel(DataModel formsDataModel) + { + this.formsDataModel = formsDataModel; + } + /** * @return */ @@ -299,46 +336,76 @@ public class CreateWebsiteWizard extends BaseWizardBean new String[] {this.name, this.description, buf.toString()}); } + /** + * @return List of UI items to represent the available Forms for all websites + */ public List getFormsList() { - List forms = new ArrayList(); - UIListItem item = new UIListItem(); - item.setValue("0001"); - item.setLabel("Company Press Release"); - item.setDescription("Standard monthly press release form"); - item.setTooltip("Standard monthly press release form"); - item.setImage(WebResources.IMAGE_SANDBOX_32); - forms.add(item); - item = new UIListItem(); - item.setValue("0002"); - item.setLabel("Company Site Note"); - item.setDescription("Main site footer node"); - item.setTooltip("Basic footer node addition form"); - item.setImage(WebResources.IMAGE_SANDBOX_32); - forms.add(item); - item = new UIListItem(); - item.setValue("0003"); - item.setLabel("Index Generator"); - item.setDescription("Complete site index"); - item.setTooltip("Complete site index generation form"); - item.setImage(WebResources.IMAGE_SANDBOX_32); - forms.add(item); - return forms; + Collection forms = FormsService.getInstance().getForms(); + List items = new ArrayList(forms.size()); + for (Form form : forms) + { + UIListItem item = new UIListItem(); + item.setValue(form.getName()); + item.setLabel(form.getName()); + item.setDescription((String)this.nodeService.getProperty( + form.getNodeRef(), ContentModel.PROP_DESCRIPTION)); + item.setImage(WebResources.IMAGE_WEBFORM_32); + items.add(item); + } + this.formsList = items; + return items; } - public String[] getFormsSelectedValue() + /** + * Action handler called when the Add to List button is pressed for a form template + */ + public void addForm(ActionEvent event) { - return testValue; + UISelectList selectList = (UISelectList)event.getComponent().findComponent(COMPONENT_FORMLIST); + int index = selectList.getRowIndex(); + if (index != -1) + { + this.forms.add(new FormWrapper((String)this.formsList.get(index).getValue())); + } } - public void setFormsSelectedValue(String[] value) + /** + * Remove a template form from the selected list + */ + public void removeForm(ActionEvent event) { - testValue = value; + FormWrapper wrapper = (FormWrapper)this.formsDataModel.getRowData(); + if (wrapper != null) + { + this.forms.remove(wrapper); + } } - private String[] testValue = new String[] {"0001"}; - + /** + * Action method to navigate to setup a form dialog for the current row context + */ + public void setupFormAction(ActionEvent event) + { + setActionForm( (FormWrapper)this.formsDataModel.getRowData() ); + } + /** + * @return the current action form for dialog context + */ + public FormWrapper getActionForm() + { + return this.actionForm; + } + + /** + * @param actionForm For dialog context + */ + public void setActionForm(FormWrapper actionForm) + { + this.actionForm = actionForm; + } + /** * @return the InviteWebsiteUsersWizard delegate bean */ @@ -596,4 +663,51 @@ public class CreateWebsiteWizard extends BaseWizardBean logger.debug(" " + name + ": " + props.get(name)); } } + + + /** + * Wrapper class for a configurable template Form instance in the UI + */ + public static class FormWrapper + { + private String name; + private String title; + private String description; + + FormWrapper(String name) + { + this.name = name; + this.title = name; + } + + public String getName() + { + return this.name; + } + + public String getTitle() + { + return this.title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getDescription() + { + return this.description; + } + + public void setDescription(String description) + { + this.description = description; + } + + public String getDetails() + { + return "Using workflow 'default-workflow', pre-script, post-script, no templates selected."; + } + } } diff --git a/source/java/org/alfresco/web/bean/wcm/FormDetailsDialog.java b/source/java/org/alfresco/web/bean/wcm/FormDetailsDialog.java new file mode 100644 index 0000000000..c4025ee708 --- /dev/null +++ b/source/java/org/alfresco/web/bean/wcm/FormDetailsDialog.java @@ -0,0 +1,183 @@ +/* + * 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.wcm; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.faces.context.FacesContext; + +import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.web.bean.dialog.BaseDialogBean; +import org.alfresco.web.ui.common.component.UIListItem; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * @author Kevin Roast + */ +public class FormDetailsDialog extends BaseDialogBean +{ + private static final Log logger = LogFactory.getLog(FormDetailsDialog.class); + + protected AVMService avmService; + protected CreateWebsiteWizard websiteWizard; + + private String title; + private String description; + private String preScript; + private String postScript; + private String[] workflowSelectedValue; + + + /** + * @see org.alfresco.web.bean.dialog.BaseDialogBean#init(java.util.Map) + */ + @Override + public void init(Map parameters) + { + super.init(parameters); + this.title = null; + this.description = null; + } + + /** + * @param avmService The avmService to set. + */ + public void setAvmService(AVMService avmService) + { + this.avmService = avmService; + } + + /** + * @param wizard The Create Website Wizard to set. + */ + public void setCreateWebsiteWizard(CreateWebsiteWizard wizard) + { + this.websiteWizard = wizard; + } + + /** + * @return Returns the description. + */ + public String getDescription() + { + if (this.description == null) + { + this.description = this.websiteWizard.getActionForm().getDescription(); + } + return this.description; + } + + /** + * @param description The description to set. + */ + public void setDescription(String description) + { + this.description = description; + } + + /** + * @return Returns the title. + */ + public String getTitle() + { + if (this.title == null) + { + this.title = this.websiteWizard.getActionForm().getTitle(); + } + return this.title; + } + + /** + * @param title The title to set. + */ + public void setTitle(String title) + { + this.title = title; + } + + /** + * @return Returns the post-save Script. + */ + public String getPostScript() + { + return this.postScript; + } + + /** + * @param postScript The post-save Script to set. + */ + public void setPostScript(String postScript) + { + this.postScript = postScript; + } + + /** + * @return Returns the pre-save Script. + */ + public String getPreScript() + { + return this.preScript; + } + + /** + * @param preScript The pre-save Script to set. + */ + public void setPreScript(String preScript) + { + this.preScript = preScript; + } + + /** + * @return Returns the workflow Selected Value. + */ + public String[] getWorkflowSelectedValue() + { + return this.workflowSelectedValue; + } + + /** + * @param workflowSelectedValue The workflow Selected Value to set. + */ + public void setWorkflowSelectedValue(String[] workflowSelectedValue) + { + this.workflowSelectedValue = workflowSelectedValue; + } + + public List getWorkflowList() + { + List items = new ArrayList(); + + return items; + } + + + // ------------------------------------------------------------------------------ + // Dialog implementation + + /** + * @see org.alfresco.web.bean.dialog.BaseDialogBean#finishImpl(javax.faces.context.FacesContext, java.lang.String) + */ + @Override + protected String finishImpl(FacesContext context, String outcome) throws Exception + { + // TODO: push values from title/description etc. back into action FormWrapper! + return outcome; + } +} diff --git a/source/java/org/alfresco/web/forms/FormsService.java b/source/java/org/alfresco/web/forms/FormsService.java index f71cb3cb57..d6f97c7977 100644 --- a/source/java/org/alfresco/web/forms/FormsService.java +++ b/source/java/org/alfresco/web/forms/FormsService.java @@ -16,34 +16,56 @@ */ package org.alfresco.web.forms; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Serializable; +import java.io.StringWriter; +import java.io.Writer; import java.lang.reflect.Constructor; -import java.util.*; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + import javax.faces.context.FacesContext; -import javax.xml.parsers.*; -import javax.xml.transform.*; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; + +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.model.WCMModel; -import org.alfresco.repo.avm.*; -import org.alfresco.service.ServiceRegistry; +import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.service.cmr.avm.AVMNotFoundException; import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.dictionary.DictionaryService; -import org.alfresco.service.cmr.model.*; +import org.alfresco.service.cmr.model.FileFolderService; import org.alfresco.service.cmr.repository.AssociationRef; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.search.*; +import org.alfresco.service.cmr.search.ResultSet; +import org.alfresco.service.cmr.search.ResultSetRow; +import org.alfresco.service.cmr.search.SearchParameters; +import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; import org.alfresco.web.app.Application; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.wcm.AVMConstants; -import org.alfresco.web.forms.xforms.*; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.Document; @@ -134,28 +156,22 @@ public final class FormsService */ public Collection getForms() { - try - { - final SearchParameters sp = new SearchParameters(); - sp.addStore(Repository.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("ASPECT:\"" + WCMModel.ASPECT_FORM + "\""); + final SearchParameters sp = new SearchParameters(); + sp.addStore(Repository.getStoreRef()); + sp.setLanguage(SearchService.LANGUAGE_LUCENE); + sp.setQuery("ASPECT:\"" + WCMModel.ASPECT_FORM + "\""); + if (LOGGER.isDebugEnabled()) LOGGER.debug("running query [" + sp.getQuery() + "]"); - final ResultSet rs = this.searchService.query(sp); + final ResultSet rs = this.searchService.query(sp); + if (LOGGER.isDebugEnabled()) LOGGER.debug("received " + rs.length() + " results"); - final Collection result = new LinkedList(); - for (ResultSetRow row : rs) - { - final NodeRef nodeRef = row.getNodeRef(); - result.add(this.newForm(nodeRef)); - } - return result; - } - catch (RuntimeException re) + final Collection result = new LinkedList(); + for (ResultSetRow row : rs) { - LOGGER.error(re); - throw re; + final NodeRef nodeRef = row.getNodeRef(); + result.add(this.newForm(nodeRef)); } + return result; } /** @@ -165,35 +181,28 @@ public final class FormsService */ public Form getForm(final String name) { - try - { - final SearchParameters sp = new SearchParameters(); - sp.addStore(Repository.getStoreRef()); - sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("ASPECT:\"" + WCMModel.ASPECT_FORM + - "\" AND @" + Repository.escapeQName(ContentModel.PROP_TITLE) + - ":\"" + name + "\""); + final SearchParameters sp = new SearchParameters(); + sp.addStore(Repository.getStoreRef()); + sp.setLanguage(SearchService.LANGUAGE_LUCENE); + sp.setQuery("ASPECT:\"" + WCMModel.ASPECT_FORM + + "\" AND @" + Repository.escapeQName(ContentModel.PROP_TITLE) + + ":\"" + name + "\""); + if (LOGGER.isDebugEnabled()) LOGGER.debug("running query [" + sp.getQuery() + "]"); - final ResultSet rs = this.searchService.query(sp); - NodeRef result = null; - for (ResultSetRow row : rs) - { - final NodeRef nr = row.getNodeRef(); - if (this.nodeService.getProperty(nr, ContentModel.PROP_TITLE).equals(name)) - { - result = nr; - break; - } - } - if (result == null && LOGGER.isDebugEnabled()) - LOGGER.debug("unable to find tempalte type " + name); - return result != null ? this.newForm(result) : null; - } - catch (RuntimeException re) + final ResultSet rs = this.searchService.query(sp); + NodeRef result = null; + for (ResultSetRow row : rs) { - LOGGER.error(re); - throw re; + final NodeRef nr = row.getNodeRef(); + if (this.nodeService.getProperty(nr, ContentModel.PROP_TITLE).equals(name)) + { + result = nr; + break; + } } + if (result == null && LOGGER.isDebugEnabled()) + LOGGER.debug("unable to find tempalte type " + name); + return result != null ? this.newForm(result) : null; } /** @@ -216,13 +225,16 @@ public final class FormsService */ private Form newForm(final NodeRef schemaNodeRef) { - LOGGER.debug("creating form for " + schemaNodeRef); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("creating form for " + schemaNodeRef); final String title = (String) this.nodeService.getProperty(schemaNodeRef, ContentModel.PROP_TITLE); - LOGGER.debug("title is " + title); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("title is " + title); final String schemaRootTagName = (String) this.nodeService.getProperty(schemaNodeRef, WCMModel.PROP_SCHEMA_ROOT_ELEMENT_NAME); - LOGGER.debug("root tag name is " + schemaRootTagName); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("root tag name is " + schemaRootTagName); final Form tt = new FormImpl(title, schemaNodeRef, schemaRootTagName); for (AssociationRef assoc : this.nodeService.getTargetAssocs(schemaNodeRef, WCMModel.ASSOC_RENDERING_ENGINES)) @@ -237,14 +249,17 @@ public final class FormsService final Constructor c = formDataRendererType.getConstructor(NodeRef.class, NodeService.class, ContentService.class); final RenderingEngine tom = (RenderingEngine) c.newInstance(tomNodeRef, this.nodeService, this.contentService); - LOGGER.debug("loaded form data renderer type " + tom.getClass().getName() + - " for extension " + tom.getFileExtensionForRendition() + - ", " + tomNodeRef); + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("loaded form data renderer type " + tom.getClass().getName() + + " for extension " + tom.getFileExtensionForRendition() + + ", " + tomNodeRef); + } tt.addRenderingEngine(tom); } catch (Exception e) { - LOGGER.error(e); + throw new AlfrescoRuntimeException(e.getMessage(), e); } } return tt; @@ -303,8 +318,9 @@ public final class FormsService props = new HashMap(1, 1.0f); props.put(ContentModel.PROP_TITLE, renditionFileName); nodeService.addAspect(renditionNodeRef, ContentModel.ASPECT_TITLED, props); - - LOGGER.debug("generated " + renditionFileName + " using " + re); + + if (LOGGER.isDebugEnabled()) + LOGGER.debug("generated " + renditionFileName + " using " + re); } } @@ -362,7 +378,8 @@ public final class FormsService re.render(formInstanceData, parameters, out); out.close(); - LOGGER.debug("generated " + renditionFileName + " using " + re); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("generated " + renditionFileName + " using " + re); } } @@ -398,14 +415,14 @@ public final class FormsService if (LOGGER.isDebugEnabled()) { LOGGER.debug("writing out a document for " + - (n instanceof Document - ? ((Document)n).getDocumentElement() - : n).getNodeName() + - " to " + (output instanceof StringWriter - ? "string" - : output)); - final StringWriter sw = new StringWriter(); - t.transform(new DOMSource(n), new StreamResult(sw)); + (n instanceof Document + ? ((Document)n).getDocumentElement() + : n).getNodeName() + + " to " + (output instanceof StringWriter + ? "string" + : output)); + final StringWriter sw = new StringWriter(); + t.transform(new DOMSource(n), new StreamResult(sw)); LOGGER.debug(sw.toString()); } t.transform(new DOMSource(n), new StreamResult(output)); diff --git a/source/java/org/alfresco/web/forms/XSLTRenderingEngine.java b/source/java/org/alfresco/web/forms/XSLTRenderingEngine.java index c7cc42acba..f08f902370 100644 --- a/source/java/org/alfresco/web/forms/XSLTRenderingEngine.java +++ b/source/java/org/alfresco/web/forms/XSLTRenderingEngine.java @@ -121,7 +121,8 @@ public class XSLTRenderingEngine final FormDataFunctions ef = XSLTRenderingEngine.getFormDataFunctions(); path = XSLTRenderingEngine.toAVMPath(ec, path); final Map resultMap = ef.parseXMLDocuments(formName, path); - LOGGER.debug("received " + resultMap.size() + " documents in " + path); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("received " + resultMap.size() + " documents in " + path); // create a root document for rooting all the results. we do this // so that each document root element has a common parent node @@ -154,7 +155,8 @@ public class XSLTRenderingEngine public void detach() { - LOGGER.debug("detaching NodeIterator"); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("detaching NodeIterator"); resultMap.clear(); documents.clear(); this.detached = true; @@ -189,7 +191,8 @@ public class XSLTRenderingEngine public Node nextNode() throws DOMException { - LOGGER.debug("NodeIterator.nextNode(" + index + ")"); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("NodeIterator.nextNode(" + index + ")"); if (this.detached) throw new DOMException(DOMException.INVALID_STATE_ERR, null); if (index == documents.size()) @@ -200,7 +203,8 @@ public class XSLTRenderingEngine public Node previousNode() throws DOMException { - LOGGER.debug("NodeIterator.previousNode(" + index + ")"); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("NodeIterator.previousNode(" + index + ")"); if (this.detached) throw new DOMException(DOMException.INVALID_STATE_ERR, null); if (index == -1) @@ -337,14 +341,15 @@ public class XSLTRenderingEngine } try { - LOGGER.debug("loading " + uri); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("loading " + uri); final Document d = ts.parseXML(uri.toURL().openStream()); - LOGGER.debug("loaded " + ts.writeXMLToString(d)); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("loaded " + ts.writeXMLToString(d)); return new DOMSource(d); } catch (Exception e) { - LOGGER.warn(e); throw new TransformerException("unable to load " + uri, e); } } diff --git a/source/java/org/alfresco/web/ui/common/component/UISelectList.java b/source/java/org/alfresco/web/ui/common/component/UISelectList.java index 112c8435b3..dac0b66e01 100644 --- a/source/java/org/alfresco/web/ui/common/component/UISelectList.java +++ b/source/java/org/alfresco/web/ui/common/component/UISelectList.java @@ -29,6 +29,10 @@ import javax.faces.component.UIInput; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import javax.faces.el.ValueBinding; +import javax.faces.event.AbortProcessingException; +import javax.faces.event.FacesEvent; +import javax.faces.event.FacesListener; +import javax.faces.event.PhaseId; import org.alfresco.web.ui.common.Utils; @@ -47,10 +51,12 @@ import org.alfresco.web.ui.common.Utils; * * @author Kevin Roast */ -public class UISelectList extends UIInput +public class UISelectList extends UIInput implements NamingContainer { private Boolean multiSelect; private Boolean activeSelect; + private int rowIndex = -1; + private int itemCount; // ------------------------------------------------------------------------------ @@ -82,6 +88,7 @@ public class UISelectList extends UIInput super.restoreState(context, values[0]); this.multiSelect = (Boolean)values[1]; this.activeSelect = (Boolean)values[2]; + this.itemCount = (Integer)values[3]; } /** @@ -89,14 +96,107 @@ public class UISelectList extends UIInput */ public Object saveState(FacesContext context) { - Object values[] = new Object[3]; + Object values[] = new Object[4]; // standard component attributes are saved by the super class values[0] = super.saveState(context); values[1] = this.multiSelect; values[2] = this.activeSelect; + values[3] = this.itemCount; return (values); } + /** + * @return the client Id for this naming container component - based on the current row context. + * This allows a single component rendered multiple times in a list to dynamically base + * their ID on the current row - so that the 'correct' component is decoded and event is + * queued with the current row value. + */ + @Override + public String getClientId(FacesContext context) + { + String clientId = super.getClientId(context); + int rowIndex = getRowIndex(); + if (rowIndex == -1) + { + return clientId; + } + return clientId + "_" + rowIndex; + } + + /** + * Override the processing of child component decodes - we set the current row context so any + * events queued by child components wrapped in FacesEventWrapper have current row value. + */ + @Override + public void processDecodes(FacesContext context) + { + if (!isRendered()) + { + return; + } + + setRowIndex(-1); + for (Iterator itr=getChildren().iterator(); itr.hasNext(); /**/) + { + UIComponent child = (UIComponent)itr.next(); + if (child instanceof UIListItem == false && child instanceof UIListItems == false) + { + for (int i=0; i'); // get the child components and look for compatible ListItem objects + this.itemCount = 0; + setRowIndex(-1); for (Iterator i = getChildren().iterator(); i.hasNext(); /**/) { UIComponent child = (UIComponent)i.next(); @@ -177,8 +279,10 @@ public class UISelectList extends UIInput { requestMap.put(var, item); } + setRowIndex(this.itemCount); renderItem(context, out, item); } + this.itemCount++; } } } @@ -192,10 +296,13 @@ public class UISelectList extends UIInput { requestMap.put(var, item); } + setRowIndex(this.itemCount); renderItem(context, out, item); } + this.itemCount++; } } + setRowIndex(-1); if (var != null) { requestMap.remove(var); @@ -318,6 +425,37 @@ public class UISelectList extends UIInput // ------------------------------------------------------------------------------ // Strongly typed property accessors + /** + * @return current row index + */ + public int getRowIndex() + { + return this.rowIndex; + } + + /** + * Set the transient current row index. Setting this value causes all child components to + * have their ID values reset - so that cached clientID values are regenerated when next requested. + * + * @param rowIndex + */ + public void setRowIndex(int rowIndex) + { + this.rowIndex = rowIndex; + for (Iterator itr=getChildren().iterator(); itr.hasNext(); /**/) + { + UIComponent child = (UIComponent)itr.next(); + if (child instanceof UIListItem == false && child instanceof UIListItems == false) + { + // forces a reset of the clientId for the component + // This is then regenerated - relative to this naming container which itself uses the + // current row index as part of the Id. This is what facilities the correct component + // rendering submit script and then identified during the decode() phase. + child.setId(child.getId()); + } + } + } + /** * Get the multi-select rendering flag * @@ -399,4 +537,61 @@ public class UISelectList extends UIInput UIForm form = Utils.getParentForm(context, component); return form.getClientId(context) + NamingContainer.SEPARATOR_CHAR + "selectlist"; } + + + /** + * Wrapper for a FacesEvent to hold current row value when the event was fired + */ + private static class FacesEventWrapper extends FacesEvent + { + private FacesEvent wrappedFacesEvent; + private int rowIndex; + + public FacesEventWrapper(FacesEvent facesEvent, int rowIndex, UISelectList redirectComponent) + { + super(redirectComponent); + wrappedFacesEvent = facesEvent; + this.rowIndex = rowIndex; + } + + public PhaseId getPhaseId() + { + return wrappedFacesEvent.getPhaseId(); + } + + public void setPhaseId(PhaseId phaseId) + { + wrappedFacesEvent.setPhaseId(phaseId); + } + + public void queue() + { + wrappedFacesEvent.queue(); + } + + public String toString() + { + return wrappedFacesEvent.toString(); + } + + public boolean isAppropriateListener(FacesListener faceslistener) + { + return wrappedFacesEvent.isAppropriateListener(faceslistener); + } + + public void processListener(FacesListener faceslistener) + { + wrappedFacesEvent.processListener(faceslistener); + } + + public FacesEvent getWrappedFacesEvent() + { + return wrappedFacesEvent; + } + + public int getRowIndex() + { + return rowIndex; + } + } } diff --git a/source/java/org/alfresco/web/ui/wcm/WebResources.java b/source/java/org/alfresco/web/ui/wcm/WebResources.java index 0eac43f1b0..8e13e48179 100644 --- a/source/java/org/alfresco/web/ui/wcm/WebResources.java +++ b/source/java/org/alfresco/web/ui/wcm/WebResources.java @@ -24,4 +24,5 @@ public class WebResources extends org.alfresco.web.ui.repo.WebResources // Image paths public static final String IMAGE_SANDBOX_32 = "/images/icons/sandbox_large.gif"; public static final String IMAGE_USERSANDBOX_32 = "/images/icons/user_sandbox_large.gif"; + public static final String IMAGE_WEBFORM_32 = "/images/icons/webform_large.gif"; } diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index f7a40c5104..a36cc574e0 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -2513,6 +2513,27 @@ + + + The bean that backs up the Form Template Details dialog + + FormDetailsDialog + org.alfresco.web.bean.wcm.FormDetailsDialog + session + + avmService + #{AVMService} + + + nodeService + #{NodeService} + + + createWebsiteWizard + #{CreateWebsiteWizard} + + + diff --git a/source/web/css/main.css b/source/web/css/main.css index 34f8b9dafc..ca47a41ab1 100644 --- a/source/web/css/main.css +++ b/source/web/css/main.css @@ -563,7 +563,9 @@ a.topToolbarLinkHighlight, a.topToolbarLinkHighlight:link, a.topToolbarLinkHighl .selectListTable { border: 1px solid #999999; - padding: 2px; + padding-top: 2px; + padding-left: 2px; + padding-right: 2px; } .selectListItem diff --git a/source/web/images/icons/webform_large.gif b/source/web/images/icons/webform_large.gif new file mode 100644 index 0000000000..def3c84410 Binary files /dev/null and b/source/web/images/icons/webform_large.gif differ diff --git a/source/web/jsp/wcm/create-form-wizard/configure-rendering-engines.jsp b/source/web/jsp/wcm/create-form-wizard/configure-rendering-engines.jsp index d4aabc277e..0ca938b285 100644 --- a/source/web/jsp/wcm/create-form-wizard/configure-rendering-engines.jsp +++ b/source/web/jsp/wcm/create-form-wizard/configure-rendering-engines.jsp @@ -162,7 +162,7 @@ else cellpadding="2" styleClass="selectedItems" rowClasses="selectedItemsHeader,selectedItemsRow"> - + diff --git a/source/web/jsp/wcm/create-website-wizard/details.jsp b/source/web/jsp/wcm/create-website-wizard/details.jsp index 3277617c19..2cedf84858 100644 --- a/source/web/jsp/wcm/create-website-wizard/details.jsp +++ b/source/web/jsp/wcm/create-website-wizard/details.jsp @@ -40,7 +40,8 @@ function checkButtonState() { - if (document.getElementById("wizard:wizard-body:name").value.length == 0) + if (document.getElementById("wizard:wizard-body:name").value.length == 0 || + document.getElementById("wizard:wizard-body:dnsname").value.length < 2) { document.getElementById("wizard:next-button").disabled = true; document.getElementById("wizard:finish-button").disabled = true; diff --git a/source/web/jsp/wcm/create-website-wizard/form-details.jsp b/source/web/jsp/wcm/create-website-wizard/form-details.jsp new file mode 100644 index 0000000000..5ff3d81610 --- /dev/null +++ b/source/web/jsp/wcm/create-website-wizard/form-details.jsp @@ -0,0 +1,152 @@ +<%-- + 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" %> + +<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> +<%@ page isELIgnored="false" %> + + + <%-- Form properties --%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <%-- Save scripts --%> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <%-- Workflow --%> + + + + + + + + + + + + + + + + + + + + + <%-- Workflow selection list - scrollable DIV area --%> + + + + + + + + + + + + + + + diff --git a/source/web/jsp/wcm/create-website-wizard/forms.jsp b/source/web/jsp/wcm/create-website-wizard/forms.jsp index 9920ca7de2..a81cac558a 100644 --- a/source/web/jsp/wcm/create-website-wizard/forms.jsp +++ b/source/web/jsp/wcm/create-website-wizard/forms.jsp @@ -22,25 +22,55 @@ <%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %> <%@ page isELIgnored="false" %> - + + <%-- Form selection list - scrollable DIV area --%> - - - + + + + + + + + - - - - + <%-- Selected Form table, with configuration buttons and info text --%> + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - + + + + + + diff --git a/source/web/jsp/wcm/create-website-wizard/invite.jsp b/source/web/jsp/wcm/create-website-wizard/invite.jsp index a4dbb3987e..777c336d3c 100644 --- a/source/web/jsp/wcm/create-website-wizard/invite.jsp +++ b/source/web/jsp/wcm/create-website-wizard/invite.jsp @@ -54,7 +54,7 @@ License. - +