1 /*
2 * Copyright 2006-2016 The JGUIraffe Team.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License")
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package net.sf.jguiraffe.di.impl;
17
18 import net.sf.jguiraffe.di.BeanProvider;
19 import net.sf.jguiraffe.di.BeanStore;
20 import net.sf.jguiraffe.di.Dependency;
21 import net.sf.jguiraffe.di.DependencyProvider;
22 import net.sf.jguiraffe.di.InjectionException;
23
24 /**
25 * <p>
26 * An implementation of the <code>Dependency</code> interface that allows to
27 * define a dependency based on a bean class.
28 * </p>
29 *
30 * @author Oliver Heger
31 * @version $Id: ClassDependency.java 205 2012-01-29 18:29:57Z oheger $
32 */
33 public final class ClassDependency implements Dependency
34 {
35 /** Stores the class description of this dependency. */
36 private ClassDescription dependentClass;
37
38 /**
39 * Creates a new instance of <code>ClassDependency</code> and sets the
40 * dependent class. Clients use the static <code>getInstance()</code>
41 * method for obtaining instances of this class.
42 *
43 * @param cls the description of the dependent class
44 */
45 private ClassDependency(ClassDescription cls)
46 {
47 dependentClass = cls;
48 }
49
50 /**
51 * Returns the description of the class of this dependency.
52 *
53 * @return the class of this dependency
54 */
55 public ClassDescription getDependentClass()
56 {
57 return dependentClass;
58 }
59
60 /**
61 * Resolves this dependency on the specified bean store. This implementation
62 * iterates over the beans defined in the store. If a bean provider is found
63 * whose bean class is either the same or a sub class of the class defined
64 * in this dependency, it is returned. Otherwise the parent bean store will
65 * be searched recursively.
66 *
67 * @param store the bean store to be searched
68 * @param depProvider the dependency provider
69 * @return the found bean provider
70 * @throws InjectionException if no fitting bean provider can be found
71 */
72 public BeanProvider resolve(BeanStore store, DependencyProvider depProvider)
73 {
74 if (store == null)
75 {
76 throw new InjectionException(
77 "Could not resolve dependency for class "
78 + getDependentClass());
79 }
80
81 Class<?> depClass = getDependentClass().getTargetClass(depProvider);
82 for (String n : store.providerNames())
83 {
84 BeanProvider provider = store.getBeanProvider(n);
85 if (depClass.isAssignableFrom(
86 provider.getBeanClass(depProvider)))
87 {
88 return provider;
89 }
90 }
91
92 // recursive call for parent store
93 return resolve(store.getParent(), depProvider);
94 }
95
96 /**
97 * Compares this object with another one. Two class dependencies are
98 * considered equal if and only if they refer to the same class.
99 *
100 * @param obj the object to compare to
101 * @return a flag whether the objects are equal
102 */
103 @Override
104 public boolean equals(Object obj)
105 {
106 if (this == obj)
107 {
108 return true;
109 }
110 if (!(obj instanceof ClassDependency))
111 {
112 return false;
113 }
114 ClassDependency c = (ClassDependency) obj;
115 return getDependentClass().equals(c.getDependentClass());
116 }
117
118 /**
119 * Returns a hash code for this object.
120 *
121 * @return a hash code
122 */
123 @Override
124 public int hashCode()
125 {
126 return getDependentClass().hashCode();
127 }
128
129 /**
130 * Returns a string representation of this object. This string will contain
131 * the name of the class referred to by this dependency.
132 *
133 * @return a string for this object
134 */
135 @Override
136 public String toString()
137 {
138 StringBuilder buf = new StringBuilder(getClass().getName());
139 buf.append("[ class = ").append(getDependentClass());
140 buf.append(" ]");
141 return buf.toString();
142 }
143
144 /**
145 * Returns a <code>ClassDependency</code> instance for the specified
146 * class.
147 *
148 * @param cls the class of the dependency (must not be <b>null</b>)
149 * @return an instance pointing to the specified class
150 * @throws IllegalArgumentException if the class is <b>null</b>
151 */
152 public static ClassDependency getInstance(Class<?> cls)
153 {
154 return getInstance((cls != null) ? ClassDescription.getInstance(cls)
155 : null);
156 }
157
158 /**
159 * Returns a <code>ClassDependency</code> instance for the specified
160 * <code>ClassDescription</code>.
161 *
162 * @param clsdsc the class description
163 * @return an instance pointing to the specified class
164 * @throws IllegalArgumentException if the class description is <b>null</b>
165 */
166 public static ClassDependency getInstance(ClassDescription clsdsc)
167 {
168 if (clsdsc == null)
169 {
170 throw new IllegalArgumentException(
171 "Dependent class must not be null!");
172 }
173 return new ClassDependency(clsdsc);
174 }
175 }