001/* 002 * Copyright 2017 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.odfweb.observation; 017 018import java.util.Map; 019 020import org.apache.avalon.framework.service.ServiceException; 021import org.apache.avalon.framework.service.ServiceManager; 022import org.apache.avalon.framework.service.Serviceable; 023import org.apache.commons.lang.StringUtils; 024import org.apache.commons.lang3.ArrayUtils; 025 026import org.ametys.cms.ObservationConstants; 027import org.ametys.cms.content.ContentHelper; 028import org.ametys.cms.contenttype.ContentAttributeDefinition; 029import org.ametys.cms.contenttype.ContentType; 030import org.ametys.cms.contenttype.ContentTypeExtensionPoint; 031import org.ametys.cms.repository.Content; 032import org.ametys.core.observation.Event; 033import org.ametys.core.observation.Observer; 034import org.ametys.odf.ProgramItem; 035import org.ametys.odf.enumeration.OdfReferenceTableHelper; 036import org.ametys.odf.orgunit.OrgUnit; 037import org.ametys.odf.program.ProgramFactory; 038import org.ametys.odf.tree.OdfClassificationHandler; 039import org.ametys.plugins.odfweb.repository.FirstLevelPageFactory; 040import org.ametys.plugins.odfweb.repository.OdfPageHandler; 041import org.ametys.plugins.repository.AmetysObjectIterable; 042import org.ametys.plugins.repository.AmetysObjectResolver; 043import org.ametys.plugins.repository.query.expression.Expression; 044import org.ametys.plugins.repository.query.expression.VirtualFactoryExpression; 045import org.ametys.runtime.model.ModelItem; 046import org.ametys.runtime.plugin.component.AbstractLogEnabled; 047import org.ametys.web.repository.page.Page; 048import org.ametys.web.repository.page.PageQueryHelper; 049 050/** 051 * This observer clears the cache of enumerated {@link OrgUnit} values or {@link Content}s which are {@link ContentHelper#isReferenceTable(Content) part of reference table} 052 * when an {@link OrgUnit} or reference table content is added, modified, moved or deleted. 053 */ 054public class ClearLevelCacheObserver extends AbstractLogEnabled implements Observer, Serviceable 055{ 056 private ContentHelper _contentHelper; 057 private OdfClassificationHandler _odfClassificationHandler; 058 private AmetysObjectResolver _resolver; 059 private OdfPageHandler _odfPageHandler; 060 private ContentTypeExtensionPoint _cTypeEP; 061 private OdfReferenceTableHelper _odfReferenceTableHelper; 062 063 @Override 064 public void service(ServiceManager manager) throws ServiceException 065 { 066 _contentHelper = (ContentHelper) manager.lookup(ContentHelper.ROLE); 067 _odfClassificationHandler = (OdfClassificationHandler) manager.lookup(OdfClassificationHandler.ROLE); 068 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 069 _odfPageHandler = (OdfPageHandler) manager.lookup(OdfPageHandler.ROLE); 070 _cTypeEP = (ContentTypeExtensionPoint) manager.lookup(ContentTypeExtensionPoint.ROLE); 071 _odfReferenceTableHelper = (OdfReferenceTableHelper) manager.lookup(OdfReferenceTableHelper.ROLE); 072 } 073 074 @Override 075 public boolean supports(Event event) 076 { 077 String eventId = event.getId(); 078 Content content = (Content) event.getArguments().get(ObservationConstants.ARGS_CONTENT); 079 return (eventId.equals(ObservationConstants.EVENT_CONTENT_DELETING) 080 || eventId.equals(ObservationConstants.EVENT_CONTENT_MODIFIED/* handles moved orgUnit too */) 081 || eventId.equals(ObservationConstants.EVENT_CONTENT_ADDED)) 082 && content != null && (content instanceof OrgUnit || _contentHelper.isReferenceTable(content)); 083 } 084 085 @Override 086 public int getPriority(Event event) 087 { 088 return MAX_PRIORITY; 089 } 090 091 @Override 092 public void observe(Event event, Map<String, Object> transientVars) throws Exception 093 { 094 Content content = (Content) event.getArguments().get(ObservationConstants.ARGS_CONTENT); 095 if (content instanceof OrgUnit) 096 { 097 _odfClassificationHandler.clearLevelValues(ProgramItem.ORG_UNITS_REFERENCES, content.getLanguage()); 098 } 099 else 100 { 101 AmetysObjectIterable<Page> rootPages = _getODFRootPages(); 102 if (rootPages.getSize() == 0) 103 { 104 getLogger().debug("There is no ODF root page, nothing to invalidate"); 105 return; 106 } 107 108 if (_odfReferenceTableHelper.isTableReferenceEntry(content)) 109 { 110 // The target content is an entry of a reference table 111 for (Page rootPage : rootPages) 112 { 113 String level1Attribute = _odfPageHandler.getLevel1Metadata(rootPage); 114 if (_isPartOfClassification(content, level1Attribute)) 115 { 116 _odfClassificationHandler.clearLevelValues(level1Attribute, null); 117 } 118 119 String level2Attribute = _odfPageHandler.getLevel2Metadata(rootPage); 120 if (_isPartOfClassification(content, level2Attribute)) 121 { 122 _odfClassificationHandler.clearLevelValues(level2Attribute, null); 123 } 124 } 125 126 } 127 } 128 } 129 130 private boolean _isPartOfClassification(Content targetContent, String attributName) 131 { 132 if (StringUtils.isNotEmpty(attributName)) 133 { 134 ContentType programCType = _cTypeEP.getExtension(ProgramFactory.PROGRAM_CONTENT_TYPE); 135 136 if (programCType.hasModelItem(attributName)) 137 { 138 ModelItem modelItem = programCType.getModelItem(attributName); 139 140 if (modelItem instanceof ContentAttributeDefinition) 141 { 142 return ArrayUtils.contains(targetContent.getTypes(), ((ContentAttributeDefinition) modelItem).getContentTypeId()); 143 } 144 } 145 } 146 147 return false; 148 } 149 150 /** 151 * Get the ODF root pages 152 * @return the ODF root pages 153 */ 154 protected AmetysObjectIterable<Page> _getODFRootPages() 155 { 156 Expression expression = new VirtualFactoryExpression(FirstLevelPageFactory.class.getName()); 157 String query = PageQueryHelper.getPageXPathQuery(null, null, null, expression, null); 158 159 return _resolver.query(query); 160 } 161}