support/general no longer depends on hibernate-jpa
[utils] / system / general / src / main / java / org / wamblee / system / core / DefaultRequiredInterface.java
1 /*
2  * Copyright 2007 the original author or authors.
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 org.wamblee.system.core;
17
18 import java.util.Arrays;
19
20 import org.wamblee.reflection.ReflectionUtils;
21
22 public class DefaultRequiredInterface implements RequiredInterface {
23
24         private String _name;
25         private boolean _optional; 
26         private Class[] _required;
27         private ProvidedInterface _provider; 
28         
29         public DefaultRequiredInterface(String aName, Class aInterface) {
30                 this(aName, new Class[] { aInterface }); 
31         }
32
33         public DefaultRequiredInterface(String aName, Class[] aInterfaces) {
34                 this(aName, aInterfaces, false); 
35         }
36         
37         public DefaultRequiredInterface(String aName, Class aInterface, boolean aIsOptional) {
38             this(aName, new Class[] { aInterface }, aIsOptional );
39         }
40
41         
42         public DefaultRequiredInterface(String aName, Class[] aInterfaces, boolean aIsOptional) {
43                 _name = aName; 
44                 _optional = aIsOptional; 
45                 _required = aInterfaces; 
46         }
47
48         @Override
49         public String getName() {
50                 return _name;
51         }
52         
53         @Override
54         public boolean isOptional() {
55                 return _optional; 
56         }
57         
58         @Override
59         public boolean implementedBy(ProvidedInterface aDescriptor) {
60                 Class[] provided = aDescriptor.getInterfaceTypes();
61                 for (Class required : _required) {
62                         if ( !serviceProvided(required, provided)) { 
63                                 return false; 
64                         }
65                 }
66                 // all required interfaces are provided.
67                 return true; 
68         }
69         
70         /**
71          * Check if the required interface is implemented by one of the provided interfaces. 
72          * @param aRequired required interface
73          * @param aProvided Provided interfaces.
74          * @return
75          */
76         private boolean serviceProvided(Class aRequired, Class[] aProvided) { 
77                 for (Class provided: aProvided) {
78                         try {
79                                 provided = ReflectionUtils.wrapIfNeeded(provided);
80                                 aRequired = ReflectionUtils.wrapIfNeeded(aRequired);
81                                 provided.asSubclass(aRequired);
82                                 return true; 
83                         } catch (ClassCastException e) {
84                                 // No match, try the next one.
85                         }
86                 }
87                 return false; 
88         }
89         
90         @Override
91         public ProvidedInterface getProvider() {
92                 return _provider; 
93         }
94         
95         @Override
96         public void setProvider(ProvidedInterface aProvider) {
97             assert aProvider != null; 
98             assert implementedBy(aProvider);
99                 _provider = aProvider;  
100         }
101         
102         @Override
103         public boolean equals(Object obj) { 
104             return this == obj; 
105         }
106         
107         @Override
108         public boolean covers(RequiredInterface obj) {
109             // TODO do more than equals. 
110                 if ( !(obj instanceof DefaultRequiredInterface)) { 
111                         return false; 
112                 }
113                 DefaultRequiredInterface descr = (DefaultRequiredInterface)obj;
114                 if ( _required.length != descr._required.length ) { 
115                         return false; 
116                 }
117                 String[] interfaces1 = new String[_required.length];
118                 String[] interfaces2 = new String[_required.length];
119                 for (int i = 0; i < _required.length; i++) {  
120                         interfaces1[i] = _required[i].getName();
121                         interfaces2[i] = descr._required[i].getName();
122                 }
123                 Arrays.sort(interfaces1);
124                 Arrays.sort(interfaces2);
125                 return Arrays.equals(interfaces1, interfaces2);
126         }
127
128         @Override
129         public int hashCode() {
130                 return _required.hashCode(); 
131         }
132         
133         @Override
134         public String toString() {
135                 StringBuffer buf = new StringBuffer();
136                 buf.append("." + getName() + ":");
137                 for (Class intf: _required) { 
138                         buf.append("." + intf.getName());
139                 }
140                 return buf.toString();
141         }
142 }