Source code: org/apache/derby/impl/sql/catalog/SPSNameCacheable.java
1 /*
2
3 Derby - Class org.apache.derby.impl.sql.catalog.SPSNameCacheable
4
5 Copyright 1999, 2004 The Apache Software Foundation or its licensors, as applicable.
6
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 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, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18
19 */
20
21 package org.apache.derby.impl.sql.catalog;
22
23 import org.apache.derby.iapi.services.cache.Cacheable;
24 import org.apache.derby.iapi.services.cache.CacheManager;
25
26 import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
27
28 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
29 import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;
30
31 import org.apache.derby.iapi.error.StandardException;
32
33 import org.apache.derby.iapi.services.sanity.SanityManager;
34
35 /**
36 * This class implements a Cacheable for a DataDictionary cache of
37 * sps descriptors, with the lookup key being the name/schema of the sps.
38 * Assumes client passes in a string that includes the schema name.
39 * <p>
40 * The cache ensures that the class of the target sps is loaded
41 * if the sps is found in cache. This is ensured by calling
42 * loadGeneratedClass() on the sps when it is added to the cache.
43 * Each subsequent user of the sps cache will do its own load/unload
44 * on the class. Because the class manager/loader maintains reference
45 * counts on the classes it is handling, the user load/unload will
46 * just increment/decrement the use count. Only when the sps is
47 * uncached will it be unloaded.
48 */
49 class SPSNameCacheable implements Cacheable
50 {
51 private TableKey identity;
52 private SPSDescriptor spsd;
53 private final DataDictionaryImpl dd;
54
55
56 SPSNameCacheable(DataDictionaryImpl dd) {
57 this.dd = dd;
58 }
59
60 /* Cacheable interface */
61
62 /** @see Cacheable#clearIdentity */
63 public void clearIdentity()
64 {
65 if (spsd != null)
66 {
67 dd.spsCacheEntryRemoved(spsd);
68
69 if (SanityManager.DEBUG)
70 {
71 if (SanityManager.DEBUG_ON("SPSNameCacheTrace"))
72 {
73 System.out.println("SPSCACHE: clearIdentity() on "+spsd.getName());
74 }
75 }
76 spsd = null;
77 identity = null;
78 }
79 }
80
81 /** @see Cacheable#getIdentity */
82 public Object getIdentity()
83 {
84 return identity;
85 }
86
87 /** @see Cacheable#createIdentity */
88 public Cacheable createIdentity(Object key, Object createParameter)
89 {
90 if (SanityManager.DEBUG)
91 {
92 if (!(key instanceof TableKey))
93 {
94 SanityManager.THROWASSERT("Key for a SPSNameCacheElement is a " +
95 key.getClass().getName() +
96 " instead of a TableKey");
97 }
98 if (!(createParameter instanceof SPSDescriptor))
99 {
100 SanityManager.THROWASSERT("Create parameter for a SPSNameCacheElement is a " +
101 createParameter.getClass().getName() +
102 "instead of a SPSDescriptorImpl");
103 }
104 }
105
106 identity = (TableKey)key;
107 spsd = (SPSDescriptor) createParameter;
108
109 if (spsd != null)
110 {
111 if (SanityManager.DEBUG)
112 {
113 if (SanityManager.DEBUG_ON("SPSNameCacheTrace"))
114 {
115 System.out.println("SPSCACHE: createIdentity() on "+spsd.getName());
116 }
117 }
118
119 dd.spsCacheEntryAdded(spsd);
120 try
121 {
122 spsd.loadGeneratedClass();
123 } catch (StandardException e)
124 {
125 /*
126 ** We cannot throw an exception here, and although
127 ** we don't expect a problem, we'll put some debugging
128 ** under sanity just in case. Note that even if we
129 ** do get an exception here, everything else will work
130 ** ok -- subsequent attempts to access the generated
131 ** class for this sps will do a load themselves, and
132 ** they will throw their exception back to the user.
133 */
134 if (SanityManager.DEBUG)
135 {
136 System.out.println("Error loading class for "+spsd.getName());
137 System.out.println(e);
138 e.printStackTrace();
139 }
140 }
141 return this;
142 }
143 else
144 {
145 return null;
146 }
147 }
148
149 /**
150 * @see Cacheable#setIdentity
151 *
152 * @exception StandardException Thrown on error
153 */
154 public Cacheable setIdentity(Object key) throws StandardException
155 {
156 if (SanityManager.DEBUG)
157 {
158 if (!(key instanceof TableKey))
159 {
160 SanityManager.THROWASSERT("Key for a SPSNameCacheable Element is a " +
161 key.getClass().getName() +
162 " instead of a TableKey");
163 }
164 }
165
166
167 identity = (TableKey)key ;
168 spsd = dd.getUncachedSPSDescriptor(identity);
169 if (spsd != null)
170 {
171 if (SanityManager.DEBUG)
172 {
173 if (SanityManager.DEBUG_ON("SPSNameCacheTrace"))
174 {
175 System.out.println("SPSCACHE: setIdentity() on "+spsd.getName());
176 }
177 }
178
179 dd.spsCacheEntryAdded(spsd);
180 try
181 {
182 spsd.loadGeneratedClass();
183 } catch (StandardException e)
184 {
185 /*
186 ** We cannot throw an exception here, and although
187 ** we don't expect a problem, we'll put some debugging
188 ** under sanity just in case. Note that even if we
189 ** do get an exception here, everything else will work
190 ** ok -- subsequent attempts to access the generated
191 ** class for this sps will do a load themselves, and
192 ** they will throw their exception back to the user.
193 */
194 if (SanityManager.DEBUG)
195 {
196 System.out.println("Error loading class for "+spsd.getName());
197 System.out.println(e);
198 e.printStackTrace();
199 }
200 }
201 return this;
202 }
203 else
204 {
205 return null;
206 }
207 }
208
209 /* Cacheable interface */
210
211 /** @see Cacheable#clean */
212 public void clean(boolean forRemove)
213 {
214 return;
215 }
216
217 /** @see Cacheable#isDirty */
218 public boolean isDirty()
219 {
220 return false;
221 }
222
223 /**
224 * Get the sps descriptor that is associated with this Cacheable
225 */
226 public SPSDescriptor getSPSDescriptor()
227 {
228 return spsd;
229 }
230
231 /**
232 * Check the consistency of the table descriptor held by this TDCacheable
233 * versus an uncached table descriptor.
234 *
235 * @param uncachedSpsd The uncached descriptor to compare to
236 * @param identity The identity of the table descriptor
237 * @param reportInconsistent A HeaderPrintWriter to send complaints to
238 *
239 * @return true if the descriptors are the same, false if they're different
240 *
241 * @exception StandardException Thrown on error
242 */
243 private boolean checkConsistency(SPSDescriptor uncachedSpsd,
244 Object identity,
245 HeaderPrintWriter reportInconsistent)
246 throws StandardException
247 {
248 boolean retval = true;
249
250 if (SanityManager.DEBUG)
251 {
252 if (uncachedSpsd == null)
253 {
254 reportInconsistent.println(
255 "Inconsistent SPSNameCacheable: identity = " + identity +
256 ", uncached table descriptor not found.");
257 retval = false;
258 }
259 else
260 {
261 if (
262 (!uncachedSpsd.getText().equals(spsd.getText())) ||
263 (!uncachedSpsd.getUsingText().equals(spsd.getUsingText())) ||
264 (!uncachedSpsd.getQualifiedName().equals(spsd.getQualifiedName()))
265 )
266 {
267 reportInconsistent.println(
268 "Inconsistent SPSNameCacheable: identity = " + identity +
269 ", cached SPS = " +
270 spsd +
271 ", uncached SPS = " +
272 uncachedSpsd);
273
274 retval = false;
275 }
276 }
277 }
278
279 return retval;
280 }
281 }