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.extraction.component; 017 018import java.util.Collections; 019import java.util.HashSet; 020import java.util.Map; 021import java.util.Set; 022 023import org.apache.avalon.framework.configuration.Configuration; 024import org.apache.avalon.framework.configuration.ConfigurationException; 025import org.apache.avalon.framework.service.ServiceException; 026import org.apache.avalon.framework.service.ServiceManager; 027import org.apache.cocoon.xml.AttributesImpl; 028import org.apache.cocoon.xml.XMLUtils; 029import org.xml.sax.ContentHandler; 030 031import org.ametys.cms.contenttype.ContentType; 032import org.ametys.cms.repository.Content; 033import org.ametys.core.util.I18nUtils; 034import org.ametys.plugins.extraction.ExtractionConstants; 035import org.ametys.plugins.extraction.execution.ExtractionExecutionContext; 036import org.ametys.plugins.extraction.execution.ExtractionExecutionContextHierarchyElement; 037import org.ametys.plugins.repository.AmetysObjectIterable; 038import org.ametys.plugins.thesaurus.Thesaurus; 039import org.ametys.plugins.thesaurus.ThesaurusDAO; 040import org.ametys.runtime.i18n.I18nizableText; 041 042/** 043 * This class represents a thesaurus component of the extraction module 044 */ 045public class ThesaurusExtractionComponent extends AbstractExtractionComponent 046{ 047 private String _microThesaurusId; 048 private Thesaurus _thesaurus; 049 private ContentType _microThesaurus; 050 private int _maxLevel; 051 052 private I18nUtils _i18nUtils; 053 054 @Override 055 public void service(ServiceManager serviceManager) throws ServiceException 056 { 057 super.service(serviceManager); 058 _i18nUtils = (I18nUtils) serviceManager.lookup(I18nUtils.ROLE); 059 } 060 061 @Override 062 public void configure(Configuration thesaurus) throws ConfigurationException 063 { 064 super.configure(thesaurus); 065 _microThesaurusId = thesaurus.getAttribute("microThesaurus"); 066 _maxLevel = thesaurus.getAttributeAsInteger("max-level", -1); 067 068 Set<String> ancestors = _contentTypesHelper.getAncestors(_microThesaurusId); 069 if (!ancestors.contains(ThesaurusDAO.MICROTHESAURUS_ABSTRACT_CONTENT_TYPE)) 070 { 071 throw new IllegalArgumentException(getLogsPrefix() + "'" + _microThesaurusId + "' is not a valid microthesaurus id"); 072 } 073 074 _initializeThesaurus(); 075 } 076 077 void _initializeThesaurus() 078 { 079 _microThesaurus = _contentTypeExtensionPoint.getExtension(_microThesaurusId); 080 _thesaurus = _thesaurusDAO.getParentThesaurus(_microThesaurus); 081 if (_thesaurus == null) 082 { 083 throw new IllegalArgumentException(getLogsPrefix() + "The microthesaurus '" + _microThesaurusId + "' has no attached thesaurus."); 084 } 085 } 086 087 @Override 088 public void executeComponent(ContentHandler contentHandler, ExtractionExecutionContext context) throws Exception 089 { 090 I18nizableText i18nLabel = _microThesaurus.getLabel(); 091 String label = _i18nUtils.translate(i18nLabel, null); // FIXME Use user preference language 092 093 AttributesImpl thesaurusAttributes = new AttributesImpl(); 094 thesaurusAttributes.addCDATAAttribute("thesaurusLabel", _thesaurus.getLabel()); 095 thesaurusAttributes.addCDATAAttribute("microThesaurusLabel", label); 096 thesaurusAttributes.addCDATAAttribute("microThesaurusId", _microThesaurusId); 097 XMLUtils.startElement(contentHandler, _tagName, thesaurusAttributes); 098 099 AmetysObjectIterable<Content> children = _thesaurusDAO.getRootTerms(_microThesaurusId); 100 _processChildren(contentHandler, children, 1, context); 101 102 XMLUtils.endElement(contentHandler, _tagName); 103 } 104 105 public Set<String> getContentTypes() 106 { 107 return new HashSet<>(Collections.singletonList(_microThesaurusId)); 108 } 109 110 private void _processChildren(ContentHandler contentHandler, AmetysObjectIterable<Content> children, int currentLevel, ExtractionExecutionContext context) throws Exception 111 { 112 long nbTermChildren = -1; 113 int currentChildIndex = 0; 114 if (getLogger().isDebugEnabled()) 115 { 116 nbTermChildren = children.getSize(); 117 } 118 119 for (Content term : children) 120 { 121 if (getLogger().isDebugEnabled()) 122 { 123 getLogger().debug(getLogsPrefix() + "executing term " + ++currentChildIndex + "/" + nbTermChildren + " at level " + currentLevel); 124 } 125 126 AttributesImpl attributes = new AttributesImpl(); 127 attributes.addCDATAAttribute("name", term.getTitle()); 128 XMLUtils.startElement(contentHandler, "term", attributes); 129 130 if (_maxLevel < 0 || currentLevel < _maxLevel) 131 { 132 ExtractionExecutionContextHierarchyElement currentContext = new ExtractionExecutionContextHierarchyElement(this, Collections.singleton(term), false); 133 executeSubComponents(contentHandler, context, currentContext); 134 _processChildren(contentHandler, _thesaurusDAO.getChildTerms(_microThesaurusId, term.getId()), currentLevel + 1, context); 135 } 136 else 137 { 138 ExtractionExecutionContextHierarchyElement currentContext = new ExtractionExecutionContextHierarchyElement(this, Collections.singleton(term)); 139 executeSubComponents(contentHandler, context, currentContext); 140 } 141 142 XMLUtils.endElement(contentHandler, "term"); 143 } 144 } 145 146 @Override 147 public Map<String, Object> getComponentDetailsForTree() 148 { 149 Map<String, Object> details = super.getComponentDetailsForTree(); 150 details.put("tag", ExtractionConstants.THESAURUS_COMPONENT_TAG); 151 152 @SuppressWarnings("unchecked") 153 Map<String, Object> data = (Map<String, Object>) details.get("data"); 154 data.put("thesaurusId", _thesaurus.getId()); 155 data.put("microThesaurusId", getMicroThesaurusId()); 156 data.put("maxLevel", this.getMaxLevel()); 157 details.put("iconCls", "ametysicon-books"); 158 159 return details; 160 } 161 162 @Override 163 protected String getDefaultTagName() 164 { 165 return "thesaurus"; 166 } 167 168 @Override 169 protected String getLogsPrefix() 170 { 171 return "Thesaurus component '" + _tagName + "': "; 172 } 173 174 /** 175 * Retrieves the component microthesaurus id 176 * @return The microthesaurus id 177 */ 178 public String getMicroThesaurusId() 179 { 180 return _microThesaurusId; 181 } 182 183 /** 184 * Set the microthesaurus id 185 * @param microThesaurusId The microthesaurus id to set 186 */ 187 public void setMicroThesaurusId(String microThesaurusId) 188 { 189 _microThesaurusId = microThesaurusId; 190 } 191 192 /** 193 * Retrieves the maximum level of specific terms to look at 194 * @return The maximum level 195 */ 196 public int getMaxLevel() 197 { 198 return _maxLevel; 199 } 200 201 /** 202 * Set the maximum level of specific terms to look at 203 * @param maxLevel The maximum level to set 204 */ 205 public void setMaxLevel(int maxLevel) 206 { 207 _maxLevel = maxLevel; 208 } 209}