1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.pool2.proxy;
18
19 import java.lang.reflect.Method;
20
21 import org.apache.commons.pool2.UsageTracking;
22
23 /**
24 * Base implementation for object wrappers when using a
25 * {@link ProxiedObjectPool}.
26 *
27 * @param <T> type of the wrapped pooled object
28 * @since 2.0
29 */
30 class BaseProxyHandler<T> {
31
32 private volatile T pooledObject;
33 private final UsageTracking<T> usageTracking;
34
35 /**
36 * Constructs a new wrapper for the given pooled object.
37 *
38 * @param pooledObject The object to wrap
39 * @param usageTracking The instance, if any (usually the object pool) to
40 * be provided with usage tracking information for this
41 * wrapped object
42 */
43 BaseProxyHandler(final T pooledObject, final UsageTracking<T> usageTracking) {
44 this.pooledObject = pooledObject;
45 this.usageTracking = usageTracking;
46 }
47
48 /**
49 * Disable the proxy wrapper. Called when the object has been returned to
50 * the pool. Further use of the wrapper should result in an
51 * {@link IllegalStateException}.
52 *
53 * @return the object that this proxy was wrapping
54 */
55 T disableProxy() {
56 final T result = pooledObject;
57 pooledObject = null;
58 return result;
59 }
60
61 /**
62 * Invoke the given method on the wrapped object.
63 *
64 * @param method The method to invoke
65 * @param args The arguments to the method
66 * @return The result of the method call
67 * @throws Throwable If the method invocation fails
68 */
69 Object doInvoke(final Method method, final Object[] args) throws Throwable {
70 validateProxiedObject();
71 final T object = getPooledObject();
72 if (usageTracking != null) {
73 usageTracking.use(object);
74 }
75 return method.invoke(object, args);
76 }
77
78 /**
79 * Gets the wrapped, pooled object.
80 *
81 * @return the underlying pooled object
82 */
83 T getPooledObject() {
84 return pooledObject;
85 }
86
87 /**
88 * @since 2.4.3
89 */
90 @Override
91 public String toString() {
92 final StringBuilder builder = new StringBuilder();
93 builder.append(getClass().getName());
94 builder.append(" [pooledObject=");
95 builder.append(pooledObject);
96 builder.append(", usageTracking=");
97 builder.append(usageTracking);
98 builder.append("]");
99 return builder.toString();
100 }
101
102 /**
103 * Check that the proxy is still valid (i.e. that {@link #disableProxy()}
104 * has not been called).
105 *
106 * @throws IllegalStateException if {@link #disableProxy()} has been called
107 */
108 void validateProxiedObject() {
109 if (pooledObject == null) {
110 throw new IllegalStateException("This object may no longer be " +
111 "used as it has been returned to the Object Pool.");
112 }
113 }
114 }