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 /**
021 * Reference is a named (lazy) reference from one object to another. This data class is updated when the reference
022 * is resolved which can be immedately when the ref is created, or later when an instance with the referenced
023 * name is created.
024 * <p/>
025 * When the reference is resolved, an optional Action will be invoked which is commonly used to update a
026 * property on the source object of the reference.
027 */
028 public class Reference {
029 private final String name;
030 private boolean resolved;
031 private Object instance;
032 private Action action;
033
034 /**
035 * Create a reference to the specified name.
036 * @param name the name of the referenced object
037 */
038 public Reference(String name) {
039 this.name = name;
040 }
041
042 /**
043 * Gets the name of the referenced object.
044 * @return name the name of the referenced object
045 */
046 public String getName() {
047 return name;
048 }
049
050 /**
051 * Has this reference been resolved?
052 * @return true if the reference has been resolved; false otherwise
053 */
054 public boolean isResolved() {
055 return resolved;
056 }
057
058 /**
059 * Gets the referenced object instance or null if the reference has not been resolved yet;
060 *
061 * @return the referenced object instance or null
062 */
063 public Object get() {
064 return instance;
065 }
066
067 /**
068 * Sets the referenced object instance. If an action is registered the onSet method is invoked.
069 *
070 * @param object the reference instance
071 */
072 public void set(Object object) {
073 if (resolved) {
074 throw new ConstructionException("Reference has already been resolved");
075 }
076 resolved = true;
077 this.instance = object;
078 if (action != null) {
079 action.onSet(this);
080 }
081 }
082
083 /**
084 * Registers an action to invoke when the instance is set. If the instance, has already been set, the
085 * onSet method will immedately be invoked.
086 *
087 * @return the action to invoke when this refernce is resolved; not null
088 */
089 public void setAction(Action action) {
090 if (action == null) {
091 throw new NullPointerException("action is null");
092 }
093 this.action = action;
094 if (resolved) {
095 action.onSet(this);
096 }
097 }
098
099 public static interface Action {
100 void onSet(Reference ref);
101 }
102 }