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 */
018package org.apache.xbean.recipe;
019
020import java.util.Collections;
021import java.util.List;
022import java.lang.reflect.Type;
023
024import org.apache.xbean.recipe.AbstractRecipe;
025import org.apache.xbean.recipe.ConstructionException;
026import org.apache.xbean.recipe.ExecutionContext;
027import org.apache.xbean.recipe.NoSuchObjectException;
028import org.apache.xbean.recipe.Recipe;
029import 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 */
035public 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}