001 /*******************************************************************************
002 * Copyright (C) PicoContainer Organization. All rights reserved.
003 * ---------------------------------------------------------------------------
004 * The software in this package is published under the terms of the BSD style
005 * license a copy of which has been included with this distribution in the
006 * LICENSE.txt file.
007 ******************************************************************************/
008 package org.picocontainer.parameters;
009
010 import java.io.Serializable;
011 import java.lang.annotation.Annotation;
012 import java.lang.reflect.Type;
013
014 import org.picocontainer.ComponentAdapter;
015 import org.picocontainer.NameBinding;
016 import org.picocontainer.PicoCompositionException;
017 import org.picocontainer.PicoContainer;
018 import org.picocontainer.PicoVisitor;
019
020 /**
021 * Once in a great while, you actually want to pass in 'null' as an argument. Instead
022 * of bypassing the type checking mechanisms available in
023 * {@link org.picocontainer.parameters.ConstantParameter ConstantParameter}, we provide a <em>Special Type</em>
024 * geared to marking nulls.
025 * @author Michael Rimov
026 *
027 */
028 @SuppressWarnings("serial")
029 public class NullParameter extends AbstractParameter implements Serializable {
030
031 /**
032 * The one and only instance of null parameter.
033 */
034 public static final NullParameter INSTANCE = new NullParameter();
035
036 /**
037 * Only once instance of Null parameter needed.
038 */
039 protected NullParameter() {
040 }
041
042 /**
043 * {@inheritDoc}
044 * @see org.picocontainer.Parameter#accept(org.picocontainer.PicoVisitor)
045 */
046 public void accept(PicoVisitor visitor) {
047 visitor.visitParameter(this);
048 }
049
050 /**
051 * {@inheritDoc}
052 * @see org.picocontainer.Parameter#resolve(org.picocontainer.PicoContainer, org.picocontainer.ComponentAdapter, org.picocontainer.ComponentAdapter, java.lang.reflect.Type, org.picocontainer.NameBinding, boolean, java.lang.annotation.Annotation)
053 */
054 public Resolver resolve(PicoContainer container,
055 ComponentAdapter<?> forAdapter,
056 ComponentAdapter<?> injecteeAdapter, Type expectedType,
057 NameBinding expectedNameBinding, boolean useNames,
058 Annotation binding) {
059 return new ValueResolver(isAssignable(expectedType), null, null);
060 }
061
062 /**
063 * {@inheritDoc}
064 * @see org.picocontainer.Parameter#verify(org.picocontainer.PicoContainer, org.picocontainer.ComponentAdapter, java.lang.reflect.Type, org.picocontainer.NameBinding, boolean, java.lang.annotation.Annotation)
065 */
066 public void verify(PicoContainer container, ComponentAdapter<?> adapter,
067 Type expectedType, NameBinding expectedNameBinding,
068 boolean useNames, Annotation binding) {
069 if (!isAssignable(expectedType)) {
070 throw new PicoCompositionException(expectedType + " cannot be assigned a null value");
071 }
072 }
073
074 /**
075 * Nulls cannot be assigned to primitives.
076 * @param expectedType
077 * @return
078 */
079 protected boolean isAssignable(Type expectedType) {
080 if (expectedType instanceof Class<?>) {
081 Class<?> expectedClass = Class.class.cast(expectedType);
082 if (expectedClass.isPrimitive()) {
083 return false;
084 }
085 }
086 return true;
087 }
088
089
090 }