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 }