From e80a27b73cd7014176a0fc3a001d0cd626d1bf83 Mon Sep 17 00:00:00 2001 From: Derek Hulley Date: Tue, 19 Jan 2010 13:18:50 +0000 Subject: [PATCH] Merged V3.2 to HEAD 17410: Merged V3.1 to V3.2 16667: (record-only) Fix ETHREEOH-2477 - group-based perms (MT env) 16883: Fix ETHREEOH-1544 - cannot paste an item, if cut from another web project (modifyLock errror) 16918: Fix ETHREEOH-3053 - Deployment of non-stale file in a stale layered folder removes the file from FSR 16947: (record-only) Temporarily comment-out testSubmitChangedAssets1 (intermittent permission failure) 17162: Fix ETHREEOH-2850 - submitting delete of (web form) xml instance does not submit the associated deleted renditions 17319: Fix ETHREEOH-3111 - ManageReviewTaskDialog (fix-up contributed patch) 17418: Merged V3.1 to V3.2 17141: Fix ETHREEOH-3088: Cut/Paste into self causes stack overflow 17216: Fixed ETHREEOH-3170: DB errors on MSSQL with Snapshot Isolation enabled while CIFS copying 17255: Fixed ETHREEOH-3180: Error appears when trying to search resources on Manage Task page 17419: Fix for ETHREEOH-3296: Enterprise 3.X / Permissions Error When Cut & Paste on Sub-Folder 17421: Review and tweaks of DB script port 17423: Follow-on for ETHREEOH-3088 17424: Missed check-in for ETHREEOH-3032 (CHK-10240) 17437: ETHREEOH-2790 - OpenOffice-startup-context.xml needs to also initiate the connection to OpenOffice 17441: Build fix: Fix AVM permission inheritance to match DM and fix common permission dao component 17470: Fix for ETHREEOH-3350: Admin Console - Viewing user properties for user without home folder throws exception ___________________________________________________________________ Modified: svn:mergeinfo Merged /alfresco/BRANCHES/V3.1:r16667,16883,16918,16947,17141,17162,17216,17255,17319 Merged /alfresco/BRANCHES/V3.2:r17410,17418-17419,17421,17423-17424,17437,17441,17470 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18137 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../web/bean/wcm/ManageReviewTaskDialog.java | 2 +- .../alfresco/web/bean/wcm/SubmitDialog.java | 62 +- .../alfresco/web/forms/FormInstanceData.java | 25 +- .../web/forms/FormInstanceDataImpl.java | 786 +++++++++--------- .../org/alfresco/web/forms/Rendition.java | 178 ++-- .../org/alfresco/web/forms/RenditionImpl.java | 8 +- 6 files changed, 539 insertions(+), 522 deletions(-) diff --git a/source/java/org/alfresco/web/bean/wcm/ManageReviewTaskDialog.java b/source/java/org/alfresco/web/bean/wcm/ManageReviewTaskDialog.java index 3a0f655bee..d8d03cf48f 100644 --- a/source/java/org/alfresco/web/bean/wcm/ManageReviewTaskDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/ManageReviewTaskDialog.java @@ -64,7 +64,7 @@ public class ManageReviewTaskDialog extends ManageTaskDialog protected String webapp; protected NodeRef webProjectRef; protected AVMBrowseBean avmBrowseBean; - transient protected PermissionService permissionService; + transient private PermissionService permissionService; private static final Log logger = LogFactory.getLog(ManageReviewTaskDialog.class); diff --git a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java index b9db4179fa..9f886adb16 100644 --- a/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java +++ b/source/java/org/alfresco/web/bean/wcm/SubmitDialog.java @@ -65,9 +65,7 @@ import org.alfresco.web.app.servlet.FacesHelper; import org.alfresco.web.bean.BrowseBean; import org.alfresco.web.bean.dialog.BaseDialogBean; import org.alfresco.web.bean.repository.Repository; -import org.alfresco.web.forms.Form; import org.alfresco.web.forms.FormInstanceData; -import org.alfresco.web.forms.FormNotFoundException; import org.alfresco.web.forms.FormsService; import org.alfresco.web.forms.Rendition; import org.alfresco.web.ui.common.Utils; @@ -737,81 +735,63 @@ public class SubmitDialog extends BaseDialogBean this.warningItems.add(new ItemWrapper(node)); continue; } - NodeRef ref = AVMNodeConverter.ToNodeRef(-1, node.getPath()); if (submittedPaths.contains(node.getPath())) { continue; } - if (node.isDeleted()) - { - // found a deleted node for submit - this.submitItems.add(new ItemWrapper(node)); - submittedPaths.add(node.getPath()); - } - // lookup if this item was created via a form - then lookup the workflow defaults - // for that form and store into the list of available workflows - else if (!getNodeService().hasAspect(ref, WCMAppModel.ASPECT_FORM_INSTANCE_DATA)) + boolean isForm = getNodeService().hasAspect(ref, WCMAppModel.ASPECT_FORM_INSTANCE_DATA); + boolean isRendition = getNodeService().hasAspect(ref, WCMAppModel.ASPECT_RENDITION); + + if (((!isForm) && (!isRendition)) || (node.isDeleted() && (!isForm))) { + // found single item for submit + // note: could be a single deleted rendition - to enable deletion of old renditions (eg. if template no longer applicable) this.submitItems.add(new ItemWrapper(node)); submittedPaths.add(node.getPath()); } else { + // item is a form (note: could be deleted) or a rendition + FormInstanceData fid = null; - // check if this is a rendition - as they also have the forminstancedata aspect - if (getNodeService().hasAspect(ref, WCMAppModel.ASPECT_RENDITION)) + if (isRendition) { // found a generated rendition asset - locate the parent form instance data file // and use this to find all generated assets that are appropriate // NOTE: this path value is store relative - fid = getFormsService().getRendition(ref).getPrimaryFormInstanceData(); + fid = getFormsService().getRendition(ref).getPrimaryFormInstanceData(true); } else { fid = getFormsService().getFormInstanceData(ref); } - // check form's default workflow (if any) - Form f = null; - try - { - f = fid.getForm(); - } - catch (FormNotFoundException fnfe) - { - String formName = (String)getNodeService().getProperty(ref, WCMAppModel.PROP_PARENT_FORM_NAME); - logger.warn("Cannot check default workflow (if any) for missing form '"+formName+"' (may have been deleted) - when submitting '"+node.getPath()+"'"); - //Utils.addErrorMessage(fnfe.getMessage(), fnfe); - } - // add the form instance data file to the list for submission if (!submittedPaths.contains(fid.getPath())) { - this.submitItems.add(new ItemWrapper(getAvmService().lookup(-1, fid.getPath()))); + this.submitItems.add(new ItemWrapper(getAvmService().lookup(-1, fid.getPath(), true))); submittedPaths.add(fid.getPath()); } // locate renditions for this form instance data file and add to list for submission - for (final Rendition rendition : fid.getRenditions()) + for (final Rendition rendition : fid.getRenditions(true)) { final String renditionPath = rendition.getPath(); if (!submittedPaths.contains(renditionPath)) { - this.submitItems.add(new ItemWrapper(getAvmService().lookup(-1, renditionPath))); + this.submitItems.add(new ItemWrapper(getAvmService().lookup(-1, renditionPath, true))); submittedPaths.add(renditionPath); } } - if (f != null) + // lookup the workflow defaults for that form and store into the list of available workflows + WorkflowDefinition defaultWfDef = fid.getForm().getDefaultWorkflow(); + if (defaultWfDef != null) { - WorkflowDefinition defaultWfDef = f.getDefaultWorkflow(); - if (defaultWfDef != null) - { - this.workflows.add(new FormWorkflowWrapper(defaultWfDef.getName(), - f.getDefaultWorkflowParameters())); - } + this.workflows.add(new FormWorkflowWrapper(defaultWfDef.getName(), + fid.getForm().getDefaultWorkflowParameters())); } // See WCM-1090 ACT-1551 @@ -825,14 +805,14 @@ public class SubmitDialog extends BaseDialogBean } } } - + tx.commit(); } catch (Throwable e) { // rollback the transaction on error try { if (tx != null) {tx.rollback();} } catch (Exception ex) {} - + // rethrow the exception to highlight the problem throw (RuntimeException)e; } @@ -1106,4 +1086,4 @@ public class SubmitDialog extends BaseDialogBean return descriptor.getPath().hashCode(); } } -} +} \ 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 38f4115267..a0dcaed2fc 100644 --- a/source/java/org/alfresco/web/forms/FormInstanceData.java +++ b/source/java/org/alfresco/web/forms/FormInstanceData.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Alfresco Software Limited. + * Copyright (C) 2005-2009 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 @@ -47,39 +47,39 @@ public interface FormInstanceData private static final long serialVersionUID = -3827878774655260635L; private final RenderingEngineTemplate ret; - private final String path; + private final String path; private final Rendition r; private final Exception e; public RegenerateResult(final RenderingEngineTemplate ret, - final String path, + final String path, final Rendition r) { this.ret = ret; this.r = r; this.e = null; - this.path = path; + this.path = path; } public RegenerateResult(final RenderingEngineTemplate ret, - final String path, + final String path, final Exception e) { this.ret = ret; this.e = e; this.r = null; - this.path = path; + this.path = path; } public RenderingEngineTemplate getRenderingEngineTemplate() { return this.ret; } - - public String getPath() - { - return this.path; - } + + public String getPath() + { + return this.path; + } public Rendition getRendition() { @@ -123,4 +123,7 @@ public interface FormInstanceData /** returns all renditions of this form instance data */ public List getRenditions(); + + /** returns all renditions of this form instance data (include deleted AVM nodes) */ + public List getRenditions(boolean includeDeleted); } diff --git a/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java b/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java index 10e4b65d6e..844ee0c626 100644 --- a/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java +++ b/source/java/org/alfresco/web/forms/FormInstanceDataImpl.java @@ -1,381 +1,405 @@ -/* - * Copyright (C) 2005-2009 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.forms; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; - -import javax.faces.context.FacesContext; - -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.avm.locking.AVMLock; -import org.alfresco.service.cmr.avm.locking.AVMLockingService; -import org.alfresco.service.cmr.dictionary.DataTypeDefinition; -import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.cmr.repository.StoreRef; -import org.alfresco.web.app.servlet.FacesHelper; -import org.alfresco.web.bean.repository.Repository; -import org.alfresco.web.bean.wcm.AVMUtil; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.w3c.dom.Document; -import org.xml.sax.SAXException; - -/** - * Encapsulation of a rendition. - * - * @author Ariel Backenroth - */ -/* package */ class FormInstanceDataImpl implements FormInstanceData -{ - private static final long serialVersionUID = -7806221587661854013L; - - private static final Log logger = LogFactory.getLog(RenditionImpl.class); - - private final NodeRef nodeRef; - private transient FormsService formsService; - - /* package */ FormInstanceDataImpl(final NodeRef nodeRef, - final FormsService formsService) - { - if (nodeRef == null) - { - throw new NullPointerException(); - } - if (formsService == null) - { - throw new NullPointerException(); - } - final AVMService avmService = this.getServiceRegistry().getAVMService(); - if (!avmService.hasAspect(AVMNodeConverter.ToAVMVersionPath(nodeRef).getFirst(), - AVMNodeConverter.ToAVMVersionPath(nodeRef).getSecond(), - WCMAppModel.ASPECT_FORM_INSTANCE_DATA)) - { - throw new IllegalArgumentException("node " + nodeRef + - " does not have aspect " + WCMAppModel.ASPECT_FORM_INSTANCE_DATA); - } - this.nodeRef = nodeRef; - this.formsService = formsService; - } - - /* package */ FormInstanceDataImpl(final int version, - final String avmPath, - final FormsService formsService) - { - this(AVMNodeConverter.ToNodeRef(version, avmPath), formsService); - } - - private FormsService getFormsService() - { - if (formsService == null) - { - formsService = (FormsService) FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "FormsService"); - } - return formsService; - } - - /** the name of this rendition */ - public String getName() - { -// final AVMService avmService = this.getServiceRegistry().getAVMService(); -// return avmService.getNodeProperty(AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getFirst(), -// AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond(), -// ContentModel.PROP_NAME).getStringValue(); - return AVMNodeConverter.SplitBase(AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond())[1]; - } - - public String getWebappRelativePath() - { - return AVMUtil.getWebappRelativePath(this.getPath()); - } - - public String getSandboxRelativePath() - { - return AVMUtil.getSandboxRelativePath(this.getPath()); - } - - public String getPath() - { - return AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond(); - } - - public Document getDocument() - throws IOException, SAXException - { - return XMLUtil.parse(AVMNodeConverter.ToAVMVersionPath(nodeRef).getFirst(), - AVMNodeConverter.ToAVMVersionPath(nodeRef).getSecond(), - this.getServiceRegistry().getAVMService()); - } - - public Form getForm() - throws FormNotFoundException - { - final String parentFormName = this.getParentFormName(); - try - { - // TODO - forms should be identified by nodeRef rather than name (which can be non-unique) - if (getNodeRef().getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_AVM)) - { - return this.getFormsService().getWebForm(parentFormName); - } - else - { - return this.getFormsService().getForm(parentFormName); - } - } - catch (FormNotFoundException fnfe) - { - throw new FormNotFoundException(parentFormName, this); - } - } - - /** the node ref containing the contents of this rendition */ - public NodeRef getNodeRef() - { - return this.nodeRef; - } - - public String getUrl() - { - return AVMUtil.getPreviewURI(this.getPath()); - } - - public List regenerateRenditions() - throws FormNotFoundException - { - if (logger.isDebugEnabled()) - logger.debug("regenerating renditions of " + this); - - AVMLockingService avmLockService = this.getServiceRegistry().getAVMLockingService(); - final AVMService avmService = this.getServiceRegistry().getAVMService(); - PropertyValue pv = avmService.getNodeProperty( - AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getFirst(), - AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond(), - WCMAppModel.PROP_ORIGINAL_PARENT_PATH); - - String originalParentAvmPath = (pv == null) ? - AVMNodeConverter.SplitBase(this.getPath())[0] : pv.getStringValue(); - - final HashSet allRets = - new HashSet(this.getForm().getRenderingEngineTemplates()); - final List result = new LinkedList(); - // regenerate existing renditions - boolean renditionLockedBefore = false; - String path = null; - - for (final Rendition r : this.getRenditions()) - { - // Try to skip renditions without rendering engine template. - if (r instanceof RenditionImpl) - { - RenditionImpl rImpl = (RenditionImpl)r; - RenderingEngineTemplate ret = rImpl.getRenderingEngineTemplate(); - if ((ret != null) && (ret instanceof RenderingEngineTemplateImpl)) - { - RenderingEngineTemplateImpl retImpl = (RenderingEngineTemplateImpl) ret; - if (!retImpl.isExists()) - { - continue; - } - } - - } - final RenderingEngineTemplate ret = r.getRenderingEngineTemplate(); - if (ret == null || !allRets.contains(ret)) - { - continue; - } - try - { - if (logger.isDebugEnabled()) - logger.debug("regenerating rendition " + r + " using template " + ret); - - renditionLockedBefore = false; - path = r.getPath(); - AVMLock lock = avmLockService.getLock(AVMUtil.getStoreId(path), AVMUtil.getStoreRelativePath(path)); - if (lock != null) - { - renditionLockedBefore = true; - - if (logger.isDebugEnabled()) - logger.debug("Lock already exists for " + path); - } - - ret.render(this, r); - allRets.remove(ret); - result.add(new RegenerateResult(ret, path, r)); - } - catch (Exception e) - { - result.add(new RegenerateResult(ret, path, e)); - - // remove lock if there wasn't one before - if (renditionLockedBefore == false) - { - avmLockService.removeLock(AVMUtil.getStoreId(path), AVMUtil.getStoreRelativePath(path)); - - if (logger.isDebugEnabled()) - logger.debug("Removed lock for " + path + " as it failed to generate"); - } - } - } - - // render all renditions for newly added templates - for (final RenderingEngineTemplate ret : allRets) - { - try - { - renditionLockedBefore = false; - path = ret.getOutputPathForRendition(this, originalParentAvmPath, getName()); - - if (logger.isDebugEnabled()) - logger.debug("regenerating rendition of " + this.getPath() + - " at " + path + " using template " + ret); - - AVMLock lock = avmLockService.getLock(AVMUtil.getStoreId(path), AVMUtil.getStoreRelativePath(path)); - if (lock != null) - { - renditionLockedBefore = true; - - if (logger.isDebugEnabled()) - logger.debug("Lock already exists for " + path); - } - - result.add(new RegenerateResult(ret, path, ret.render(this, path))); - } - catch (Exception e) - { - result.add(new RegenerateResult(ret, path, e)); - - // remove lock if there wasn't one before - if (renditionLockedBefore == false) - { - avmLockService.removeLock(AVMUtil.getStoreId(path), AVMUtil.getStoreRelativePath(path)); - - if (logger.isDebugEnabled()) - logger.debug("Removed lock for " + path + " as it failed to generate"); - } - } - } - return result; - } - - public List getRenditions() - { - final AVMService avmService = this.getServiceRegistry().getAVMLockingAwareService(); - 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 = AVMUtil.getStoreName(this.getPath()); - final List result = new ArrayList(renditionPaths.size()); - for (Serializable path : renditionPaths) - { - if (avmService.lookup(-1, storeName + ':' + (String)path) == null) - { - if (logger.isDebugEnabled()) - logger.debug("ignoring dangling rendition at " + storeName + ':' + (String)path); - } - else - { - final Rendition r = new RenditionImpl(-1, - storeName + ':' + (String)path, - this.getFormsService()); - try - { - if (!this.equals(r.getPrimaryFormInstanceData())) - { - if (logger.isDebugEnabled()) - logger.debug("rendition " + r + - " points at form instance data " + r.getPrimaryFormInstanceData() + - " instead of " + this + ". Not including in renditions list."); - continue; - } - } - catch (FileNotFoundException fnfe) - { - continue; - } - if (r.getRenderingEngineTemplate() != null) - { - result.add(r); - } - } - } - return result; - } - - private ServiceRegistry getServiceRegistry() - { - final FacesContext fc = FacesContext.getCurrentInstance(); - return Repository.getServiceRegistry(fc); - } - - public int hashCode() - { - return this.getPath().hashCode(); - } - - public String toString() - { - try - { - return (this.getClass().getName() + "{path : " + this.getPath() + - ", form : " + this.getForm().getName() + "}"); - } - catch (FormNotFoundException fnfe) - { - return (this.getClass().getName() + "{path : " + this.getPath() + - ", form : " + this.getParentFormName() + " NOT_FOUND! }"); - - } - } - - public boolean equals(final Object other) - { - return (other instanceof FormInstanceDataImpl && - this.getNodeRef().equals(((FormInstanceDataImpl)other).getNodeRef())); - - } - - protected String getParentFormName() - { - final AVMService avmService = this.getServiceRegistry().getAVMService(); - return avmService.getNodeProperty(AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getFirst(), - AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond(), - WCMAppModel.PROP_PARENT_FORM_NAME).getStringValue(); - } -} +/* + * Copyright (C) 2005-2009 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.forms; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; + +import javax.faces.context.FacesContext; + +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.avm.locking.AVMLock; +import org.alfresco.service.cmr.avm.locking.AVMLockingService; +import org.alfresco.service.cmr.dictionary.DataTypeDefinition; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.web.app.servlet.FacesHelper; +import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.bean.wcm.AVMUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Document; +import org.xml.sax.SAXException; + +/** + * Encapsulation of a rendition. + * + * @author Ariel Backenroth + */ +/* package */ class FormInstanceDataImpl implements FormInstanceData +{ + private static final long serialVersionUID = -7806221587661854013L; + + private static final Log logger = LogFactory.getLog(RenditionImpl.class); + + private final NodeRef nodeRef; + private transient FormsService formsService; + + /* package */ FormInstanceDataImpl(final NodeRef nodeRef, + final FormsService formsService) + { + if (nodeRef == null) + { + throw new NullPointerException(); + } + if (formsService == null) + { + throw new NullPointerException(); + } + final AVMService avmService = this.getServiceRegistry().getAVMService(); + if (!avmService.hasAspect(AVMNodeConverter.ToAVMVersionPath(nodeRef).getFirst(), + AVMNodeConverter.ToAVMVersionPath(nodeRef).getSecond(), + WCMAppModel.ASPECT_FORM_INSTANCE_DATA)) + { + throw new IllegalArgumentException("node " + nodeRef + + " does not have aspect " + WCMAppModel.ASPECT_FORM_INSTANCE_DATA); + } + this.nodeRef = nodeRef; + this.formsService = formsService; + } + + /* package */ FormInstanceDataImpl(final int version, + final String avmPath, + final FormsService formsService) + { + this(AVMNodeConverter.ToNodeRef(version, avmPath), formsService); + } + + private FormsService getFormsService() + { + if (formsService == null) + { + formsService = (FormsService) FacesHelper.getManagedBean(FacesContext.getCurrentInstance(), "FormsService"); + } + return formsService; + } + + /** the name of this rendition */ + public String getName() + { +// final AVMService avmService = this.getServiceRegistry().getAVMService(); +// return avmService.getNodeProperty(AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getFirst(), +// AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond(), +// ContentModel.PROP_NAME).getStringValue(); + return AVMNodeConverter.SplitBase(AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond())[1]; + } + + public String getWebappRelativePath() + { + return AVMUtil.getWebappRelativePath(this.getPath()); + } + + public String getSandboxRelativePath() + { + return AVMUtil.getSandboxRelativePath(this.getPath()); + } + + public String getPath() + { + return AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond(); + } + + public Document getDocument() + throws IOException, SAXException + { + return XMLUtil.parse(AVMNodeConverter.ToAVMVersionPath(nodeRef).getFirst(), + AVMNodeConverter.ToAVMVersionPath(nodeRef).getSecond(), + this.getServiceRegistry().getAVMService()); + } + + public Form getForm() + throws FormNotFoundException + { + final String parentFormName = this.getParentFormName(); + try + { + // TODO - forms should be identified by nodeRef rather than name (which can be non-unique) + if (getNodeRef().getStoreRef().getProtocol().equals(StoreRef.PROTOCOL_AVM)) + { + return this.getFormsService().getWebForm(parentFormName); + } + else + { + return this.getFormsService().getForm(parentFormName); + } + } + catch (FormNotFoundException fnfe) + { + throw new FormNotFoundException(parentFormName, this); + } + } + + /** the node ref containing the contents of this rendition */ + public NodeRef getNodeRef() + { + return this.nodeRef; + } + + public String getUrl() + { + return AVMUtil.getPreviewURI(this.getPath()); + } + + public List regenerateRenditions() + throws FormNotFoundException + { + if (logger.isDebugEnabled()) + { + logger.debug("regenerating renditions of " + this); + } + + AVMLockingService avmLockService = this.getServiceRegistry().getAVMLockingService(); + final AVMService avmService = this.getServiceRegistry().getAVMService(); + PropertyValue pv = avmService.getNodeProperty( + AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getFirst(), + AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond(), + WCMAppModel.PROP_ORIGINAL_PARENT_PATH); + + String originalParentAvmPath = (pv == null) ? + AVMNodeConverter.SplitBase(this.getPath())[0] : pv.getStringValue(); + + final HashSet allRets = + new HashSet(this.getForm().getRenderingEngineTemplates()); + final List result = new LinkedList(); + // regenerate existing renditions + boolean renditionLockedBefore = false; + String path = null; + + for (final Rendition r : this.getRenditions()) + { + // Try to skip renditions without rendering engine template. + if (r instanceof RenditionImpl) + { + RenditionImpl rImpl = (RenditionImpl)r; + RenderingEngineTemplate ret = rImpl.getRenderingEngineTemplate(); + if ((ret != null) && (ret instanceof RenderingEngineTemplateImpl)) + { + RenderingEngineTemplateImpl retImpl = (RenderingEngineTemplateImpl) ret; + if (!retImpl.isExists()) + { + continue; + } + } + + } + final RenderingEngineTemplate ret = r.getRenderingEngineTemplate(); + if (ret == null || !allRets.contains(ret)) + { + continue; + } + try + { + if (logger.isDebugEnabled()) + { + logger.debug("regenerating rendition " + r + " using template " + ret); + } + + renditionLockedBefore = false; + path = r.getPath(); + AVMLock lock = avmLockService.getLock(AVMUtil.getStoreId(path), AVMUtil.getStoreRelativePath(path)); + if (lock != null) + { + renditionLockedBefore = true; + + if (logger.isDebugEnabled()) + { + logger.debug("Lock already exists for " + path); + } + } + + ret.render(this, r); + allRets.remove(ret); + result.add(new RegenerateResult(ret, path, r)); + } + catch (Exception e) + { + result.add(new RegenerateResult(ret, path, e)); + + // remove lock if there wasn't one before + if (renditionLockedBefore == false) + { + avmLockService.removeLock(AVMUtil.getStoreId(path), AVMUtil.getStoreRelativePath(path)); + + if (logger.isDebugEnabled()) + { + logger.debug("Removed lock for " + path + " as it failed to generate"); + } + } + } + } + + // render all renditions for newly added templates + for (final RenderingEngineTemplate ret : allRets) + { + try + { + renditionLockedBefore = false; + path = ret.getOutputPathForRendition(this, originalParentAvmPath, getName()); + + if (logger.isDebugEnabled()) + { + logger.debug("regenerating rendition of " + this.getPath() + + " at " + path + " using template " + ret); + } + + AVMLock lock = avmLockService.getLock(AVMUtil.getStoreId(path), AVMUtil.getStoreRelativePath(path)); + if (lock != null) + { + renditionLockedBefore = true; + + if (logger.isDebugEnabled()) + { + logger.debug("Lock already exists for " + path); + } + } + + result.add(new RegenerateResult(ret, path, ret.render(this, path))); + } + catch (Exception e) + { + result.add(new RegenerateResult(ret, path, e)); + + // remove lock if there wasn't one before + if (renditionLockedBefore == false) + { + avmLockService.removeLock(AVMUtil.getStoreId(path), AVMUtil.getStoreRelativePath(path)); + + if (logger.isDebugEnabled()) + { + logger.debug("Removed lock for " + path + " as it failed to generate"); + } + } + } + } + return result; + } + + public List getRenditions() + { + return getRenditions(false); + } + + public List getRenditions(boolean includeDeleted) + { + final AVMService avmService = this.getServiceRegistry().getAVMLockingAwareService(); + 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 = AVMUtil.getStoreName(this.getPath()); + final List result = new ArrayList(renditionPaths.size()); + for (Serializable path : renditionPaths) + { + String avmRenditionPath = AVMUtil.buildAVMPath(storeName, (String)path); + if (avmService.lookup(-1, avmRenditionPath, includeDeleted) == null) + { + if (logger.isDebugEnabled()) + { + logger.debug("ignoring dangling rendition at: " + avmRenditionPath); + } + } + else + { + final Rendition r = new RenditionImpl(-1, + avmRenditionPath, + this.getFormsService()); + try + { + if (!this.equals(r.getPrimaryFormInstanceData(includeDeleted))) + { + if (logger.isDebugEnabled()) + { + logger.debug("rendition " + r + + " points at form instance data " + r.getPrimaryFormInstanceData(includeDeleted) + + " instead of " + this + ". Not including in renditions list."); + } + continue; + } + } + catch (FileNotFoundException fnfe) + { + continue; + } + if (r.getRenderingEngineTemplate() != null) + { + result.add(r); + } + } + } + return result; + } + + private ServiceRegistry getServiceRegistry() + { + final FacesContext fc = FacesContext.getCurrentInstance(); + return Repository.getServiceRegistry(fc); + } + + public int hashCode() + { + return this.getPath().hashCode(); + } + + public String toString() + { + try + { + return (this.getClass().getName() + "{path : " + this.getPath() + + ", form : " + this.getForm().getName() + "}"); + } + catch (FormNotFoundException fnfe) + { + return (this.getClass().getName() + "{path : " + this.getPath() + + ", form : " + this.getParentFormName() + " NOT_FOUND! }"); + + } + } + + public boolean equals(final Object other) + { + return (other instanceof FormInstanceDataImpl && + this.getNodeRef().equals(((FormInstanceDataImpl)other).getNodeRef())); + + } + + protected String getParentFormName() + { + final AVMService avmService = this.getServiceRegistry().getAVMService(); + return avmService.getNodeProperty(AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getFirst(), + AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond(), + WCMAppModel.PROP_PARENT_FORM_NAME).getStringValue(); + } +} diff --git a/source/java/org/alfresco/web/forms/Rendition.java b/source/java/org/alfresco/web/forms/Rendition.java index 2d01f606dd..dfad7610ef 100644 --- a/source/java/org/alfresco/web/forms/Rendition.java +++ b/source/java/org/alfresco/web/forms/Rendition.java @@ -1,87 +1,91 @@ -/* - * 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.forms; - -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.OutputStream; -import java.io.Serializable; -import org.xml.sax.SAXException; - -/** - * Encapsulation of a rendition. - * - * @author Ariel Backenroth - */ -public interface Rendition - extends Serializable -{ - /** the name of this rendition */ - public String getName(); - - /** the description of this rendition */ - public String getDescription(); - - /** the path relative to the containing webapp */ - public String getWebappRelativePath(); - - /** the path relative to the sandbox */ - public String getSandboxRelativePath(); - - /** the primary form instance data used to generate this rendition */ - public FormInstanceData getPrimaryFormInstanceData() - throws FileNotFoundException; - - /** the rendering engine template that generated this rendition */ - public RenderingEngineTemplate getRenderingEngineTemplate(); - - /** the path to the contents of this rendition */ - public String getPath(); - - /** the url to the asset */ - public String getUrl(); - - /** the file type image for the rendition */ - public String getFileTypeImage(); - - /** the output stream for the rendition */ - public OutputStream getOutputStream(); - - /** the HTML label attribute for UI */ - public String getLabelAttribute(); - - /** the HTML description attribute for UI */ - public String getDescriptionAttribute(); - - /** 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; -} +/* + * Copyright (C) 2005-2009 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.forms; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.OutputStream; +import java.io.Serializable; +import org.xml.sax.SAXException; + +/** + * Encapsulation of a rendition. + * + * @author Ariel Backenroth + */ +public interface Rendition + extends Serializable +{ + /** the name of this rendition */ + public String getName(); + + /** the description of this rendition */ + public String getDescription(); + + /** the path relative to the containing webapp */ + public String getWebappRelativePath(); + + /** the path relative to the sandbox */ + public String getSandboxRelativePath(); + + /** the primary form instance data used to generate this rendition */ + public FormInstanceData getPrimaryFormInstanceData() + throws FileNotFoundException; + + /** the primary form instance data used to generate this rendition (include deleted AVM nodes) */ + public FormInstanceData getPrimaryFormInstanceData(boolean includeDeleted) + throws FileNotFoundException; + + /** the rendering engine template that generated this rendition */ + public RenderingEngineTemplate getRenderingEngineTemplate(); + + /** the path to the contents of this rendition */ + public String getPath(); + + /** the url to the asset */ + public String getUrl(); + + /** the file type image for the rendition */ + public String getFileTypeImage(); + + /** the output stream for the rendition */ + public OutputStream getOutputStream(); + + /** the HTML label attribute for UI */ + public String getLabelAttribute(); + + /** the HTML description attribute for UI */ + public String getDescriptionAttribute(); + + /** 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 4cb64daf19..2f387d3565 100644 --- a/source/java/org/alfresco/web/forms/RenditionImpl.java +++ b/source/java/org/alfresco/web/forms/RenditionImpl.java @@ -135,6 +135,12 @@ import org.xml.sax.SAXException; } public FormInstanceData getPrimaryFormInstanceData() + throws FileNotFoundException + { + return getPrimaryFormInstanceData(false); + } + + public FormInstanceData getPrimaryFormInstanceData(boolean includeDeleted) throws FileNotFoundException { final AVMService avmService = this.getServiceRegistry().getAVMLockingAwareService(); @@ -145,7 +151,7 @@ import org.xml.sax.SAXException; String avmStore = AVMNodeConverter.ToAVMVersionPath(this.nodeRef).getSecond(); avmStore = avmStore.substring(0, avmStore.indexOf(':')); final String path = avmStore + ':' + fidAVMStoreRelativePath; - if (avmService.lookup(-1, path) == null) + if (avmService.lookup(-1, path, includeDeleted) == null) { throw new FileNotFoundException("unable to find primary form instance data " + path); }