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 }