diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index c3e2c23f38..18a35f4280 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -292,6 +292,7 @@ add_content=Add Content create_content=Create Content create_form=Create Web Form edit_form=Edit Web Form +regenerate_renditions=Regenerate Renditions add_multiple_files=Add Multiple Files import_directory=Import Directory advanced_space_wizard=Advanced Space Wizard @@ -707,6 +708,22 @@ content=Content text_content=Plain Text Content html_content=HTML Content xml_content=XML Content + +regenerate_renditions_title=Regenerate Renditions Wizard +regenerate_renditions_desc=This wizard helps you regenerate renditions. +regenerate_renditions_select_renditions_title=Select Renditions +regenerate_renditions_select_renditions_step_title=Select Renditions +regenerate_renditions_select_renditions_desc=Select which renditions you want to regenerate. +regenerate_renditions_select_renditions_select_item_desc={0} related renditions in {1}. +regenerate_renditions_select_renditions_select_web_project=Select the web project in which you want to regenerate renditions. +regenerate_renditions_select_renditions_select_regenerate_scope=Select which renditions you want to regenerate within the selected web project. +regenerate_renditions_select_renditions_scope_all=Choose this option to regenerate all renditions of all form generated content within the selected web project. +regenerate_renditions_select_renditions_scope_form=Choose this option to regenerate all renditions of content generated by a particular set of forms configured for the selected web project. +regenerate_renditions_select_renditions_scope_rendering_engine_templates=Choose this option to regenerate particular renditions generated by a particular set of rendering engine templates. +regenerate_renditions_select_renditions_instruction=To regenerate renditions based on your selection, click next. +regenerate_renditions_summary_desc={0} renditions have been regenerated in web project {1}. +regenerate_renditions_summary_instruction=To commit these changes to the web project, click Finish. + create_form_title=Create Web Form Wizard edit_form_title=Edit Web Form Wizard create_form_desc=This wizard helps you create a new form. @@ -740,6 +757,7 @@ create_web_content_summary_submit_message=Submit {0,choice,0#__SHOULD NOT BE ZER default_rendition_description=Rendered by {0} into {1} rendering_engine_type=Rendering Engine apply_default_workflow=Apply default workflow +rendering_engine_template=Rendering Engine Template rendering_engine_templates=Rendering Engine Templates selected_rendering_engine_templates=Selected Rendering Engines rendering_engine_template_file=Rendering Engine Template File @@ -748,7 +766,8 @@ output_path_pattern=Output path pattern mimetype_for_renditions=Rendition mimetype schema=Schema schema_root_element_name=Root element -form=Form +form=Web Form +web_project=Web Project # Rule and Action Wizard messages run_action_title=Run Action Wizard @@ -986,6 +1005,7 @@ website_browse_files=Browse Files creator=Creator modified_items=Modified Items content_forms=Web Forms + store_created_on=Created On store_created_by=Created By store_working_users=There {0,choice,0#are no users|1#is one user|1 + + + org.alfresco.web.action.evaluator.RegenerateRenditionsEvaluator + regenerate_renditions + /images/icons/regenerate_renditions.gif + wizard:regenerateRenditions + #{BrowseBean.setupSpaceAction} + + #{actionContext.id} + + + @@ -700,7 +712,7 @@ - + diff --git a/config/alfresco/web-client-config-wcm-actions.xml b/config/alfresco/web-client-config-wcm-actions.xml index e16145e079..d033f53511 100644 --- a/config/alfresco/web-client-config-wcm-actions.xml +++ b/config/alfresco/web-client-config-wcm-actions.xml @@ -409,6 +409,7 @@ false + @@ -418,6 +419,7 @@ + @@ -427,11 +429,11 @@ + - diff --git a/config/alfresco/web-client-config-wizards.xml b/config/alfresco/web-client-config-wizards.xml index 8f2895d8d3..07b04cff3d 100644 --- a/config/alfresco/web-client-config-wizards.xml +++ b/config/alfresco/web-client-config-wizards.xml @@ -419,7 +419,27 @@ instruction-id="content_finish_instruction" /> - + + + + + + + + + + + - \ No newline at end of file + diff --git a/source/java/org/alfresco/web/action/evaluator/RegenerateRenditionsEvaluator.java b/source/java/org/alfresco/web/action/evaluator/RegenerateRenditionsEvaluator.java new file mode 100644 index 0000000000..cae888fc88 --- /dev/null +++ b/source/java/org/alfresco/web/action/evaluator/RegenerateRenditionsEvaluator.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.web.action.evaluator; + +import javax.faces.context.FacesContext; +import org.alfresco.model.WCMAppModel; +import org.alfresco.service.ServiceRegistry; +import org.alfresco.service.cmr.repository.Path; +import org.alfresco.service.cmr.security.PermissionService; +import org.alfresco.web.action.ActionEvaluator; +import org.alfresco.web.app.Application; +import org.alfresco.web.app.servlet.FacesHelper; +import org.alfresco.web.bean.NavigationBean; +import org.alfresco.web.bean.repository.Node; +import org.alfresco.web.bean.repository.Repository; + +/** + * UI Action Evaluator for Regenerate Renditions in the Forms DataDictionary folder + * + * @author Ariel Backenroth + */ +public class RegenerateRenditionsEvaluator implements ActionEvaluator +{ + /** + * @see org.alfresco.web.action.ActionEvaluator#evaluate(org.alfresco.web.bean.repository.Node) + */ + public boolean evaluate(final Node node) + { + final FacesContext fc = FacesContext.getCurrentInstance(); + final ServiceRegistry services = Repository.getServiceRegistry(fc); + final NavigationBean navigator = (NavigationBean)FacesHelper.getManagedBean(fc, NavigationBean.BEAN_NAME); + + // get the path to the current name - compare last element with the Website folder assoc name + final Path path = navigator.getCurrentNode().getNodePath(); + final Path.Element element = path.get(path.size() - 1); + final String endPath = element.getPrefixedString(services.getNamespaceService()); + + return (node.hasAspect(WCMAppModel.ASPECT_FORM) || + node.hasAspect(WCMAppModel.ASPECT_RENDERING_ENGINE_TEMPLATE) || + Application.getContentFormsFolderName(fc).equals(endPath)); + } +} diff --git a/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java b/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java index 25072800fe..9818ade7e9 100644 --- a/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java +++ b/source/java/org/alfresco/web/bean/wcm/AVMEditBean.java @@ -21,6 +21,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.text.MessageFormat; import java.util.HashSet; +import java.util.List; import java.util.Map; import javax.faces.context.FacesContext; @@ -542,53 +543,14 @@ public class AVMEditBean @Override public Form getForm() { return AVMEditBean.this.getForm(); } }; - - if (LOGGER.isDebugEnabled()) - LOGGER.debug("regenerating renditions of " + fid); - String originalParentAvmPath = (String) - this.nodeService.getProperty(((FormInstanceDataImpl)fid).getNodeRef(), - WCMAppModel.PROP_ORIGINAL_PARENT_PATH); - if (originalParentAvmPath == null) + final List result = fid.regenerateRenditions(); + for (FormInstanceData.RegenerateResult rr : result) { - originalParentAvmPath = AVMNodeConverter.SplitBase(avmPath)[0]; - } - final HashSet allRets = - new HashSet(this.getForm().getRenderingEngineTemplates()); - - // regenerate existing renditions - for (final Rendition r : fid.getRenditions()) - { - final RenderingEngineTemplate ret = r.getRenderingEngineTemplate(); - if (!allRets.contains(ret)) + if (rr.getException() != null) { - continue; - } - try - { - ret.render(fid, r); - allRets.remove(ret); - } - catch (Exception e) - { - Utils.addErrorMessage("error regenerating rendition using " + ret.getName() + - ": " + e.getMessage(), - e); - } - } - - // render all renditions for newly added templates - for (final RenderingEngineTemplate ret : allRets) - { - try - { - final String path = ret.getOutputPathForRendition(fid, originalParentAvmPath); - ret.render(fid, path); - } - catch (Exception e) - { - Utils.addErrorMessage("error regenerating rendition using " + ret.getName() + - ": " + e.getMessage(), - e); + Utils.addErrorMessage("error regenerating rendition using " + rr.getRenderingEngineTemplate().getName() + + ": " + rr.getException().getMessage(), + rr.getException()); } } } diff --git a/source/java/org/alfresco/web/bean/wcm/CreateFormWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateFormWizard.java index 6b6791b1c5..fb8089dbce 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateFormWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateFormWizard.java @@ -1044,8 +1044,7 @@ public class CreateFormWizard { // get list of workflows from config definitions final List workflowDefs = AVMWorkflowUtil.getConfiguredWorkflows(); - this.defaultWorkflowChoices = new ArrayList(workflowDefs.size() + 1); - + this.defaultWorkflowChoices = new ArrayList(workflowDefs.size()); for (WorkflowDefinition workflowDef : workflowDefs) { final UIListItem item = new UIListItem(); diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java index 15e2c712db..f92c5164a7 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java @@ -405,6 +405,8 @@ public class CreateWebContentWizard extends BaseContentWizard this.nodeService); parameters.put(WorkflowModel.ASSOC_PACKAGE, packageNodeRef); + parameters.put(WCMWorkflowModel.ASSOC_WEBPROJECT, + this.avmBrowseBean.getWebsite().getNodeRef()); // TODO: capture label and comment? parameters.put(WCMWorkflowModel.PROP_LABEL, MimetypeMap.MIMETYPE_XML.equals(this.mimeType) && this.formName != null diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java index fe7e95333a..76abd6bcab 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateWebsiteWizard.java @@ -38,7 +38,6 @@ import javax.faces.event.ActionEvent; import javax.faces.model.DataModel; import javax.faces.model.ListDataModel; -import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ApplicationModel; import org.alfresco.model.ContentModel; import org.alfresco.model.WCMAppModel; @@ -97,8 +96,6 @@ public class CreateWebsiteWizard extends BaseWizardBean protected String webapp = WEBAPP_DEFAULT; protected List deployTo; - protected String websitesFolderId = null; - protected AVMService avmService; protected WorkflowService workflowService; protected PersonService personService; @@ -163,10 +160,10 @@ public class CreateWebsiteWizard extends BaseWizardBean protected String finishImpl(FacesContext context, String outcome) throws Exception { // create the website space in the correct parent folder - String websiteParentId = getWebsitesFolderId(); + final NodeRef websiteParent = WebProject.getWebsitesFolder(); FileInfo fileInfo = this.fileFolderService.create( - new NodeRef(Repository.getStoreRef(), websiteParentId), + websiteParent, this.name, WCMAppModel.TYPE_AVMWEBFOLDER); NodeRef nodeRef = fileInfo.getNodeRef(); @@ -218,7 +215,7 @@ public class CreateWebsiteWizard extends BaseWizardBean saveWebProjectModel(nodeRef); // navigate to the Websites folder so we can see the newly created folder - this.navigator.setCurrentNodeId(websiteParentId); + this.navigator.setCurrentNodeId(websiteParent.getId()); outcome = AlfrescoNavigationHandler.CLOSE_WIZARD_OUTCOME; } @@ -803,37 +800,6 @@ public class CreateWebsiteWizard extends BaseWizardBean // ------------------------------------------------------------------------------ // Helper methods - /** - * Helper to get the ID of the 'Websites' system folder - * - * @return ID of the 'Websites' system folder - * - * @throws AlfrescoRuntimeException if unable to find the required folder - */ - private String getWebsitesFolderId() - { - if (this.websitesFolderId == null) - { - // get the template from the special Content Templates folder - FacesContext fc = FacesContext.getCurrentInstance(); - String xpath = Application.getRootPath(fc) + "/" + Application.getWebsitesFolderName(fc); - - NodeRef rootNodeRef = this.nodeService.getRootNode(Repository.getStoreRef()); - NamespaceService resolver = Repository.getServiceRegistry(fc).getNamespaceService(); - List results = this.searchService.selectNodes(rootNodeRef, xpath, null, resolver, false); - if (results.size() == 1) - { - this.websitesFolderId = results.get(0).getId(); - } - else - { - throw new AlfrescoRuntimeException("Unable to find 'Websites' system folder at: " + xpath); - } - } - - return this.websitesFolderId; - } - // ------------------------------------------------------------------------------ // Inner classes diff --git a/source/java/org/alfresco/web/bean/wcm/RegenerateRenditionsWizard.java b/source/java/org/alfresco/web/bean/wcm/RegenerateRenditionsWizard.java new file mode 100644 index 0000000000..d41cfa3318 --- /dev/null +++ b/source/java/org/alfresco/web/bean/wcm/RegenerateRenditionsWizard.java @@ -0,0 +1,548 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.web.bean.wcm; + +import java.io.File; +import java.io.Serializable; +import java.text.MessageFormat; +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; + +import javax.faces.application.FacesMessage; +import javax.faces.component.UIViewRoot; +import javax.faces.context.FacesContext; +import javax.faces.event.ActionEvent; +import javax.faces.event.ValueChangeEvent; +import javax.faces.model.DataModel; +import javax.faces.model.ListDataModel; +import javax.faces.model.SelectItem; + +import org.alfresco.web.ui.common.component.UIListItems; +import org.alfresco.web.ui.common.component.data.UIRichList; +import org.alfresco.model.ContentModel; +import org.alfresco.model.WCMAppModel; +import org.alfresco.repo.avm.AVMNodeConverter; +import org.alfresco.repo.content.MimetypeMap; +import org.alfresco.service.cmr.avm.AVMService; +import org.alfresco.service.cmr.avmsync.AVMDifference; +import org.alfresco.service.cmr.avmsync.AVMSyncService; +import org.alfresco.service.cmr.model.FileExistsException; +import org.alfresco.service.cmr.model.FileInfo; +import org.alfresco.service.cmr.repository.*; +import org.alfresco.service.cmr.search.*; +import org.alfresco.service.namespace.QName; +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.bean.wizard.BaseWizardBean; +import org.alfresco.web.data.IDataContainer; +import org.alfresco.web.data.QuickSort; +import org.alfresco.web.forms.*; +import org.alfresco.web.ui.common.Utils; +import org.alfresco.web.ui.common.component.UIListItem; +import org.alfresco.web.ui.wcm.WebResources; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Document; + +/** + * @author arielb + */ +public class RegenerateRenditionsWizard + extends BaseWizardBean +{ + + public final String REGENERATE_SCOPE_ALL = "all"; + public final String REGENERATE_SCOPE_FORM = "form"; + public final String REGENERATE_SCOPE_RENDERING_ENGINE_TEMPLATE = "rendering_engine_template"; + + private final static Log LOGGER = LogFactory.getLog(RegenerateRenditionsWizard.class); + + private AVMService avmService; + private AVMSyncService avmSyncService; + private ContentService contentService; + private SearchService searchService; + private WebProject selectedWebProject; + private String[] selectedForms; + private String[] selectedRenderingEngineTemplates; + private UIRichList renditionChoicesRichList; + private List regeneratedRenditions; + private String regenerateScope; + + // ------------------------------------------------------------------------------ + // Wizard implementation + + @Override + protected String finishImpl(final FacesContext context, final String outcome) + throws Exception + { + if (this.regeneratedRenditions != null) + { + final List diffList = new ArrayList(this.regeneratedRenditions.size()); + for (final Rendition r : this.regeneratedRenditions) + { + diffList.add(new AVMDifference(-1, r.getPath(), + -1, AVMUtil.getCorrespondingPathInMainStore(r.getPath()), + AVMDifference.NEWER)); + } + LOGGER.debug("updating " + diffList.size() + " renditions in staging"); + this.avmSyncService.update(diffList, null, true, true, true, true, null, null); + } + return outcome; + } + + @Override + public void init(final Map parameters) + { + super.init(parameters); + this.selectedWebProject = null; + this.selectedForms = null; + this.selectedRenderingEngineTemplates = null; + this.renditionChoicesRichList = null; + this.regeneratedRenditions = null; + this.regenerateScope = REGENERATE_SCOPE_ALL; + if (this.browseBean.getDocument() != null) + { + if (this.browseBean.getDocument().hasAspect(WCMAppModel.ASPECT_FORM)) + { + this.selectedForms = new String[] { this.browseBean.getDocument().getName() }; + } + else if (this.browseBean.getDocument().hasAspect(WCMAppModel.ASPECT_RENDERING_ENGINE_TEMPLATE)) + { +// System.err.println("how to handle ? " + this.browseBean.getDocument()); +// this.selectedRenderingEngineTemplates = new String[] { "*: + } + } + else if (this.browseBean.getActionSpace() != null) + { + this.selectedForms = new String[] { this.browseBean.getActionSpace().getName() }; + } + } + + @Override + public String next() + { + final int step = Application.getWizardManager().getCurrentStep(); + if (step == 2) + { + try + { + this.regeneratedRenditions = this.regenerateRenditions(); + } + catch (Exception e) + { + Application.getWizardManager().getState().setCurrentStep(step - 1); + Utils.addErrorMessage(e.getMessage(), e); + } + } + return super.next(); + } + + @Override + public String cancel() + { + if (this.selectedWebProject != null) + { + final String stagingStoreName = this.selectedWebProject.getStoreId(); + final String previewStoreName = AVMUtil.getCorrespondingPreviewStoreName(stagingStoreName); + this.avmSyncService.resetLayer(AVMUtil.buildStoreRootPath(previewStoreName)); + } + return super.cancel(); + } + + @Override + public boolean getNextButtonDisabled() + { + return false; + } + + @Override + public String getStepDescription() + { + final ResourceBundle bundle = Application.getBundle(FacesContext.getCurrentInstance()); + final String stepName = Application.getWizardManager().getCurrentStepName(); + if ("summary".equals(stepName)) + { + final String s = this.selectedWebProject.getTitle(); + return MessageFormat.format(bundle.getString("regenerate_renditions_summary_desc"), + this.regeneratedRenditions.size(), + s != null && s.length() != 0 ? s : this.selectedWebProject.getName()); + } + else + { + return super.getContainerDescription(); + } + } + + // ------------------------------------------------------------------------------ + // Bean Getters and Setters + + public String getRegenerateScope() + { + return this.regenerateScope; + } + + public void setRegenerateScope(final String regenerateScope) + { + this.regenerateScope = regenerateScope; + } + + public List getWebProjectChoices() + { + final List webProjects = WebProject.getWebProjects(); + final List result = new ArrayList(webProjects.size()); + for (final WebProject wp : webProjects) + { + final String s = wp.getTitle(); + if (this.selectedWebProject == null) + { + this.selectedWebProject = wp; + } + result.add(new SelectItem(wp.getNodeRef().toString(), s != null && s.length() != 0 ? s : wp.getName())); + } + return result; + } + + public String getSelectedWebProject() + { + return this.selectedWebProject == null ? null : this.selectedWebProject.getNodeRef().toString(); + } + + public void setSelectedWebProject(final String webProject) + { + this.selectedWebProject = (webProject == null || webProject.length() == 0 + ? null + : new WebProject(new NodeRef(webProject))); + + final UIViewRoot c = FacesContext.getCurrentInstance().getViewRoot(); + ((UIListItems)c.findComponent("wizard:wizard-body:select_list_form_choices:list_items_form_choices")).setValue(null); + ((UIListItems)c.findComponent("wizard:wizard-body:select_list_rendering_engine_template_choices:list_items_rendering_engine_template_choices")).setValue(null); + this.renditionChoicesRichList = null; + } + + public List getFormChoices() + { + final List result = new LinkedList(); + final ResourceBundle bundle = Application.getBundle(FacesContext.getCurrentInstance()); + if (this.selectedWebProject != null) + { + for (final Form f : this.selectedWebProject.getForms()) + { + final UIListItem item = new UIListItem(); + item.setValue(f.getName()); + item.setLabel(f.getTitle()); + final List fids = this.getRelatedFormInstanceData(this.selectedWebProject, f); + + item.setDescription(MessageFormat.format(bundle.getString("regenerate_renditions_select_renditions_select_item_desc"), + fids.size() * f.getRenderingEngineTemplates().size(), + this.selectedWebProject.getName())); + item.setImage("/images/icons/webform_large.gif"); + result.add(item); + } + } + return result; + } + + public String[] getSelectedForms() + { + return this.selectedForms; + } + + public void setSelectedForms(final String[] forms) + { + this.selectedForms = forms == null || forms.length == 0 ? null : forms; + } + + public String getSelectedForm() + { + return this.selectedForms != null && this.selectedForms.length != 0 ? this.selectedForms[0] : null; + } + + public void setSelectedForm(final String form) + { + this.selectedForms = form == null || form.length() == 0 ? null : new String[] { form }; + this.renditionChoicesRichList = null; + } + + public List getRenderingEngineTemplateChoices() + { + final List result = new LinkedList(); + final ResourceBundle bundle = Application.getBundle(FacesContext.getCurrentInstance()); + for (final Form f : this.selectedWebProject.getForms()) + { + for (final RenderingEngineTemplate ret : f.getRenderingEngineTemplates()) + { + final UIListItem item = new UIListItem(); + item.setValue(f.getName() + ":" + ret.getName()); + item.setLabel(ret.getTitle() + "(" + ret.getMimetypeForRendition() + ")"); + final List rs = this.getRelatedRenditions(this.selectedWebProject, ret); + item.setDescription(MessageFormat.format(bundle.getString("regenerate_renditions_select_renditions_select_item_desc"), + rs.size(), + this.selectedWebProject.getName())); + item.setImage(Utils.getFileTypeImage(ret.getName(), false)); + result.add(item); + } + } + return result; + } + + public String[] getSelectedRenderingEngineTemplates() + { + return this.selectedRenderingEngineTemplates; + } + + public void setSelectedRenderingEngineTemplates(final String[] renderingEngineTemplates) + { + this.selectedRenderingEngineTemplates = renderingEngineTemplates; + this.renditionChoicesRichList = null; + } + + + public List getRegeneratedRenditions() + { + return this.regeneratedRenditions; + } + + public void setRegeneratedRenditionsRichList(UIRichList richList) + { + this.renditionChoicesRichList = richList; + } + + public UIRichList getRegeneratedRenditionsRichList() + { + return this.renditionChoicesRichList; + } + + // ------------------------------------------------------------------------------ + // Service Injection + + /** + * @param contentService The contentService to set. + */ + public void setContentService(final ContentService contentService) + { + this.contentService = contentService; + } + + /** + * @param avmService The AVMService to set. + */ + public void setAvmService(final AVMService avmService) + { + this.avmService = avmService; + } + + /** + * @param avmSyncService The AVMSyncService to set. + */ + public void setAvmSyncService(final AVMSyncService avmSyncService) + { + this.avmSyncService = avmSyncService; + } + + /** + * @param searchService The SearchService to set. + */ + public void setSearchService(final SearchService searchService) + { + this.searchService = searchService; + } + + // ------------------------------------------------------------------------------ + // Helper Methods + + private List getRelatedFormInstanceData(final WebProject webProject, final Form f) + { + final SearchParameters sp = new SearchParameters(); + final StoreRef storeRef = AVMNodeConverter.ToStoreRef(webProject.getStagingStore()); + sp.addStore(storeRef); + sp.setLanguage(SearchService.LANGUAGE_LUCENE); + StringBuilder query = new StringBuilder(); + query.append("+ASPECT:\"" + WCMAppModel.ASPECT_FORM_INSTANCE_DATA + "\""); + query.append("-ASPECT:\"" + WCMAppModel.ASPECT_RENDITION + "\""); + query.append(" +@" + Repository.escapeQName(WCMAppModel.PROP_PARENT_FORM_NAME) + + ":\"" + f.getName() + "\""); + + LOGGER.debug("running query " + query); + sp.setQuery(query.toString()); + final ResultSet rs = this.searchService.query(sp); + final List result = new ArrayList(rs.length()); + for (final ResultSetRow row : rs) + { + final String avmPath = AVMNodeConverter.ToAVMVersionPath(row.getNodeRef()).getSecond(); + final String previewAvmPath = AVMUtil.getCorrespondingPathInPreviewStore(avmPath); + final FormInstanceDataImpl fid = new FormInstanceDataImpl(-1, previewAvmPath) + { + @Override + public Form getForm() + { + return RegenerateRenditionsWizard.this.selectedWebProject.getForm(super.getForm().getName()); + } + }; + result.add(fid); + } + return result; + } + + private List getRelatedRenditions(final WebProject webProject, final RenderingEngineTemplate ret) + { + final SearchParameters sp = new SearchParameters(); + final StoreRef storeRef = AVMNodeConverter.ToStoreRef(webProject.getStagingStore()); + sp.addStore(storeRef); + sp.setLanguage(SearchService.LANGUAGE_LUCENE); + StringBuilder query = new StringBuilder(); + query.append("+ASPECT:\"" + WCMAppModel.ASPECT_RENDITION + "\""); + query.append("+@" + Repository.escapeQName(WCMAppModel.PROP_PARENT_RENDERING_ENGINE_TEMPLATE) + + ":\"" + ((RenderingEngineTemplateImpl)ret).getNodeRef() + "\""); + + LOGGER.debug("running query " + query); + sp.setQuery(query.toString()); + final ResultSet rs = this.searchService.query(sp); + final List result = new ArrayList(rs.length()); + for (final ResultSetRow row : rs) + { + final String avmPath = AVMNodeConverter.ToAVMVersionPath(row.getNodeRef()).getSecond(); + final String previewAvmPath = AVMUtil.getCorrespondingPathInPreviewStore(avmPath); + final Rendition r = new RenditionImpl(-1, previewAvmPath); + result.add(r); + } + return result; + } + + private List regenerateRenditions() + { + final String stagingStoreName = this.selectedWebProject.getStoreId(); + final String previewStoreName = AVMUtil.getCorrespondingPreviewStoreName(stagingStoreName); + this.avmSyncService.resetLayer(AVMUtil.buildStoreRootPath(previewStoreName)); + + final SearchParameters sp = new SearchParameters(); + final StoreRef storeRef = AVMNodeConverter.ToStoreRef(this.selectedWebProject.getStagingStore()); + sp.addStore(storeRef); + sp.setLanguage(SearchService.LANGUAGE_LUCENE); + StringBuilder query = new StringBuilder(); + if (this.regenerateScope.equals(REGENERATE_SCOPE_ALL) || + this.regenerateScope.equals(REGENERATE_SCOPE_FORM)) + { + query.append("+ASPECT:\"" + WCMAppModel.ASPECT_FORM_INSTANCE_DATA + "\""); + query.append("-ASPECT:\"" + WCMAppModel.ASPECT_RENDITION + "\""); + } + else + { + query.append("+ASPECT:\"" + WCMAppModel.ASPECT_RENDITION + "\""); + } + + if (this.regenerateScope.equals(REGENERATE_SCOPE_FORM)) + { + query.append(" +("); + for (int i = 0; i < this.selectedForms.length; i++) + { + query.append("@" + Repository.escapeQName(WCMAppModel.PROP_PARENT_FORM_NAME) + + ":\"" + this.selectedForms[i] + "\""); + if (i != this.selectedForms.length - 1) + { + query.append(" OR "); + } + } + query.append(") "); + } + if (this.regenerateScope.equals(REGENERATE_SCOPE_RENDERING_ENGINE_TEMPLATE)) + { + query.append(" +("); + for (int i = 0; i < this.selectedRenderingEngineTemplates.length; i++) + { + + final Form f = this.selectedWebProject.getForm(this.selectedRenderingEngineTemplates[i].split(":")[0]); + final RenderingEngineTemplate ret = f.getRenderingEngineTemplate((String)this.selectedRenderingEngineTemplates[i].split(":")[1]); + query.append("@" + Repository.escapeQName(WCMAppModel.PROP_PARENT_RENDERING_ENGINE_TEMPLATE) + + ":\"" + ((RenderingEngineTemplateImpl)ret).getNodeRef() + "\""); + if (i != this.selectedRenderingEngineTemplates.length - 1) + { + query.append(" OR "); + } + } + query.append(") "); + } + + LOGGER.debug("running query " + query); + sp.setQuery(query.toString()); + final ResultSet rs = this.searchService.query(sp); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("received " + rs.length() + " results"); + + final List result = new ArrayList(rs.length()); + for (final ResultSetRow row : rs) + { + final String avmPath = AVMNodeConverter.ToAVMVersionPath(row.getNodeRef()).getSecond(); + final String previewAvmPath = AVMUtil.getCorrespondingPathInPreviewStore(avmPath); + if (this.regenerateScope.equals(REGENERATE_SCOPE_ALL) || + this.regenerateScope.equals(REGENERATE_SCOPE_FORM)) + { + final FormInstanceDataImpl fid = new FormInstanceDataImpl(-1, previewAvmPath) + { + @Override + public Form getForm() + { + return RegenerateRenditionsWizard.this.selectedWebProject.getForm(super.getForm().getName()); + } + }; + + final List regenResults = fid.regenerateRenditions(); + for (final FormInstanceData.RegenerateResult rr : regenResults) + { + if (rr.getException() != null) + { + Utils.addErrorMessage("error regenerating rendition using " + rr.getRenderingEngineTemplate().getName() + + ": " + rr.getException().getMessage(), + rr.getException()); + } + else + { + result.add(rr.getRendition()); + } + } + } + else + { + final Rendition r = new RenditionImpl(-1, previewAvmPath); + try + { + r.regenerate(); + result.add(r); + } + catch (Exception e) + { + Utils.addErrorMessage("error regenerating rendition using " + r.getRenderingEngineTemplate().getName() + + ": " + e.getMessage(), + e); + } + } + } + return result; + } +} diff --git a/source/java/org/alfresco/web/bean/wcm/WebProject.java b/source/java/org/alfresco/web/bean/wcm/WebProject.java index 2aeaf6adad..04ddc1af10 100644 --- a/source/java/org/alfresco/web/bean/wcm/WebProject.java +++ b/source/java/org/alfresco/web/bean/wcm/WebProject.java @@ -33,6 +33,7 @@ import java.util.Map; import javax.faces.context.FacesContext; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.model.WCMAppModel; import org.alfresco.sandbox.SandboxConstants; @@ -42,7 +43,14 @@ import org.alfresco.service.cmr.dictionary.DataTypeDefinition; import org.alfresco.service.cmr.repository.ChildAssociationRef; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.search.ResultSet; +import org.alfresco.service.cmr.search.ResultSetRow; +import org.alfresco.service.cmr.search.SearchParameters; +import org.alfresco.service.cmr.search.SearchService; +import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.service.namespace.QName; import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.web.app.Application; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.repository.User; import org.alfresco.web.data.IDataContainer; @@ -52,6 +60,8 @@ import org.alfresco.web.forms.FormImpl; import org.alfresco.web.forms.FormsService; import org.alfresco.web.forms.RenderingEngineTemplate; import org.alfresco.web.forms.RenderingEngineTemplateImpl; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; /** * Provides configured data for a web project. @@ -165,6 +175,9 @@ public class WebProject ///////////////////////////////////////////////////////////////////////////// + private final static Log LOGGER = LogFactory.getLog(WebProject.class); + private static String websitesFolderId; + private final NodeRef nodeRef; public WebProject(final NodeRef nodeRef) @@ -180,6 +193,16 @@ public class WebProject SandboxConstants.PROP_WEB_PROJECT_NODE_REF).getValue(DataTypeDefinition.NODE_REF); } + /** + * Returns the noderef for the webproject + * + * @return the noderef for the webproject. + */ + public NodeRef getNodeRef() + { + return this.nodeRef; + } + /** * Returns the name of the web project. * @@ -192,6 +215,30 @@ public class WebProject return (String)nodeService.getProperty(this.nodeRef, ContentModel.PROP_NAME); } + /** + * Returns the title of the web project. + * + * @return the title of the web project. + */ + public String getTitle() + { + final ServiceRegistry serviceRegistry = this.getServiceRegistry(); + final NodeService nodeService = serviceRegistry.getNodeService(); + return (String)nodeService.getProperty(this.nodeRef, ContentModel.PROP_TITLE); + } + + /** + * Returns the description of the web project. + * + * @return the description of the web project. + */ + public String getDescription() + { + final ServiceRegistry serviceRegistry = this.getServiceRegistry(); + final NodeService nodeService = serviceRegistry.getNodeService(); + return (String)nodeService.getProperty(this.nodeRef, ContentModel.PROP_DESCRIPTION); + } + /** * Returns the store id for this web project. * @@ -221,8 +268,8 @@ public class WebProject */ public List
getForms() { - List forms = new ArrayList(this.getFormsImpl().values()); - QuickSort sorter = new QuickSort(forms, "name", true, IDataContainer.SORT_CASEINSENSITIVE); + final List forms = new ArrayList(this.getFormsImpl().values()); + final QuickSort sorter = new QuickSort(forms, "name", true, IDataContainer.SORT_CASEINSENSITIVE); sorter.sort(); return Collections.unmodifiableList(forms); } @@ -290,6 +337,60 @@ public class WebProject nodeService.getProperty(this.nodeRef, WCMAppModel.PROP_DEFAULTWEBAPP); } + /** + * Helper to get the ID of the 'Websites' system folder + * + * @return ID of the 'Websites' system folder + * + * @throws AlfrescoRuntimeException if unable to find the required folder + */ + public static NodeRef getWebsitesFolder() + { + if (WebProject.websitesFolderId == null) + { + // get the template from the special Content Templates folder + final FacesContext fc = FacesContext.getCurrentInstance(); + final String xpath = Application.getRootPath(fc) + "/" + Application.getWebsitesFolderName(fc); + + final NodeRef rootNodeRef = WebProject.getServiceRegistry().getNodeService().getRootNode(Repository.getStoreRef()); + final NamespaceService resolver = Repository.getServiceRegistry(fc).getNamespaceService(); + final List results = WebProject.getServiceRegistry().getSearchService().selectNodes(rootNodeRef, xpath, null, resolver, false); + if (results.size() == 1) + { + WebProject.websitesFolderId = results.get(0).getId(); + } + else + { + throw new AlfrescoRuntimeException("Unable to find 'Websites' system folder at: " + xpath); + } + } + + return new NodeRef(Repository.getStoreRef(), WebProject.websitesFolderId); + } + + public static List getWebProjects() + { + final ServiceRegistry serviceRegistry = WebProject.getServiceRegistry(); + final SearchParameters sp = new SearchParameters(); + sp.addStore(Repository.getStoreRef()); + sp.setLanguage(SearchService.LANGUAGE_LUCENE); + sp.setQuery("+TYPE:\"" + WCMAppModel.TYPE_AVMWEBFOLDER + + "\" +PARENT:\"" + WebProject.getWebsitesFolder() + "\""); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("running query [" + sp.getQuery() + "]"); + final ResultSet rs = serviceRegistry.getSearchService().query(sp); + if (LOGGER.isDebugEnabled()) + LOGGER.debug("received " + rs.length() + " results"); + final List result = new ArrayList(rs.length()); + for (ResultSetRow row : rs) + { + result.add(new WebProject(row.getNodeRef())); + } + QuickSort sorter = new QuickSort((List)result, "name", true, IDataContainer.SORT_CASEINSENSITIVE); + sorter.sort(); + return result; + } + private Map getFormsImpl() { final ServiceRegistry serviceRegistry = this.getServiceRegistry(); @@ -309,9 +410,21 @@ public class WebProject return result; } - private ServiceRegistry getServiceRegistry() + private static ServiceRegistry getServiceRegistry() { final FacesContext fc = FacesContext.getCurrentInstance(); return Repository.getServiceRegistry(fc); } -} \ No newline at end of file + + public boolean equals(final Object other) + { + return (other != null && + other instanceof WebProject && + this.getNodeRef().equals(((WebProject)other).getNodeRef())); + } + + public int hashCode() + { + return this.nodeRef.hashCode(); + } +} diff --git a/source/java/org/alfresco/web/forms/FormImpl.java b/source/java/org/alfresco/web/forms/FormImpl.java index f141f7af69..722b2e6e30 100644 --- a/source/java/org/alfresco/web/forms/FormImpl.java +++ b/source/java/org/alfresco/web/forms/FormImpl.java @@ -19,7 +19,8 @@ * and Open Source Software ("FLOSS") applications as described in Alfresco's * FLOSS exception. You should have recieved a copy of the text describing * the FLOSS exception, and it is also available here: - * http://www.alfresco.com/legal/licensing */ + * http://www.alfresco.com/legal/licensing + */ package org.alfresco.web.forms; import freemarker.ext.dom.NodeModel; diff --git a/source/java/org/alfresco/web/forms/FormInstanceData.java b/source/java/org/alfresco/web/forms/FormInstanceData.java index 7590d157d7..5fb0fada57 100644 --- a/source/java/org/alfresco/web/forms/FormInstanceData.java +++ b/source/java/org/alfresco/web/forms/FormInstanceData.java @@ -38,6 +38,49 @@ public interface FormInstanceData extends Serializable { + ///////////////////////////////////////////////////////////////////////////// + + public static class RegenerateResult + { + + private final RenderingEngineTemplate ret; + private final Rendition r; + private final Exception e; + + public RegenerateResult(final RenderingEngineTemplate ret, + final Rendition r) + { + this.ret = ret; + this.r = r; + this.e = null; + } + + public RegenerateResult(final RenderingEngineTemplate ret, + final Exception e) + { + this.ret = ret; + this.e = e; + this.r = null; + } + + public RenderingEngineTemplate getRenderingEngineTemplate() + { + return this.ret; + } + + public Rendition getRendition() + { + return this.r; + } + + public Exception getException() + { + return this.e; + } + } + + ///////////////////////////////////////////////////////////////////////////// + /** the form generate this form instance data */ public Form getForm(); @@ -60,6 +103,9 @@ public interface FormInstanceData public Document getDocument() throws IOException, SAXException; + /** Regenerates all renditions of this form instance data */ + public List regenerateRenditions(); + /** 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 b8efb5c404..d3932c4d20 100644 --- a/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java +++ b/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java @@ -119,6 +119,61 @@ public class FormInstanceDataImpl return AVMUtil.buildAssetUrl(this.getPath()); } + public List regenerateRenditions() + { + + if (LOGGER.isDebugEnabled()) + LOGGER.debug("regenerating renditions of " + this); + String originalParentAvmPath = (String) + this.getServiceRegistry().getNodeService().getProperty(this.getNodeRef(), + WCMAppModel.PROP_ORIGINAL_PARENT_PATH); + if (originalParentAvmPath == null) + { + originalParentAvmPath = AVMNodeConverter.SplitBase(this.getPath())[0]; + } + final HashSet allRets = + new HashSet(this.getForm().getRenderingEngineTemplates()); + final List result = new LinkedList(); + // regenerate existing renditions + for (final Rendition r : this.getRenditions()) + { + final RenderingEngineTemplate ret = r.getRenderingEngineTemplate(); + if (ret == null || !allRets.contains(ret)) + { + continue; + } + try + { + LOGGER.debug("regenerating rendition " + r + " using template " + ret); + ret.render(this, r); + allRets.remove(ret); + result.add(new RegenerateResult(ret, r)); + } + catch (Exception e) + { + result.add(new RegenerateResult(ret, e)); + } + } + + // render all renditions for newly added templates + for (final RenderingEngineTemplate ret : allRets) + { + try + { + final String path = ret.getOutputPathForRendition(this, originalParentAvmPath); + LOGGER.debug("regenerating rendition of " + this.getPath() + + " at " + path + " using template " + ret); + + result.add(new RegenerateResult(ret, ret.render(this, path))); + } + catch (Exception e) + { + result.add(new RegenerateResult(ret, e)); + } + } + return result; + } + public List getRenditions() { final AVMService avmService = this.getServiceRegistry().getAVMService(); @@ -131,8 +186,18 @@ public class FormInstanceDataImpl final List result = new ArrayList(renditionPaths.size()); for (Serializable path : renditionPaths) { - result.add(new RenditionImpl(AVMNodeConverter.ToNodeRef(-1, storeName + ':' + (String)path))); - + if (avmService.lookup(-1, storeName + ':' + (String)path) != null) + { + final Rendition r = new RenditionImpl(AVMNodeConverter.ToNodeRef(-1, storeName + ':' + (String)path)); + if (r.getRenderingEngineTemplate() != null) + { + result.add(r); + } + } + else + { + LOGGER.debug("ignoring dangling rendition at " + storeName + ':' + (String)path); + } } return result; } @@ -142,4 +207,15 @@ public class FormInstanceDataImpl final FacesContext fc = FacesContext.getCurrentInstance(); return Repository.getServiceRegistry(fc); } + + public int hashCode() + { + return this.getPath().hashCode() ^ this.getForm().hashCode(); + } + + public String toString() + { + return (this.getClass().getName() + "{path : " + this.getPath() + + ", form : " + this.getForm().getName() + "}"); + } } diff --git a/source/java/org/alfresco/web/forms/FormsService.java b/source/java/org/alfresco/web/forms/FormsService.java index df4833ba79..122f796922 100644 --- a/source/java/org/alfresco/web/forms/FormsService.java +++ b/source/java/org/alfresco/web/forms/FormsService.java @@ -186,7 +186,8 @@ public final class FormsService final SearchParameters sp = new SearchParameters(); sp.addStore(Repository.getStoreRef()); sp.setLanguage(SearchService.LANGUAGE_LUCENE); - sp.setQuery("ASPECT:\"" + WCMAppModel.ASPECT_FORM + "\""); + sp.setQuery("+ASPECT:\"" + WCMAppModel.ASPECT_FORM + + "\" +PARENT:\"" + this.getContentFormsNodeRef() + "\""); if (LOGGER.isDebugEnabled()) LOGGER.debug("running query [" + sp.getQuery() + "]"); final ResultSet rs = this.searchService.query(sp); diff --git a/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java b/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java index 05c032f28a..5ea28d12fd 100644 --- a/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java +++ b/source/java/org/alfresco/web/forms/RenderingEngineTemplateImpl.java @@ -19,7 +19,8 @@ * and Open Source Software ("FLOSS") applications as described in Alfresco's * FLOSS exception. You should have recieved a copy of the text describing * the FLOSS exception, and it is also available here: - * http://www.alfresco.com/legal/licensing */ + * http://www.alfresco.com/legal/licensing + */ package org.alfresco.web.forms; import freemarker.ext.dom.NodeModel; @@ -564,5 +565,10 @@ public class RenderingEngineTemplateImpl { return this.getName().hashCode(); } + + public String toString() + { + return this.getClass().getName() + "{name : " + this.getName() + "}"; + } } diff --git a/source/java/org/alfresco/web/forms/RenditionImpl.java b/source/java/org/alfresco/web/forms/RenditionImpl.java index f792f02ddb..1148b735a7 100644 --- a/source/java/org/alfresco/web/forms/RenditionImpl.java +++ b/source/java/org/alfresco/web/forms/RenditionImpl.java @@ -19,7 +19,8 @@ * and Open Source Software ("FLOSS") applications as described in Alfresco's * FLOSS exception. You should have recieved a copy of the text describing * the FLOSS exception, and it is also available here: - * http://www.alfresco.com/legal/licensing" */ + * http://www.alfresco.com/legal/licensing" + */ package org.alfresco.web.forms; import java.io.FileNotFoundException; @@ -35,6 +36,7 @@ import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.avm.AVMService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.util.Pair; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.bean.wcm.AVMUtil; import org.alfresco.web.ui.common.Utils; @@ -65,6 +67,11 @@ public class RenditionImpl this.nodeRef = nodeRef; } + public RenditionImpl(final int version, final String avmPath) + { + this(AVMNodeConverter.ToNodeRef(version, avmPath)); + } + /** the name of this rendition */ public String getName() { @@ -118,9 +125,22 @@ public class RenditionImpl final NodeRef retNodeRef = (NodeRef) nodeService.getProperty(this.nodeRef, WCMAppModel.PROP_PARENT_RENDERING_ENGINE_TEMPLATE); + if (retNodeRef == null) + { + LOGGER.debug("unable to locate parent rendering engine template of rendition " + + this.getPath()); + return null; + } + final NodeRef rpNodeRef = (NodeRef) nodeService.getProperty(this.nodeRef, WCMAppModel.PROP_PARENT_RENDITION_PROPERTIES); + if (rpNodeRef == null) + { + LOGGER.debug("unable to locate parent rendering engine template properties of rendition " + + this.getPath()); + return null; + } this.renderingEngineTemplate = new RenderingEngineTemplateImpl(retNodeRef, rpNodeRef); } return this.renderingEngineTemplate; @@ -149,7 +169,12 @@ public class RenditionImpl public OutputStream getOutputStream() { - return this.getServiceRegistry().getAVMService().getFileOutputStream(this.getPath()); + final AVMService avmService = this.getServiceRegistry().getAVMService(); + final Pair p = AVMNodeConverter.ToAVMVersionPath(this.nodeRef); + return (avmService.lookup(p.getFirst(), p.getSecond()) == null + ? avmService.createFile(AVMNodeConverter.SplitBase(p.getSecond())[0], + AVMNodeConverter.SplitBase(p.getSecond())[1]) + : avmService.getFileOutputStream(this.getPath())); } public void regenerate() @@ -174,4 +199,17 @@ public class RenditionImpl final FacesContext fc = FacesContext.getCurrentInstance(); return Repository.getServiceRegistry(fc); } + + public int hashCode() + { + return this.getPath().hashCode() ^ this.getRenderingEngineTemplate().hashCode(); + } + + public String toString() + { + return (this.getClass().getName() + + "{path : " + this.getPath() + + ", rendering_engine_template : " + this.getRenderingEngineTemplate() + + "}"); + } } diff --git a/source/java/org/alfresco/web/ui/common/component/UIListItems.java b/source/java/org/alfresco/web/ui/common/component/UIListItems.java index e0ef61d8a0..68fffa4538 100644 --- a/source/java/org/alfresco/web/ui/common/component/UIListItems.java +++ b/source/java/org/alfresco/web/ui/common/component/UIListItems.java @@ -57,7 +57,6 @@ public class UIListItems extends SelfRenderingComponent this.value = vb.getValue(getFacesContext()); } } - return this.value; } @@ -85,11 +84,8 @@ public class UIListItems extends SelfRenderingComponent */ public Object saveState(FacesContext context) { - Object values[] = new Object[2]; // standard component attributes are saved by the super class - values[0] = super.saveState(context); - values[1] = this.value; - return (values); + return new Object[] { super.saveState(context), this.value }; } } diff --git a/source/java/org/alfresco/web/ui/common/component/UISelectList.java b/source/java/org/alfresco/web/ui/common/component/UISelectList.java index 1f2497b6dc..2156a4af5f 100644 --- a/source/java/org/alfresco/web/ui/common/component/UISelectList.java +++ b/source/java/org/alfresco/web/ui/common/component/UISelectList.java @@ -27,6 +27,7 @@ package org.alfresco.web.ui.common.component; import java.io.IOException; import java.util.Collection; import java.util.Iterator; +import java.util.List; import java.util.Map; import javax.faces.component.NamingContainer; @@ -65,7 +66,7 @@ public class UISelectList extends UIInput implements NamingContainer private Boolean activeSelect; private int rowIndex = -1; private int itemCount; - + private String onchange = null; // ------------------------------------------------------------------------------ // Component Impl @@ -97,6 +98,7 @@ public class UISelectList extends UIInput implements NamingContainer this.multiSelect = (Boolean)values[1]; this.activeSelect = (Boolean)values[2]; this.itemCount = (Integer)values[3]; + this.onchange = (String)values[4]; } /** @@ -104,13 +106,14 @@ public class UISelectList extends UIInput implements NamingContainer */ public Object saveState(FacesContext context) { - Object values[] = new Object[4]; - // standard component attributes are saved by the super class - values[0] = super.saveState(context); - values[1] = this.multiSelect; - values[2] = this.activeSelect; - values[3] = this.itemCount; - return (values); + return new Object[] + { + super.saveState(context), + this.multiSelect, + this.activeSelect, + this.itemCount, + this.onchange + }; } /** @@ -124,11 +127,7 @@ public class UISelectList extends UIInput implements NamingContainer { String clientId = super.getClientId(context); int rowIndex = getRowIndex(); - if (rowIndex == -1) - { - return clientId; - } - return clientId + "_" + rowIndex; + return (rowIndex == -1 ? clientId : clientId + "_" + rowIndex); } /** @@ -144,9 +143,8 @@ public class UISelectList extends UIInput implements NamingContainer } setRowIndex(-1); - for (Iterator itr=getChildren().iterator(); itr.hasNext(); /**/) + for (UIComponent child : (List)this.getChildren()) { - UIComponent child = (UIComponent)itr.next(); if (child instanceof UIListItem == false && child instanceof UIListItems == false) { for (int i=0; i)this.getChildren()) { - UIComponent child = (UIComponent)i.next(); if (child instanceof UIListItems) { // get the value of the list items component and iterate through it's collection Object listItems = ((UIListItems)child).getValue(); if (listItems instanceof Collection) { - for (Iterator iter = ((Collection)listItems).iterator(); iter.hasNext(); /**/) + for (final UIListItem item : (Collection)listItems) { - UIListItem item = (UIListItem)iter.next(); if (item.isRendered()) { if (var != null) @@ -355,7 +351,11 @@ public class UISelectList extends UIInput implements NamingContainer out.write(id); out.write("' value='"); out.write(itemValue); - out.write('\''); + out.write("'"); + if (this.onchange != null) + { + out.write(" onchange='" + this.onchange + "'"); + } String[] value = (String[])getValue(); if (multiSelect) { @@ -454,9 +454,8 @@ public class UISelectList extends UIInput implements NamingContainer if (isActiveSelect()) { this.rowIndex = rowIndex; - for (Iterator itr=getChildren().iterator(); itr.hasNext(); /**/) + for (UIComponent child : (List)this.getChildren()) { - UIComponent child = (UIComponent)itr.next(); if (child instanceof UIListItem == false && child instanceof UIListItems == false) { // forces a reset of the clientId for the component @@ -482,15 +481,7 @@ public class UISelectList extends UIInput implements NamingContainer this.multiSelect = (Boolean)vb.getValue(getFacesContext()); } - if (this.multiSelect != null) - { - return this.multiSelect.booleanValue(); - } - else - { - // return the default - return false; - } + return this.multiSelect != null ? this.multiSelect.booleanValue() : false; } /** @@ -516,15 +507,7 @@ public class UISelectList extends UIInput implements NamingContainer this.activeSelect = (Boolean)vb.getValue(getFacesContext()); } - if (this.activeSelect != null) - { - return this.activeSelect.booleanValue(); - } - else - { - // return the default - return false; - } + return (this.activeSelect != null ? this.activeSelect.booleanValue() : false; } /** diff --git a/source/java/org/alfresco/web/ui/common/tag/SelectListTag.java b/source/java/org/alfresco/web/ui/common/tag/SelectListTag.java index 8340df6f29..b935619269 100644 --- a/source/java/org/alfresco/web/ui/common/tag/SelectListTag.java +++ b/source/java/org/alfresco/web/ui/common/tag/SelectListTag.java @@ -59,6 +59,7 @@ public class SelectListTag extends HtmlComponentTag setStringProperty(component, "itemStyle", this.itemStyle); setStringProperty(component, "itemStyleClass", this.itemStyleClass); setStringProperty(component, "value", this.value); + setStringProperty(component, "onchange", this.onchange); } /** @@ -73,6 +74,7 @@ public class SelectListTag extends HtmlComponentTag this.itemStyle = null; this.itemStyleClass = null; this.value = null; + this.onchange = null; } /** @@ -135,6 +137,16 @@ public class SelectListTag extends HtmlComponentTag this.value = value; } + /** + * Set the onchange handler + * + * @param value the onchange handler. + */ + public void setOnchange(final String onchange) + { + this.onchange = onchange; + } + /** the selected value */ private String value; @@ -152,4 +164,7 @@ public class SelectListTag extends HtmlComponentTag /** the variable name for row item context */ private String var; + + /** the event handler for a change in selection */ + private String onchange; } diff --git a/source/web/WEB-INF/alfresco.tld b/source/web/WEB-INF/alfresco.tld index a1e09d9fec..e6a1a76aa6 100644 --- a/source/web/WEB-INF/alfresco.tld +++ b/source/web/WEB-INF/alfresco.tld @@ -1959,6 +1959,12 @@ true + + onchange + false + true + + value false diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index 07d853f8be..5910222c97 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -2482,6 +2482,51 @@ #{WorkflowService} + + + + The bean that backs up the Regenerate Renditions Wizard + + RegenerateRenditionsWizard + org.alfresco.web.bean.wcm.RegenerateRenditionsWizard + session + + nodeService + #{NodeService} + + + fileFolderService + #{FileFolderService} + + + searchService + #{SearchService} + + + namespaceService + #{NamespaceService} + + + navigator + #{NavigationBean} + + + browseBean + #{BrowseBean} + + + contentService + #{ContentService} + + + avmService + #{AVMService} + + + avmSyncService + #{AVMSyncService} + + diff --git a/source/web/images/icons/regenerate_renditions.gif b/source/web/images/icons/regenerate_renditions.gif new file mode 100644 index 0000000000..f614348cc7 Binary files /dev/null and b/source/web/images/icons/regenerate_renditions.gif differ diff --git a/source/web/images/icons/regenerate_renditions_large.gif b/source/web/images/icons/regenerate_renditions_large.gif new file mode 100644 index 0000000000..9a06053822 Binary files /dev/null and b/source/web/images/icons/regenerate_renditions_large.gif differ diff --git a/source/web/jsp/wcm/create-form-wizard/details.jsp b/source/web/jsp/wcm/create-form-wizard/details.jsp index 3bd29714c3..9ca19b93fd 100644 --- a/source/web/jsp/wcm/create-form-wizard/details.jsp +++ b/source/web/jsp/wcm/create-form-wizard/details.jsp @@ -1,4 +1,4 @@ -<%-- + + - - + + + + - diff --git a/source/web/jsp/wcm/regenerate-renditions-wizard/select_renditions.jsp b/source/web/jsp/wcm/regenerate-renditions-wizard/select_renditions.jsp new file mode 100644 index 0000000000..26ad3d6463 --- /dev/null +++ b/source/web/jsp/wcm/regenerate-renditions-wizard/select_renditions.jsp @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/web/jsp/wcm/regenerate-renditions-wizard/summary.jsp b/source/web/jsp/wcm/regenerate-renditions-wizard/summary.jsp new file mode 100644 index 0000000000..4127a32f37 --- /dev/null +++ b/source/web/jsp/wcm/regenerate-renditions-wizard/summary.jsp @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +