Java tutorial
// Copyright 2006 The Apache Software Foundation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package org.ops4j.gaderian.service.impl; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.apache.commons.logging.Log; import org.ops4j.gaderian.AssemblyInstruction; import org.ops4j.gaderian.AssemblyParameters; import org.ops4j.gaderian.Gaderian; import org.ops4j.gaderian.impl.BaseLocatable; import org.ops4j.gaderian.internal.Module; import org.ops4j.gaderian.service.EventLinker; import org.ops4j.gaderian.util.PropertyUtils; /** * Implements support for explicit and implicit (autowiring) dependency injection, event * registration, and service initialization for core service implementation objects. Instances * correspond to the <assembly> element as defined by the "gaderian.Assembly" * schema. * * @author Knut Wannheden * @since 1.2 */ public class AssemblyInstructionImpl extends BaseLocatable implements AssemblyInstruction { private List<BuilderFacet> _properties = new ArrayList<BuilderFacet>(); private List<EventRegistration> _events = new ArrayList<EventRegistration>(); private String _initializeMethod; private boolean _autowireServices; /** @since gaderian-1.1 - always perform null checks by default */ private boolean _performNullChecks = true; public void addProperty(BuilderFacet facet) { _properties.add(facet); } public List getProperties() { return _properties; } public void addEventRegistration(EventRegistration registration) { _events.add(registration); } public List getEventRegistrations() { return _events; } public String getInitializeMethod() { return _initializeMethod; } public void setInitializeMethod(String string) { _initializeMethod = string; } public boolean getAutowireServices() { return _autowireServices; } public void setAutowireServices(boolean autowireServices) { _autowireServices = autowireServices; } public void assemble(Object service, AssemblyParameters assemblyParameters) { setProperties(service, assemblyParameters); registerForEvents(service, assemblyParameters); invokeInitializer(service, assemblyParameters); } private void setProperties(Object service, AssemblyParameters factoryParameters) { // Track the writeable properties, removing names as they are wired or autowired. Set writeableProperties = new HashSet(PropertyUtils.getWriteableProperties(service)); for (Iterator i = _properties.iterator(); i.hasNext();) { BuilderFacet facet = (BuilderFacet) i.next(); String propertyName = facet.wireProperty(service, factoryParameters); if (propertyName != null) writeableProperties.remove(propertyName); } if (_autowireServices) { for (Iterator i = writeableProperties.iterator(); i.hasNext();) { String propertyName = (String) i.next(); autowireService(service, propertyName, factoryParameters); } } } private void autowireService(Object service, String propertyName, AssemblyParameters factoryParameters) { Class propertyType = PropertyUtils.getPropertyType(service, propertyName); final Module invokingModule = factoryParameters.getInvokingModule(); final Log log = factoryParameters.getLog(); try { // Ignore properties for which there are no corresponding // service points... if (invokingModule.containsService(propertyType)) { Object collaboratingService = invokingModule.getService(propertyType); PropertyUtils.write(service, propertyName, collaboratingService); if (log.isDebugEnabled()) { log.debug("Autowired service property " + propertyName + " to " + collaboratingService); } } } catch (Exception ex) { invokingModule.getErrorHandler().error(log, ServiceMessages.autowirePropertyFailure(propertyName, factoryParameters.getServiceId(), ex), getLocation(), ex); } } private void registerForEvents(Object result, AssemblyParameters factoryParameters) { List eventRegistrations = getEventRegistrations(); if (eventRegistrations.isEmpty()) return; EventLinker linker = new EventLinkerImpl(factoryParameters.getErrorLog()); Iterator i = eventRegistrations.iterator(); while (i.hasNext()) { EventRegistration er = (EventRegistration) i.next(); // Will log any errors to the errorHandler linker.addEventListener(er.getProducer(), er.getEventSetName(), result, er.getLocation()); } } private void invokeInitializer(Object service, AssemblyParameters factoryParameters) { String methodName = getInitializeMethod(); boolean allowMissing = Gaderian.isBlank(methodName); String searchMethodName = allowMissing ? "initializeService" : methodName; try { findAndInvokeInitializerMethod(service, searchMethodName, allowMissing); } catch (InvocationTargetException ex) { Throwable cause = ex.getTargetException(); factoryParameters.getErrorLog() .error(ServiceMessages.unableToInitializeService(factoryParameters.getServiceId(), searchMethodName, service.getClass(), cause), getLocation(), cause); } catch (Exception ex) { factoryParameters.getErrorLog().error(ServiceMessages.unableToInitializeService( factoryParameters.getServiceId(), searchMethodName, service.getClass(), ex), getLocation(), ex); } } private void findAndInvokeInitializerMethod(Object service, String methodName, boolean allowMissing) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { Class serviceClass = service.getClass(); try { Method m = serviceClass.getMethod(methodName, null); m.invoke(service, null); } catch (NoSuchMethodException ex) { if (allowMissing) return; throw ex; } } public void setPerformNullChecks(final boolean performNullChecks) { _performNullChecks = performNullChecks; } public boolean getPerformNullChecks() { return _performNullChecks; } }