001    /**
002     *
003     * Licensed to the Apache Software Foundation (ASF) under one or more
004     * contributor license agreements.  See the NOTICE file distributed with
005     * this work for additional information regarding copyright ownership.
006     * The ASF licenses this file to You under the Apache License, Version 2.0
007     * (the "License"); you may not use this file except in compliance with
008     * the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    package org.apache.xbean.recipe;
019    
020    import java.util.Collections;
021    import java.util.List;
022    import java.lang.reflect.Type;
023    
024    import org.apache.xbean.recipe.AbstractRecipe;
025    import org.apache.xbean.recipe.ConstructionException;
026    import org.apache.xbean.recipe.ExecutionContext;
027    import org.apache.xbean.recipe.NoSuchObjectException;
028    import org.apache.xbean.recipe.Recipe;
029    import org.apache.xbean.recipe.RecipeHelper;
030    
031    /*
032     * The ReferenceNameRecipe is used to inject the reference name into the object (as a String).
033     * The ReferenceNameRecipe ensures the actual reference object exists before the reference name is injected. 
034     */
035    public class ReferenceNameRecipe extends AbstractRecipe {
036        
037        private String referenceName;
038    
039        public ReferenceNameRecipe(String referenceName) {
040            this.referenceName = referenceName;
041        }
042    
043        public String getReferenceName() {
044            return referenceName;
045        }
046    
047        private Object getReference() {
048            if (referenceName == null) {
049                throw new ConstructionException("Reference name has not been set");
050            }
051            ExecutionContext context = ExecutionContext.getContext();
052            if (!context.containsObject(referenceName)) {
053                throw new NoSuchObjectException(referenceName);
054            }
055            return context.getObject(referenceName);
056        }
057        
058        public List<Recipe> getNestedRecipes() {
059            Object object = getReference();
060            if (object instanceof Recipe) {
061                Recipe recipe = (Recipe) object;
062                return Collections.singletonList(recipe);
063            } else {
064                return Collections.emptyList();
065            }
066        }
067    
068        public List<Recipe> getConstructorRecipes() {
069            return getNestedRecipes();
070        }
071        
072        public boolean canCreate(Type type) {
073            Object object = getReference();
074            return String.class == RecipeHelper.toClass(type);
075        }
076    
077        protected Object internalCreate(Type expectedType, boolean lazyRefAllowed) throws ConstructionException {
078            Object object = getReference();
079            return referenceName;
080        }
081        
082    }