001 // Copyright 2007 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 015 package org.apache.hivemind.impl; 016 017 import java.util.Iterator; 018 019 import org.apache.commons.logging.Log; 020 import org.apache.commons.logging.LogFactory; 021 import org.apache.hivemind.ErrorHandler; 022 import org.apache.hivemind.Location; 023 import org.apache.hivemind.definition.ConfigurationParserDefinition; 024 import org.apache.hivemind.definition.ConfigurationPointDefinition; 025 import org.apache.hivemind.definition.ContributionDefinition; 026 import org.apache.hivemind.definition.DefinitionMessages; 027 import org.apache.hivemind.definition.ModuleDefinition; 028 import org.apache.hivemind.definition.RegistryDefinition; 029 import org.apache.hivemind.definition.ImplementationDefinition; 030 import org.apache.hivemind.definition.InterceptorDefinition; 031 import org.apache.hivemind.definition.ServicePointDefinition; 032 import org.apache.hivemind.definition.UnresolvedExtension; 033 import org.apache.hivemind.definition.Visibility; 034 import org.apache.hivemind.util.IdUtils; 035 036 /** 037 * Resolves the {@link UnresolvedExtension unresolved extensions} in all 038 * modules of a {@link RegistryDefinition} during 039 * the construction of a registry by {@link RegistryBuilder}. 040 * Every unresolved extension (e.g. contribution, interceptor) references 041 * an extension point by its fully qualified id. This class looks for these 042 * extension points in the registry definition and adds the formerly unresolved 043 * extension directly to the extension points. 044 * The error handling is delegated to an instance of {@link ErrorHandler}. 045 * 046 * @author Achim Huegen 047 */ 048 public class ExtensionResolver 049 { 050 private static final Log LOG = LogFactory.getLog(ExtensionResolver.class); 051 052 private ErrorHandler _errorHandler; 053 054 private RegistryDefinition _definition; 055 056 public ExtensionResolver(RegistryDefinition definition, ErrorHandler errorHandler) 057 { 058 _errorHandler = errorHandler; 059 _definition = definition; 060 } 061 062 /** 063 * Resolves all unresolved extensions in the registry definition passed in the constructor. 064 * During this process the object graph represented by the registry definition is changed, 065 * so that afterwards it doesn't contain unresolved extensions any longer if anything went ok. 066 * If errors occur it depends on the assigned {@link ErrorHandler} whether an exceptions 067 * is raised or errors are logged only. In the latter case all extensions that couldn't 068 * be resolved will remain in the module definitions. 069 */ 070 public void resolveExtensions() 071 { 072 for (Iterator iterModules = _definition.getModules().iterator(); iterModules.hasNext();) 073 { 074 ModuleDefinition module = (ModuleDefinition) iterModules.next(); 075 076 resolveImplementations(module); 077 resolveInterceptors(module); 078 resolveContributions(module); 079 resolveConfigurationParsers(module); 080 } 081 } 082 083 private void resolveImplementations(ModuleDefinition module) 084 { 085 for (Iterator iter = module.getImplementations().iterator(); iter.hasNext();) 086 { 087 UnresolvedExtension unresolved = (UnresolvedExtension) iter.next(); 088 String servicePointId = unresolved.getExtensionPointId(); 089 if (LOG.isDebugEnabled()) { 090 LOG.debug("Trying to resolve service point " + servicePointId + " referenced by" + 091 " implementation" + logLocation(unresolved.getExtension().getLocation())); 092 } 093 ServicePointDefinition servicePoint = _definition.getServicePoint(servicePointId); 094 if (servicePoint == null) 095 { 096 _errorHandler.error( 097 LOG, 098 DefinitionMessages.unknownServicePoint( 099 IdUtils.extractModule(servicePointId), 100 IdUtils.stripModule(servicePointId)), 101 unresolved.getExtension().getLocation(), 102 null); 103 } else { 104 servicePoint.addImplementation((ImplementationDefinition) unresolved.getExtension()); 105 } 106 iter.remove(); 107 } 108 } 109 110 private String logLocation(Location location) 111 { 112 if (location == null) { 113 return ""; 114 } else { 115 return " at " + location.toString(); 116 } 117 } 118 119 private void resolveInterceptors(ModuleDefinition module) 120 { 121 for (Iterator iter = module.getInterceptors().iterator(); iter.hasNext();) 122 { 123 UnresolvedExtension unresolved = (UnresolvedExtension) iter.next(); 124 String servicePointId = unresolved.getExtensionPointId(); 125 if (LOG.isDebugEnabled()) { 126 LOG.debug("Trying to resolve service point " + servicePointId + " referenced by" + 127 " interceptor" + logLocation(unresolved.getExtension().getLocation())); 128 } 129 ServicePointDefinition servicePoint = _definition.getServicePoint(servicePointId); 130 if (servicePoint == null) 131 { 132 _errorHandler.error( 133 LOG, 134 DefinitionMessages.unknownServicePoint( 135 IdUtils.extractModule(servicePointId), 136 IdUtils.stripModule(servicePointId)), 137 unresolved.getExtension().getLocation(), 138 null); 139 } else { 140 servicePoint.addInterceptor((InterceptorDefinition) unresolved.getExtension()); 141 } 142 iter.remove(); 143 } 144 } 145 146 private void resolveContributions(ModuleDefinition module) 147 { 148 for (Iterator iter = module.getContributions().iterator(); iter.hasNext();) 149 { 150 UnresolvedExtension unresolved = (UnresolvedExtension) iter.next(); 151 String configurationPointId = unresolved.getExtensionPointId(); 152 if (LOG.isDebugEnabled()) { 153 LOG.debug("Trying to resolve configuration point " + configurationPointId + " referenced by" + 154 " contribution " + logLocation(unresolved.getExtension().getLocation())); 155 } 156 ConfigurationPointDefinition configurationPoint = _definition.getConfigurationPoint(configurationPointId); 157 if (configurationPoint == null) 158 { 159 _errorHandler.error( 160 LOG, 161 DefinitionMessages.unknownConfigurationPoint( 162 IdUtils.extractModule(configurationPointId), 163 IdUtils.stripModule(configurationPointId)), 164 unresolved.getExtension().getLocation(), 165 null); 166 } else { 167 configurationPoint.addContribution((ContributionDefinition) unresolved.getExtension()); 168 } 169 iter.remove(); 170 } 171 } 172 173 private void resolveConfigurationParsers(ModuleDefinition module) 174 { 175 for (Iterator iter = module.getConfigurationParsers().iterator(); iter.hasNext();) 176 { 177 UnresolvedExtension unresolved = (UnresolvedExtension) iter.next(); 178 String configurationPointId = unresolved.getExtensionPointId(); 179 if (LOG.isDebugEnabled()) { 180 LOG.debug("Trying to resolve configuration point " + configurationPointId + " referenced by" + 181 " ConfigurationParser " + logLocation(unresolved.getExtension().getLocation())); 182 } 183 ConfigurationPointDefinition configurationPoint = _definition.getConfigurationPoint(configurationPointId); 184 if (configurationPoint == null) 185 { 186 _errorHandler.error( 187 LOG, 188 DefinitionMessages.unknownConfigurationPoint( 189 IdUtils.extractModule(configurationPointId), 190 IdUtils.stripModule(configurationPointId)), 191 unresolved.getExtension().getLocation(), 192 null); 193 } else { 194 if (Visibility.PRIVATE.equals(configurationPoint.getVisibility()) 195 && !module.getId().equals(IdUtils.extractModule(configurationPointId))) { 196 _errorHandler.error( 197 LOG, 198 DefinitionMessages.configurationPointNotVisible( 199 configurationPoint, 200 module), 201 unresolved.getExtension().getLocation(), 202 null); 203 204 } 205 206 configurationPoint.addParser((ConfigurationParserDefinition) unresolved.getExtension()); 207 } 208 iter.remove(); 209 } 210 } 211 212 }