001 // Copyright 2004, 2005 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.service.impl; 016 017 import org.apache.commons.logging.Log; 018 import org.apache.hivemind.ServiceImplementationFactoryParameters; 019 import org.apache.hivemind.impl.BaseLocatable; 020 import org.apache.hivemind.util.PropertyUtils; 021 022 /** 023 * Represents one facet of constructing a service implementation instance. A facet is either a 024 * property to be set on the constructed instance, or a parameter to the instance class' 025 * constructor. Facets are nested properties within 026 * {@link org.apache.hivemind.service.impl.BuilderParameter}, and are used by 027 * {@link org.apache.hivemind.service.impl.BuilderFactory}. 028 * 029 * @author Howard Lewis Ship 030 */ 031 public abstract class BuilderFacet extends BaseLocatable 032 { 033 private String _propertyName; 034 035 /** 036 * Implemented in subclasses to provide a specific value for the facet (for use as a constructor 037 * parameter, or as a value to set a property to). 038 * 039 * @param factoryParameters 040 * the parameters that define the service point and its environment 041 * @param targetType 042 * the desired property type (extracted from the property type of the property to be 043 * updated, when a property is known) 044 */ 045 public abstract Object getFacetValue(ServiceImplementationFactoryParameters factoryParameters, 046 Class targetType); 047 048 public abstract boolean isAssignableToType( 049 ServiceImplementationFactoryParameters factoryParameters, Class targetType); 050 051 public String getPropertyName() 052 { 053 return _propertyName; 054 } 055 056 public void setPropertyName(String string) 057 { 058 _propertyName = string; 059 } 060 061 /** 062 * Attempts to autowire a property of the target. This requires that 063 * <ul> 064 * <li>The facet type defines a default property name and facet type 065 * <li>The facet instance does not have a specified property name 066 * <li>The (default) property is writeable 067 * <li>The (default) property is assignable from the facet type 068 * </ul> 069 * If all conditions are met, then the property is updated to the facet value, and the property 070 * name is returned. In all other cases, null is returned. 071 * 072 * @param target 073 * The service implementation being constructed 074 * @param factoryParameters 075 * the parameters that define the service point and its environment 076 */ 077 public String autowire(Object target, ServiceImplementationFactoryParameters factoryParameters) 078 { 079 if (_propertyName != null) 080 return null; 081 082 String defaultPropertyName = getDefaultPropertyName(); 083 084 if (defaultPropertyName == null) 085 return null; 086 087 if (!PropertyUtils.isWritable(target, defaultPropertyName)) 088 return null; 089 090 Class propertyType = PropertyUtils.getPropertyType(target, defaultPropertyName); 091 092 if (isAssignableToType(factoryParameters, propertyType)) 093 { 094 Object facetValue = getFacetValue(factoryParameters, propertyType); 095 096 PropertyUtils.write(target, defaultPropertyName, facetValue); 097 098 Log log = factoryParameters.getLog(); 099 100 if (log.isDebugEnabled()) 101 log.debug("Autowired property " + defaultPropertyName + " to " + facetValue); 102 103 return defaultPropertyName; 104 } 105 106 return null; 107 } 108 109 /** 110 * Returns null. Subclasses can provide the default name for a property used by 111 * {@link #autowire(Object, ServiceImplementationFactoryParameters)}. 112 */ 113 protected String getDefaultPropertyName() 114 { 115 return null; 116 } 117 118 /** @since 1.1 */ 119 public boolean canAutowireConstructorParameter() 120 { 121 return false; 122 } 123 124 }