/*
- * Copyright 2007 the original author or authors.
+ * Copyright 2005-2010 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
package org.wamblee.system.core;
+import org.wamblee.reflection.ReflectionUtils;
+
import java.util.Arrays;
+/**
+ *
+ * @author $author$
+ * @version $Revision$
+ */
public class DefaultRequiredInterface implements RequiredInterface {
+ private String name;
+
+ private boolean optional;
+
+ private Class[] required;
+
+ private ProvidedInterface provider;
+
+ /**
+ * Creates a new DefaultRequiredInterface object.
+ *
+ */
+ public DefaultRequiredInterface(String aName, Class aInterface) {
+ this(aName, new Class[] { aInterface });
+ }
+
+ /**
+ * Creates a new DefaultRequiredInterface object.
+ *
+ */
+ public DefaultRequiredInterface(String aName, Class[] aInterfaces) {
+ this(aName, aInterfaces, false);
+ }
+
+ /**
+ * Creates a new DefaultRequiredInterface object.
+ *
+ */
+ public DefaultRequiredInterface(String aName, Class aInterface,
+ boolean aIsOptional) {
+ this(aName, new Class[] { aInterface }, aIsOptional);
+ }
+
+ /**
+ * Creates a new DefaultRequiredInterface object.
+ *
+ */
+ public DefaultRequiredInterface(String aName, Class[] aInterfaces,
+ boolean aIsOptional) {
+ name = aName;
+ optional = aIsOptional;
+ required = aInterfaces;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public boolean isOptional() {
+ return optional;
+ }
+
+ @Override
+ public boolean implementedBy(ProvidedInterface aDescriptor) {
+ Class[] provided = aDescriptor.getInterfaceTypes();
+
+ for (Class requiredIntf : required) {
+ if (!serviceProvided(requiredIntf, provided)) {
+ return false;
+ }
+ }
+
+ // all required interfaces are provided.
+ return true;
+ }
+
+ /**
+ * Check if the required interface is implemented by one of the provided
+ * interfaces.
+ *
+ * @param aRequired
+ * required interface
+ * @param aProvided
+ * Provided interfaces.
+ *
+ * @return
+ */
+ private boolean serviceProvided(Class aRequired, Class[] aProvided) {
+ for (Class provided : aProvided) {
+ try {
+ provided = ReflectionUtils.wrapIfNeeded(provided);
+ aRequired = ReflectionUtils.wrapIfNeeded(aRequired);
+ provided.asSubclass(aRequired);
+
+ return true;
+ } catch (ClassCastException e) {
+ // No match, try the next one.
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public ProvidedInterface getProvider() {
+ return provider;
+ }
+
+ @Override
+ public void setProvider(ProvidedInterface aProvider) {
+ assert aProvider != null;
+ assert implementedBy(aProvider);
+ provider = aProvider;
+ }
+
+ @Override
+ public boolean equals(Object aObject) {
+ return this == aObject;
+ }
+
+ @Override
+ public boolean covers(RequiredInterface aObject) {
+ // TODO do more than equals.
+ if (!(aObject instanceof DefaultRequiredInterface)) {
+ return false;
+ }
+
+ DefaultRequiredInterface descr = (DefaultRequiredInterface) aObject;
+
+ if (required.length != descr.required.length) {
+ return false;
+ }
+
+ String[] interfaces1 = new String[required.length];
+ String[] interfaces2 = new String[required.length];
+
+ for (int i = 0; i < required.length; i++) {
+ interfaces1[i] = required[i].getName();
+ interfaces2[i] = descr.required[i].getName();
+ }
+
+ Arrays.sort(interfaces1);
+ Arrays.sort(interfaces2);
+
+ return Arrays.equals(interfaces1, interfaces2);
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(required);
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+ buf.append("." + getName() + ":");
+
+ for (Class intf : required) {
+ buf.append("." + intf.getName());
+ }
- private String _name;
- private Class[] _required;
- private ProvidedInterface _provider;
-
- public DefaultRequiredInterface(String aName, Class aInterface) {
- this(aName, new Class[] { aInterface });
- }
-
- public DefaultRequiredInterface(String aName, Class[] aInterfaces) {
- _name = aName;
- _required = aInterfaces;
- }
-
- @Override
- public String getName() {
- return _name;
- }
-
- @Override
- public boolean implementedBy(ProvidedInterface aDescriptor) {
- Class[] provided = aDescriptor.getInterfaceTypes();
- for (Class required : _required) {
- if ( !serviceProvided(required, provided)) {
- return false;
- }
- }
- // all required interfaces are provided.
- return true;
- }
-
- /**
- * Check if the required interface is implemented by one of the provided interfaces.
- * @param aRequired required interface
- * @param aProvided Provided interfaces.
- * @return
- */
- private boolean serviceProvided(Class aRequired, Class[] aProvided) {
- for (Class provided: aProvided) {
- try {
- provided.asSubclass(aRequired);
- return true;
- } catch (ClassCastException e) {
- // No match, try the next one.
- }
- }
- return false;
- }
-
- @Override
- public ProvidedInterface getProvider() {
- return _provider;
- }
-
- @Override
- public void setProvider(ProvidedInterface aProvider) {
- _provider = aProvider;
- }
-
- @Override
- public <T> T getImplementation(Class<T> aClass) {
- if ( _provider == null ) {
- return null;
- }
- return (T)_provider.getImplementation();
- }
-
- @Override
- public boolean equals(Object obj) {
- if ( !(obj instanceof DefaultRequiredInterface)) {
- return false;
- }
- DefaultRequiredInterface descr = (DefaultRequiredInterface)obj;
- if ( _required.length != descr._required.length ) {
- return false;
- }
- String[] interfaces1 = new String[_required.length];
- String[] interfaces2 = new String[_required.length];
- for (int i = 0; i < _required.length; i++) {
- interfaces1[i] = _required[i].getName();
- interfaces2[i] = descr._required[i].getName();
- }
- Arrays.sort(interfaces1);
- Arrays.sort(interfaces2);
- return Arrays.equals(interfaces1, interfaces2);
- }
-
- @Override
- public int hashCode() {
- return _required.hashCode();
- }
-
- @Override
- public String toString() {
- StringBuffer buf = new StringBuffer();
- for (Class intf: _required) {
- buf.append("." + intf.getName());
- }
- return buf.toString();
- }
+ return buf.toString();
+ }
}