1 /*
2 * #%L
3 * Nuiton Utils
4 * %%
5 * Copyright (C) 2004 - 2010 CodeLutin
6 * %%
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Lesser Public License for more details.
16 *
17 * You should have received a copy of the GNU General Lesser Public
18 * License along with this program. If not, see
19 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
20 * #L%
21 */
22
23 /* *
24 * TransparenteWeakReference.java
25 *
26 * Created: 10 mai 2004
27 *
28 * @author Benjamin Poussin - poussin@codelutin.com
29 * Copyright Code Lutin
30 *
31 *
32 * Mise a jour: $Date$
33 * par : */
34 package org.nuiton.util;
35
36 import java.lang.ref.Reference;
37 import java.lang.ref.ReferenceQueue;
38 import java.lang.ref.WeakReference;
39
40 /**
41 * Cette classe etant WeakReference et surcharge les méthodes equals et
42 * hashCode pour que ces méthodes retournes les mêmes résultat que les objets
43 * contenu.
44 *
45 * @param <T> type of object
46 */
47 public class TransparenteWeakReference<T> extends WeakReference<T> {
48
49 protected int hash;
50
51 protected String toString;
52
53 protected boolean objectToStringUsed = true;
54
55 public TransparenteWeakReference(T o) {
56 this(o, true);
57 }
58
59 public TransparenteWeakReference(T o, ReferenceQueue<? super T> queue) {
60 this(o, queue, true);
61 }
62
63 /**
64 * @param o TODO ?
65 * @param objectToStringUsed if true, this ref used toString method of
66 * encapsulated object otherwize used default Object toString
67 */
68 public TransparenteWeakReference(T o, boolean objectToStringUsed) {
69 super(o);
70 init(o, objectToStringUsed);
71 }
72
73 public TransparenteWeakReference(T o,
74 ReferenceQueue<? super T> queue,
75 boolean objectToStringUsed) {
76 super(o, queue);
77 init(o, objectToStringUsed);
78 }
79
80 /**
81 * On conserve le hash pour que la Reference puisse encore se faire
82 * passer pour l'objet alors que celui-ci a disparu de la memoire
83 *
84 * @param o TODO ?
85 * @param objectToStringUsed TODO ?
86 */
87 protected void init(T o, boolean objectToStringUsed) {
88 if (o == null) {
89 hash = 0;
90 } else {
91 hash = o.hashCode();
92 if (objectToStringUsed) {
93 toString = o.toString();
94 }
95 if (toString == null) {
96 toString = o.getClass().getName() + '@' +
97 Integer.toHexString(hash);
98 }
99 if (toString.length() > 100) {
100 toString = toString.substring(0, 100) + "...";
101 }
102 }
103 }
104
105 /**
106 * @param o l'objet a comparer
107 * @return {@code true} si meme reference memoire on les objets
108 * references sont egaux
109 */
110 @Override
111 public boolean equals(Object o) {
112 if (o == this) {
113 return true;
114 }
115 // on travail avec un variable local pour ne pas etre obligé de
116 // synchroniser la méthode
117 Object local = get();
118 Object other = o;
119 if (o instanceof Reference<?>) {
120 other = ((Reference<?>) o).get();
121
122 if (other == null) {
123 // on fait l'egalite sur les hash car on a perdu les objets
124 return o.hashCode() == hashCode();
125 }
126 }
127
128 return other == null && local == null ||
129 other != null && other.equals(local);
130 }
131
132 @Override
133 public int hashCode() {
134 return hash;
135 }
136
137 @Override
138 public String toString() {
139 return toString;
140 }
141 }