From a25d85ee8385b1c9096ae16a044983f5ee2fb592 Mon Sep 17 00:00:00 2001 From: Ariel Backenroth Date: Sun, 31 Dec 2006 08:45:42 +0000 Subject: [PATCH] - moving generic xml parsing utilities out of FormsService and into their own class - refactoring to generate and regenerate methods to make it easier to use project level overridden properties, and to at some point (soon) make it possible to make error handling for rendering engines more robust - added a web project object to encapsulate web project properties and provide a central location for getting forms and rendering engines with web project level overridden properties - made select default workflow screen match wireframes - using the same workflowdefault type in the wcm model for web projects and forms. - using outputpathpattern aspect consistently - using commons.io to parse paths - using form name rather than noderef as parameter for selected form from content forms dashlet - fixed bug where rendition properties noderef wasn't being properly associated with renditions causing problems with regenerate - using multivalued properties to track renditions - remove weird registerRendition/registerFormInstanceData calls. no longer necessary since generateRendition and regenerate are done within forminstancedata and rendition - adding default workflow parameters as property of Form - adding a unique name property to rendering engine templates to allow for looking one up by name git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4702 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/messages/webclient.properties | 5 +- .../web-client-application-context.xml | 3 - .../web/app/servlet/UploadFileServlet.java | 352 +++++++++--------- .../alfresco/web/bean/wcm/AVMBrowseBean.java | 66 ++-- .../alfresco/web/bean/wcm/AVMConstants.java | 64 +++- .../alfresco/web/bean/wcm/AVMEditBean.java | 70 ++-- .../web/bean/wcm/AVMWorkflowUtil.java | 6 +- .../web/bean/wcm/CreateFormWizard.java | 195 ++++++---- .../web/bean/wcm/CreateWebContentWizard.java | 146 +++----- .../web/bean/wcm/CreateWebsiteWizard.java | 89 ++--- .../alfresco/web/bean/wcm/EditFormWizard.java | 26 +- .../web/bean/wcm/EditWebsiteWizard.java | 26 +- .../web/bean/wcm/FormDetailsDialog.java | 20 +- .../web/bean/wcm/FormTemplatesDialog.java | 2 +- .../alfresco/web/bean/wcm/SubmitDialog.java | 2 +- .../org/alfresco/web/bean/wcm/WebProject.java | 309 +++++++++++++++ .../web/forms/AbstractRenderingEngine.java | 18 + source/java/org/alfresco/web/forms/Form.java | 26 +- .../alfresco/web/forms/FormDataFunctions.java | 27 +- .../java/org/alfresco/web/forms/FormImpl.java | 120 ++++-- .../alfresco/web/forms/FormInstanceData.java | 8 +- .../web/forms/FormInstanceDataImpl.java | 61 +-- .../org/alfresco/web/forms/FormsService.java | 300 +-------------- .../web/forms/FreeMarkerRenderingEngine.java | 21 +- .../alfresco/web/forms/RenderingEngine.java | 11 +- .../web/forms/RenderingEngineTemplate.java | 17 +- .../forms/RenderingEngineTemplateImpl.java | 128 +++++-- .../org/alfresco/web/forms/Rendition.java | 23 +- .../org/alfresco/web/forms/RenditionImpl.java | 51 ++- .../java/org/alfresco/web/forms/XMLUtil.java | 165 ++++++++ .../web/forms/XSLFORenderingEngine.java | 33 +- .../web/forms/XSLTRenderingEngine.java | 37 +- .../web/forms/xforms/SchemaFormBuilder.java | 17 +- .../alfresco/web/forms/xforms/SchemaUtil.java | 5 +- .../alfresco/web/forms/xforms/XFormsBean.java | 34 +- .../web/forms/xforms/XFormsProcessor.java | 5 +- .../web/ui/wcm/component/UIUserSandboxes.java | 60 +-- .../configure-rendering-engines.jsp | 47 ++- .../select-default-workflow.jsp | 40 +- .../wcm/create-web-content-wizard/summary.jsp | 2 +- .../create-website-wizard/form-details.jsp | 4 +- .../create-website-wizard/form-templates.jsp | 4 +- .../jsp/wcm/create-website-wizard/summary.jsp | 4 +- 43 files changed, 1546 insertions(+), 1103 deletions(-) create mode 100644 source/java/org/alfresco/web/bean/wcm/WebProject.java create mode 100644 source/java/org/alfresco/web/forms/XMLUtil.java diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index 8f8aac7533..70faf8ecc0 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -45,6 +45,7 @@ no_icons_found=No icons found # UI Component messages yes=Yes no=No +no_not_now=No not now kilobyte=KB megabyte=MB gigabyte=GB @@ -667,6 +668,8 @@ create_form_configure_rendering_engine_templates_step1_desc=Select the rendering create_form_configure_rendering_engine_templates_step2_desc=Specify details for the new rendering engine template create_form_select_default_workflow_title=Stop Three - Select default workflow create_form_select_default_workflow_desc=Select the workflow you want to be used by default for form {0}. +create_form_select_default_workflow_apply_default_workflow=Do you want to apply a default workflow now? +create_form_select_default_workflow_select_workflow=Select a workflow create_web_content_summary_desc=The wizard has successfully created the content and all renditions. create_web_content_summary_content_details=Content Details create_web_content_summary_rendition_details=Rendition Details @@ -839,7 +842,7 @@ website_filename_pattern=Filename pattern website_filename_match=Filename pattern match website_workflow=Workflow website_workflow_info=Use the following workflow -website_form_summary=Using workflow ''{0}'', with filename pattern ''{1}'', {2,choice,0#no rendering engines|1#one rendering engine|1<{2,number} rendering engines} selected. +website_form_summary=Using workflow ''{0}'', with output path pattern ''{1}'', {2,choice,0#no rendering engines|1#one rendering engine|1<{2,number} rendering engines} selected. website_forms=Define Forms form_template_details=Form Details form_template_details_desc=Edit the details of this Form Template diff --git a/config/alfresco/web-client-application-context.xml b/config/alfresco/web-client-application-context.xml index 5c757faba3..fac2f10bc4 100644 --- a/config/alfresco/web-client-application-context.xml +++ b/config/alfresco/web-client-application-context.xml @@ -49,9 +49,6 @@ - - - diff --git a/source/java/org/alfresco/web/app/servlet/UploadFileServlet.java b/source/java/org/alfresco/web/app/servlet/UploadFileServlet.java index 0e78caa932..3be52a0312 100644 --- a/source/java/org/alfresco/web/app/servlet/UploadFileServlet.java +++ b/source/java/org/alfresco/web/app/servlet/UploadFileServlet.java @@ -1,179 +1,173 @@ -/* - * 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.app.servlet; - -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.Iterator; -import java.util.List; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.alfresco.error.AlfrescoRuntimeException; -import org.alfresco.util.TempFileProvider; -import org.alfresco.web.app.Application; -import org.alfresco.web.bean.FileUploadBean; -import org.apache.commons.fileupload.FileItem; -import org.apache.commons.fileupload.RequestContext; -import org.apache.commons.fileupload.disk.DiskFileItemFactory; -import org.apache.commons.fileupload.servlet.ServletFileUpload; -import org.apache.commons.fileupload.servlet.ServletRequestContext; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Servlet that takes a file uploaded via a browser and represents it as an - * UploadFileBean in the session - * - * @author gavinc - */ -public class UploadFileServlet extends BaseServlet -{ - private static final long serialVersionUID = -5482538466491052873L; - private static final Log logger = LogFactory.getLog(UploadFileServlet.class); - - /** - * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) - */ - protected void service(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException - { - String uploadId = null; - String returnPage = null; - final RequestContext requestContext = new ServletRequestContext(request); - boolean isMultipart = ServletFileUpload.isMultipartContent(requestContext); - - try - { - AuthenticationStatus status = servletAuthenticate(request, response); - if (status == AuthenticationStatus.Failure) - { - return; - } - - if (!isMultipart) - { - throw new AlfrescoRuntimeException("This servlet can only be used to handle file upload requests, make" + - "sure you have set the enctype attribute on your form to multipart/form-data"); - } - - if (logger.isDebugEnabled()) - logger.debug("Uploading servlet servicing..."); - - HttpSession session = request.getSession(); - ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory()); - - // ensure that the encoding is handled correctly - upload.setHeaderEncoding("UTF-8"); - - List fileItems = upload.parseRequest(request); - - FileUploadBean bean = new FileUploadBean(); - for (FileItem item : fileItems) - { - if(item.isFormField()) - { - if (item.getFieldName().equalsIgnoreCase("return-page")) - { - returnPage = item.getString(); - } - else if (item.getFieldName().equalsIgnoreCase("upload-id")) - { - uploadId = item.getString(); - } - } - else - { - String filename = item.getName(); - if (filename != null && filename.length() != 0) - { - if (logger.isDebugEnabled()) - { - logger.debug("Processing uploaded file: " + filename); - } - // workaround a bug in IE where the full path is returned - // IE is only available for Windows so only check for the Windows path separator - int idx = filename.lastIndexOf('\\'); - if (idx == -1) - { - // if there is no windows path separator check for *nix - idx = filename.lastIndexOf('/'); - } - - if (idx != -1) - { - filename = filename.substring(idx + File.separator.length()); - } - - File tempFile = TempFileProvider.createTempFile("alfresco", ".upload"); - item.write(tempFile); - bean.setFile(tempFile); - bean.setFileName(filename); - bean.setFilePath(tempFile.getAbsolutePath()); - if (logger.isDebugEnabled()) - { - logger.debug("Temp file: " + tempFile.getAbsolutePath() + - " created from upload filename: " + filename); - } - } - } - } - - session.setAttribute(FileUploadBean.getKey(uploadId), bean); - - if (returnPage == null || returnPage.length() == 0) - { - throw new AlfrescoRuntimeException("return-page parameter has not been supplied"); - } - - if (returnPage.startsWith("javascript:")) - { - returnPage = returnPage.substring("javascript:".length()); - // finally redirect - if (logger.isDebugEnabled()) - { - logger.debug("Sending back javascript response " + returnPage); - } - - final PrintWriter out = response.getWriter(); - out.println(""); - out.close(); - } - else - { - // finally redirect - if (logger.isDebugEnabled()) - { - logger.debug("Upload servicing complete, redirecting to: " + returnPage); - } - - response.sendRedirect(returnPage); - } - } - catch (Throwable error) - { - Application.handleServletError(getServletContext(), (HttpServletRequest)request, - (HttpServletResponse)response, error, logger, returnPage); - } - } -} +/* + * 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.app.servlet; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Iterator; +import java.util.List; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.util.TempFileProvider; +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.FileUploadBean; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.RequestContext; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.fileupload.servlet.ServletRequestContext; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Servlet that takes a file uploaded via a browser and represents it as an + * UploadFileBean in the session + * + * @author gavinc + */ +public class UploadFileServlet extends BaseServlet +{ + private static final long serialVersionUID = -5482538466491052873L; + private static final Log logger = LogFactory.getLog(UploadFileServlet.class); + + /** + * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + protected void service(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException + { + String uploadId = null; + String returnPage = null; + final RequestContext requestContext = new ServletRequestContext(request); + boolean isMultipart = ServletFileUpload.isMultipartContent(requestContext); + + try + { + AuthenticationStatus status = servletAuthenticate(request, response); + if (status == AuthenticationStatus.Failure) + { + return; + } + + if (!isMultipart) + { + throw new AlfrescoRuntimeException("This servlet can only be used to handle file upload requests, make" + + "sure you have set the enctype attribute on your form to multipart/form-data"); + } + + if (logger.isDebugEnabled()) + logger.debug("Uploading servlet servicing..."); + + HttpSession session = request.getSession(); + ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory()); + + // ensure that the encoding is handled correctly + upload.setHeaderEncoding("UTF-8"); + + List fileItems = upload.parseRequest(request); + + FileUploadBean bean = new FileUploadBean(); + for (FileItem item : fileItems) + { + if(item.isFormField()) + { + if (item.getFieldName().equalsIgnoreCase("return-page")) + { + returnPage = item.getString(); + } + else if (item.getFieldName().equalsIgnoreCase("upload-id")) + { + uploadId = item.getString(); + } + } + else + { + String filename = item.getName(); + if (filename != null && filename.length() != 0) + { + if (logger.isDebugEnabled()) + { + logger.debug("Processing uploaded file: " + filename); + } + // workaround a bug in IE where the full path is returned + // IE is only available for Windows so only check for the Windows path separator + filename = FilenameUtils.getName(filename); + final File tempFile = TempFileProvider.createTempFile("alfresco", ".upload"); + item.write(tempFile); + bean.setFile(tempFile); + bean.setFileName(filename); + bean.setFilePath(tempFile.getAbsolutePath()); + if (logger.isDebugEnabled()) + { + logger.debug("Temp file: " + tempFile.getAbsolutePath() + + " created from upload filename: " + filename); + } + } + } + } + + session.setAttribute(FileUploadBean.getKey(uploadId), bean); + + if (bean.getFile() == null) + { + logger.warn("no file uploaded for upload " + uploadId); + } + if (returnPage == null || returnPage.length() == 0) + { + throw new AlfrescoRuntimeException("return-page parameter has not been supplied"); + } + + if (returnPage.startsWith("javascript:")) + { + returnPage = returnPage.substring("javascript:".length()); + // finally redirect + if (logger.isDebugEnabled()) + { + logger.debug("Sending back javascript response " + returnPage); + } + + final PrintWriter out = response.getWriter(); + out.println(""); + out.close(); + } + else + { + // finally redirect + if (logger.isDebugEnabled()) + { + logger.debug("Upload servicing complete, redirecting to: " + returnPage); + } + + response.sendRedirect(returnPage); + } + } + catch (Throwable error) + { + Application.handleServletError(getServletContext(), (HttpServletRequest)request, + (HttpServletResponse)response, error, logger, returnPage); + } + } +} diff --git a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java index 6552faf875..6516b4096c 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMBrowseBean.java @@ -100,9 +100,6 @@ public class AVMBrowseBean implements IContextListener /** Top-level JSF form ID */ static final String FORM_ID = "browse-website"; - /** Content Manager role name */ - private static final String ROLE_CONTENT_MANAGER = "ContentManager"; - /** Snapshot date filter selection */ private String snapshotDateFilter = UISandboxSnapshots.FILTER_DATE_TODAY; @@ -140,6 +137,9 @@ public class AVMBrowseBean implements IContextListener /** The last displayed website node id */ private String lastWebsiteId = null; + /** The current webProject */ + private WebProject webProject = null; + /** breadcrumb location */ private List location = null; @@ -158,7 +158,6 @@ public class AVMBrowseBean implements IContextListener /** Action service bean reference */ protected ActionService actionService; - /** * Default Constructor */ @@ -236,7 +235,7 @@ public class AVMBrowseBean implements IContextListener final ResourceBundle msg = Application.getBundle(fc); final String stagingStore = this.getStagingStore(); final AVMStoreDescriptor store = this.avmService.getStore(stagingStore); - final String storeId = (String)getWebsite().getProperties().get(WCMAppModel.PROP_AVMSTORE); + final String storeId = (String)this.getWebProject().getStoreId(); if (store != null) { summary.append(msg.getString(MSG_CREATED_ON)).append(": ") @@ -245,9 +244,7 @@ public class AVMBrowseBean implements IContextListener summary.append(msg.getString(MSG_CREATED_BY)).append(": ") .append(store.getCreator()) .append("

"); - final int numUsers = this.getRelatedStoreNames(storeId, - AVMConstants.PROP_SANDBOX_AUTHOR_MAIN).size(); - + final int numUsers = this.getRelatedStoreNames(storeId, AVMConstants.PROP_SANDBOX_AUTHOR_MAIN).size(); summary.append(MessageFormat.format(msg.getString(MSG_WORKING_USERS), numUsers)); } @@ -288,8 +285,7 @@ public class AVMBrowseBean implements IContextListener */ public String getStagingStore() { - String storeRoot = (String)getWebsite().getProperties().get(WCMAppModel.PROP_AVMSTORE); - return AVMConstants.buildStagingStoreName(storeRoot); + return this.getWebProject().getStagingStore(); } /** @@ -395,7 +391,7 @@ public class AVMBrowseBean implements IContextListener { if (this.webapp == null) { - this.webapp = (String)getWebsite().getProperties().get(WCMAppModel.PROP_DEFAULTWEBAPP); + this.webapp = this.getWebProject().getDefaultWebapp(); } return this.webapp; } @@ -481,14 +477,27 @@ public class AVMBrowseBean implements IContextListener public Node getWebsite() { // check to see if the website we are browsing has changed since the last time - if (this.navigator.getCurrentNodeId().equals(this.lastWebsiteId) == false) + if (!this.navigator.getCurrentNodeId().equals(this.lastWebsiteId)) { // clear context when we are browsing a new website this.lastWebsiteId = this.navigator.getCurrentNodeId(); this.webapp = null; + this.webProject = null; } return this.navigator.getCurrentNode(); } + + /** + * @return the web project the view is currently within + */ + public WebProject getWebProject() + { + if (this.webProject == null) + { + this.webProject = new WebProject(this.getWebsite().getNodeRef()); + } + return this.webProject; + } /** * @return Returns the current AVM node action context. @@ -584,32 +593,8 @@ public class AVMBrowseBean implements IContextListener */ public boolean getIsManagerRole() { - boolean isManager = false; - - User user = Application.getCurrentUser(FacesContext.getCurrentInstance()); - if (user.isAdmin() == false) - { - String currentUser = user.getUserName(); - List userInfoRefs = this.nodeService.getChildAssocs( - getWebsite().getNodeRef(), WCMAppModel.ASSOC_WEBUSER, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef ref : userInfoRefs) - { - NodeRef userInfoRef = ref.getChildRef(); - String username = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); - String userrole = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); - if (currentUser.equals(username) && ROLE_CONTENT_MANAGER.equals(userrole)) - { - isManager = true; - break; - } - } - } - else - { - isManager = true; - } - - return isManager; + final User user = Application.getCurrentUser(FacesContext.getCurrentInstance()); + return this.getWebProject().isManager(user); } /** @@ -773,8 +758,7 @@ public class AVMBrowseBean implements IContextListener else { // get the staging store from the current website node - setSandbox(AVMConstants.buildStagingStoreName( - (String)getWebsite().getProperties().get(WCMAppModel.PROP_AVMSTORE))); + setSandbox(this.getStagingStore()); } // update UI state ready for return to the previous screen @@ -943,8 +927,6 @@ public class AVMBrowseBean implements IContextListener public void createFormContent(ActionEvent event) { UIActionLink link = (UIActionLink)event.getComponent(); - Map params = link.getParameterMap(); - String id = params.get(UIUserSandboxes.PARAM_FORM_ID); // setup the correct sandbox for the create action setupSandboxAction(event); diff --git a/source/java/org/alfresco/web/bean/wcm/AVMConstants.java b/source/java/org/alfresco/web/bean/wcm/AVMConstants.java index f407840a9c..59bab2f60b 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMConstants.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMConstants.java @@ -18,6 +18,7 @@ package org.alfresco.web.bean.wcm; import java.text.MessageFormat; import java.util.Map; +import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -25,7 +26,9 @@ import javax.faces.context.FacesContext; import org.alfresco.config.JNDIConstants; import org.alfresco.mbeans.VirtServerRegistry; +import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.repo.domain.PropertyValue; +import org.alfresco.service.cmr.avm.AVMNotFoundException; import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.namespace.QName; import org.alfresco.service.ServiceRegistry; @@ -37,6 +40,7 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.jsf.FacesContextUtils; /** + * @author Ariel Backenroth * @author Kevin Roast */ public final class AVMConstants @@ -368,9 +372,9 @@ public final class AVMConstants { throw new IllegalArgumentException("Asset path is mandatory."); } - if (assetPath.startsWith( '/' + JNDIConstants.DIR_DEFAULT_WWW + '/' + JNDIConstants.DIR_DEFAULT_APPBASE )) + if (assetPath.startsWith('/' + JNDIConstants.DIR_DEFAULT_WWW + '/' + JNDIConstants.DIR_DEFAULT_APPBASE)) { - assetPath = assetPath.substring(('/' + JNDIConstants.DIR_DEFAULT_WWW + '/' + JNDIConstants.DIR_DEFAULT_APPBASE ).length()); + assetPath = assetPath.substring(('/' + JNDIConstants.DIR_DEFAULT_WWW + '/' + JNDIConstants.DIR_DEFAULT_APPBASE).length()); } if (assetPath.startsWith('/' + DIR_ROOT)) { @@ -516,6 +520,44 @@ public final class AVMConstants return m.matches() && m.group(1).length() != 0 ? m.group(1) : null; } + /** + * Creates all directories for a path if they do not already exist. + */ + public static void makeAllDirectories(final String avmDirectoryPath) + { + final ServiceRegistry serviceRegistry = + Repository.getServiceRegistry(FacesContext.getCurrentInstance()); + final AVMService avmService = serviceRegistry.getAVMService(); + // LOGGER.debug("mkdir -p " + avmDirectoryPath); + String s = avmDirectoryPath; + final Stack dirNames = new Stack(); + while (s != null) + { + try + { + if (avmService.lookup(-1, s) != null) + { + // LOGGER.debug("path " + s + " exists"); + break; + } + } + catch (AVMNotFoundException avmfe) + { + } + final String[] sb = AVMNodeConverter.SplitBase(s); + s = sb[0]; + // LOGGER.debug("pushing " + sb[1]); + dirNames.push(sb); + } + + while (!dirNames.isEmpty()) + { + final String[] sb = dirNames.pop(); + // LOGGER.debug("creating " + sb[1] + " in " + sb[0]); + avmService.createDirectory(sb[0], sb[1]); + } + } + /** * @param path Path to match against * @@ -628,18 +670,16 @@ public final class AVMConstants private final static Pattern STORE_RELATIVE_PATH_PATTERN = Pattern.compile("[^:]+:(.+)"); private final static Pattern WEBAPP_RELATIVE_PATH_PATTERN = - Pattern.compile("([^:]+:/" + JNDIConstants.DIR_DEFAULT_WWW + - "/" + JNDIConstants.DIR_DEFAULT_APPBASE + "/([^/]+))(.*)"); + Pattern.compile("([^:]+:/" + JNDIConstants.DIR_DEFAULT_WWW + + "/" + JNDIConstants.DIR_DEFAULT_APPBASE + "/([^/]+))(.*)"); private final static Pattern SANDBOX_RELATIVE_PATH_PATTERN = - Pattern.compile("([^:]+:/" + JNDIConstants.DIR_DEFAULT_WWW + - "/" + JNDIConstants.DIR_DEFAULT_APPBASE + ")(.*)"); + Pattern.compile("([^:]+:/" + JNDIConstants.DIR_DEFAULT_WWW + + "/" + JNDIConstants.DIR_DEFAULT_APPBASE + ")(.*)"); // patterns for WEB-INF files that require virtualisation server reload private final static Pattern WEB_INF_PATH_PATTERN = - Pattern.compile( ".*:/" + - JNDIConstants.DIR_DEFAULT_WWW + "/" + - JNDIConstants.DIR_DEFAULT_APPBASE + "/" + - ".*/WEB-INF/((classes/.*)|(lib/.*)|(web.xml))", - Pattern.CASE_INSENSITIVE - ); + Pattern.compile(".*:/" + JNDIConstants.DIR_DEFAULT_WWW + + "/" + JNDIConstants.DIR_DEFAULT_APPBASE + "/" + + ".*/WEB-INF/((classes/.*)|(lib/.*)|(web.xml))", + Pattern.CASE_INSENSITIVE); } diff --git a/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java b/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java index a2d0fdb672..8b5e62e9d2 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java @@ -45,11 +45,12 @@ import org.alfresco.web.bean.CheckinCheckoutBean; import org.alfresco.web.bean.FileUploadBean; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.forms.Form; +import org.alfresco.web.forms.FormInstanceData; import org.alfresco.web.forms.FormInstanceDataImpl; import org.alfresco.web.forms.FormProcessor; -import org.alfresco.web.forms.FormsService; import org.alfresco.web.forms.Rendition; import org.alfresco.web.forms.RenditionImpl; +import org.alfresco.web.forms.XMLUtil; import org.alfresco.web.ui.common.Utils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -232,11 +233,10 @@ public class AVMEditBean */ public Form getForm() { - final NodeRef ttNodeRef = (NodeRef) + final String formName = (String) this.nodeService.getProperty(this.getAvmNode().getNodeRef(), - WCMAppModel.PROP_PARENT_FORM); - final FormsService ts = FormsService.getInstance(); - return ts.getForm(ttNodeRef); + WCMAppModel.PROP_PARENT_FORM_NAME); + return this.avmBrowseBean.getWebProject().getForm(formName); } /** @@ -247,18 +247,17 @@ public class AVMEditBean { if (this.instanceDataDocument == null) { - final FormsService fs = FormsService.getInstance(); final String content = this.getEditorOutput(); try { this.instanceDataDocument = (content != null - ? fs.parseXML(content) - : fs.newDocument()); + ? XMLUtil.parse(content) + : XMLUtil.newDocument()); } catch (Exception e) { Utils.addErrorMessage("error parsing document", e); - return fs.newDocument(); + return XMLUtil.newDocument(); } } return this.instanceDataDocument; @@ -292,21 +291,19 @@ public class AVMEditBean this.avmBrowseBean.setupContentAction(event); // retrieve the content reader for this node - NodeRef avmRef = AVMNodeConverter.ToNodeRef(-1, getAvmNode().getPath()); - if (this.nodeService.hasAspect(avmRef, WCMAppModel.ASPECT_RENDITION)) + String avmPath = getAvmNode().getPath(); + if (this.avmService.hasAspect(-1, avmPath, WCMAppModel.ASPECT_RENDITION)) { if (LOGGER.isDebugEnabled()) - LOGGER.debug(avmRef + " is a rendition, editing primary rendition instead"); - avmRef = new RenditionImpl(avmRef).getPrimaryFormInstanceData().getNodeRef(); + LOGGER.debug(avmPath + " is a rendition, editing primary rendition instead"); + avmPath = new RenditionImpl(AVMNodeConverter.ToNodeRef(-1, avmPath)).getPrimaryFormInstanceData().getPath(); - final Pair p = AVMNodeConverter.ToAVMVersionPath(avmRef); if (LOGGER.isDebugEnabled()) - LOGGER.debug("Editing primary form instance data " + p.getSecond() + " version " + p.getFirst()); - final AVMNode avmNode = new AVMNode(this.avmService.lookup(p.getFirst(), p.getSecond())); - this.avmBrowseBean.setAvmActionNode(avmNode); + LOGGER.debug("Editing primary form instance data " + avmPath); + this.avmBrowseBean.setAvmActionNode(new AVMNode(this.avmService.lookup(-1, avmPath))); } - if (this.nodeService.hasAspect(avmRef, WCMAppModel.ASPECT_FORM_INSTANCE_DATA)) + if (this.avmService.hasAspect(-1, avmPath, WCMAppModel.ASPECT_FORM_INSTANCE_DATA)) { // reset the preview layer String storeName = AVMConstants.getStoreName(this.avmBrowseBean.getCurrentPath()); @@ -318,8 +315,8 @@ public class AVMEditBean } if (LOGGER.isDebugEnabled()) - LOGGER.debug("Editing AVM node: " + avmRef.toString()); - ContentReader reader = contentService.getReader(avmRef, ContentModel.PROP_CONTENT); + LOGGER.debug("Editing AVM node: " + avmPath); + ContentReader reader = this.avmService.getContentReader(-1, avmPath); if (reader != null) { String mimetype = reader.getMimetype(); @@ -335,7 +332,7 @@ public class AVMEditBean // navigate to appropriate screen outcome = ((MimetypeMap.MIMETYPE_XML.equals(mimetype) && - this.nodeService.hasAspect(avmRef, WCMAppModel.ASPECT_FORM_INSTANCE_DATA)) + this.avmService.hasAspect(-1, avmPath, WCMAppModel.ASPECT_FORM_INSTANCE_DATA)) ? "dialog:editAvmXmlInline" : "dialog:editAvmTextInline"); } @@ -389,18 +386,18 @@ public class AVMEditBean return null; } - final FormsService formsService = FormsService.getInstance(); - final NodeRef avmRef = AVMNodeConverter.ToNodeRef(-1, avmNode.getPath()); + final String avmPath = avmNode.getPath(); + LOGGER.debug("saving " + avmPath); try { tx = Repository.getUserTransaction(FacesContext.getCurrentInstance()); tx.begin(); // get an updating writer that we can use to modify the content on the current node - ContentWriter writer = this.contentService.getWriter(avmRef, ContentModel.PROP_CONTENT, true); - if (nodeService.hasAspect(avmRef, WCMAppModel.ASPECT_FORM_INSTANCE_DATA)) + final ContentWriter writer = this.avmService.getContentWriter(avmPath); + if (this.avmService.hasAspect(-1, avmPath, WCMAppModel.ASPECT_FORM_INSTANCE_DATA)) { - this.editorOutput = formsService.writeXMLToString(this.instanceDataDocument); + this.editorOutput = XMLUtil.toString(this.instanceDataDocument); } writer.putContent(this.editorOutput); @@ -408,10 +405,27 @@ public class AVMEditBean tx.commit(); // regenerate form content - if (nodeService.hasAspect(avmRef, WCMAppModel.ASPECT_FORM_INSTANCE_DATA)) + if (this.avmService.hasAspect(-1, avmPath, WCMAppModel.ASPECT_FORM_INSTANCE_DATA)) { - formsService.regenerateRenditions(new FormInstanceDataImpl(avmRef)); + final FormInstanceData fid = new FormInstanceDataImpl(AVMNodeConverter.ToNodeRef(-1, avmPath)) + { + @Override + public Form getForm() { return AVMEditBean.this.getForm(); } + }; + LOGGER.debug("regenerating renditions of " + fid); + for (Rendition rendition : fid.getRenditions()) + { + try + { + rendition.regenerate(fid); + } + catch (Throwable t) + { + LOGGER.error(t, t); + } + } final NodeRef[] uploadedFiles = this.formProcessorSession.getUploadedFiles(); + LOGGER.debug("updating " + uploadedFiles.length + " uploaded files"); final List diffList = new ArrayList(uploadedFiles.length); for (NodeRef uploadedFile : uploadedFiles) { diff --git a/source/java/org/alfresco/web/bean/wcm/AVMWorkflowUtil.java b/source/java/org/alfresco/web/bean/wcm/AVMWorkflowUtil.java index 02b5623df5..778e5afe04 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMWorkflowUtil.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMWorkflowUtil.java @@ -112,7 +112,9 @@ public class AVMWorkflowUtil extends WorkflowUtil oos.close(); // write the serialized Map as a binary content stream - like database blob! ContentService cs = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getContentService(); - ContentWriter writer = cs.getWriter(workflowRef, WCMAppModel.PROP_WORKFLOWDEFAULTS, true); + ContentWriter writer = cs.getWriter(workflowRef, + WCMAppModel.PROP_WORKFLOW_DEFAULT_PROPERTIES, + true); writer.setMimetype(MimetypeMap.MIMETYPE_BINARY); writer.putContent(new ByteArrayInputStream(baos.toByteArray())); } @@ -136,7 +138,7 @@ public class AVMWorkflowUtil extends WorkflowUtil // restore the serialized Map from a binary content stream - like database blob! Serializable params = null; ContentService cs = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getContentService(); - ContentReader reader = cs.getReader(workflowRef, WCMAppModel.PROP_WORKFLOWDEFAULTS); + ContentReader reader = cs.getReader(workflowRef, WCMAppModel.PROP_WORKFLOW_DEFAULT_PROPERTIES); if (reader != null) { ObjectInputStream ois = new ObjectInputStream(reader.getContentInputStream()); diff --git a/source/java/org/alfresco/web/bean/wcm/CreateFormWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateFormWizard.java index 0cdf8fb99c..e84a17e7a6 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateFormWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateFormWizard.java @@ -52,6 +52,7 @@ import org.alfresco.web.ui.wcm.WebResources; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xerces.xs.*; +import org.apache.commons.io.FilenameUtils; import org.w3c.dom.Document; /** @@ -65,8 +66,6 @@ public class CreateFormWizard ///////////////////////////////////////////////////////////////////////////// - private static final String NO_DEFAULT_WORKFLOW_SELECTED = "no_default_workflow_selected"; - /** * Simple wrapper class to represent a form data renderer */ @@ -76,6 +75,7 @@ public class CreateFormWizard private final String fileName; private final NodeRef nodeRef; private final File file; + private final String name; private final String title; private final String description; private final String mimetypeForRendition; @@ -85,8 +85,9 @@ public class CreateFormWizard public RenderingEngineTemplateData(final RenderingEngineTemplate ret) { this.file = null; - this.nodeRef = ret.getNodeRef(); + this.nodeRef = ((RenderingEngineTemplateImpl)ret).getNodeRef(); this.fileName = ret.getName(); + this.name = ret.getName(); this.title = ret.getTitle(); this.description = ret.getDescription(); this.outputPathPatternForRendition = ret.getOutputPathPattern(); @@ -96,6 +97,7 @@ public class CreateFormWizard public RenderingEngineTemplateData(final String fileName, final File file, + final String name, final String title, final String description, final String outputPathPatternForRendition, @@ -105,6 +107,7 @@ public class CreateFormWizard this.nodeRef = null; this.fileName = fileName; this.file = file; + this.name = name; this.title = title; this.description = description; this.outputPathPatternForRendition = outputPathPatternForRendition; @@ -137,6 +140,11 @@ public class CreateFormWizard return this.nodeRef; } + public String getName() + { + return this.name; + } + public String getTitle() { return this.title; @@ -176,6 +184,7 @@ public class CreateFormWizard private final static Log LOGGER = LogFactory.getLog(CreateFormWizard.class); protected String defaultWorkflowName = null; + protected boolean applyDefaultWorkflow = true; protected List renderingEngineTemplates = null; protected transient XSModel schema; protected String schemaFileName; @@ -188,6 +197,7 @@ public class CreateFormWizard private String formTitle = null; private String formDescription = null; private String outputPathPatternForFormInstanceData = null; + private String renderingEngineTemplateName = null; private String renderingEngineTemplateTitle = null; private String renderingEngineTemplateDescription = null; @@ -198,6 +208,7 @@ public class CreateFormWizard private String mimetypeForRendition = null; private transient List mimetypeChoices = null; private transient List schemaRootElementNameChoices = null; + private transient List defaultWorkflowChoices = null; // ------------------------------------------------------------------------------ // Wizard implementation @@ -211,9 +222,8 @@ public class CreateFormWizard LOGGER.debug("creating form " + this.getFormName()); } - final FormsService ts = FormsService.getInstance(); // get the node ref of the node that will contain the content - final NodeRef contentFormsNodeRef = ts.getContentFormsNodeRef(); + final NodeRef contentFormsNodeRef = FormsService.getInstance().getContentFormsNodeRef(); final FileInfo folderInfo = this.fileFolderService.create(contentFormsNodeRef, @@ -224,32 +234,41 @@ public class CreateFormWizard this.getSchemaFileName(), ContentModel.TYPE_CONTENT); // get a writer for the content and put the file - ContentWriter writer = this.contentService.getWriter(fileInfo.getNodeRef(), - ContentModel.PROP_CONTENT, - true); + final ContentWriter writer = this.contentService.getWriter(fileInfo.getNodeRef(), + ContentModel.PROP_CONTENT, + true); // set the mimetype and encoding writer.setMimetype(MimetypeMap.MIMETYPE_XML); writer.setEncoding("UTF-8"); writer.putContent(this.getSchemaFile()); // apply the titled aspect - title and description - Map props = new HashMap(2, 1.0f); + final Map props = new HashMap(2, 1.0f); props.put(ContentModel.PROP_TITLE, this.getFormTitle()); props.put(ContentModel.PROP_DESCRIPTION, this.getFormDescription()); this.nodeService.addAspect(folderInfo.getNodeRef(), ContentModel.ASPECT_TITLED, props); - props = new HashMap(3, 1.0f); + props.clear(); props.put(WCMAppModel.PROP_XML_SCHEMA, fileInfo.getNodeRef()); props.put(WCMAppModel.PROP_XML_SCHEMA_ROOT_ELEMENT_NAME, this.getSchemaRootElementName()); - props.put(WCMAppModel.PROP_OUTPUT_PATH_PATTERN_FORM_INSTANCE_DATA, - this.getOutputPathPatternForFormInstanceData()); - if (this.defaultWorkflowName != null) - { - props.put(WCMAppModel.PROP_DEFAULT_WORKFLOW_NAME, this.defaultWorkflowName); - } this.nodeService.addAspect(folderInfo.getNodeRef(), WCMAppModel.ASPECT_FORM, props); - + if (this.applyDefaultWorkflow) + { + props.clear(); + props.put(WCMAppModel.PROP_WORKFLOW_NAME, this.getDefaultWorkflowName()); + this.nodeService.createNode(folderInfo.getNodeRef(), + WCMAppModel.ASSOC_FORM_WORKFLOW_DEFAULTS, + WCMAppModel.ASSOC_FORM_WORKFLOW_DEFAULTS, + WCMAppModel.TYPE_WORKFLOW_DEFAULTS, + props); + } + + props.clear(); + props.put(WCMAppModel.PROP_OUTPUT_PATH_PATTERN, + this.getOutputPathPatternForFormInstanceData()); + this.nodeService.addAspect(folderInfo.getNodeRef(), + WCMAppModel.ASPECT_OUTPUT_PATH_PATTERN, props); for (RenderingEngineTemplateData retd : this.renderingEngineTemplates) { this.saveRenderingEngineTemplate(retd, folderInfo.getNodeRef()); @@ -265,17 +284,17 @@ public class CreateFormWizard " to form " + this.getFormName()); NodeRef renderingEngineTemplateNodeRef = - this.fileFolderService.searchSimple(formNodeRef, retd.getFileName()); - HashMap props; + this.fileFolderService.searchSimple(formNodeRef, retd.getName()); + final HashMap props = new HashMap(); if (renderingEngineTemplateNodeRef == null) { try { final FileInfo fileInfo = this.fileFolderService.create(formNodeRef, - retd.getFileName(), + retd.getName(), ContentModel.TYPE_CONTENT); if (LOGGER.isDebugEnabled()) - LOGGER.debug("Created file node for file: " + retd.getFileName()); + LOGGER.debug("Created file node for file: " + retd.getName()); renderingEngineTemplateNodeRef = fileInfo.getNodeRef(); } catch (final FileExistsException fee) @@ -298,7 +317,7 @@ public class CreateFormWizard this.nodeService.createAssociation(formNodeRef, renderingEngineTemplateNodeRef, WCMAppModel.ASSOC_RENDERING_ENGINE_TEMPLATES); - props = new HashMap(2, 1.0f); + props.clear(); props.put(WCMAppModel.PROP_PARENT_RENDERING_ENGINE_NAME, retd.getRenderingEngine().getName()); props.put(WCMAppModel.PROP_FORM_SOURCE, formNodeRef); @@ -307,7 +326,7 @@ public class CreateFormWizard props); // apply the titled aspect - title and description - props = new HashMap(2, 1.0f); + props.clear(); props.put(ContentModel.PROP_TITLE, retd.getTitle()); props.put(ContentModel.PROP_DESCRIPTION, retd.getDescription()); this.nodeService.addAspect(renderingEngineTemplateNodeRef, @@ -316,16 +335,19 @@ public class CreateFormWizard } LOGGER.debug("adding rendition properties to " + renderingEngineTemplateNodeRef); - props = new HashMap(2, 1.0f); - props.put(WCMAppModel.PROP_OUTPUT_PATH_PATTERN_RENDITION, - retd.getOutputPathPatternForRendition()); + props.clear(); props.put(WCMAppModel.PROP_MIMETYPE_FOR_RENDITION, retd.getMimetypeForRendition()); - this.nodeService.createNode(renderingEngineTemplateNodeRef, - WCMAppModel.ASSOC_RENDITION_PROPERTIES, - WCMAppModel.ASSOC_RENDITION_PROPERTIES, - WCMAppModel.TYPE_RENDITION_PROPERTIES, - props); + + final NodeRef rpNodeRef = this.nodeService.createNode(renderingEngineTemplateNodeRef, + WCMAppModel.ASSOC_RENDITION_PROPERTIES, + WCMAppModel.ASSOC_RENDITION_PROPERTIES, + WCMAppModel.TYPE_RENDITION_PROPERTIES, + props).getChildRef(); + props.clear(); + props.put(WCMAppModel.PROP_OUTPUT_PATH_PATTERN, + retd.getOutputPathPatternForRendition()); + this.nodeService.addAspect(rpNodeRef, WCMAppModel.ASPECT_OUTPUT_PATH_PATTERN, props); } @Override @@ -342,6 +364,7 @@ public class CreateFormWizard this.formName = null; this.formTitle = null; this.formDescription = null; + this.renderingEngineTemplateName = null; this.renderingEngineTemplateTitle = null; this.renderingEngineTemplateDescription = null; this.renderingEngine = null; @@ -350,6 +373,8 @@ public class CreateFormWizard this.outputPathPatternForRendition = null; this.mimetypeForRendition = null; this.defaultWorkflowName = null; + this.defaultWorkflowChoices = null; + this.applyDefaultWorkflow = true; } @Override @@ -469,10 +494,17 @@ public class CreateFormWizard */ public void addSelectedRenderingEngineTemplate(final ActionEvent event) { + final String name = this.getRenderingEngineTemplateName(); final String opp = this.getOutputPathPatternForRendition(); final String mimetype = this.getMimetypeForRendition(); for (RenderingEngineTemplateData retd : this.renderingEngineTemplates) { + if (name.equals(retd.getName())) + { + Utils.addErrorMessage("A rendering engine template with the name " + name + + " already exists"); + return; + } if (opp.equals(retd.getOutputPathPatternForRendition()) && opp.indexOf(DEFAULT_EXTENSION_PATTERN) >= 0 && mimetype.equals(retd.getMimetypeForRendition())) @@ -485,6 +517,7 @@ public class CreateFormWizard final RenderingEngineTemplateData data = this.new RenderingEngineTemplateData(this.getRenderingEngineTemplateFileName(), this.getRenderingEngineTemplateFile(), + this.getRenderingEngineTemplateName(), this.getRenderingEngineTemplateTitle(), this.getRenderingEngineTemplateDescription(), opp, @@ -495,6 +528,7 @@ public class CreateFormWizard this.renderingEngine = null; this.outputPathPatternForRendition = null; this.mimetypeForRendition = null; + this.renderingEngineTemplateName = null; this.renderingEngineTemplateTitle = null; this.renderingEngineTemplateDescription = null; } @@ -560,8 +594,7 @@ public class CreateFormWizard { try { - final FormsService formsService = FormsService.getInstance(); - final Document d = formsService.parseXML(this.getSchemaFile()); + final Document d = XMLUtil.parse(this.getSchemaFile()); this.schema = SchemaUtil.parseSchema(d); } catch (Exception e) @@ -809,7 +842,7 @@ public class CreateFormWizard public String getFormName() { return (this.formName == null && this.getSchemaFileName() != null - ? this.getSchemaFileName().replaceAll("(.+)\\..*", "$1") + ? FilenameUtils.removeExtension(this.getSchemaFileName()) : this.formName); } /** @@ -846,7 +879,7 @@ public class CreateFormWizard public String getFormTitle() { return (this.formTitle == null && this.getSchemaFileName() != null - ? this.getSchemaFileName().replaceAll("(.+)\\..*", "$1") + ? FilenameUtils.removeExtension(this.getSchemaFileName()) : this.formTitle); } @@ -866,6 +899,23 @@ public class CreateFormWizard return this.formDescription; } + /** + * Sets the name for this renderingEngineTemplate. + */ + public void setRenderingEngineTemplateName(final String renderingEngineTemplateName) + { + this.renderingEngineTemplateName = renderingEngineTemplateName; + } + + /** + * @return the name for this renderingEngineTemplate. + */ + public String getRenderingEngineTemplateName() + { + return (this.renderingEngineTemplateName == null && this.getRenderingEngineTemplateFileName() != null + ? FilenameUtils.removeExtension(this.getRenderingEngineTemplateFileName()) + : this.renderingEngineTemplateName); + } /** * Sets the title for this renderingEngineTemplate. */ @@ -880,7 +930,7 @@ public class CreateFormWizard public String getRenderingEngineTemplateTitle() { return (this.renderingEngineTemplateTitle == null && this.getRenderingEngineTemplateFileName() != null - ? this.getRenderingEngineTemplateFileName().replaceAll("(.+)\\..*", "$1") + ? FilenameUtils.removeExtension(this.getRenderingEngineTemplateFileName()) : this.renderingEngineTemplateTitle); } @@ -900,56 +950,61 @@ public class CreateFormWizard return this.renderingEngineTemplateDescription; } - public void setDefaultWorkflowName(final String[] defaultWorkflowName) - { - assert defaultWorkflowName.length == 1; - this.defaultWorkflowName = (NO_DEFAULT_WORKFLOW_SELECTED.equals(defaultWorkflowName[0]) - ? null - : defaultWorkflowName[0]); - } - public WorkflowDefinition getDefaultWorkflowDefinition() { - return (this.defaultWorkflowName == null + return (this.defaultWorkflowName == null || !this.applyDefaultWorkflow ? null : this.workflowService.getDefinitionByName(this.defaultWorkflowName)); } - public String[] getDefaultWorkflowName() + public void setDefaultWorkflowName(final String[] defaultWorkflowName) { - return new String[] { - (this.defaultWorkflowName == null - ? NO_DEFAULT_WORKFLOW_SELECTED - : this.defaultWorkflowName) - }; + assert defaultWorkflowName.length == 1; + this.defaultWorkflowName = defaultWorkflowName[0]; } + public String[] getDefaultWorkflowName() + { + if (this.defaultWorkflowName == null && this.getDefaultWorkflowChoices().size() != 0) + { + this.defaultWorkflowName = (String)this.getDefaultWorkflowChoices().get(0).getValue(); + } + return new String[] { this.defaultWorkflowName }; + } + + public void setApplyDefaultWorkflow(final boolean applyDefaultWorkflow) + { + this.applyDefaultWorkflow = applyDefaultWorkflow; + } + + public boolean getApplyDefaultWorkflow() + { + return this.applyDefaultWorkflow; + } + /** * @return List of UI items to represent the available Workflows for all websites */ public List getDefaultWorkflowChoices() { - // TODO: add list of workflows from config - // @see org.alfresco.web.wcm.FormDetailsDialog#getWorkflowList() - final List workflowDefs = this.workflowService.getDefinitions(); - final List result = new ArrayList(workflowDefs.size() + 1); - - UIListItem item = new UIListItem(); - item.setValue(NO_DEFAULT_WORKFLOW_SELECTED); - item.setLabel("None"); - item.setImage(WebResources.IMAGE_WORKFLOW_32); - result.add(item); - - for (WorkflowDefinition workflowDef : workflowDefs) + if (this.defaultWorkflowChoices == null) { - item = new UIListItem(); - item.setValue(workflowDef.getName()); - item.setLabel(workflowDef.getTitle()); - item.setDescription(workflowDef.getDescription()); - item.setImage(WebResources.IMAGE_WORKFLOW_32); - result.add(item); + // TODO: add list of workflows from config + // @see org.alfresco.web.wcm.FormDetailsDialog#getWorkflowList() + final List workflowDefs = this.workflowService.getDefinitions(); + this.defaultWorkflowChoices = new ArrayList(workflowDefs.size() + 1); + + for (WorkflowDefinition workflowDef : workflowDefs) + { + final UIListItem item = new UIListItem(); + item.setValue(workflowDef.getName()); + item.setLabel(workflowDef.getTitle()); + item.setDescription(workflowDef.getDescription()); + item.setImage(WebResources.IMAGE_WORKFLOW_32); + this.defaultWorkflowChoices.add(item); + } } - return result; + return this.defaultWorkflowChoices; } // ------------------------------------------------------------------------------ diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java index d87ceab150..caff23f41a 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java @@ -21,6 +21,7 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.ResourceBundle; @@ -63,7 +64,9 @@ import org.alfresco.web.forms.FormInstanceData; import org.alfresco.web.forms.FormInstanceDataImpl; import org.alfresco.web.forms.FormProcessor; import org.alfresco.web.forms.FormsService; +import org.alfresco.web.forms.RenderingEngineTemplate; import org.alfresco.web.forms.Rendition; +import org.alfresco.web.forms.XMLUtil; import org.alfresco.web.ui.common.Utils; import org.alfresco.web.ui.common.component.UIListItem; import org.alfresco.web.ui.wcm.component.UIUserSandboxes; @@ -170,13 +173,11 @@ public class CreateWebContentWizard extends BaseContentWizard this.formSelectDisabled = false; // check for a form ID being passed in as a parameter - if (this.parameters.get(UIUserSandboxes.PARAM_FORM_ID) != null) + if (this.parameters.get(UIUserSandboxes.PARAM_FORM_NAME) != null) { // it is used to init the dialog to a specific template - String webFormId = parameters.get(UIUserSandboxes.PARAM_FORM_ID); - NodeRef webFormRef = new NodeRef(Repository.getStoreRef(), webFormId); - String formName = (String)this.nodeService.getProperty(webFormRef, WCMAppModel.PROP_FORMNAME); - Form form = FormsService.getInstance().getForm(formName); + final String formName = parameters.get(UIUserSandboxes.PARAM_FORM_NAME); + final Form form = this.avmBrowseBean.getWebProject().getForm(formName); if (form != null) { this.formName = form.getName(); @@ -225,17 +226,13 @@ public class CreateWebContentWizard extends BaseContentWizard LOGGER.debug("clearing form instance data"); if (this.formInstanceData != null) { - final NodeRef nr = this.formInstanceData.getNodeRef(); - final String path = AVMNodeConverter.ToAVMVersionPath(nr).getSecond(); - this.avmService.removeNode(path); + this.avmService.removeNode(this.formInstanceData.getPath()); } if (this.renditions != null) { for (Rendition r : this.renditions) { - final NodeRef nr = r.getNodeRef(); - final String path = AVMNodeConverter.ToAVMVersionPath(nr).getSecond(); - this.avmService.removeNode(path); + this.avmService.removeNode(r.getPath()); } } this.formInstanceData = null; @@ -277,7 +274,7 @@ public class CreateWebContentWizard extends BaseContentWizard AVMDifference.NEWER)); for (Rendition rendition : this.renditions) { - final String path = AVMNodeConverter.ToAVMVersionPath(rendition.getNodeRef()).getSecond(); + final String path = rendition.getPath(); diffList.add(new AVMDifference(-1, path, -1, AVMConstants.getCorrespondingPathInMainStore(path), AVMDifference.NEWER)); @@ -315,48 +312,8 @@ public class CreateWebContentWizard extends BaseContentWizard } if (this.startWorkflow) { - WorkflowDefinition wd = null; - Map parameters = null; - - // get the workflow definition and parameters - final Node website = this.avmBrowseBean.getWebsite(); - final List webFormRefs = this.nodeService.getChildAssocs( - website.getNodeRef(), WCMAppModel.ASSOC_WEBFORM, RegexQNamePattern.MATCH_ALL); - for (ChildAssociationRef ref : webFormRefs) - { - final String formName = (String) - this.nodeService.getProperty(ref.getChildRef(), WCMAppModel.PROP_FORMNAME); - if (formName.equals(this.getForm().getName())) - { - if (LOGGER.isDebugEnabled()) - LOGGER.debug("loading workflowRefs for " + formName); - - final List workflowRefs = - this.nodeService.getChildAssocs(ref.getChildRef(), - WCMAppModel.ASSOC_WORKFLOWDEFAULTS, - RegexQNamePattern.MATCH_ALL); - if (workflowRefs.size() == 0) - { - throw new AlfrescoRuntimeException("no workflow parameters found for form " + formName); - } - if (workflowRefs.size() > 1) - { - throw new AlfrescoRuntimeException("found more than one workflow parameters node for " + formName); - } - - final NodeRef workflowRef = workflowRefs.get(0).getChildRef(); - final String workflowName = (String)this.nodeService.getProperty(workflowRef, WCMAppModel.PROP_WORKFLOW_NAME); - - if (LOGGER.isDebugEnabled()) - LOGGER.debug("using workflow " + workflowName + " for form " + formName); - wd = this.workflowService.getDefinitionByName(workflowName); - - // deserialize the workflow parameters - parameters = (Map)AVMWorkflowUtil.deserializeWorkflowParams(workflowRef); - - break; - } - } + final WorkflowDefinition wd = this.getForm().getDefaultWorkflow(); + final Map parameters = this.getForm().getDefaultWorkflowParameters(); if (LOGGER.isDebugEnabled()) LOGGER.debug("starting workflow " + wd + " with parameters " + parameters); @@ -385,11 +342,9 @@ public class CreateWebContentWizard extends BaseContentWizard // collect diffs for form data instance and all renditions for (Rendition rendition : this.getRenditions()) { - final String renditionPath = AVMNodeConverter.ToAVMVersionPath(rendition.getNodeRef()).getSecond(); - srcPaths.add(AVMConstants.getCorrespondingPath(renditionPath, sandboxName)); + srcPaths.add(AVMConstants.getCorrespondingPath(rendition.getPath(), sandboxName)); } - final String instancePath = AVMNodeConverter.ToAVMVersionPath(this.formInstanceData.getNodeRef()).getSecond(); - srcPaths.add(AVMConstants.getCorrespondingPath(instancePath, sandboxName)); + srcPaths.add(AVMConstants.getCorrespondingPath(this.formInstanceData.getPath(), sandboxName)); } else { @@ -454,7 +409,6 @@ public class CreateWebContentWizard extends BaseContentWizard protected void saveContent() throws Exception { - final FormsService fs = FormsService.getInstance(); // get the parent path of the location to save the content String fileName = this.fileName; if (LOGGER.isDebugEnabled()) @@ -462,13 +416,16 @@ public class CreateWebContentWizard extends BaseContentWizard String path = this.avmBrowseBean.getCurrentPath(); path = AVMConstants.getCorrespondingPathInPreviewStore(path); - if (MimetypeMap.MIMETYPE_XML.equals(this.mimeType) && this.formName != null) + final Form form = (MimetypeMap.MIMETYPE_XML.equals(this.mimeType) + ? this.getForm() + : null); + if (form != null) { - path = this.getForm().getOutputPathForFormInstanceData(this.instanceDataDocument, - fileName, - path, - this.avmBrowseBean.getWebapp()); - this.content = FormsService.getInstance().writeXMLToString(this.instanceDataDocument); + path = form.getOutputPathForFormInstanceData(this.instanceDataDocument, + fileName, + path, + this.avmBrowseBean.getWebapp()); + this.content = XMLUtil.toString(this.instanceDataDocument); final String[] sb = AVMNodeConverter.SplitBase(path); path = sb[0]; fileName = sb[1]; @@ -477,7 +434,7 @@ public class CreateWebContentWizard extends BaseContentWizard if (LOGGER.isDebugEnabled()) LOGGER.debug("creating all directories in path " + path); - fs.makeAllDirectories(path); + AVMConstants.makeAllDirectories(path); if (LOGGER.isDebugEnabled()) LOGGER.debug("creating file " + fileName + " in " + path); @@ -492,15 +449,26 @@ public class CreateWebContentWizard extends BaseContentWizard // add titled aspect for the read/edit properties screens final NodeRef formInstanceDataNodeRef = AVMNodeConverter.ToNodeRef(-1, this.createdPath); - Map titledProps = new HashMap(1, 1.0f); - titledProps.put(ContentModel.PROP_TITLE, fileName); - this.nodeService.addAspect(formInstanceDataNodeRef, ContentModel.ASPECT_TITLED, titledProps); + final Map props = new HashMap(1, 1.0f); + props.put(ContentModel.PROP_TITLE, fileName); + this.nodeService.addAspect(formInstanceDataNodeRef, ContentModel.ASPECT_TITLED, props); - if (MimetypeMap.MIMETYPE_XML.equals(this.mimeType) && this.formName != null) + if (form != null) { - this.formInstanceData = new FormInstanceDataImpl(formInstanceDataNodeRef); - this.getForm().registerFormInstanceData(formInstanceDataNodeRef); - this.renditions = FormsService.getInstance().generateRenditions(this.formInstanceData); + this.formInstanceData = new FormInstanceDataImpl(formInstanceDataNodeRef) + { + @Override + public Form getForm() { return form; } + }; + props.clear(); + props.put(WCMAppModel.PROP_PARENT_FORM_NAME, form.getName()); + this.nodeService.addAspect(formInstanceDataNodeRef, WCMAppModel.ASPECT_FORM_INSTANCE_DATA, props); + + this.renditions = new LinkedList(); + for (RenderingEngineTemplate ret : form.getRenderingEngineTemplates()) + { + this.renditions.add(ret.render(this.formInstanceData)); + } } else { @@ -533,23 +501,11 @@ public class CreateWebContentWizard extends BaseContentWizard */ public List getFormChoices() { - final Node website = this.avmBrowseBean.getWebsite(); - if (website == null) + final List

forms = this.avmBrowseBean.getWebProject().getForms(); + final List items = new ArrayList(forms.size()); + for (final Form f : forms) { - throw new IllegalStateException("CreateWebContentWizard must be called within a Web Project context!"); - } - final List webFormRefs = this.nodeService.getChildAssocs( - website.getNodeRef(), WCMAppModel.ASSOC_WEBFORM, RegexQNamePattern.MATCH_ALL); - final List items = new ArrayList(webFormRefs.size()); - for (ChildAssociationRef ref : webFormRefs) - { - final String formName = (String) - this.nodeService.getProperty(ref.getChildRef(), WCMAppModel.PROP_FORMNAME); - final Form form = FormsService.getInstance().getForm(formName); - if (form != null) - { - items.add(new SelectItem(formName, form.getTitle())); - } + items.add(new SelectItem(f.getName(), f.getTitle())); } final QuickSort sorter = new QuickSort(items, "label", true, IDataContainer.SORT_CASEINSENSITIVE); @@ -613,8 +569,9 @@ public class CreateWebContentWizard extends BaseContentWizard public Form getForm() { - final FormsService ts = FormsService.getInstance(); - return ts.getForm(this.getFormName()); + return (this.getFormName() != null + ? this.avmBrowseBean.getWebProject().getForm(this.getFormName()) + : null); } /** @@ -633,18 +590,17 @@ public class CreateWebContentWizard extends BaseContentWizard { if (this.instanceDataDocument == null) { - final FormsService fs = FormsService.getInstance(); final String content = this.getContent(); try { this.instanceDataDocument = (content != null - ? fs.parseXML(content) - : fs.newDocument()); + ? XMLUtil.parse(content) + : XMLUtil.newDocument()); } catch (Exception e) { Utils.addErrorMessage("error parsing document", e); - this.instanceDataDocument = fs.newDocument(); + this.instanceDataDocument = XMLUtil.newDocument(); } } return this.instanceDataDocument; diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java index 4a549b0cde..b6c467edeb 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java @@ -223,10 +223,10 @@ public class CreateWebsiteWizard extends BaseWizardBean // create web form with name as per the name of the form object in the DD props.put(WCMAppModel.PROP_FORMNAME, form.getName()); NodeRef formRef = this.nodeService.createNode(nodeRef, - WCMAppModel.ASSOC_WEBFORM, - WCMAppModel.ASSOC_WEBFORM, - WCMAppModel.TYPE_WEBFORM, - props).getChildRef(); + WCMAppModel.ASSOC_WEBFORM, + WCMAppModel.ASSOC_WEBFORM, + WCMAppModel.TYPE_WEBFORM, + props).getChildRef(); // add title aspect for user defined title and description labels props.clear(); @@ -235,11 +235,11 @@ public class CreateWebsiteWizard extends BaseWizardBean this.nodeService.addAspect(formRef, ContentModel.ASPECT_TITLED, props); // add filename pattern aspect if a filename pattern has been applied - if (form.getFilenamePattern() != null) + if (form.getOutputPathPattern() != null) { props.clear(); - props.put(WCMAppModel.PROP_FILENAMEPATTERN, form.getFilenamePattern()); - this.nodeService.addAspect(formRef, WCMAppModel.ASPECT_FILENAMEPATTERN, props); + props.put(WCMAppModel.PROP_OUTPUT_PATH_PATTERN, form.getOutputPathPattern()); + this.nodeService.addAspect(formRef, WCMAppModel.ASPECT_OUTPUT_PATH_PATTERN, props); } // associate to workflow defaults if any are present @@ -249,10 +249,10 @@ public class CreateWebsiteWizard extends BaseWizardBean props.clear(); props.put(WCMAppModel.PROP_WORKFLOW_NAME, workflow.getName()); NodeRef workflowRef = this.nodeService.createNode(formRef, - WCMAppModel.ASSOC_WORKFLOWDEFAULTS, - WCMAppModel.ASSOC_WORKFLOWDEFAULTS, - WCMAppModel.TYPE_WORKFLOWDEFAULTS, - props).getChildRef(); + WCMAppModel.ASSOC_WORKFLOWDEFAULTS, + WCMAppModel.ASSOC_WORKFLOWDEFAULTS, + WCMAppModel.TYPE_WORKFLOW_DEFAULTS, + props).getChildRef(); // persist workflow default params if (workflow.getParams() != null) @@ -265,19 +265,20 @@ public class CreateWebsiteWizard extends BaseWizardBean for (PresentationTemplate template : form.getTemplates()) { props.clear(); - props.put(WCMAppModel.PROP_ENGINE, template.getRenderingEngineTemplate().getNodeRef()); + props.put(WCMAppModel.PROP_BASE_RENDERING_ENGINE_TEMPLATE_NAME, + template.getRenderingEngineTemplate().getName()); NodeRef templateRef = this.nodeService.createNode(formRef, - WCMAppModel.ASSOC_WEBFORMTEMPLATE, - WCMAppModel.ASSOC_WEBFORMTEMPLATE, - WCMAppModel.TYPE_WEBFORMTEMPLATE, - props).getChildRef(); + WCMAppModel.ASSOC_WEBFORMTEMPLATE, + WCMAppModel.ASSOC_WEBFORMTEMPLATE, + WCMAppModel.TYPE_WEBFORMTEMPLATE, + props).getChildRef(); // add filename pattern aspect if a filename pattern has been applied - if (template.getFilenamePattern() != null) + if (template.getOutputPathPattern() != null) { props.clear(); - props.put(WCMAppModel.PROP_FILENAMEPATTERN, template.getFilenamePattern()); - this.nodeService.addAspect(templateRef, WCMAppModel.ASPECT_FILENAMEPATTERN, props); + props.put(WCMAppModel.PROP_OUTPUT_PATH_PATTERN, template.getOutputPathPattern()); + this.nodeService.addAspect(templateRef, WCMAppModel.ASPECT_OUTPUT_PATH_PATTERN, props); } } } @@ -288,10 +289,10 @@ public class CreateWebsiteWizard extends BaseWizardBean props.clear(); props.put(WCMAppModel.PROP_WORKFLOW_NAME, workflow.getName()); NodeRef workflowRef = this.nodeService.createNode(nodeRef, - WCMAppModel.ASSOC_WEBWORKFLOWDEFAULTS, - WCMAppModel.ASSOC_WEBWORKFLOWDEFAULTS, - WCMAppModel.TYPE_WEBWORKFLOWDEFAULTS, - props).getChildRef(); + WCMAppModel.ASSOC_WEBWORKFLOWDEFAULTS, + WCMAppModel.ASSOC_WEBWORKFLOWDEFAULTS, + WCMAppModel.TYPE_WEBWORKFLOWDEFAULTS, + props).getChildRef(); // persist workflow default params if (workflow.getParams() != null) @@ -747,7 +748,7 @@ public class CreateWebsiteWizard extends BaseWizardBean private String title; private String description; private WorkflowWrapper workflow; - private String filenamePattern; + private String outputPathPattern; private List templates = null; FormWrapper(Form form) @@ -808,23 +809,23 @@ public class CreateWebsiteWizard extends BaseWizardBean } /** - * @return Returns the filename pattern. + * @return Returns the output path pattern. */ - public String getFilenamePattern() + public String getOutputPathPattern() { - if (this.filenamePattern == null) + if (this.outputPathPattern == null) { - this.filenamePattern = this.form.getOutputPathPattern(); + this.outputPathPattern = this.form.getOutputPathPattern(); } - return this.filenamePattern; + return this.outputPathPattern; } /** - * @param filenamePattern The filename pattern to set. + * @param outputPathPattern The output path pattern to set. */ - public void setFilenamePattern(String filenamePattern) + public void setOutputPathPattern(String outputPathPattern) { - this.filenamePattern = filenamePattern; + this.outputPathPattern = outputPathPattern; } /** @@ -872,7 +873,7 @@ public class CreateWebsiteWizard extends BaseWizardBean String none = '<' + Application.getMessage(FacesContext.getCurrentInstance(), MSG_NONE) + '>'; return MessageFormat.format(Application.getMessage(FacesContext.getCurrentInstance(), MSG_FORM_SUMMARY), getWorkflow() != null ? this.workflow.title : none, - getFilenamePattern() != null ? this.filenamePattern : none, + getOutputPathPattern() != null ? this.outputPathPattern : none, getTemplates() != null ? this.templates.size() : 0); } } @@ -885,17 +886,17 @@ public class CreateWebsiteWizard extends BaseWizardBean private RenderingEngineTemplate ret; private String title; private String description; - private String filenamePattern; + private String outputPathPattern; public PresentationTemplate(RenderingEngineTemplate ret) { this(ret, null); } - public PresentationTemplate(RenderingEngineTemplate ret, String filenamePattern) + public PresentationTemplate(RenderingEngineTemplate ret, String outputPathPattern) { this.ret = ret; - this.filenamePattern = filenamePattern; + this.outputPathPattern = outputPathPattern; } public RenderingEngineTemplate getRenderingEngineTemplate() @@ -922,23 +923,23 @@ public class CreateWebsiteWizard extends BaseWizardBean } /** - * @return Returns the filename pattern. + * @return Returns the output path pattern. */ - public String getFilenamePattern() + public String getOutputPathPattern() { - if (this.filenamePattern == null) + if (this.outputPathPattern == null) { - this.filenamePattern = ret.getOutputPathPattern(); + this.outputPathPattern = ret.getOutputPathPattern(); } - return this.filenamePattern; + return this.outputPathPattern; } /** - * @param filenamePattern The filename pattern to set. + * @param outputPathPattern The output path pattern to set. */ - public void setFilenamePattern(String filenamePattern) + public void setOutputPathPattern(String outputPathPattern) { - this.filenamePattern = filenamePattern; + this.outputPathPattern = outputPathPattern; } } diff --git a/source/java/org/alfresco/web/bean/wcm/EditFormWizard.java b/source/java/org/alfresco/web/bean/wcm/EditFormWizard.java index 1527bcc656..0ecb0544e5 100644 --- a/source/java/org/alfresco/web/bean/wcm/EditFormWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/EditFormWizard.java @@ -17,6 +17,7 @@ package org.alfresco.web.bean.wcm; import java.io.Serializable; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -120,7 +121,7 @@ public class EditFormWizard this.nodeService.setProperty(formNodeRef, ContentModel.PROP_TITLE, this.getFormTitle()); this.nodeService.setProperty(formNodeRef, ContentModel.PROP_DESCRIPTION, this.getFormDescription()); this.nodeService.setProperty(formNodeRef, - WCMAppModel.PROP_OUTPUT_PATH_PATTERN_FORM_INSTANCE_DATA, + WCMAppModel.PROP_OUTPUT_PATH_PATTERN, this.getOutputPathPatternForFormInstanceData()); this.nodeService.setProperty(formNodeRef, WCMAppModel.PROP_XML_SCHEMA_ROOT_ELEMENT_NAME, @@ -128,9 +129,26 @@ public class EditFormWizard final WorkflowDefinition wd = this.getDefaultWorkflowDefinition(); if (wd != null) { - this.nodeService.setProperty(formNodeRef, - WCMAppModel.PROP_DEFAULT_WORKFLOW_NAME, - wd.getName()); + final List workflowRefs = + this.nodeService.getChildAssocs(formNodeRef, + WCMAppModel.ASSOC_FORM_WORKFLOW_DEFAULTS, + RegexQNamePattern.MATCH_ALL); + if (workflowRefs.size() == 0) + { + final Map props = new HashMap(1, 1.0f); + props.put(WCMAppModel.PROP_WORKFLOW_NAME, wd.getName()); + this.nodeService.createNode(formNodeRef, + WCMAppModel.ASSOC_FORM_WORKFLOW_DEFAULTS, + WCMAppModel.ASSOC_FORM_WORKFLOW_DEFAULTS, + WCMAppModel.TYPE_WORKFLOW_DEFAULTS, + props); + } + else + { + this.nodeService.setProperty(workflowRefs.get(0).getChildRef(), + WCMAppModel.PROP_WORKFLOW_NAME, + wd.getName()); + } } if (this.getSchemaFile() != null) diff --git a/source/java/org/alfresco/web/bean/wcm/EditWebsiteWizard.java b/source/java/org/alfresco/web/bean/wcm/EditWebsiteWizard.java index f793487c24..df6f8edece 100644 --- a/source/java/org/alfresco/web/bean/wcm/EditWebsiteWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/EditWebsiteWizard.java @@ -90,7 +90,7 @@ public class EditWebsiteWizard extends CreateWebsiteWizard FormWrapper form = new FormWrapper(formImpl); form.setTitle((String)this.nodeService.getProperty(formRef, ContentModel.PROP_TITLE)); form.setDescription((String)this.nodeService.getProperty(formRef, ContentModel.PROP_DESCRIPTION)); - form.setFilenamePattern((String)this.nodeService.getProperty(formRef, WCMAppModel.PROP_FILENAMEPATTERN)); + form.setOutputPathPattern((String)this.nodeService.getProperty(formRef, WCMAppModel.PROP_OUTPUT_PATH_PATTERN)); // the single workflow attached to the form List workflowRefs = this.nodeService.getChildAssocs( @@ -118,18 +118,16 @@ public class EditWebsiteWizard extends CreateWebsiteWizard formRef, WCMAppModel.ASSOC_WEBFORMTEMPLATE, RegexQNamePattern.MATCH_ALL); for (ChildAssociationRef tChildRef : templateRefs) { - NodeRef templateRef = tChildRef.getChildRef(); - NodeRef engineRef = (NodeRef)this.nodeService.getProperty(templateRef, WCMAppModel.PROP_ENGINE); - for (RenderingEngineTemplate ret : engineTemplates) + final NodeRef templateRef = tChildRef.getChildRef(); + final String renderingEngineTemplateName = (String) + this.nodeService.getProperty(templateRef, + WCMAppModel.PROP_BASE_RENDERING_ENGINE_TEMPLATE_NAME); + final RenderingEngineTemplate ret = formImpl.getRenderingEngineTemplate(renderingEngineTemplateName); + if (ret != null) { - if (engineRef.equals(ret.getNodeRef())) - { - String filenamePattern = (String)this.nodeService.getProperty(templateRef, - WCMAppModel.PROP_FILENAMEPATTERN); - PresentationTemplate template = new PresentationTemplate(ret, filenamePattern); - form.addTemplate(template); - break; - } + final String outputPathPattern = (String) + this.nodeService.getProperty(templateRef, WCMAppModel.PROP_OUTPUT_PATH_PATTERN); + form.addTemplate(new PresentationTemplate(ret, outputPathPattern)); } } @@ -149,8 +147,8 @@ public class EditWebsiteWizard extends CreateWebsiteWizard { WorkflowWrapper wfWrapper = new WorkflowWrapper(wfName, wfDef.getTitle(), wfDef.getDescription()); wfWrapper.setParams((Map)AVMWorkflowUtil.deserializeWorkflowParams(wfRef)); - wfWrapper.setFilenamePattern((String)this.nodeService.getProperty( - wfRef, WCMAppModel.PROP_FILENAMEPATTERN)); + wfWrapper.setFilenamePattern((String)this.nodeService.getProperty(wfRef, + WCMAppModel.PROP_FILENAMEPATTERN)); if (wfDef.startTaskDefinition != null) { wfWrapper.setType(wfDef.startTaskDefinition.metadata.getName()); diff --git a/source/java/org/alfresco/web/bean/wcm/FormDetailsDialog.java b/source/java/org/alfresco/web/bean/wcm/FormDetailsDialog.java index 5c38acff34..08f2a0388d 100644 --- a/source/java/org/alfresco/web/bean/wcm/FormDetailsDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/FormDetailsDialog.java @@ -50,7 +50,7 @@ public class FormDetailsDialog extends BaseDialogBean private String title; private String description; - private String filenamePattern; + private String outputPathPattern; private String[] workflowSelectedValue; @@ -63,7 +63,7 @@ public class FormDetailsDialog extends BaseDialogBean super.init(parameters); this.title = null; this.description = null; - this.filenamePattern = null; + this.outputPathPattern = null; this.workflowSelectedValue = null; } @@ -142,21 +142,21 @@ public class FormDetailsDialog extends BaseDialogBean /** * @return Returns the filename pattern */ - public String getFilenamePattern() + public String getOutputPathPattern() { - if (this.filenamePattern == null) + if (this.outputPathPattern == null) { - this.filenamePattern = getActionForm().getFilenamePattern(); + this.outputPathPattern = getActionForm().getOutputPathPattern(); } - return this.filenamePattern; + return this.outputPathPattern; } /** * @param pattern The filename pattern to set. */ - public void setFilenamePattern(String pattern) + public void setOutputPathPattern(String pattern) { - this.filenamePattern = pattern; + this.outputPathPattern = pattern; } /** @@ -225,9 +225,9 @@ public class FormDetailsDialog extends BaseDialogBean { form.setDescription(this.description); } - if (this.filenamePattern != null) + if (this.outputPathPattern != null) { - form.setFilenamePattern(this.filenamePattern); + form.setOutputPathPattern(this.outputPathPattern); } if (this.workflowSelectedValue != null && this.workflowSelectedValue.length != 0) { diff --git a/source/java/org/alfresco/web/bean/wcm/FormTemplatesDialog.java b/source/java/org/alfresco/web/bean/wcm/FormTemplatesDialog.java index b247c29f74..9a9f621a22 100644 --- a/source/java/org/alfresco/web/bean/wcm/FormTemplatesDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/FormTemplatesDialog.java @@ -153,7 +153,7 @@ public class FormTemplatesDialog extends BaseDialogBean { PresentationTemplate template = (PresentationTemplate)this.templateList.get(index).getValue(); // clone the PresentationTemplate into one the user can modify - this.templates.add(new PresentationTemplate(template.getRenderingEngineTemplate(), template.getFilenamePattern())); + this.templates.add(new PresentationTemplate(template.getRenderingEngineTemplate(), template.getOutputPathPattern())); } } diff --git a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java index ca38ad0b62..37a181c562 100644 --- a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java @@ -168,7 +168,7 @@ public class SubmitDialog extends BaseDialogBean NodeRef webFormRef = ref.getChildRef(); String form = (String)this.nodeService.getProperty(webFormRef, WCMAppModel.PROP_FORMNAME); List wfRefs = this.nodeService.getChildAssocs( - webFormRef, WCMAppModel.TYPE_WORKFLOWDEFAULTS, RegexQNamePattern.MATCH_ALL); + webFormRef, WCMAppModel.TYPE_WORKFLOW_DEFAULTS, RegexQNamePattern.MATCH_ALL); if (wfRefs.size() == 1) { NodeRef wfDefaultsRef = wfRefs.get(0).getChildRef(); diff --git a/source/java/org/alfresco/web/bean/wcm/WebProject.java b/source/java/org/alfresco/web/bean/wcm/WebProject.java new file mode 100644 index 0000000000..9462e23da7 --- /dev/null +++ b/source/java/org/alfresco/web/bean/wcm/WebProject.java @@ -0,0 +1,309 @@ +/* + * 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 org.alfresco.web.bean.repository.User; +import java.io.Serializable; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.workflow.WorkflowDefinition; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; +import java.io.IOException; +import java.io.Serializable; +import java.util.List; +import java.util.*; +import javax.faces.context.FacesContext; +import org.alfresco.model.ContentModel; +import org.alfresco.model.WCMAppModel; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.repository.AssociationRef; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +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.repository.TemplateService; +import org.alfresco.service.cmr.workflow.WorkflowDefinition; +import org.alfresco.service.cmr.workflow.WorkflowService; +import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.bean.wcm.AVMConstants; +import org.alfresco.web.forms.*; +import org.alfresco.web.forms.xforms.XFormsProcessor; +import org.alfresco.web.app.servlet.DownloadContentServlet; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.*; + +/** + * Provides configured data for a web project. + * + * @author Ariel Backenroth + */ +public class WebProject + implements Serializable +{ + + ///////////////////////////////////////////////////////////////////////////// + + /** + * Wraps a form object to provide overridden values at the web project level + */ + private class FormWrapper + extends FormImpl + { + private final NodeRef formNodeRef; + private Form baseForm; + private NodeRef defaultWorkflowNodeRef; + + private FormWrapper(final Form form, final NodeRef formNodeRef) + { + super(((FormImpl)form).getNodeRef()); + this.formNodeRef = formNodeRef; + } + + @Override + public String getTitle() + { + final NodeService nodeService = this.getServiceRegistry().getNodeService(); + return (String)nodeService.getProperty(this.formNodeRef, + ContentModel.PROP_TITLE); + } + + @Override + public String getDescription() + { + final NodeService nodeService = this.getServiceRegistry().getNodeService(); + return (String)nodeService.getProperty(this.formNodeRef, + ContentModel.PROP_DESCRIPTION); + } + + @Override + public String getOutputPathPattern() + { + final NodeService nodeService = this.getServiceRegistry().getNodeService(); + final String result = (String) + nodeService.getProperty(this.formNodeRef, + WCMAppModel.PROP_OUTPUT_PATH_PATTERN); + return (result != null ? result : this.baseForm.getOutputPathPattern()); + } + + @Override + protected NodeRef getDefaultWorkflowNodeRef() + { + if (this.defaultWorkflowNodeRef == null) + { + final NodeService nodeService = this.getServiceRegistry().getNodeService(); + final List workflowRefs = + nodeService.getChildAssocs(this.formNodeRef, + WCMAppModel.ASSOC_WORKFLOWDEFAULTS, + RegexQNamePattern.MATCH_ALL); + if (workflowRefs.size() == 0) + { + return null; + } + + this.defaultWorkflowNodeRef = workflowRefs.get(0).getChildRef(); + } + return this.defaultWorkflowNodeRef; + } + + @Override + protected Map loadRenderingEngineTemplates() + { + final Map allRets = super.loadRenderingEngineTemplates(); + + final NodeService nodeService = this.getServiceRegistry().getNodeService(); + final List retNodeRefs = + nodeService.getChildAssocs(this.formNodeRef, + WCMAppModel.ASSOC_WEBFORMTEMPLATE, + RegexQNamePattern.MATCH_ALL); + final Map result = + new HashMap(retNodeRefs.size(), 1.0f); + for (ChildAssociationRef car : retNodeRefs) + { + final String renderingEngineTemplateName = (String) + nodeService.getProperty(car.getChildRef(), + WCMAppModel.PROP_BASE_RENDERING_ENGINE_TEMPLATE_NAME); + final String outputPathPattern = (String) + nodeService.getProperty(car.getChildRef(), WCMAppModel.PROP_OUTPUT_PATH_PATTERN); + final RenderingEngineTemplateImpl ret = (RenderingEngineTemplateImpl) + allRets.get(renderingEngineTemplateName); + result.put(ret.getName(), + new RenderingEngineTemplateImpl(ret.getNodeRef(), + ret.getRenditionPropertiesNodeRef()) + { + @Override + public String getOutputPathPattern() + { + return outputPathPattern; + } + }); + + } + return result; + } + } + + ///////////////////////////////////////////////////////////////////////////// + + /** Content Manager role name */ + private static final String ROLE_CONTENT_MANAGER = "ContentManager"; + + private final NodeRef nodeRef; + private Map forms; + + public WebProject(final NodeRef nodeRef) + { + this.nodeRef = nodeRef; + } + + /** + * Returns the name of the web project. + * + * @return the name of the web project. + */ + public String getName() + { + final ServiceRegistry serviceRegistry = this.getServiceRegistry(); + final NodeService nodeService = serviceRegistry.getNodeService(); + return (String)nodeService.getProperty(this.nodeRef, ContentModel.PROP_NAME); + } + + /** + * Returns the store id for this web project. + * + * @return the store id for this web project. + */ + public String getStoreId() + { + final ServiceRegistry serviceRegistry = this.getServiceRegistry(); + final NodeService nodeService = serviceRegistry.getNodeService(); + return (String)nodeService.getProperty(this.nodeRef, WCMAppModel.PROP_AVMSTORE); + } + + /** + * Returns the staging store name. + * + * @return the staging store name. + */ + public String getStagingStore() + { + return AVMConstants.buildStagingStoreName(this.getStoreId()); + } + + /** + * Returns the forms configured for this web project. + * + * @return the forms configured for this web project. + */ + public List getForms() + { + return Collections.unmodifiableList(new ArrayList(this.getFormsImpl().values())); + } + + /** + * Returns the form with the given name or null if not found. + * + * @param name the name of the form + * @return the form or null if not found. + * @exception NullPointerException if the name is null. + */ + public Form getForm(final String name) + { + if (name == null) + { + throw new NullPointerException(); + } + return this.getFormsImpl().get(name); + } + + /** + * Returns true if the user is a manager of this web project. + * + * @param user the user + * @return true if the user is a manager, false otherwise. + * @exception NullPointerException if the user is null. + */ + public boolean isManager(final User user) + { + if (user.isAdmin()) + { + return true; + } + + final ServiceRegistry serviceRegistry = this.getServiceRegistry(); + final NodeService nodeService = serviceRegistry.getNodeService(); + final String currentUser = user.getUserName(); + final List userInfoRefs = + nodeService.getChildAssocs(this.nodeRef, + WCMAppModel.ASSOC_WEBUSER, + RegexQNamePattern.MATCH_ALL); + for (ChildAssociationRef ref : userInfoRefs) + { + final NodeRef userInfoRef = ref.getChildRef(); + final String username = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERNAME); + final String userrole = (String)nodeService.getProperty(userInfoRef, WCMAppModel.PROP_WEBUSERROLE); + if (currentUser.equals(username) && ROLE_CONTENT_MANAGER.equals(userrole)) + { + return true; + } + } + return false; + } + + /** + * Returns the default webapp for this web project. + * + * @return the default webapp for this web project. + */ + public String getDefaultWebapp() + { + final ServiceRegistry serviceRegistry = this.getServiceRegistry(); + final NodeService nodeService = serviceRegistry.getNodeService(); + return (String) + nodeService.getProperty(this.nodeRef, WCMAppModel.PROP_DEFAULTWEBAPP); + } + + private Map getFormsImpl() + { + if (this.forms == null) + { + final ServiceRegistry serviceRegistry = this.getServiceRegistry(); + final NodeService nodeService = serviceRegistry.getNodeService(); + final List formRefs = + nodeService.getChildAssocs(this.nodeRef, + WCMAppModel.ASSOC_WEBFORM, + RegexQNamePattern.MATCH_ALL); + this.forms = new HashMap(formRefs.size(), 1.0f); + for (final ChildAssociationRef ref : formRefs) + { + final String formName = (String) + nodeService.getProperty(ref.getChildRef(), WCMAppModel.PROP_FORMNAME); + final Form baseForm = FormsService.getInstance().getForm(formName); + this.forms.put(formName, new FormWrapper(baseForm, ref.getChildRef())); + } + } + return this.forms; + } + + private ServiceRegistry getServiceRegistry() + { + final FacesContext fc = FacesContext.getCurrentInstance(); + return Repository.getServiceRegistry(fc); + } +} \ No newline at end of file diff --git a/source/java/org/alfresco/web/forms/AbstractRenderingEngine.java b/source/java/org/alfresco/web/forms/AbstractRenderingEngine.java index ffd64f02e1..ced4a85c0a 100644 --- a/source/java/org/alfresco/web/forms/AbstractRenderingEngine.java +++ b/source/java/org/alfresco/web/forms/AbstractRenderingEngine.java @@ -16,8 +16,11 @@ */ package org.alfresco.web.forms; +import java.util.HashMap; +import java.util.Map; import javax.faces.context.FacesContext; import org.alfresco.model.WCMModel; +import org.alfresco.repo.avm.AVMNodeConverter; import org.alfresco.service.cmr.remote.AVMRemote; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.NodeRef; @@ -56,4 +59,19 @@ public abstract class AbstractRenderingEngine { return new FormDataFunctions(AbstractRenderingEngine.getAVMRemote()); } + + protected HashMap getStandardParameters(final FormInstanceData formInstanceData, + final Rendition rendition) + { + final String formInstanceDataAvmPath = formInstanceData.getPath(); + final String renditionAvmPath = rendition.getPath(); + final HashMap parameters = new HashMap(); + parameters.put("avm_sandbox_url", AVMConstants.buildStoreUrl(formInstanceDataAvmPath)); + parameters.put("form_instance_data_file_name", AVMNodeConverter.SplitBase(formInstanceDataAvmPath)[1]); + parameters.put("rendition_file_name", AVMNodeConverter.SplitBase(renditionAvmPath)[1]); + parameters.put("parent_path", AVMNodeConverter.SplitBase(formInstanceDataAvmPath)[0]); + final FacesContext fc = FacesContext.getCurrentInstance(); + parameters.put("request_context_path", fc.getExternalContext().getRequestContextPath()); + return parameters; + } } \ No newline at end of file diff --git a/source/java/org/alfresco/web/forms/Form.java b/source/java/org/alfresco/web/forms/Form.java index c928305a74..47f34b7a17 100644 --- a/source/java/org/alfresco/web/forms/Form.java +++ b/source/java/org/alfresco/web/forms/Form.java @@ -16,14 +16,15 @@ */ package org.alfresco.web.forms; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.workflow.WorkflowDefinition; -import org.w3c.dom.Document; -import org.xml.sax.SAXException; import java.io.IOException; import java.io.Serializable; -import java.net.URI; import java.util.List; +import java.util.Map; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.workflow.WorkflowDefinition; +import org.alfresco.service.namespace.QName; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; /** * Encapsulation of a form. @@ -55,6 +56,12 @@ public interface Form */ public WorkflowDefinition getDefaultWorkflow(); + /** + * @return the parameters for the default workflow or null + * if none were configured. + */ + public Map getDefaultWorkflowParameters(); + /** the xml schema for this template type */ public Document getSchema() throws IOException, SAXException; @@ -93,10 +100,11 @@ public interface Form */ public List getRenderingEngineTemplates(); - /** - * Associates properties with the form instance data registering it as - * generated by this form. + * Provides the rendering engine template by name. + * + * @param name the name of the rendering engine template. + * @return the rendering engine template or null if not found. */ - public void registerFormInstanceData(final NodeRef formInstanceDataNodeRef); + public RenderingEngineTemplate getRenderingEngineTemplate(final String name); } diff --git a/source/java/org/alfresco/web/forms/FormDataFunctions.java b/source/java/org/alfresco/web/forms/FormDataFunctions.java index 4bbfd5d783..129da52d55 100644 --- a/source/java/org/alfresco/web/forms/FormDataFunctions.java +++ b/source/java/org/alfresco/web/forms/FormDataFunctions.java @@ -61,13 +61,10 @@ public class FormDataFunctions throws IOException, SAXException { - final DocumentBuilder db = this.getDocumentBuilder(); final InputStream istream = this.avmRemote.getFileInputStream(-1, avmPath); - - Document result; try { - return db.parse(istream); + return XMLUtil.parse(istream); } finally { @@ -89,7 +86,6 @@ public class FormDataFunctions { final Map entries = this.avmRemote.getDirectoryListing(-1, avmPath); - final DocumentBuilder db = this.getDocumentBuilder(); final Map result = new HashMap(); for (Map.Entry entry : entries.entrySet()) { @@ -121,7 +117,7 @@ public class FormDataFunctions final InputStream istream = this.avmRemote.getFileInputStream(-1, avmPath + '/' + entryName); try { - result.put(entryName, db.parse(istream)); + result.put(entryName, XMLUtil.parse(istream)); } finally { @@ -131,23 +127,4 @@ public class FormDataFunctions } return result; } - - private static DocumentBuilder getDocumentBuilder() - { - if (FormDataFunctions.documentBuilder == null) - { - try - { - final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - dbf.setValidating(false); - FormDataFunctions.documentBuilder = dbf.newDocumentBuilder(); - } - catch (ParserConfigurationException pce) - { - LOGGER.error(pce); - } - } - return FormDataFunctions.documentBuilder; - } } \ No newline at end of file diff --git a/source/java/org/alfresco/web/forms/FormImpl.java b/source/java/org/alfresco/web/forms/FormImpl.java index 473cddb49e..d251c50992 100644 --- a/source/java/org/alfresco/web/forms/FormImpl.java +++ b/source/java/org/alfresco/web/forms/FormImpl.java @@ -25,7 +25,6 @@ import freemarker.template.TemplateModel; import freemarker.template.TemplateModelException; import java.io.*; import java.net.URI; -import java.io.Serializable; import java.util.*; import javax.faces.context.FacesContext; import org.alfresco.model.ContentModel; @@ -43,19 +42,20 @@ import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.wcm.AVMConstants; +import org.alfresco.web.bean.wcm.AVMWorkflowUtil; import org.alfresco.web.forms.xforms.XFormsProcessor; -import org.alfresco.web.app.servlet.DownloadContentServlet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.w3c.dom.*; import org.xml.sax.SAXException; -class FormImpl +public class FormImpl implements Form { private static final Log LOGGER = LogFactory.getLog(FormImpl.class); private final NodeRef folderNodeRef; + private transient Map renderingEngineTemplates; private final static LinkedList PROCESSORS = new LinkedList(); @@ -94,18 +94,47 @@ class FormImpl { final NodeService nodeService = this.getServiceRegistry().getNodeService(); return (String)nodeService.getProperty(this.folderNodeRef, - WCMAppModel.PROP_OUTPUT_PATH_PATTERN_FORM_INSTANCE_DATA); + WCMAppModel.PROP_OUTPUT_PATH_PATTERN); } public WorkflowDefinition getDefaultWorkflow() { final NodeService nodeService = this.getServiceRegistry().getNodeService(); - final String defaultWorkflowName = (String)nodeService.getProperty(this.folderNodeRef, - WCMAppModel.PROP_DEFAULT_WORKFLOW_NAME); final WorkflowService workflowService = this.getServiceRegistry().getWorkflowService(); - return (defaultWorkflowName != null - ? workflowService.getDefinitionByName(defaultWorkflowName) - : null); + + final NodeRef workflowRef = this.getDefaultWorkflowNodeRef(); + final String workflowName = + (workflowRef != null + ? (String)nodeService.getProperty(workflowRef, WCMAppModel.PROP_WORKFLOW_NAME) + : null); + + if (LOGGER.isDebugEnabled()) + LOGGER.debug("using workflow " + workflowName + " for form " + this.getName()); + + return workflowName != null ? workflowService.getDefinitionByName(workflowName) : null; + } + + public Map getDefaultWorkflowParameters() + { + final NodeRef workflowRef = this.getDefaultWorkflowNodeRef(); + return (Map)AVMWorkflowUtil.deserializeWorkflowParams(workflowRef); + } + + protected NodeRef getDefaultWorkflowNodeRef() + { + final NodeService nodeService = this.getServiceRegistry().getNodeService(); + final List workflowRefs = + nodeService.getChildAssocs(this.folderNodeRef, + WCMAppModel.ASSOC_FORM_WORKFLOW_DEFAULTS, + RegexQNamePattern.MATCH_ALL); + if (workflowRefs.size() == 0) + { + return null; + } + + assert workflowRefs.size() == 1 : "found more than one workflow parameters node for " + this.getName(); + + return workflowRefs.get(0).getChildRef(); } public String getOutputPathForFormInstanceData(final Document formInstanceData, @@ -144,11 +173,11 @@ class FormImpl throws IOException, SAXException { - final FormsService ts = FormsService.getInstance(); final NodeService nodeService = this.getServiceRegistry().getNodeService(); - final NodeRef schemaNodeRef = (NodeRef)nodeService.getProperty(folderNodeRef, - WCMAppModel.PROP_XML_SCHEMA); - return ts.parseXML(schemaNodeRef); + final NodeRef schemaNodeRef = (NodeRef) + nodeService.getProperty(folderNodeRef, WCMAppModel.PROP_XML_SCHEMA); + return XMLUtil.parse(schemaNodeRef, + this.getServiceRegistry().getContentService()); } public List getFormProcessors() @@ -158,41 +187,30 @@ class FormImpl public void addRenderingEngineTemplate(final RenderingEngineTemplate ret) { -// this.renderingEngineTemplates.add(ret); throw new UnsupportedOperationException(); } public List getRenderingEngineTemplates() { - final NodeService nodeService = this.getServiceRegistry().getNodeService(); - final List refs = nodeService.getTargetAssocs(this.folderNodeRef, - WCMAppModel.ASSOC_RENDERING_ENGINE_TEMPLATES); - final List result = new ArrayList(refs.size()); - for (AssociationRef assoc : refs) + if (this.renderingEngineTemplates == null) { - final NodeRef retNodeRef = assoc.getTargetRef(); - for (ChildAssociationRef assoc2 : nodeService.getChildAssocs(retNodeRef, - WCMAppModel.ASSOC_RENDITION_PROPERTIES, - RegexQNamePattern.MATCH_ALL)) - { - final NodeRef renditionPropertiesNodeRef = assoc2.getChildRef(); - - final RenderingEngineTemplate ret = - new RenderingEngineTemplateImpl(retNodeRef, renditionPropertiesNodeRef); - LOGGER.debug("loaded rendering engine template " + ret); - result.add(ret); - } + this.renderingEngineTemplates = this.loadRenderingEngineTemplates(); } - return result; + return Collections.unmodifiableList(new ArrayList(this.renderingEngineTemplates.values())); } - public void registerFormInstanceData(final NodeRef formInstanceDataNodeRef) + public RenderingEngineTemplate getRenderingEngineTemplate(final String name) { - final NodeService nodeService = this.getServiceRegistry().getNodeService(); - final Map props = new HashMap(2, 1.0f); - props.put(WCMAppModel.PROP_PARENT_FORM, this.folderNodeRef); - props.put(WCMAppModel.PROP_PARENT_FORM_NAME, this.getName()); - nodeService.addAspect(formInstanceDataNodeRef, WCMAppModel.ASPECT_FORM_INSTANCE_DATA, props); + if (this.renderingEngineTemplates == null) + { + this.renderingEngineTemplates = this.loadRenderingEngineTemplates(); + } + return this.renderingEngineTemplates.get(name); + } + + public NodeRef getNodeRef() + { + return this.folderNodeRef; } public int hashCode() @@ -209,9 +227,33 @@ class FormImpl "}"); } - private ServiceRegistry getServiceRegistry() + protected ServiceRegistry getServiceRegistry() { final FacesContext fc = FacesContext.getCurrentInstance(); return Repository.getServiceRegistry(fc); } + + protected Map loadRenderingEngineTemplates() + { + final NodeService nodeService = this.getServiceRegistry().getNodeService(); + final List refs = nodeService.getTargetAssocs(this.folderNodeRef, + WCMAppModel.ASSOC_RENDERING_ENGINE_TEMPLATES); + final Map result = new HashMap(refs.size(), 1.0f); + for (AssociationRef assoc : refs) + { + final NodeRef retNodeRef = assoc.getTargetRef(); + for (ChildAssociationRef assoc2 : nodeService.getChildAssocs(retNodeRef, + WCMAppModel.ASSOC_RENDITION_PROPERTIES, + RegexQNamePattern.MATCH_ALL)) + { + final NodeRef renditionPropertiesNodeRef = assoc2.getChildRef(); + + final RenderingEngineTemplate ret = + new RenderingEngineTemplateImpl(retNodeRef, renditionPropertiesNodeRef); + LOGGER.debug("loaded rendering engine template " + ret); + result.put(ret.getName(), ret); + } + } + return result; + } } \ No newline at end of file diff --git a/source/java/org/alfresco/web/forms/FormInstanceData.java b/source/java/org/alfresco/web/forms/FormInstanceData.java index e978fcb360..c5e437aa68 100644 --- a/source/java/org/alfresco/web/forms/FormInstanceData.java +++ b/source/java/org/alfresco/web/forms/FormInstanceData.java @@ -16,9 +16,12 @@ */ package org.alfresco.web.forms; +import java.io.IOException; import java.io.Serializable; import java.util.List; import org.alfresco.service.cmr.repository.NodeRef; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; /** * Encapsulation of form instance data. @@ -47,8 +50,9 @@ public interface FormInstanceData /** the url to the asset */ public String getUrl(); - /** the noderef containing the form instance data */ - public NodeRef getNodeRef(); + /** returns the parsed form instance data */ + public Document getDocument() + throws IOException, SAXException; /** returns all renditions of this form instance data */ public List getRenditions(); diff --git a/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java b/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java index c868edb01c..0ddc676fce 100644 --- a/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java +++ b/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java @@ -16,27 +16,25 @@ */ package org.alfresco.web.forms; -import java.util.LinkedList; -import java.util.List; +import java.io.*; +import java.util.*; import javax.faces.context.FacesContext; import org.alfresco.model.ContentModel; import org.alfresco.model.WCMAppModel; -import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.repo.avm.AVMNodeConverter; +import org.alfresco.repo.domain.PropertyValue; import org.alfresco.service.ServiceRegistry; -import org.alfresco.service.cmr.repository.ContentReader; -import org.alfresco.service.cmr.repository.ContentService; -import org.alfresco.service.cmr.repository.MimetypeService; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.TemplateNode; -import org.alfresco.service.cmr.repository.TemplateService; +import org.alfresco.service.cmr.avm.AVMNotFoundException; +import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.dictionary.DataTypeDefinition; +import org.alfresco.service.cmr.repository.*; import org.alfresco.service.namespace.QName; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.wcm.AVMConstants; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.w3c.dom.*; +import org.xml.sax.SAXException; /** * Encapsulation of a rendition. @@ -53,6 +51,10 @@ public class FormInstanceDataImpl public FormInstanceDataImpl(final NodeRef nodeRef) { + if (nodeRef == null) + { + throw new NullPointerException(); + } this.nodeRef = nodeRef; } @@ -79,13 +81,20 @@ public class FormInstanceDataImpl return AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond(); } + public Document getDocument() + throws IOException, SAXException + { + return XMLUtil.parse(this.getNodeRef(), + this.getServiceRegistry().getContentService()); + } + public Form getForm() { final NodeService nodeService = this.getServiceRegistry().getNodeService(); - final NodeRef formNodeRef = (NodeRef) + final String parentFormName = (String) nodeService.getProperty(this.nodeRef, - WCMAppModel.PROP_PARENT_FORM); - return new FormImpl(formNodeRef); + WCMAppModel.PROP_PARENT_FORM_NAME); + return FormsService.getInstance().getForm(parentFormName); } /** the node ref containing the contents of this rendition */ @@ -102,21 +111,17 @@ public class FormInstanceDataImpl public List getRenditions() { final AVMService avmService = this.getServiceRegistry().getAVMService(); - final List result = new LinkedList(); - for (RenderingEngineTemplate ret : this.getForm().getRenderingEngineTemplates()) + final PropertyValue pv = + avmService.getNodeProperty(-1, this.getPath(), WCMAppModel.PROP_RENDITIONS); + final Collection renditionPaths = (pv == null + ? Collections.EMPTY_LIST + : pv.getCollection(DataTypeDefinition.TEXT)); + final String storeName = AVMConstants.getStoreName(this.getPath()); + final List result = new ArrayList(renditionPaths.size()); + for (Serializable path : renditionPaths) { - final String renditionAvmPath = ret.getOutputPathForRendition(this); - if (avmService.lookup(-1, renditionAvmPath) == null) - { - LOGGER.warn("unable to locate rendition " + renditionAvmPath + - " for form instance data " + this.getName()); - } - else - { - final NodeRef renditionNodeRef = - AVMNodeConverter.ToNodeRef(-1, renditionAvmPath); - result.add(new RenditionImpl(renditionNodeRef)); - } + result.add(new RenditionImpl(AVMNodeConverter.ToNodeRef(-1, storeName + ':' + (String)path))); + } return result; } diff --git a/source/java/org/alfresco/web/forms/FormsService.java b/source/java/org/alfresco/web/forms/FormsService.java index df3e798e67..2bbbd548f3 100644 --- a/source/java/org/alfresco/web/forms/FormsService.java +++ b/source/java/org/alfresco/web/forms/FormsService.java @@ -16,35 +16,15 @@ */ package org.alfresco.web.forms; -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.text.MessageFormat; +import java.io.*; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.ResourceBundle; -import java.util.Stack; import javax.faces.context.FacesContext; -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; @@ -89,7 +69,7 @@ public final class FormsService /** the single instance initialized using spring */ private static FormsService INSTANCE; - private static DocumentBuilder documentBuilder; + private static final RenderingEngine[] RENDERING_ENGINES = new RenderingEngine[] { @@ -102,7 +82,6 @@ public final class FormsService private final NodeService nodeService; private final NamespaceService namespaceService; private final SearchService searchService; - private final AVMService avmService; private NodeRef contentFormsNodeRef; @@ -110,14 +89,12 @@ public final class FormsService public FormsService(final ContentService contentService, final NodeService nodeService, final NamespaceService namespaceService, - final SearchService searchService, - final AVMService avmService) + final SearchService searchService) { this.contentService = contentService; this.nodeService = nodeService; this.namespaceService = namespaceService; this.searchService = searchService; - this.avmService = avmService; if (INSTANCE == null) INSTANCE = this; } @@ -180,7 +157,7 @@ public final class FormsService Application.getContentFormsFolderName(fc)); LOGGER.debug("locating content forms at " + xpath); final List results = - searchService.selectNodes(nodeService.getRootNode(Repository.getStoreRef()), + searchService.selectNodes(this.nodeService.getRootNode(Repository.getStoreRef()), xpath, null, namespaceService, @@ -262,273 +239,4 @@ public final class FormsService LOGGER.debug("loaded form " + result); return result; } - - /** - * Generates renditions for the provided formInstanceData. - * - * @param formInstanceDataNodeRef the noderef containing the form instance data - */ - public List generateRenditions(final FormInstanceData formInstanceData) - throws IOException, - SAXException, - RenderingEngine.RenderingException - { - final Form form = formInstanceData.getForm(); - - final Document formInstanceDataDocument = this.parseXML(formInstanceData.getNodeRef()); - - final String formInstanceDataFileName = formInstanceData.getName(); - final String formInstanceDataAvmPath = formInstanceData.getPath(); - LOGGER.debug("generating renditions for " + formInstanceDataAvmPath); - - final List result = new LinkedList(); - for (RenderingEngineTemplate ret : form.getRenderingEngineTemplates()) - { - // get the node ref of the node that will contain the content - final String renditionAvmPath = ret.getOutputPathForRendition(formInstanceData); - final String parentAVMPath = AVMNodeConverter.SplitBase(renditionAvmPath)[0]; - this.makeAllDirectories(parentAVMPath); - final OutputStream out = this.avmService.createFile(parentAVMPath, - AVMNodeConverter.SplitBase(renditionAvmPath)[1]); - - if (LOGGER.isDebugEnabled()) - LOGGER.debug("Created file node for file: " + renditionAvmPath); - - final HashMap parameters = - this.getRenderingEngineParameters(formInstanceDataAvmPath, - renditionAvmPath); - ret.getRenderingEngine().render(formInstanceDataDocument, ret, parameters, out); - out.close(); - - final NodeRef renditionNodeRef = AVMNodeConverter.ToNodeRef(-1, renditionAvmPath); - final Rendition rendition = new RenditionImpl(renditionNodeRef); - form.registerFormInstanceData(renditionNodeRef); - ret.registerRendition(rendition, formInstanceData); - - Map props = new HashMap(1, 1.0f); - props.put(ContentModel.PROP_TITLE, AVMNodeConverter.SplitBase(renditionAvmPath)[1]); - - final ResourceBundle bundle = Application.getBundle(FacesContext.getCurrentInstance()); - props.put(ContentModel.PROP_DESCRIPTION, - MessageFormat.format(bundle.getString("default_rendition_description"), - ret.getTitle(), - AVMConstants.getSandboxRelativePath(renditionAvmPath))); - nodeService.addAspect(renditionNodeRef, ContentModel.ASPECT_TITLED, props); - result.add(rendition); - if (LOGGER.isDebugEnabled()) - LOGGER.debug("generated " + renditionAvmPath + " using " + ret); - } - return result; - } - - /** - * Regenerates all renditions of the provided form instance data. - * - * @param formInstanceDataNodeRef the node ref containing the form instance data. - */ - public List regenerateRenditions(final FormInstanceData formInstanceData) - throws IOException, - SAXException, - RenderingEngine.RenderingException - { - final Form form = formInstanceData.getForm(); - - final Document formInstanceDataDocument = this.parseXML(formInstanceData.getNodeRef()); - final String formInstanceDataFileName = formInstanceData.getName(); - - // other parameter values passed to rendering engine - final String formInstanceDataAvmPath = formInstanceData.getPath(); - LOGGER.debug("regenerating renditions for " + formInstanceDataAvmPath); - final List result = new LinkedList(); - for (RenderingEngineTemplate ret : form.getRenderingEngineTemplates()) - { - final String renditionAvmPath = ret.getOutputPathForRendition(formInstanceData); - - if (LOGGER.isDebugEnabled()) - LOGGER.debug("regenerating file node for : " + formInstanceDataFileName + - " (" + formInstanceData.toString() + - ") to " + renditionAvmPath); - - // get a writer for the content and put the file - OutputStream out = null; - try - { - out = this.avmService.getFileOutputStream(renditionAvmPath); - } - catch (AVMNotFoundException e) - { - out = this.avmService.createFile(AVMNodeConverter.SplitBase(renditionAvmPath)[0], - AVMNodeConverter.SplitBase(renditionAvmPath)[1]); - } - - final HashMap parameters = - this.getRenderingEngineParameters(formInstanceDataAvmPath, renditionAvmPath); - ret.getRenderingEngine().render(formInstanceDataDocument, ret, parameters, out); - out.close(); - - final NodeRef renditionNodeRef = AVMNodeConverter.ToNodeRef(-1, renditionAvmPath); - result.add(new RenditionImpl(renditionNodeRef)); - if (LOGGER.isDebugEnabled()) - LOGGER.debug("regenerated " + renditionAvmPath + " using " + ret); - } - return result; - } - - private static HashMap getRenderingEngineParameters(final String formInstanceDataAvmPath, - final String renditionAvmPath) - { - final HashMap parameters = new HashMap(); - parameters.put("avm_sandbox_url", AVMConstants.buildStoreUrl(formInstanceDataAvmPath)); - parameters.put("form_instance_data_file_name", AVMNodeConverter.SplitBase(formInstanceDataAvmPath)[1]); - parameters.put("rendition_file_name", AVMNodeConverter.SplitBase(renditionAvmPath)[1]); - parameters.put("parent_path", AVMNodeConverter.SplitBase(formInstanceDataAvmPath)[0]); - final FacesContext fc = FacesContext.getCurrentInstance(); - parameters.put("request_context_path", fc.getExternalContext().getRequestContextPath()); - return parameters; - } - - // XXXarielb relocate - public void makeAllDirectories(final String avmDirectoryPath) - { - LOGGER.debug("mkdir -p " + avmDirectoryPath); - String s = avmDirectoryPath; - final Stack dirNames = new Stack(); - while (s != null) - { - try - { - if (this.avmService.lookup(-1, s) != null) - { - LOGGER.debug("path " + s + " exists"); - break; - } - } - catch (AVMNotFoundException avmfe) - { - } - final String[] sb = AVMNodeConverter.SplitBase(s); - s = sb[0]; - LOGGER.debug("pushing " + sb[1]); - dirNames.push(sb); - } - - while (!dirNames.isEmpty()) - { - final String[] sb = dirNames.pop(); - LOGGER.debug("creating " + sb[1] + " in " + sb[0]); - this.avmService.createDirectory(sb[0], sb[1]); - } - } - - /** utility function for creating a document */ - public Document newDocument() - { - return this.getDocumentBuilder().newDocument(); - } - - /** utility function for serializing a node */ - public void writeXML(final Node n, final Writer output) - { - try - { - final TransformerFactory tf = TransformerFactory.newInstance(); - final Transformer t = tf.newTransformer(); - t.setOutputProperty(OutputKeys.INDENT, "yes"); - - if (LOGGER.isDebugEnabled()) - { - LOGGER.debug("writing out a document for " + - (n instanceof Document - ? ((Document)n).getDocumentElement() - : n).getNodeName() + - " to " + (output instanceof StringWriter - ? "string" - : output)); - } - t.transform(new DOMSource(n), new StreamResult(output)); - } - catch (TransformerException te) - { - te.printStackTrace(); - assert false : te.getMessage(); - } - } - - /** utility function for serializing a node */ - public void writeXML(final Node n, final File output) - throws IOException - { - this.writeXML(n, new FileWriter(output)); - } - - /** utility function for serializing a node */ - public String writeXMLToString(final Node n) - { - final StringWriter result = new StringWriter(); - this.writeXML(n, result); - return result.toString(); - } - - /** utility function for parsing xml */ - public Document parseXML(final String source) - throws SAXException, - IOException - { - return this.parseXML(new ByteArrayInputStream(source.getBytes())); - } - - /** utility function for parsing xml */ - public Document parseXML(final NodeRef nodeRef) - throws SAXException, - IOException - { - final ContentReader contentReader = - this.contentService.getReader(nodeRef, ContentModel.TYPE_CONTENT); - final InputStream in = contentReader.getContentInputStream(); - return this.parseXML(in); - } - - /** utility function for parsing xml */ - public Document parseXML(final File source) - throws SAXException, - IOException - { - return this.parseXML(new FileInputStream(source)); - } - - /** utility function for parsing xml */ - public Document parseXML(final InputStream source) - throws SAXException, - IOException - { - final DocumentBuilder db = this.getDocumentBuilder(); - - final Document result = db.parse(source); - source.close(); - return result; - } - - private static String stripExtension(final String s) - { - return s.replaceAll("(.+)\\..*", "$1"); - } - - public DocumentBuilder getDocumentBuilder() - { - if (FormsService.documentBuilder == null) - { - try - { - final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - dbf.setValidating(false); - FormsService.documentBuilder = dbf.newDocumentBuilder(); - } - catch (ParserConfigurationException pce) - { - LOGGER.error(pce); - } - } - return FormsService.documentBuilder; - } } diff --git a/source/java/org/alfresco/web/forms/FreeMarkerRenderingEngine.java b/source/java/org/alfresco/web/forms/FreeMarkerRenderingEngine.java index d3d1b65e8e..2eb37acb48 100644 --- a/source/java/org/alfresco/web/forms/FreeMarkerRenderingEngine.java +++ b/source/java/org/alfresco/web/forms/FreeMarkerRenderingEngine.java @@ -35,6 +35,7 @@ import org.apache.commons.logging.LogFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; +import org.xml.sax.SAXException; /** * Implementation of a form data renderer for processing xml instance data @@ -69,13 +70,15 @@ public class FreeMarkerRenderingEngine * a variable named alfresco at the root. the alfresco variable contains a hash of * all parameters and all extension functions. */ - public void render(final Document xmlContent, + public void render(final FormInstanceData formInstanceData, final RenderingEngineTemplate ret, - final Map parameters, - final OutputStream out) + final Rendition rendition) throws IOException, - RenderingEngine.RenderingException + RenderingEngine.RenderingException, + SAXException { + final Map parameters = + this.getStandardParameters(formInstanceData, rendition); final Configuration cfg = new Configuration(); cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); @@ -85,11 +88,12 @@ public class FreeMarkerRenderingEngine cfg); // wrap the xml instance in a model - final TemplateHashModel instanceDataModel = NodeModel.wrap(xmlContent); + final TemplateHashModel instanceDataModel = NodeModel.wrap(formInstanceData.getDocument()); // build models for each of the extension functions final HashMap methodModels = new HashMap(3, 1.0f); + methodModels.put("parseXMLDocument", new TemplateMethodModel() { public Object exec(final List args) @@ -130,9 +134,7 @@ public class FreeMarkerRenderingEngine // create a root document for rooting all the results. we do this // so that each document root element has a common parent node // and so that xpath axes work properly - final FormsService fs = FormsService.getInstance(); - final DocumentBuilder documentBuilder = fs.getDocumentBuilder(); - final Document rootNodeDocument = documentBuilder.newDocument(); + final Document rootNodeDocument = XMLUtil.newDocument(); final Element rootNodeDocumentEl = rootNodeDocument.createElementNS(ALFRESCO_NS, ALFRESCO_NS_PREFIX + ":file_list"); @@ -213,7 +215,7 @@ public class FreeMarkerRenderingEngine }; // process the form - final Writer writer = new OutputStreamWriter(out); + final Writer writer = new OutputStreamWriter(rendition.getOutputStream()); try { t.process(rootModel, writer); @@ -226,6 +228,7 @@ public class FreeMarkerRenderingEngine finally { writer.flush(); + writer.close(); } } } diff --git a/source/java/org/alfresco/web/forms/RenderingEngine.java b/source/java/org/alfresco/web/forms/RenderingEngine.java index 9797ca8524..dccc8329a0 100644 --- a/source/java/org/alfresco/web/forms/RenderingEngine.java +++ b/source/java/org/alfresco/web/forms/RenderingEngine.java @@ -22,6 +22,7 @@ import java.io.OutputStream; import java.io.Serializable; import java.util.Map; import org.w3c.dom.Document; +import org.xml.sax.SAXException; /** * Serializes the xml instance data collected by a form to a writer. @@ -78,12 +79,10 @@ public interface RenderingEngine * @param formInstanceData the xml content to serialize. * @param ret the rendering engine template * @param form the form that collected the xml content. - * @param parameters the set of parameters to the rendering engine - * @param out the output stream to serialize to. + * @param rendition the rendition to serialize to. */ - public void render(final Document formInstanceData, + public void render(final FormInstanceData formInstanceData, final RenderingEngineTemplate ret, - final Map parameters, - final OutputStream out) - throws IOException, RenderingException; + final Rendition rendition) + throws IOException, RenderingException, SAXException; } diff --git a/source/java/org/alfresco/web/forms/RenderingEngineTemplate.java b/source/java/org/alfresco/web/forms/RenderingEngineTemplate.java index 67c4f7ebf1..3aa26d2fd9 100644 --- a/source/java/org/alfresco/web/forms/RenderingEngineTemplate.java +++ b/source/java/org/alfresco/web/forms/RenderingEngineTemplate.java @@ -23,6 +23,7 @@ import java.io.OutputStream; import java.io.Serializable; import java.util.Map; import org.w3c.dom.Document; +import org.xml.sax.SAXException; /** * Describes a template that is used for rendering form instance data. @@ -51,13 +52,6 @@ public interface RenderingEngineTemplate */ public RenderingEngine getRenderingEngine(); - /** - * Provides the noderef for this template. - * - * @return the noderef for this template. - */ - public NodeRef getNodeRef(); - /** * Provides an input stream to the rendering engine template. * @@ -82,6 +76,11 @@ public interface RenderingEngineTemplate */ public String getMimetypeForRendition(); - public void registerRendition(final Rendition rendition, - final FormInstanceData primaryFormInstanceData); + /** + * Produces a rendition of the provided formInstanceData. + */ + public Rendition render(final FormInstanceData formInstanceData) + throws IOException, + SAXException, + RenderingEngine.RenderingException; } diff --git a/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java b/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java index c890515466..25eb589887 100644 --- a/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java +++ b/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java @@ -17,32 +17,21 @@ package org.alfresco.web.forms; import freemarker.ext.dom.NodeModel; -import freemarker.template.SimpleDate; -import freemarker.template.SimpleHash; -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateHashModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; +import freemarker.template.*; +import java.io.*; +import java.text.MessageFormat; +import java.util.*; import javax.faces.context.FacesContext; import org.alfresco.model.ContentModel; import org.alfresco.model.WCMAppModel; import org.alfresco.repo.avm.AVMNodeConverter; +import org.alfresco.repo.domain.PropertyValue; import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.avm.AVMService; -import org.alfresco.service.cmr.repository.ContentReader; -import org.alfresco.service.cmr.repository.ContentService; -import org.alfresco.service.cmr.repository.MimetypeService; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.NodeService; -import org.alfresco.service.cmr.repository.TemplateNode; -import org.alfresco.service.cmr.repository.TemplateService; +import org.alfresco.service.cmr.dictionary.DataTypeDefinition; +import org.alfresco.service.cmr.repository.*; 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.apache.commons.logging.Log; @@ -64,6 +53,14 @@ public class RenderingEngineTemplateImpl protected RenderingEngineTemplateImpl(final NodeRef nodeRef, final NodeRef renditionPropertiesNodeRef) { + if (nodeRef == null) + { + throw new NullPointerException(); + } + if (renditionPropertiesNodeRef == null) + { + throw new NullPointerException(); + } this.nodeRef = nodeRef; this.renditionPropertiesNodeRef = renditionPropertiesNodeRef; } @@ -91,7 +88,7 @@ public class RenderingEngineTemplateImpl { final NodeService nodeService = this.getServiceRegistry().getNodeService(); return (String)nodeService.getProperty(this.renditionPropertiesNodeRef, - WCMAppModel.PROP_OUTPUT_PATH_PATTERN_RENDITION); + WCMAppModel.PROP_OUTPUT_PATH_PATTERN); } public NodeRef getNodeRef() @@ -99,6 +96,11 @@ public class RenderingEngineTemplateImpl return this.nodeRef; } + public NodeRef getRenditionPropertiesNodeRef() + { + return this.renditionPropertiesNodeRef; + } + /** * Provides an input stream to the rendering engine template. * @@ -133,15 +135,12 @@ public class RenderingEngineTemplateImpl * * @return the output path to use for renditions. */ - public String getOutputPathForRendition(final FormInstanceData formInstanceData) + public String getOutputPathForRendition(final FormInstanceData formInstanceData /*,final String parentAVMPath */) { final ServiceRegistry sr = this.getServiceRegistry(); final NodeService nodeService = sr.getNodeService(); final AVMService avmService = sr.getAVMService(); - final String outputPathPattern = (String) - nodeService.getProperty(this.renditionPropertiesNodeRef, - WCMAppModel.PROP_OUTPUT_PATH_PATTERN_RENDITION); final String formInstanceDataAVMPath = formInstanceData.getPath(); final Map root = new HashMap(); @@ -161,20 +160,20 @@ public class RenderingEngineTemplateImpl try { - final FormsService fs = FormsService.getInstance(); - root.put("xml", NodeModel.wrap(fs.parseXML(formInstanceData.getNodeRef()))); + root.put("xml", NodeModel.wrap(formInstanceData.getDocument())); } catch (Exception e) { LOGGER.error(e); } - root.put("node", new TemplateNode(formInstanceData.getNodeRef(), sr, null)); + root.put("node", new TemplateNode(((FormInstanceDataImpl)formInstanceData).getNodeRef(), sr, null)); root.put("date", new SimpleDate(new Date(), SimpleDate.DATETIME)); final TemplateService templateService = sr.getTemplateService(); + final String outputPathPattern = this.getOutputPathPattern(); String result = templateService.processTemplateString(null, - outputPathPattern, + outputPathPattern, new SimpleHash(root)); final String parentAVMPath = AVMNodeConverter.SplitBase(formInstanceDataAVMPath)[0]; result = AVMConstants.buildPath(parentAVMPath, @@ -196,19 +195,70 @@ public class RenderingEngineTemplateImpl WCMAppModel.PROP_MIMETYPE_FOR_RENDITION); } - public void registerRendition(final Rendition rendition, - final FormInstanceData primaryFormInstanceData) + /** + * Produces a rendition of the provided formInstanceData. + */ + public Rendition render(final FormInstanceData formInstanceData) + throws IOException, + SAXException, + RenderingEngine.RenderingException { - final NodeService nodeService = this.getServiceRegistry().getNodeService(); - final Map props = new HashMap(2, 1.0f); - props.put(WCMAppModel.PROP_PARENT_RENDERING_ENGINE_TEMPLATE, this.nodeRef); - - // extract a store relative path for the primary form instance data - String path = primaryFormInstanceData.getPath(); - path = path.substring(path.indexOf(':') + 1); - props.put(WCMAppModel.PROP_PRIMARY_FORM_INSTANCE_DATA, path); + final AVMService avmService = this.getServiceRegistry().getAVMService(); + final String renditionAvmPath = this.getOutputPathForRendition(formInstanceData); + if (avmService.lookup(-1, renditionAvmPath) == null) + { + final String parentAVMPath = AVMNodeConverter.SplitBase(renditionAvmPath)[0]; + AVMConstants.makeAllDirectories(parentAVMPath); + avmService.createFile(parentAVMPath, + AVMNodeConverter.SplitBase(renditionAvmPath)[1]); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("Created file node for file: " + renditionAvmPath); + } - nodeService.addAspect(rendition.getNodeRef(), WCMAppModel.ASPECT_RENDITION, props); + final Rendition result = new RenditionImpl(AVMNodeConverter.ToNodeRef(-1, renditionAvmPath)); + this.getRenderingEngine().render(formInstanceData, this, result); + + avmService.addAspect(renditionAvmPath, WCMAppModel.ASPECT_FORM_INSTANCE_DATA); + avmService.addAspect(renditionAvmPath, ContentModel.ASPECT_TITLED); + avmService.addAspect(renditionAvmPath, WCMAppModel.ASPECT_RENDITION); + + final Map props = new HashMap(5, 1.0f); + props.put(WCMAppModel.PROP_PARENT_FORM_NAME, + new PropertyValue(DataTypeDefinition.TEXT, + formInstanceData.getForm().getName())); + props.put(ContentModel.PROP_TITLE, + new PropertyValue(DataTypeDefinition.TEXT, + AVMNodeConverter.SplitBase(renditionAvmPath)[1])); + final ResourceBundle bundle = Application.getBundle(FacesContext.getCurrentInstance()); + props.put(ContentModel.PROP_DESCRIPTION, + new PropertyValue(DataTypeDefinition.TEXT, + MessageFormat.format(bundle.getString("default_rendition_description"), + this.getTitle(), + AVMConstants.getSandboxRelativePath(renditionAvmPath)))); + props.put(WCMAppModel.PROP_PARENT_RENDERING_ENGINE_TEMPLATE, + new PropertyValue(DataTypeDefinition.NODE_REF, + this.nodeRef)); + props.put(WCMAppModel.PROP_PARENT_RENDITION_PROPERTIES, + new PropertyValue(DataTypeDefinition.NODE_REF, + this.renditionPropertiesNodeRef)); + // extract a store relative path for the primary form instance data + props.put(WCMAppModel.PROP_PRIMARY_FORM_INSTANCE_DATA, + new PropertyValue(DataTypeDefinition.TEXT, + AVMConstants.getStoreRelativePath(formInstanceData.getPath()))); + + avmService.setNodeProperties(renditionAvmPath, props); + + final PropertyValue pv = + avmService.getNodeProperty(-1, formInstanceData.getPath(), WCMAppModel.PROP_RENDITIONS); + Collection renditions = (pv == null + ? new LinkedList() + : pv.getCollection(DataTypeDefinition.TEXT)); + renditions.add(AVMConstants.getStoreRelativePath(renditionAvmPath)); + avmService.setNodeProperty(formInstanceData.getPath(), + WCMAppModel.PROP_RENDITIONS, + new PropertyValue(DataTypeDefinition.TEXT, + (Serializable)renditions)); + return result; } private ServiceRegistry getServiceRegistry() diff --git a/source/java/org/alfresco/web/forms/Rendition.java b/source/java/org/alfresco/web/forms/Rendition.java index fd75bdc62e..1cee03617a 100644 --- a/source/java/org/alfresco/web/forms/Rendition.java +++ b/source/java/org/alfresco/web/forms/Rendition.java @@ -16,8 +16,11 @@ */ package org.alfresco.web.forms; -import org.alfresco.service.cmr.repository.NodeRef; +import java.io.IOException; +import java.io.OutputStream; import java.io.Serializable; +import org.alfresco.service.cmr.repository.NodeRef; +import org.xml.sax.SAXException; /** * Encapsulation of a rendition. @@ -45,9 +48,6 @@ public interface Rendition /** the rendering engine template that generated this rendition */ public RenderingEngineTemplate getRenderingEngineTemplate(); - /** the node ref containing the contents of this rendition */ - public NodeRef getNodeRef(); - /** the path to the contents of this rendition */ public String getPath(); @@ -56,4 +56,19 @@ public interface Rendition /** the file type image for the rendition */ public String getFileTypeImage(); + + /** the output stream for the rendition */ + public OutputStream getOutputStream(); + + /** regenerates the contents of this rendition using the primary form instance data */ + public void regenerate() + throws IOException, + RenderingEngine.RenderingException, + SAXException; + + /** regenerates the contents of this rendition using the provided form instance data*/ + public void regenerate(final FormInstanceData formInstanceData) + throws IOException, + RenderingEngine.RenderingException, + SAXException; } diff --git a/source/java/org/alfresco/web/forms/RenditionImpl.java b/source/java/org/alfresco/web/forms/RenditionImpl.java index 60fd2fae65..1d64bb2773 100644 --- a/source/java/org/alfresco/web/forms/RenditionImpl.java +++ b/source/java/org/alfresco/web/forms/RenditionImpl.java @@ -16,6 +16,8 @@ */ package org.alfresco.web.forms; +import java.io.IOException; +import java.io.OutputStream; import javax.faces.context.FacesContext; import org.alfresco.model.ContentModel; import org.alfresco.model.WCMAppModel; @@ -35,6 +37,7 @@ import org.alfresco.web.bean.wcm.AVMConstants; import org.alfresco.web.ui.common.Utils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.xml.sax.SAXException; /** * Encapsulation of a rendition. @@ -48,9 +51,14 @@ public class RenditionImpl private static final Log LOGGER = LogFactory.getLog(RenditionImpl.class); private final NodeRef nodeRef; + private transient RenderingEngineTemplate renderingEngineTemplate; public RenditionImpl(final NodeRef nodeRef) { + if (nodeRef == null) + { + throw new NullPointerException(); + } this.nodeRef = nodeRef; } @@ -97,14 +105,18 @@ public class RenditionImpl /** the rendering engine template that generated this rendition */ public RenderingEngineTemplate getRenderingEngineTemplate() { - final NodeService nodeService = this.getServiceRegistry().getNodeService(); - final NodeRef retNodeRef = (NodeRef) - nodeService.getProperty(this.nodeRef, - WCMAppModel.PROP_PARENT_RENDERING_ENGINE_TEMPLATE); - final NodeRef rpNodeRef = (NodeRef) - nodeService.getProperty(this.nodeRef, - WCMAppModel.PROP_PARENT_RENDITION_PROPERTIES); - return new RenderingEngineTemplateImpl(retNodeRef, rpNodeRef); + if (this.renderingEngineTemplate == null) + { + final NodeService nodeService = this.getServiceRegistry().getNodeService(); + final NodeRef retNodeRef = (NodeRef) + nodeService.getProperty(this.nodeRef, + WCMAppModel.PROP_PARENT_RENDERING_ENGINE_TEMPLATE); + final NodeRef rpNodeRef = (NodeRef) + nodeService.getProperty(this.nodeRef, + WCMAppModel.PROP_PARENT_RENDITION_PROPERTIES); + this.renderingEngineTemplate = new RenderingEngineTemplateImpl(retNodeRef, rpNodeRef); + } + return this.renderingEngineTemplate; } /** the node ref containing the contents of this rendition */ @@ -128,6 +140,29 @@ public class RenditionImpl return Utils.getFileTypeImage(this.getName(), false); } + public OutputStream getOutputStream() + { + return this.getServiceRegistry().getAVMService().getFileOutputStream(this.getPath()); + } + + public void regenerate() + throws IOException, + RenderingEngine.RenderingException, + SAXException + { + this.regenerate(this.getPrimaryFormInstanceData()); + } + + public void regenerate(final FormInstanceData formInstanceData) + throws IOException, + RenderingEngine.RenderingException, + SAXException + { + final RenderingEngineTemplate ret = this.getRenderingEngineTemplate(); + final RenderingEngine engine = ret.getRenderingEngine(); + engine.render(formInstanceData, ret, this); + } + private ServiceRegistry getServiceRegistry() { final FacesContext fc = FacesContext.getCurrentInstance(); diff --git a/source/java/org/alfresco/web/forms/XMLUtil.java b/source/java/org/alfresco/web/forms/XMLUtil.java new file mode 100644 index 0000000000..ae8383042c --- /dev/null +++ b/source/java/org/alfresco/web/forms/XMLUtil.java @@ -0,0 +1,165 @@ +/* + * 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.forms; + +import java.io.*; +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.model.ContentModel; +import org.alfresco.service.cmr.repository.ContentReader; +import org.alfresco.service.cmr.repository.ContentService; +import org.alfresco.service.cmr.repository.NodeRef; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; + +/** + * XML utility functions. + * + * @author Ariel Backenroth + */ +public class XMLUtil +{ + private static final Log LOGGER = LogFactory.getLog(XMLUtil.class); + + private static DocumentBuilder documentBuilder; + + /** utility function for creating a document */ + public static Document newDocument() + { + return XMLUtil.getDocumentBuilder().newDocument(); + } + + /** utility function for serializing a node */ + public static void print(final Node n, final Writer output) + { + try + { + final TransformerFactory tf = TransformerFactory.newInstance(); + final Transformer t = tf.newTransformer(); + t.setOutputProperty(OutputKeys.INDENT, "yes"); + + if (LOGGER.isDebugEnabled()) + { + LOGGER.debug("writing out a document for " + + (n instanceof Document + ? ((Document)n).getDocumentElement() + : n).getNodeName() + + " to " + (output instanceof StringWriter + ? "string" + : output)); + } + t.transform(new DOMSource(n), new StreamResult(output)); + } + catch (TransformerException te) + { + te.printStackTrace(); + assert false : te.getMessage(); + } + } + + /** utility function for serializing a node */ + public static void print(final Node n, final File output) + throws IOException + { + XMLUtil.print(n, new FileWriter(output)); + } + + /** utility function for serializing a node */ + public static String toString(final Node n) + { + final StringWriter result = new StringWriter(); + XMLUtil.print(n, result); + return result.toString(); + } + + /** utility function for parsing xml */ + public static Document parse(final String source) + throws SAXException, + IOException + { + return XMLUtil.parse(new ByteArrayInputStream(source.getBytes())); + } + + /** utility function for parsing xml */ + public static Document parse(final NodeRef nodeRef, + final ContentService contentService) + throws SAXException, + IOException + { + final ContentReader contentReader = + contentService.getReader(nodeRef, ContentModel.TYPE_CONTENT); + final InputStream in = contentReader.getContentInputStream(); + return XMLUtil.parse(in); + } + + /** utility function for parsing xml */ + public static Document parse(final File source) + throws SAXException, + IOException + { + return XMLUtil.parse(new FileInputStream(source)); + } + + /** utility function for parsing xml */ + public static Document parse(final InputStream source) + throws SAXException, + IOException + { + final DocumentBuilder db = XMLUtil.getDocumentBuilder(); + + final Document result = db.parse(source); + source.close(); + return result; + } + + /** provides a document builder that is namespace aware but not validating by default */ + public static DocumentBuilder getDocumentBuilder() + { + if (XMLUtil.documentBuilder == null) + { + XMLUtil.documentBuilder = XMLUtil.getDocumentBuilder(true, false); + } + return XMLUtil.documentBuilder; + } + + public static DocumentBuilder getDocumentBuilder(final boolean namespaceAware, + final boolean validating) + try + { + final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(namespaceAware); + dbf.setValidating(validating); + XMLUtil.documentBuilder = dbf.newDocumentBuilder(); + } + catch (ParserConfigurationException pce) + { + LOGGER.error(pce); + } + } + return XMLUtil.documentBuilder; + } +} \ No newline at end of file diff --git a/source/java/org/alfresco/web/forms/XSLFORenderingEngine.java b/source/java/org/alfresco/web/forms/XSLFORenderingEngine.java index 05e4738657..cd0677e0a5 100644 --- a/source/java/org/alfresco/web/forms/XSLFORenderingEngine.java +++ b/source/java/org/alfresco/web/forms/XSLFORenderingEngine.java @@ -24,13 +24,13 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXResult; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.w3c.dom.*; -import org.xml.sax.SAXException; +import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.Fop; -import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.MimeConstants; +import org.w3c.dom.*; +import org.xml.sax.SAXException; /** * A rendering engine which uses xsl-fo templates to generate renditions of @@ -86,35 +86,40 @@ public class XSLFORenderingEngine return "fo"; } - public void render(final Document xmlContent, + public void render(final FormInstanceData formInstanceData, final RenderingEngineTemplate ret, - final Map parameters, - final OutputStream out) + final Rendition rendition) throws IOException, - RenderingEngine.RenderingException + RenderingEngine.RenderingException, + SAXException { - Result result = null; + String mimetype = MIME_TYPES.get(ret.getMimetypeForRendition()); if (mimetype == null) { throw new RenderingEngine.RenderingException("mimetype " + ret.getMimetypeForRendition() + " is not supported by " + this.getName()); } + final OutputStream out = rendition.getOutputStream(); try { final FopFactory fopFactory = FopFactory.newInstance(); final FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); - final Fop fop = fopFactory.newFop(mimetype, - foUserAgent, - out); + final Fop fop = fopFactory.newFop(mimetype, foUserAgent, out); // Resulting SAX events (the generated FO) must be piped through to FOP - result = new SAXResult(fop.getDefaultHandler()); + super.render(new DOMSource(formInstanceData.getDocument()), + ret, + this.getStandardParameters(formInstanceData, rendition), + new SAXResult(fop.getDefaultHandler())); + } catch (FOPException fope) { throw new RenderingEngine.RenderingException(fope); } - - super.render(new DOMSource(xmlContent), ret, parameters, result); + finally + { + out.close(); + } } } \ No newline at end of file diff --git a/source/java/org/alfresco/web/forms/XSLTRenderingEngine.java b/source/java/org/alfresco/web/forms/XSLTRenderingEngine.java index 4145da051c..a1dee73dbb 100644 --- a/source/java/org/alfresco/web/forms/XSLTRenderingEngine.java +++ b/source/java/org/alfresco/web/forms/XSLTRenderingEngine.java @@ -36,7 +36,7 @@ import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.web.bean.wcm.AVMConstants; -import org.alfresco.web.forms.FormsService; +import org.alfresco.web.forms.XMLUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xalan.extensions.ExpressionContext; @@ -138,9 +138,7 @@ public class XSLTRenderingEngine // create a root document for rooting all the results. we do this // so that each document root element has a common parent node // and so that xpath axes work properly - final FormsService fs = FormsService.getInstance(); - final DocumentBuilder documentBuilder = fs.getDocumentBuilder(); - final Document rootNodeDocument = documentBuilder.newDocument(); + final Document rootNodeDocument = XMLUtil.newDocument(); final Element rootNodeDocumentEl = rootNodeDocument.createElementNS(ALFRESCO_NS, ALFRESCO_NS_PREFIX + ":file_list"); @@ -286,14 +284,25 @@ public class XSLTRenderingEngine } } - public void render(final Document formInstanceData, + public void render(final FormInstanceData formInstanceData, final RenderingEngineTemplate ret, - final Map parameters, - final OutputStream out) + final Rendition rendition) throws IOException, - RenderingEngine.RenderingException + RenderingEngine.RenderingException, + SAXException { - this.render(new DOMSource(formInstanceData), ret, parameters, new StreamResult(out)); + final OutputStream out = rendition.getOutputStream(); + try + { + this.render(new DOMSource(formInstanceData.getDocument()), + ret, + this.getStandardParameters(formInstanceData, rendition), + new StreamResult(out)); + } + finally + { + out.close(); + } } protected void render(final Source formInstanceDataSource, @@ -301,15 +310,15 @@ public class XSLTRenderingEngine final Map parameters, final Result result) throws IOException, - RenderingEngine.RenderingException + RenderingEngine.RenderingException, + SAXException { System.setProperty("org.apache.xalan.extensions.bsf.BSFManager", BSFManager.class.getName()); - final FormsService ts = FormsService.getInstance(); Document xslTemplate = null; try { - xslTemplate = ts.parseXML(ret.getInputStream()); + xslTemplate = XMLUtil.parse(ret.getInputStream()); } catch (final SAXException sax) { @@ -356,9 +365,9 @@ public class XSLTRenderingEngine { if (LOGGER.isDebugEnabled()) LOGGER.debug("loading " + uri); - final Document d = ts.parseXML(uri.toURL().openStream()); + final Document d = XMLUtil.parse(uri.toURL().openStream()); if (LOGGER.isDebugEnabled()) - LOGGER.debug("loaded " + ts.writeXMLToString(d)); + LOGGER.debug("loaded " + XMLUtil.toString(d)); return new DOMSource(d); } catch (Exception e) diff --git a/source/java/org/alfresco/web/forms/xforms/SchemaFormBuilder.java b/source/java/org/alfresco/web/forms/xforms/SchemaFormBuilder.java index 3d67e60c74..cf31507371 100644 --- a/source/java/org/alfresco/web/forms/xforms/SchemaFormBuilder.java +++ b/source/java/org/alfresco/web/forms/xforms/SchemaFormBuilder.java @@ -21,7 +21,7 @@ import java.io.IOException; import java.io.StringWriter; import java.util.*; import javax.xml.transform.*; -import org.alfresco.web.forms.FormsService; +import org.alfresco.web.forms.XMLUtil; import org.apache.commons.jxpath.JXPathContext; import org.apache.commons.jxpath.Pointer; import org.apache.commons.logging.Log; @@ -73,9 +73,6 @@ public class SchemaFormBuilder public final static Log LOGGER = LogFactory.getLog(SchemaFormBuilder.class); - /** XMLNS Namespace declaration. */ - public static final String XMLNS_NAMESPACE_URI = - "http://www.w3.org/2000/xmlns/"; /** Alfresco namespace declaration. */ private static final String ALFRESCO_NS = @@ -288,7 +285,7 @@ public class SchemaFormBuilder //if target namespace & we use the schema types: add it to form ns declarations // if (this.targetNamespace != null && this.targetNamespace.length() != 0) -// envelopeElement.setAttributeNS(XMLNS_NAMESPACE_URI, +// envelopeElement.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, // "xmlns:schema", // this.targetNamespace); @@ -706,7 +703,7 @@ public class SchemaFormBuilder if (annotation == null) return null; // write annotation to empty doc - final Document doc = FormsService.getInstance().newDocument(); + final Document doc = XMLUtil.newDocument(); annotation.writeAnnotation(doc, XSAnnotation.W3C_DOM_DOCUMENT); final NodeList d = doc.getElementsByTagNameNS(namespace, elementName); @@ -788,7 +785,7 @@ public class SchemaFormBuilder if (LOGGER.isDebugEnabled()) { LOGGER.debug("This attribute comes from an extension: recopy form controls. \n Model section: "); - LOGGER.debug(FormsService.getInstance().writeXMLToString(modelSection)); + LOGGER.debug(XMLUtil.toString(modelSection)); } //find the existing bind Id @@ -1396,7 +1393,7 @@ public class SchemaFormBuilder // if (LOGGER.isDebugEnabled()) { - LOGGER.debug(FormsService.getInstance().writeXMLToString(bindElement2)); + LOGGER.debug(XMLUtil.toString(bindElement2)); } NodeList binds = bindElement2.getElementsByTagNameNS(NamespaceConstants.XFORMS_NS, "bind"); Element thisBind = null; @@ -1605,7 +1602,7 @@ public class SchemaFormBuilder if (LOGGER.isDebugEnabled()) { LOGGER.debug("This element comes from an extension: recopy form controls.\n Model Section="); - LOGGER.debug(FormsService.getInstance().writeXMLToString(modelSection)); + LOGGER.debug(XMLUtil.toString(modelSection)); } //find the existing bind Id @@ -2072,7 +2069,7 @@ public class SchemaFormBuilder private Document createFormTemplate(final String formId) { - final Document xformsDocument = FormsService.getInstance().newDocument(); + final Document xformsDocument = XMLUtil.newDocument(); final Element envelopeElement = this.wrapper.createEnvelope(xformsDocument); this.addNamespace(envelopeElement, diff --git a/source/java/org/alfresco/web/forms/xforms/SchemaUtil.java b/source/java/org/alfresco/web/forms/xforms/SchemaUtil.java index 094fccabe2..dc40f7f82a 100644 --- a/source/java/org/alfresco/web/forms/xforms/SchemaUtil.java +++ b/source/java/org/alfresco/web/forms/xforms/SchemaUtil.java @@ -20,7 +20,7 @@ import java.util.*; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import org.alfresco.web.forms.FormsService; +import org.alfresco.web.forms.XMLUtil; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xerces.xs.*; @@ -216,9 +216,8 @@ public class SchemaUtil final DOMImplementationLS lsImpl = (DOMImplementationLS) registry.getDOMImplementation("XML 1.0 LS 3.0"); - final FormsService ts = FormsService.getInstance(); final LSInput in = lsImpl.createLSInput(); - in.setStringData(ts.writeXMLToString(schemaDocument)); + in.setStringData(XMLUtil.toString(schemaDocument)); final XSImplementation xsImpl = (XSImplementation) registry.getDOMImplementation("XS-Loader"); diff --git a/source/java/org/alfresco/web/forms/xforms/XFormsBean.java b/source/java/org/alfresco/web/forms/xforms/XFormsBean.java index 8a26cc2e68..ab6f7976a9 100644 --- a/source/java/org/alfresco/web/forms/xforms/XFormsBean.java +++ b/source/java/org/alfresco/web/forms/xforms/XFormsBean.java @@ -278,7 +278,7 @@ public class XFormsBean final ResponseWriter out = context.getResponseWriter(); final ChibaBean chibaBean = this.xformsSession.chibaBean; final Node xformsDocument = chibaBean.getXMLContainer(); - FormsService.getInstance().writeXML(xformsDocument, out); + XMLUtil.print(xformsDocument, out); } /** @@ -308,7 +308,7 @@ public class XFormsBean } final ResponseWriter out = context.getResponseWriter(); - FormsService.getInstance().writeXML(this.getEventLog(), out); + XMLUtil.print(this.getEventLog(), out); out.close(); } @@ -332,7 +332,7 @@ public class XFormsBean chibaBean.updateRepeatIndex(id, index); final ResponseWriter out = context.getResponseWriter(); - FormsService.getInstance().writeXML(this.getEventLog(), out); + XMLUtil.print(this.getEventLog(), out); out.close(); } @@ -353,7 +353,7 @@ public class XFormsBean chibaBean.dispatch(id, DOMEventNames.ACTIVATE); final ResponseWriter out = context.getResponseWriter(); - FormsService.getInstance().writeXML(this.getEventLog(), out); + XMLUtil.print(this.getEventLog(), out); out.close(); } @@ -368,8 +368,7 @@ public class XFormsBean final FacesContext context = FacesContext.getCurrentInstance(); final HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest(); - final FormsService formsService = FormsService.getInstance(); - final Document result = formsService.parseXML(request.getInputStream()); + final Document result = XMLUtil.parse(request.getInputStream()); final Document instanceData = this.xformsSession.getFormInstanceData(); Element documentElement = instanceData.getDocumentElement(); if (documentElement != null) @@ -383,7 +382,7 @@ public class XFormsBean instanceData.appendChild(documentElement); final ResponseWriter out = context.getResponseWriter(); - formsService.writeXML(instanceData, out); + XMLUtil.print(instanceData, out); out.close(); } catch (Throwable t) @@ -409,7 +408,7 @@ public class XFormsBean chibaBean.getContainer().lookup(toItemId)); final ResponseWriter out = context.getResponseWriter(); - FormsService.getInstance().writeXML(this.getEventLog(), out); + XMLUtil.print(this.getEventLog(), out); out.close(); } @@ -439,8 +438,7 @@ public class XFormsBean } LOGGER.debug(this + ".getFilePickerData(" + currentPath + ")"); - final FormsService formsService = FormsService.getInstance(); - final Document result = formsService.newDocument(); + final Document result = XMLUtil.newDocument(); final Element filePickerDataElement = result.createElement("file-picker-data"); result.appendChild(filePickerDataElement); @@ -483,7 +481,7 @@ public class XFormsBean } final ResponseWriter out = facesContext.getResponseWriter(); - FormsService.getInstance().writeXML(result, out); + XMLUtil.print(result, out); out.close(); } @@ -558,8 +556,7 @@ public class XFormsBean this.xformsSession.uploads.put(uploadId, uploadNodeRef); LOGGER.debug("upload complete. sending response"); - final FormsService formsService = FormsService.getInstance(); - final Document result = formsService.newDocument(); + final Document result = XMLUtil.newDocument(); final Element htmlEl = result.createElement("html"); result.appendChild(htmlEl); final Element bodyEl = result.createElement("body"); @@ -574,7 +571,7 @@ public class XFormsBean scriptEl.appendChild(scriptText); final ResponseWriter out = facesContext.getResponseWriter(); - formsService.writeXML(result, out); + XMLUtil.print(result, out); out.close(); } @@ -638,8 +635,7 @@ public class XFormsBean private Node getEventLog() { - final FormsService formsService = FormsService.getInstance(); - final Document result = formsService.newDocument(); + final Document result = XMLUtil.newDocument(); final Element eventsElement = result.createElement("events"); result.appendChild(eventsElement); for (XMLEvent xfe : this.xformsSession.eventLog) @@ -680,8 +676,7 @@ public class XFormsBean if (LOGGER.isDebugEnabled()) { - LOGGER.debug("generated event log:\n" + - formsService.writeXMLToString(result)); + LOGGER.debug("generated event log:\n" + XMLUtil.toString(result)); } return result; } @@ -740,8 +735,7 @@ public class XFormsBean resourceBundle); if (LOGGER.isDebugEnabled()) { - LOGGER.debug("generated xform: " + - FormsService.getInstance().writeXMLToString(result)); + LOGGER.debug("generated xform: " + XMLUtil.toString(result)); } return result; } diff --git a/source/java/org/alfresco/web/forms/xforms/XFormsProcessor.java b/source/java/org/alfresco/web/forms/xforms/XFormsProcessor.java index eb79e5d381..8fc179abf6 100644 --- a/source/java/org/alfresco/web/forms/xforms/XFormsProcessor.java +++ b/source/java/org/alfresco/web/forms/xforms/XFormsProcessor.java @@ -58,7 +58,6 @@ public class XFormsProcessor public void process(final Session session, final Writer out) throws FormProcessor.ProcessingException { - final FormsService ts = FormsService.getInstance(); final FacesContext fc = FacesContext.getCurrentInstance(); //make the XFormsBean available for this session final XFormsBean xforms = (XFormsBean) @@ -79,7 +78,7 @@ public class XFormsProcessor } final String cp = fc.getExternalContext().getRequestContextPath(); - final Document result = ts.newDocument(); + final Document result = XMLUtil.newDocument(); // this div is where the ui will write to final Element div = result.createElement("div"); @@ -120,6 +119,6 @@ public class XFormsProcessor div.appendChild(e); } - ts.writeXML(result, out); + XMLUtil.print(result, out); } } diff --git a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java index ee4296d2c4..5361c2fa67 100644 --- a/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java +++ b/source/java/org/alfresco/web/ui/wcm/component/UIUserSandboxes.java @@ -55,7 +55,9 @@ import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.repository.User; import org.alfresco.web.bean.wcm.AVMConstants; import org.alfresco.web.bean.wcm.AVMNode; +import org.alfresco.web.bean.wcm.WebProject; import org.alfresco.web.config.ClientConfigElement; +import org.alfresco.web.forms.Form; import org.alfresco.web.ui.common.ComponentConstants; import org.alfresco.web.ui.common.ConstantMethodBinding; import org.alfresco.web.ui.common.PanelGenerator; @@ -115,7 +117,7 @@ public class UIUserSandboxes extends SelfRenderingComponent private static final String SPACE_ICON = "/images/icons/" + BrowseBean.SPACE_SMALL_DEFAULT + ".gif"; - public static final String PARAM_FORM_ID = "form-id"; + public static final String PARAM_FORM_NAME = "form-name"; private static final String SCRIPT_MULTISELECT = " + + + + + + + + +
+ - -
+ + +
diff --git a/source/web/jsp/wcm/create-web-content-wizard/summary.jsp b/source/web/jsp/wcm/create-web-content-wizard/summary.jsp index ebea252f31..01b4dd031a 100644 --- a/source/web/jsp/wcm/create-web-content-wizard/summary.jsp +++ b/source/web/jsp/wcm/create-web-content-wizard/summary.jsp @@ -39,7 +39,7 @@ value="${WizardManager.bean.formInstanceData.name}" image="/images/filetypes32/xml.gif"> -
${msg.form}: ${WizardManager.bean.formInstanceData.form.name}
+
${msg.form}: ${WizardManager.bean.form.title}
${msg.location}: ${WizardManager.bean.formInstanceData.sandboxRelativePath}
diff --git a/source/web/jsp/wcm/create-website-wizard/form-details.jsp b/source/web/jsp/wcm/create-website-wizard/form-details.jsp index fc832cb954..79563a402c 100644 --- a/source/web/jsp/wcm/create-website-wizard/form-details.jsp +++ b/source/web/jsp/wcm/create-website-wizard/form-details.jsp @@ -114,12 +114,12 @@ - + - + diff --git a/source/web/jsp/wcm/create-website-wizard/form-templates.jsp b/source/web/jsp/wcm/create-website-wizard/form-templates.jsp index 90df20f464..4f20921a26 100644 --- a/source/web/jsp/wcm/create-website-wizard/form-templates.jsp +++ b/source/web/jsp/wcm/create-website-wizard/form-templates.jsp @@ -49,8 +49,8 @@ - - + + ${r.name} ${r.title} - - ${r.filenamePattern} + + ${r.outputPathPattern} ${r.workflow.title}