001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.cp;
018
019import static org.apache.juneau.collections.JsonMap.*;
020import static org.apache.juneau.internal.ClassUtils.*;
021
022import java.util.function.*;
023
024import org.apache.juneau.collections.*;
025import org.apache.juneau.common.utils.*;
026import org.apache.juneau.internal.*;
027
028/**
029 * Represents a bean in a {@link BeanStore}.
030 *
031 * <p>
032 * A bean entry consists of the following:
033 * <ul>
034 *    <li>A class type.
035 *    <li>A bean or bean supplier that returns an instance of the class type.  This can be a subclass of the type.
036 *    <li>An optional name.
037 * </ul>
038 *
039 * @param <T> The bean type.
040 */
041public class BeanStoreEntry<T> {
042
043   //-----------------------------------------------------------------------------------------------------------------
044   // Static
045   //-----------------------------------------------------------------------------------------------------------------
046
047   /**
048    * Static creator.
049    *
050    * @param <T> The class type to associate with the bean.
051    * @param type The class type to associate with the bean.
052    * @param bean The bean supplier.
053    * @param name Optional name to associate with the bean.  Can be <jk>null</jk>.
054    * @return A new bean store entry.
055    */
056   public static <T> BeanStoreEntry<T> create(Class<T> type, Supplier<T> bean, String name) {
057      return new BeanStoreEntry<>(type, bean, name);
058   }
059
060   //-----------------------------------------------------------------------------------------------------------------
061   // Instance
062   //-----------------------------------------------------------------------------------------------------------------
063
064   final Supplier<T> bean;
065   final Class<T> type;
066   final String name;
067
068   /**
069    * Constructor.
070    *
071    * @param type The class type to associate with the bean.
072    * @param bean The bean supplier.
073    * @param name Optional name to associate with the bean.  Can be <jk>null</jk>.
074    */
075   protected BeanStoreEntry(Class<T> type, Supplier<T> bean, String name) {
076      this.bean = Utils.assertArgNotNull("bean", bean);
077      this.type = Utils.assertArgNotNull("type", type);
078      this.name = Utils.nullIfEmpty3(name);
079   }
080
081   /**
082    * Returns <jk>true</jk> if this bean is exactly of the specified type.
083    *
084    * @param type The class to check.  Returns <jk>false</jk> if <jk>null</jk>.
085    * @return <jk>true</jk> if this bean is exactly of the specified type.
086    */
087   public boolean matches(Class<?> type) {
088      return this.type.equals(type);
089   }
090
091   /**
092    * Returns <jk>true</jk> if this bean is exactly of the specified type and has the specified name.
093    *
094    * @param type The class to check.  Returns <jk>false</jk> if <jk>null</jk>.
095    * @param name The name to check.  Can be <jk>null</jk> to only match if name of entry is <jk>null</jk>.
096    * @return <jk>true</jk> if this bean is exactly of the specified type and has the specified name.
097    */
098   public boolean matches(Class<?> type, String name) {
099      name = Utils.nullIfEmpty3(name);
100      return matches(type) && Utils.eq(this.name, name);
101   }
102
103   /**
104    * Returns the bean associated with this entry.
105    *
106    * @return The bean associated with this entry.
107    */
108   public T get() {
109      return bean.get();
110   }
111
112   /**
113    * Returns the type this bean is associated with.
114    *
115    * @return The type this bean is associated with.
116    */
117   public Class<T> getType() {
118      return type;
119   }
120
121   /**
122    * Returns the name associated with this entry.
123    *
124    * @return the name associated with this entry.  <jk>null</jk> if no name is associated.
125    */
126   public String getName() {
127      return name;
128   }
129
130   /**
131    * Returns the properties in this object as a simple map for debugging purposes.
132    *
133    * @return The properties in this object as a simple map.
134    */
135   protected JsonMap properties() {
136      return filteredMap()
137         .append("type", simpleClassName(getType()))
138         .append("bean", Utils2.identity(get()))
139         .append("name", getName());
140   }
141}