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.ObjectUtils;
023:
024: /**
025: * Canonical <code>TargetSource</code> when there is no target
026: * (or just the target class known), and behavior is supplied
027: * by interfaces and advisors only.
028: *
029: * @author Rod Johnson
030: * @author Juergen Hoeller
031: */
032: public class EmptyTargetSource implements TargetSource, Serializable {
033:
034: /** use serialVersionUID from Spring 1.2 for interoperability */
035: private static final long serialVersionUID = 3680494563553489691L;
036:
037: //---------------------------------------------------------------------
038: // Static factory methods
039: //---------------------------------------------------------------------
040:
041: /**
042: * The canonical (Singleton) instance of this {@link EmptyTargetSource}.
043: */
044: public static final EmptyTargetSource INSTANCE = new EmptyTargetSource(
045: null);
046:
047: /**
048: * Return an EmptyTargetSource for the given target Class.
049: * @param targetClass the target Class (may be <code>null</code>)
050: * @see #getTargetClass()
051: */
052: public static EmptyTargetSource forClass(Class targetClass) {
053: return (targetClass == null ? INSTANCE : new EmptyTargetSource(
054: targetClass));
055: }
056:
057: //---------------------------------------------------------------------
058: // Instance implementation
059: //---------------------------------------------------------------------
060:
061: private final Class targetClass;
062:
063: /**
064: * Create a new instance of the {@link EmptyTargetSource} class.
065: * <p>This constructor is <code>private</code> to enforce the
066: * Singleton pattern / factory method pattern.
067: * @param targetClass the target class to expose (may be <code>null</code>)
068: */
069: private EmptyTargetSource(Class targetClass) {
070: this .targetClass = targetClass;
071: }
072:
073: /**
074: * Always returns the specified target Class, or <code>null</code> if none.
075: */
076: public Class getTargetClass() {
077: return this .targetClass;
078: }
079:
080: /**
081: * Always returns <code>true</code>.
082: */
083: public boolean isStatic() {
084: return true;
085: }
086:
087: /**
088: * Always returns <code>null</code>.
089: */
090: public Object getTarget() {
091: return null;
092: }
093:
094: /**
095: * Nothing to release.
096: */
097: public void releaseTarget(Object target) {
098: }
099:
100: /**
101: * Returns the canonical instance on deserialization in case
102: * of no target class, thus protecting the Singleton pattern.
103: */
104: private Object readResolve() {
105: return (this .targetClass == null ? INSTANCE : this );
106: }
107:
108: public boolean equals(Object other) {
109: return (this == other || (other instanceof EmptyTargetSource && ObjectUtils
110: .nullSafeEquals(this .targetClass,
111: ((EmptyTargetSource) other).targetClass)));
112: }
113:
114: public int hashCode() {
115: return EmptyTargetSource.class.hashCode() * 13
116: + ObjectUtils.nullSafeHashCode(this .targetClass);
117: }
118:
119: public String toString() {
120: return "EmptyTargetSource: "
121: + (this .targetClass != null ? "target class ["
122: + this .targetClass + "]" : "no target class");
123: }
124:
125: }
|