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