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.lib.util; 016 017 /** 018 * An implementation of the <b>strategy </b> pattern. The strategy pattern allows new functionality 019 * to be assigned to an existing class. As implemented here, this is a smart lookup between a 020 * particular class (called the <em>subject class</em>) and some object instance that can provide 021 * the extra functionality (called the <em>strategy</em>). The implementation of the strategy is 022 * not relevant to the StrategyRegistry class. 023 * <p> 024 * Strategies are registered before they can be used; the registration maps a particular class to a 025 * strategy instance. The strategy instance will be used when the subject class matches the 026 * registered class, or the subject class inherits from the registered class. 027 * <p> 028 * This means that a search must be made that walks the inheritance tree (upwards from the subject 029 * class) to find a registered mapping. 030 * <p> 031 * In addition, strategies can be registered against <em>interfaces</em>. Searching of interfaces 032 * occurs after searching of classes. The exact order is: 033 * <ul> 034 * <li>Search for the subject class, then each super-class of the subject class (excluding 035 * java.lang.Object) 036 * <li>Search interfaces, starting with interfaces implemented by the subject class, continuing 037 * with interfaces implemented by the super-classes, then interfaces extended by earlier interfaces 038 * (the exact order is a bit fuzzy) 039 * <li>Search for a match for java.lang.Object, if any 040 * </ul> 041 * <p> 042 * The first match terminates the search. 043 * <p> 044 * The StrategyRegistry caches the results of search; a subsequent search for the same subject class 045 * will be resolved immediately. 046 * <p> 047 * StrategyRegistry does a minor tweak of the "natural" inheritance. Normally, the parent class of 048 * an object array (i.e., <code>Foo[]</code>) is simply <code>Object</code>, even though you 049 * may assign <code>Foo[]</code> to a variable of type <code>Object[]</code>. StrategyRegistry 050 * "fixes" this by searching for <code>Object[]</code> as if it was the superclass of any object 051 * array. This means that the search path for <code>Foo[]</code> is <code>Foo[]</code>, 052 * <code>Object[]</code>, then a couple of interfaces {@link java.lang.Cloneable}, 053 * {@link java.io.Serializable}, etc. that are implicitily implemented by arrays), and then, 054 * finally, <code>Object</code> 055 * <p> 056 * This tweak doesn't apply to arrays of primitives, since such arrays may <em>not</em> be 057 * assigned to <code>Object[]</code>. 058 * 059 * @author Howard M. Lewis Ship 060 * @see org.apache.hivemind.lib.util.StrategyRegistryImpl 061 * @since 1.1 062 */ 063 public interface StrategyRegistry 064 { 065 /** 066 * Registers an adapter for a registration class. 067 * 068 * @throws IllegalArgumentException 069 * if a strategy has already been registered for the given class. 070 */ 071 public void register(Class registrationClass, Object strategy); 072 073 /** 074 * Gets the stategy object for the specified subjectClass. 075 * 076 * @throws IllegalArgumentException 077 * if no strategy could be found. 078 */ 079 public Object getStrategy(Class subjectClass); 080 }