001 /*****************************************************************************
002 * Copyright (C) PicoContainer Organization. All rights reserved. *
003 * ------------------------------------------------------------------------- *
004 * The software in this package is published under the terms of the BSD *
005 * style license a copy of which has been included with this distribution in *
006 * the LICENSE.txt file. *
007 *****************************************************************************/
008
009 package org.picocontainer.gems.constraints;
010
011 import org.picocontainer.ComponentAdapter;
012 import org.picocontainer.NameBinding;
013 import org.picocontainer.PicoContainer;
014 import org.picocontainer.PicoCompositionException;
015 import org.picocontainer.injectors.AbstractInjector;
016 import org.picocontainer.parameters.CollectionComponentParameter;
017
018 import java.lang.reflect.Array;
019 import java.lang.reflect.Type;
020 import java.lang.annotation.Annotation;
021 import java.util.Map;
022
023 /**
024 * Base class for parameter constraints.
025 *
026 * @author Nick Sieger
027 */
028 public abstract class AbstractConstraint extends CollectionComponentParameter implements Constraint {
029
030 /** Construct an AbstractContraint. */
031 protected AbstractConstraint() {
032 super(false);
033 }
034
035 @Override
036 public Object resolveInstance(final PicoContainer container,
037 final ComponentAdapter<?> adapter,
038 final Type expectedType,
039 final NameBinding expectedNameBinding, final boolean useNames, final Annotation binding) throws PicoCompositionException
040 {
041 final Object[] array =
042 (Object[])super.resolveInstance(container, adapter, getArrayType((Class) expectedType), expectedNameBinding,
043 useNames, null);
044 if (array.length == 1) {
045 return array[0];
046 }
047 return null;
048 }
049
050 @Override
051 public boolean isResolvable(final PicoContainer container,
052 final ComponentAdapter<?> adapter,
053 final Type expectedType,
054 final NameBinding expectedNameBinding, final boolean useNames, final Annotation binding) throws PicoCompositionException
055 {
056 return super.isResolvable(container, adapter, getArrayType((Class) expectedType), expectedNameBinding, useNames,
057 binding);
058 }
059
060 @Override
061 public void verify(final PicoContainer container,
062 final ComponentAdapter<?> adapter,
063 final Type expectedType,
064 final NameBinding expectedNameBinding, final boolean useNames, final Annotation binding) throws PicoCompositionException
065 {
066 super.verify(container, adapter, getArrayType((Class) expectedType), expectedNameBinding, useNames, binding);
067 }
068
069 @Override
070 public abstract boolean evaluate(ComponentAdapter adapter);
071
072 @Override
073 protected Map<Object, ComponentAdapter<?>> getMatchingComponentAdapters(final PicoContainer container,
074 final ComponentAdapter adapter,
075 final Class keyType,
076 final Class valueType)
077 {
078 final Map<Object, ComponentAdapter<?>> map =
079 super.getMatchingComponentAdapters(container, adapter, keyType, valueType);
080 if (map.size() > 1) {
081 throw new AbstractInjector.AmbiguousComponentResolutionException(valueType, map.keySet().toArray(new Object[map.size()]));
082 }
083 return map;
084 }
085
086 private Type getArrayType(final Class expectedType) {
087 return Array.newInstance(expectedType, 0).getClass();
088 }
089 }