001 /* 002 * Copyright 2002-2004 The Apache Software Foundation 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.apache.commons.clazz.common; 017 018 import java.util.ArrayList; 019 import java.util.Collections; 020 import java.util.List; 021 022 import org.apache.commons.clazz.Clazz; 023 import org.apache.commons.clazz.ClazzLoader; 024 import org.apache.commons.clazz.ModelClazzLoader; 025 026 /** 027 * Aggregates multiple ClazzLoaders, which are invoked one after another 028 * according to the ChainOfResponsibility pattern. Note that member clazz 029 * loaders are invoked in the order reverse to the order they were added. 030 * 031 * @author <a href="mailto:dmitri@apache.org">Dmitri Plotnikov</a> 032 * @version $Id: GroupClazzLoader.java 155436 2005-02-26 13:17:48Z dirkv $ 033 */ 034 public class GroupClazzLoader extends ClazzLoader { 035 /** 036 * List of member loaders. Note that the list is always iterated in the 037 * reverse direction, so the loaded add last is the one invoked first. 038 */ 039 protected ArrayList loaders = new ArrayList(); 040 041 public GroupClazzLoader(ModelClazzLoader modelClazzLoader) { 042 super(modelClazzLoader); 043 } 044 045 /** 046 * Returns true if the supplied loader "belongs" in the group and can be 047 * added to it. The default implementation returns true. 048 */ 049 public boolean canAddClazzLoader(ClazzLoader loader) { 050 return true; 051 } 052 053 /** 054 * Adds a ClazzLoader to the group. ClazzLoaders added last are invoked 055 * first. Before the group adds the loader to itself, it checks if any 056 * of its members are groups themselves and, if so, tries to add the new 057 * loader to those subgroups. 058 */ 059 public void addClazzLoader(ClazzLoader loader) { 060 for (int i = loaders.size(); --i >= 0;) { 061 ClazzLoader member = (ClazzLoader) loaders.get(i); 062 if (member instanceof GroupClazzLoader) { 063 GroupClazzLoader group = (GroupClazzLoader) member; 064 if (group.canAddClazzLoader(loader)) { 065 group.addClazzLoader(loader); 066 return; 067 } 068 } 069 } 070 loaders.add(loader); 071 } 072 073 /** 074 * Returns true iff this group has a member loader that has or can construct 075 * a Clazz for the supplied instance. 076 */ 077 public boolean isMember(Object instance) { 078 // Note the reverse order 079 for (int i = loaders.size(); --i >= 0;) { 080 ClazzLoader loader = (ClazzLoader) loaders.get(i); 081 if (loader.isMember(instance)) { 082 return true; 083 } 084 } 085 return false; 086 } 087 088 public String getClazzName(Object instance) { 089 // Note the reverse order 090 for (int i = loaders.size(); --i >= 0;) { 091 ClazzLoader loader = (ClazzLoader) loaders.get(i); 092 String name = loader.getClazzName(instance); 093 if (name != null) { 094 return name; 095 } 096 } 097 return null; 098 } 099 100 /** 101 * Given a Clazz name, produces the corresponding Clazz by invoking member 102 * loaders one by one until the clazz is found. 103 */ 104 public Clazz getClazzForName(String name) { 105 Clazz clazz = null; 106 // Note the reverse order 107 for (int i = loaders.size(); --i >= 0;) { 108 ClazzLoader loader = (ClazzLoader) loaders.get(i); 109 clazz = loader.getClazzForName(name); 110 if (clazz != null) { 111 break; 112 } 113 } 114 return clazz; 115 } 116 117 /** 118 * @see ClazzLoader#defineClazz(String, Class, Class) 119 */ 120 public Clazz defineClazz( 121 String name, 122 Class clazzClass, 123 Class instanceClass) 124 { 125 Clazz clazz = null; 126 // Note the reverse order 127 for (int i = loaders.size(); --i >= 0;) { 128 ClazzLoader loader = (ClazzLoader) loaders.get(i); 129 clazz = loader.defineClazz(name, clazzClass, instanceClass); 130 if (clazz != null) { 131 break; 132 } 133 } 134 return clazz; 135 } 136 137 /** 138 * Returns all clazz loaders registered with this group, 139 * in the order of priority 140 */ 141 public List getClazzLoaders() { 142 return Collections.unmodifiableList(loaders); 143 } 144 145 /** 146 * Returns clazzloaders matching the supplied Predicate 147 */ 148 // public List getClazzLoaders(Predicate predicate) { 149 // } 150 }