11-22-2022 06:23 AM
I enabled for one document the property "cm:enableAutoVersionOnUpdateProps=true" and everything works as it should, but is there an "elegant" way to intercept the default versioning call and set a description on the version with a text like "Property X has been changed" ?
I had considered a behavior, but I'm having trouble retrieving the property in edit on the "OnCreateVersion" event.
11-24-2022 11:14 AM
My own solution, but is not pretty...
public void onCreateVersionVersionableAspectBehavior(QName classRef, NodeRef versionableNode, Map<String, Serializable> versionProperties, PolicyScope nodeDetails) { if(this.enable) { //logger.debug("START BEHAVIOUR METHOD '" + this.getClass().getSimpleName()+"' '"+new Object(){}.getClass().getEnclosingMethod().getName()+"'"); String currentusername = AuthenticationServiceUtilities.getCurrentLoginUsername(serviceRegistry); try { // Disable auditable aspect behaviourFilter.disableBehaviour(); // Disable rules ruleService.disableRules(); AuthenticationUtil.pushAuthentication(); AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Void>() { @Override public Void doWork() throws Exception { return TenantUtil.runAsTenant(new TenantUtil.TenantRunAsWork<Void>() { public Void doWork() throws Exception { try { // Disable auditable aspect behaviourFilter.disableBehaviour(); // Disable rules ruleService.disableRules(); // INIZIO CONTROLLI PRECHECK // tx commit, node might have been already removed... if (versionableNode == null || !nodeService.exists(versionableNode)) { logger.debug("Node '"+versionableNode+"' doesn't exist yet"); //throw new AlfrescoRuntimeException("Node '"+versionableNode+"' doesn't exist yet"); return null; } logger.debug("Noderef to check : "+versionableNode+", " + nodeService.getProperty(versionableNode, ContentModel.PROP_NAME)); if(nodeService.hasAspect(versionableNode, ContentModel.ASPECT_HIDDEN)) { logger.debug("Node '"+versionableNode+"' is hidden do nothing"); return null; } if(nodeService.hasAspect(versionableNode, RenditionModel.ASPECT_HIDDEN_RENDITION) || nodeService.hasAspect(versionableNode, RenditionModel.ASPECT_RENDITION2)){ logger.debug("Node '"+versionableNode+"' is a rendition do nothing"); return null; } if(AlfrescoLib.isThumbnail(versionableNode, nodeService, dictionaryService)) { logger.debug("Node '"+versionableNode+"' is thumbnail do nothing"); return null; } if(AlfrescoLib.isLink(versionableNode, nodeService, dictionaryService)) { logger.debug("Node '"+versionableNode+"' is link do nothing"); return null; } if(AlfrescoLib.isSite(versionableNode, nodeService, dictionaryService)) { logger.debug("Node '"+versionableNode+"' is site do nothing"); return null; } //VersionServiceUtilities.checkForCorruptedVersions(nodeRef, serviceRegistry); // CONTROLLA CLASSE {@link Version2ServiceImpl} PER DUBBI String versionComment = (String) versionProperties.get(Version.PROP_DESCRIPTION); if(StringUtils.isBlank((versionComment)) { //Map<QName,Serializable> before = nodeService.getProperties(versionableNode); //Map<QName,Serializable> after = nodeDetails.getProperties(); NodeRef old = VersionServiceUtilities.getUltimaVersione(versionableNode, serviceRegistry); Map<QName,Serializable> before = nodeService.getProperties(old); Map<QName,Serializable> after = nodeService.getProperties(versionableNode); // Mappa si supporto perche' la libreria di google fa una mappa "unmodifiable" Set<QName> qnameInModifica = new HashSet<QName>(); MapDifference<QName, Serializable> diff = Maps.difference(before, after); // Returns an unmodifiable map describing keys that appear in both maps, but with different values. Map<QName, ValueDifference<Serializable>> mapDiff = diff.entriesDiffering(); // Non basta per qualche strano motivo se i campi sono nulli alfresco non mi passa le proprieta' // devo fare un merge per quelli presenti dopo (after) , ma non presenti prima (before) Map<QName, Serializable> mapOnlyOnRight = diff.entriesOnlyOnRight(); qnameInModifica.addAll(mapDiff.keySet()); for(Map.Entry<QName,Serializable> entryDif : mapOnlyOnRight.entrySet()) { if(StringUtils.isNotBlank((String.valueOf(entryDif.getValue())) // Caso particolare per i valori booleani... && !String.valueOf(entryDif.getValue()).equalsIgnoreCase("false")) { qnameInModifica.add(entryDif.getKey()); } } //logger.debug("Proprieta' in modifica " + System.lineSeparator() + Arrays.toString(qnameInModifica.toArray())); Set<QName> proprietaNonDiAlfrescoInModifica = new HashSet<QName>(); // Filtiramo per tutte le proprieta' non di default di alfresco // e che hanno un namespace collegato in qualche modo alla conservazione // gli aspetti della classificazioni sono compresi for(QName q : qnameInModifica) { if(q != null) { // PER SICUREZZA MA NON DOVREBBE MAI SUCCEDERE QName qNameWithPrefix = q.getPrefixedQName(nameSpaceService); String prefix = QName.splitPrefixedQName(qNameWithPrefix.toPrefixString())[0]; if(prefix != null && //!NamespaceServiceUtilities.isAlfrescoDefaultPrefix(prefix) && !qNameWithPrefix.equals(Version2Model.PROP_QNAME_VERSION_DESCRIPTION) && !qNameWithPrefix.equals(Version2Model.PROP_QNAME_VERSION_NUMBER) && !qNameWithPrefix.equals(Version2Model.PROP_QNAME_VERSION_LABEL) && !qNameWithPrefix.equals(ContentModel.PROP_MODIFIED) ) { proprietaNonDiAlfrescoInModifica.add(q); } } } //if(proprietaNonDiAlfrescoInModifica.isEmpty()) { // //logger.debug("nessuna proprieta' non di default di alfresco trovata"); // return null; //} logger.debug("AGGIORNO VERSIONE COMMENTO SU PROPRIETA'"); //logger.debug("Proprieta' in modifica non di alfresco " + System.lineSeparator() + Arrays.toString(proprietaNonDiAlfrescoInModifica.toArray())); List<String> arrList = new ArrayList<String>(); for(QName q : proprietaNonDiAlfrescoInModifica) { String s = DictionaryServiceUtilities.getTitleFromQName(versionableNode, q, serviceRegistry); arrList.add(s); } String commentToInsert = "Modificato: " + String.join(",", arrList); logger.debug("AGGIORNO VERSIONE COMMENTO SU CREA VERSIONE' SU "+ classRef); versionProperties.put(Version.PROP_DESCRIPTION,commentToInsert); } return null; } catch (Throwable ex) { logger.error(ex.getMessage() + ", " + ex.getCause()); throw new AlfrescoRuntimeException(ex.getMessage() + ", " +ex.getCause(), ex); } finally { ruleService.enableRules(); behaviourFilter.enableBehaviour(); } } }, TenantUtil.getCurrentDomain()); } } ,AuthenticationUtil.getSystemUserName()); } finally { AuthenticationUtil.popAuthentication(); ruleService.enableRules(); behaviourFilter.enableBehaviour(); } //logger.debug("END BEHAVIOUR METHOD '" + this.getClass().getSimpleName()+"' '"+new Object(){}.getClass().getEnclosingMethod().getName()+"'"); }else { //logger.warn("Can't invoke the '"+new Object(){}.getClass().getEnclosingMethod().getName()+"' because the property 'enable' is false"); } }
11-24-2022 11:14 AM
My own solution, but is not pretty...
public void onCreateVersionVersionableAspectBehavior(QName classRef, NodeRef versionableNode, Map<String, Serializable> versionProperties, PolicyScope nodeDetails) { if(this.enable) { //logger.debug("START BEHAVIOUR METHOD '" + this.getClass().getSimpleName()+"' '"+new Object(){}.getClass().getEnclosingMethod().getName()+"'"); String currentusername = AuthenticationServiceUtilities.getCurrentLoginUsername(serviceRegistry); try { // Disable auditable aspect behaviourFilter.disableBehaviour(); // Disable rules ruleService.disableRules(); AuthenticationUtil.pushAuthentication(); AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Void>() { @Override public Void doWork() throws Exception { return TenantUtil.runAsTenant(new TenantUtil.TenantRunAsWork<Void>() { public Void doWork() throws Exception { try { // Disable auditable aspect behaviourFilter.disableBehaviour(); // Disable rules ruleService.disableRules(); // INIZIO CONTROLLI PRECHECK // tx commit, node might have been already removed... if (versionableNode == null || !nodeService.exists(versionableNode)) { logger.debug("Node '"+versionableNode+"' doesn't exist yet"); //throw new AlfrescoRuntimeException("Node '"+versionableNode+"' doesn't exist yet"); return null; } logger.debug("Noderef to check : "+versionableNode+", " + nodeService.getProperty(versionableNode, ContentModel.PROP_NAME)); if(nodeService.hasAspect(versionableNode, ContentModel.ASPECT_HIDDEN)) { logger.debug("Node '"+versionableNode+"' is hidden do nothing"); return null; } if(nodeService.hasAspect(versionableNode, RenditionModel.ASPECT_HIDDEN_RENDITION) || nodeService.hasAspect(versionableNode, RenditionModel.ASPECT_RENDITION2)){ logger.debug("Node '"+versionableNode+"' is a rendition do nothing"); return null; } if(AlfrescoLib.isThumbnail(versionableNode, nodeService, dictionaryService)) { logger.debug("Node '"+versionableNode+"' is thumbnail do nothing"); return null; } if(AlfrescoLib.isLink(versionableNode, nodeService, dictionaryService)) { logger.debug("Node '"+versionableNode+"' is link do nothing"); return null; } if(AlfrescoLib.isSite(versionableNode, nodeService, dictionaryService)) { logger.debug("Node '"+versionableNode+"' is site do nothing"); return null; } //VersionServiceUtilities.checkForCorruptedVersions(nodeRef, serviceRegistry); // CONTROLLA CLASSE {@link Version2ServiceImpl} PER DUBBI String versionComment = (String) versionProperties.get(Version.PROP_DESCRIPTION); if(StringUtils.isBlank((versionComment)) { //Map<QName,Serializable> before = nodeService.getProperties(versionableNode); //Map<QName,Serializable> after = nodeDetails.getProperties(); NodeRef old = VersionServiceUtilities.getUltimaVersione(versionableNode, serviceRegistry); Map<QName,Serializable> before = nodeService.getProperties(old); Map<QName,Serializable> after = nodeService.getProperties(versionableNode); // Mappa si supporto perche' la libreria di google fa una mappa "unmodifiable" Set<QName> qnameInModifica = new HashSet<QName>(); MapDifference<QName, Serializable> diff = Maps.difference(before, after); // Returns an unmodifiable map describing keys that appear in both maps, but with different values. Map<QName, ValueDifference<Serializable>> mapDiff = diff.entriesDiffering(); // Non basta per qualche strano motivo se i campi sono nulli alfresco non mi passa le proprieta' // devo fare un merge per quelli presenti dopo (after) , ma non presenti prima (before) Map<QName, Serializable> mapOnlyOnRight = diff.entriesOnlyOnRight(); qnameInModifica.addAll(mapDiff.keySet()); for(Map.Entry<QName,Serializable> entryDif : mapOnlyOnRight.entrySet()) { if(StringUtils.isNotBlank((String.valueOf(entryDif.getValue())) // Caso particolare per i valori booleani... && !String.valueOf(entryDif.getValue()).equalsIgnoreCase("false")) { qnameInModifica.add(entryDif.getKey()); } } //logger.debug("Proprieta' in modifica " + System.lineSeparator() + Arrays.toString(qnameInModifica.toArray())); Set<QName> proprietaNonDiAlfrescoInModifica = new HashSet<QName>(); // Filtiramo per tutte le proprieta' non di default di alfresco // e che hanno un namespace collegato in qualche modo alla conservazione // gli aspetti della classificazioni sono compresi for(QName q : qnameInModifica) { if(q != null) { // PER SICUREZZA MA NON DOVREBBE MAI SUCCEDERE QName qNameWithPrefix = q.getPrefixedQName(nameSpaceService); String prefix = QName.splitPrefixedQName(qNameWithPrefix.toPrefixString())[0]; if(prefix != null && //!NamespaceServiceUtilities.isAlfrescoDefaultPrefix(prefix) && !qNameWithPrefix.equals(Version2Model.PROP_QNAME_VERSION_DESCRIPTION) && !qNameWithPrefix.equals(Version2Model.PROP_QNAME_VERSION_NUMBER) && !qNameWithPrefix.equals(Version2Model.PROP_QNAME_VERSION_LABEL) && !qNameWithPrefix.equals(ContentModel.PROP_MODIFIED) ) { proprietaNonDiAlfrescoInModifica.add(q); } } } //if(proprietaNonDiAlfrescoInModifica.isEmpty()) { // //logger.debug("nessuna proprieta' non di default di alfresco trovata"); // return null; //} logger.debug("AGGIORNO VERSIONE COMMENTO SU PROPRIETA'"); //logger.debug("Proprieta' in modifica non di alfresco " + System.lineSeparator() + Arrays.toString(proprietaNonDiAlfrescoInModifica.toArray())); List<String> arrList = new ArrayList<String>(); for(QName q : proprietaNonDiAlfrescoInModifica) { String s = DictionaryServiceUtilities.getTitleFromQName(versionableNode, q, serviceRegistry); arrList.add(s); } String commentToInsert = "Modificato: " + String.join(",", arrList); logger.debug("AGGIORNO VERSIONE COMMENTO SU CREA VERSIONE' SU "+ classRef); versionProperties.put(Version.PROP_DESCRIPTION,commentToInsert); } return null; } catch (Throwable ex) { logger.error(ex.getMessage() + ", " + ex.getCause()); throw new AlfrescoRuntimeException(ex.getMessage() + ", " +ex.getCause(), ex); } finally { ruleService.enableRules(); behaviourFilter.enableBehaviour(); } } }, TenantUtil.getCurrentDomain()); } } ,AuthenticationUtil.getSystemUserName()); } finally { AuthenticationUtil.popAuthentication(); ruleService.enableRules(); behaviourFilter.enableBehaviour(); } //logger.debug("END BEHAVIOUR METHOD '" + this.getClass().getSimpleName()+"' '"+new Object(){}.getClass().getEnclosingMethod().getName()+"'"); }else { //logger.warn("Can't invoke the '"+new Object(){}.getClass().getEnclosingMethod().getName()+"' because the property 'enable' is false"); } }
Explore our Alfresco products with the links below. Use labels to filter content by product module.