1 /*
2 * ====================================================================
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 * ====================================================================
20 *
21 * This software consists of voluntary contributions made by many
22 * individuals on behalf of the Apache Software Foundation. For more
23 * information on the Apache Software Foundation, please see
24 * <http://www.apache.org/>.
25 *
26 */
27 package org.apache.http.pool;
28
29 import java.util.concurrent.TimeUnit;
30
31 import org.apache.http.annotation.GuardedBy;
32 import org.apache.http.annotation.ThreadSafe;
33 import org.apache.http.util.Args;
34
35 /**
36 * Pool entry containing a pool connection object along with its route.
37 * <p/>
38 * The connection contained by the pool entry may have an expiration time which
39 * can be either set upon construction time or updated with
40 * the {@link #updateExpiry(long, TimeUnit)}.
41 * <p/>
42 * Pool entry may also have an object associated with it that represents
43 * a connection state (usually a security principal or a unique token identifying
44 * the user whose credentials have been used while establishing the connection).
45 *
46 * @param <T> the route type that represents the opposite endpoint of a pooled
47 * connection.
48 * @param <C> the connection type.
49 * @since 4.2
50 */
51 @ThreadSafe
52 public abstract class PoolEntry<T, C> {
53
54 private final String id;
55 private final T route;
56 private final C conn;
57 private final long created;
58 private final long validUnit;
59
60 @GuardedBy("this")
61 private long updated;
62
63 @GuardedBy("this")
64 private long expiry;
65
66 private volatile Object state;
67
68 /**
69 * Creates new <tt>PoolEntry</tt> instance.
70 *
71 * @param id unique identifier of the pool entry. May be <code>null</code>.
72 * @param route route to the opposite endpoint.
73 * @param conn the connection.
74 * @param timeToLive maximum time to live. May be zero if the connection
75 * does not have an expiry deadline.
76 * @param tunit time unit.
77 */
78 public PoolEntry(final String id, final T route, final C conn,
79 final long timeToLive, final TimeUnit tunit) {
80 super();
81 Args.notNull(route, "Route");
82 Args.notNull(conn, "Connection");
83 Args.notNull(tunit, "Time unit");
84 this.id = id;
85 this.route = route;
86 this.conn = conn;
87 this.created = System.currentTimeMillis();
88 if (timeToLive > 0) {
89 this.validUnit = this.created + tunit.toMillis(timeToLive);
90 } else {
91 this.validUnit = Long.MAX_VALUE;
92 }
93 this.expiry = this.validUnit;
94 }
95
96 /**
97 * Creates new <tt>PoolEntry</tt> instance without an expiry deadline.
98 *
99 * @param id unique identifier of the pool entry. May be <code>null</code>.
100 * @param route route to the opposite endpoint.
101 * @param conn the connection.
102 */
103 public PoolEntry(final String id, final T route, final C conn) {
104 this(id, route, conn, 0, TimeUnit.MILLISECONDS);
105 }
106
107 public String getId() {
108 return this.id;
109 }
110
111 public T getRoute() {
112 return this.route;
113 }
114
115 public C getConnection() {
116 return this.conn;
117 }
118
119 public long getCreated() {
120 return this.created;
121 }
122
123 public long getValidUnit() {
124 return this.validUnit;
125 }
126
127 public Object getState() {
128 return this.state;
129 }
130
131 public void setState(final Object state) {
132 this.state = state;
133 }
134
135 public synchronized long getUpdated() {
136 return this.updated;
137 }
138
139 public synchronized long getExpiry() {
140 return this.expiry;
141 }
142
143 public synchronized void updateExpiry(final long time, final TimeUnit tunit) {
144 Args.notNull(tunit, "Time unit");
145 this.updated = System.currentTimeMillis();
146 long newExpiry;
147 if (time > 0) {
148 newExpiry = this.updated + tunit.toMillis(time);
149 } else {
150 newExpiry = Long.MAX_VALUE;
151 }
152 this.expiry = Math.min(newExpiry, this.validUnit);
153 }
154
155 public synchronized boolean isExpired(final long now) {
156 return now >= this.expiry;
157 }
158
159 /**
160 * Invalidates the pool entry and closes the pooled connection associated
161 * with it.
162 */
163 public abstract void close();
164
165 /**
166 * Returns <code>true</code> if the pool entry has been invalidated.
167 */
168 public abstract boolean isClosed();
169
170 @Override
171 public String toString() {
172 final StringBuilder buffer = new StringBuilder();
173 buffer.append("[id:");
174 buffer.append(this.id);
175 buffer.append("][route:");
176 buffer.append(this.route);
177 buffer.append("][state:");
178 buffer.append(this.state);
179 buffer.append("]");
180 return buffer.toString();
181 }
182
183 }