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.lang3.ArrayUtils; 024 025import org.ametys.cms.ObservationConstants; 026import org.ametys.cms.content.ContentHelper; 027import org.ametys.cms.contenttype.ContentType; 028import org.ametys.cms.contenttype.ContentTypeExtensionPoint; 029import org.ametys.cms.contenttype.ContentTypesHelper; 030import org.ametys.cms.contenttype.MetadataDefinition; 031import org.ametys.cms.contenttype.MetadataType; 032import org.ametys.cms.repository.Content; 033import org.ametys.core.observation.Event; 034import org.ametys.core.observation.Observer; 035import org.ametys.odf.orgunit.OrgUnit; 036import org.ametys.odf.program.AbstractProgram; 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.plugin.component.AbstractLogEnabled; 046import org.ametys.web.repository.page.Page; 047import org.ametys.web.repository.page.PageQueryHelper; 048 049/** 050 * This observer clears the cache of enumerated {@link OrgUnit} values or {@link Content}s which are {@link ContentHelper#isReferenceTable(Content) part of reference table} 051 * when an {@link OrgUnit} or reference table content is added, modified, moved or deleted. 052 */ 053public class ClearLevelCacheObserver extends AbstractLogEnabled implements Observer, Serviceable 054{ 055 private ContentHelper _contentHelper; 056 private OdfClassificationHandler _odfClassificationHandler; 057 private AmetysObjectResolver _resolver; 058 private OdfPageHandler _odfPageHandler; 059 private ContentTypeExtensionPoint _cTypeEP; 060 private ContentTypesHelper _cTypesHelper; 061 062 @Override 063 public void service(ServiceManager manager) throws ServiceException 064 { 065 _contentHelper = (ContentHelper) manager.lookup(ContentHelper.ROLE); 066 _odfClassificationHandler = (OdfClassificationHandler) manager.lookup(OdfClassificationHandler.ROLE); 067 _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE); 068 _odfPageHandler = (OdfPageHandler) manager.lookup(OdfPageHandler.ROLE); 069 _cTypeEP = (ContentTypeExtensionPoint) manager.lookup(ContentTypeExtensionPoint.ROLE); 070 _cTypesHelper = (ContentTypesHelper) manager.lookup(ContentTypesHelper.ROLE); 071 } 072 073 @Override 074 public boolean supports(Event event) 075 { 076 String eventId = event.getId(); 077 Content content = (Content) event.getArguments().get(ObservationConstants.ARGS_CONTENT); 078 return (eventId.equals(ObservationConstants.EVENT_CONTENT_DELETING) 079 || eventId.equals(ObservationConstants.EVENT_CONTENT_MODIFIED/* handles moved orgUnit too */) 080 || eventId.equals(ObservationConstants.EVENT_CONTENT_ADDED)) 081 && content != null && (content instanceof OrgUnit || _contentHelper.isReferenceTable(content)); 082 } 083 084 @Override 085 public int getPriority(Event event) 086 { 087 return MAX_PRIORITY; 088 } 089 090 @Override 091 public void observe(Event event, Map<String, Object> transientVars) throws Exception 092 { 093 Content content = (Content) event.getArguments().get(ObservationConstants.ARGS_CONTENT); 094 if (content instanceof OrgUnit) 095 { 096 _odfClassificationHandler.clearLevelValues(AbstractProgram.ORG_UNITS_REFERENCES, content.getLanguage()); 097 } 098 else 099 { 100 // is reference table 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 String[] simpleContentTypes = content.getTypes(); 109 ContentType programCType = _cTypeEP.getExtension(ProgramFactory.PROGRAM_CONTENT_TYPE); 110 111 for (Page rootPage : rootPages) 112 { 113 String level1Metadata = _odfPageHandler.getLevel1Metadata(rootPage); 114 MetadataDefinition level1MetaDef = _cTypesHelper.getMetadataDefinition(level1Metadata, programCType); 115 String level2Metadata = _odfPageHandler.getLevel2Metadata(rootPage); 116 MetadataDefinition level2MetaDef = _cTypesHelper.getMetadataDefinition(level2Metadata, programCType); 117 if (level1MetaDef.getType() == MetadataType.CONTENT && ArrayUtils.contains(simpleContentTypes, level1MetaDef.getContentType())) 118 { 119 _odfClassificationHandler.clearLevelValues(level1Metadata, content.getLanguage()); 120 } 121 if (level2MetaDef.getType() == MetadataType.CONTENT && ArrayUtils.contains(simpleContentTypes, level2MetaDef.getContentType())) 122 { 123 _odfClassificationHandler.clearLevelValues(level2Metadata, content.getLanguage()); 124 } 125 } 126 } 127 } 128 129 /** 130 * Get the ODF root pages 131 * @return the ODF root pages 132 */ 133 protected AmetysObjectIterable<Page> _getODFRootPages() 134 { 135 Expression expression = new VirtualFactoryExpression(FirstLevelPageFactory.class.getName()); 136 String query = PageQueryHelper.getPageXPathQuery(null, null, null, expression, null); 137 138 return _resolver.query(query); 139 } 140}