001: /*
002: * Copyright 2002-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.aop.target;
018:
019: import java.io.Serializable;
020:
021: import org.springframework.aop.TargetSource;
022: import org.springframework.util.Assert;
023:
024: /**
025: * {@link org.springframework.aop.TargetSource} implementation that
026: * caches a local target object, but allows the target to be swapped
027: * while the application is running.
028: *
029: * <p>If configuring an object of this class in a Spring IoC container,
030: * use constructor injection.
031: *
032: * <p>This TargetSource is serializable if the target is at the time
033: * of serialization.
034: *
035: * @author Rod Johnson
036: * @author Juergen Hoeller
037: */
038: public class HotSwappableTargetSource implements TargetSource,
039: Serializable {
040:
041: /** use serialVersionUID from Spring 1.2 for interoperability */
042: private static final long serialVersionUID = 7497929212653839187L;
043:
044: /** The current target object */
045: private Object target;
046:
047: /**
048: * Create a new HotSwappableTargetSource with the given initial target object.
049: * @param initialTarget the initial target object
050: */
051: public HotSwappableTargetSource(Object initialTarget) {
052: Assert.notNull(initialTarget, "Target object must not be null");
053: this .target = initialTarget;
054: }
055:
056: /**
057: * Return the type of the current target object.
058: * <p>The returned type should usually be constant across all target objects.
059: */
060: public synchronized Class getTargetClass() {
061: return this .target.getClass();
062: }
063:
064: public final boolean isStatic() {
065: return false;
066: }
067:
068: public synchronized Object getTarget() {
069: return this .target;
070: }
071:
072: public void releaseTarget(Object target) {
073: // nothing to do
074: }
075:
076: /**
077: * Swap the target, returning the old target object.
078: * @param newTarget the new target object
079: * @return the old target object
080: * @throws IllegalArgumentException if the new target is invalid
081: */
082: public synchronized Object swap(Object newTarget)
083: throws IllegalArgumentException {
084: Assert.notNull(newTarget, "Target object must not be null");
085: Object old = this .target;
086: this .target = newTarget;
087: return old;
088: }
089:
090: /**
091: * Two HotSwappableTargetSources are equal if the current target
092: * objects are equal.
093: */
094: public boolean equals(Object other) {
095: return (this == other || (other instanceof HotSwappableTargetSource && this .target
096: .equals(((HotSwappableTargetSource) other).target)));
097: }
098:
099: public int hashCode() {
100: return HotSwappableTargetSource.class.hashCode();
101: }
102:
103: public String toString() {
104: return "HotSwappableTargetSource for target: " + this.target;
105: }
106:
107: }
|