| /* |
| |
| Derby - Class org.apache.derby.impl.sql.catalog.SPSNameCacheable |
| |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to you under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| */ |
| |
| package org.apache.derby.impl.sql.catalog; |
| |
| import org.apache.derby.iapi.error.StandardException; |
| import org.apache.derby.iapi.services.cache.Cacheable; |
| import org.apache.derby.shared.common.sanity.SanityManager; |
| import org.apache.derby.iapi.sql.dictionary.SPSDescriptor; |
| |
| /** |
| * This class implements a Cacheable for a DataDictionary cache of |
| * sps descriptors, with the lookup key being the name/schema of the sps. |
| * Assumes client passes in a string that includes the schema name. |
| * <p> |
| * The cache ensures that the class of the target sps is loaded |
| * if the sps is found in cache. This is ensured by calling |
| * loadGeneratedClass() on the sps when it is added to the cache. |
| * Each subsequent user of the sps cache will do its own load/unload |
| * on the class. Because the class manager/loader maintains reference |
| * counts on the classes it is handling, the user load/unload will |
| * just increment/decrement the use count. Only when the sps is |
| * uncached will it be unloaded. |
| */ |
| class SPSNameCacheable implements Cacheable |
| { |
| private TableKey identity; |
| private SPSDescriptor spsd; |
| private final DataDictionaryImpl dd; |
| |
| |
| SPSNameCacheable(DataDictionaryImpl dd) { |
| this.dd = dd; |
| } |
| |
| /* Cacheable interface */ |
| |
| /** @see Cacheable#clearIdentity */ |
| public void clearIdentity() |
| { |
| if (spsd != null) |
| { |
| dd.spsCacheEntryRemoved(spsd); |
| |
| if (SanityManager.DEBUG) |
| { |
| if (SanityManager.DEBUG_ON("SPSNameCacheTrace")) |
| { |
| System.out.println("SPSCACHE: clearIdentity() on "+spsd.getName()); |
| } |
| } |
| spsd = null; |
| identity = null; |
| } |
| } |
| |
| /** @see Cacheable#getIdentity */ |
| public Object getIdentity() |
| { |
| return identity; |
| } |
| |
| /** @see Cacheable#createIdentity */ |
| public Cacheable createIdentity(Object key, Object createParameter) |
| { |
| if (SanityManager.DEBUG) |
| { |
| if (!(key instanceof TableKey)) |
| { |
| SanityManager.THROWASSERT("Key for a SPSNameCacheElement is a " + |
| key.getClass().getName() + |
| " instead of a TableKey"); |
| } |
| if (!(createParameter instanceof SPSDescriptor)) |
| { |
| SanityManager.THROWASSERT("Create parameter for a SPSNameCacheElement is a " + |
| createParameter.getClass().getName() + |
| "instead of a SPSDescriptorImpl"); |
| } |
| } |
| |
| identity = (TableKey)key; |
| spsd = (SPSDescriptor) createParameter; |
| |
| if (spsd != null) |
| { |
| if (SanityManager.DEBUG) |
| { |
| if (SanityManager.DEBUG_ON("SPSNameCacheTrace")) |
| { |
| System.out.println("SPSCACHE: createIdentity() on "+spsd.getName()); |
| } |
| } |
| |
| dd.spsCacheEntryAdded(spsd); |
| try |
| { |
| spsd.loadGeneratedClass(); |
| } catch (StandardException e) |
| { |
| /* |
| ** We cannot throw an exception here, and although |
| ** we don't expect a problem, we'll put some debugging |
| ** under sanity just in case. Note that even if we |
| ** do get an exception here, everything else will work |
| ** ok -- subsequent attempts to access the generated |
| ** class for this sps will do a load themselves, and |
| ** they will throw their exception back to the user. |
| */ |
| if (SanityManager.DEBUG) |
| { |
| System.out.println("Error loading class for "+spsd.getName()); |
| System.out.println(e); |
| e.printStackTrace(); |
| } |
| } |
| return this; |
| } |
| else |
| { |
| return null; |
| } |
| } |
| |
| /** |
| * @see Cacheable#setIdentity |
| * |
| * @exception StandardException Thrown on error |
| */ |
| public Cacheable setIdentity(Object key) throws StandardException |
| { |
| if (SanityManager.DEBUG) |
| { |
| if (!(key instanceof TableKey)) |
| { |
| SanityManager.THROWASSERT("Key for a SPSNameCacheable Element is a " + |
| key.getClass().getName() + |
| " instead of a TableKey"); |
| } |
| } |
| |
| |
| identity = (TableKey)key ; |
| spsd = dd.getUncachedSPSDescriptor(identity); |
| if (spsd != null) |
| { |
| if (SanityManager.DEBUG) |
| { |
| if (SanityManager.DEBUG_ON("SPSNameCacheTrace")) |
| { |
| System.out.println("SPSCACHE: setIdentity() on "+spsd.getName()); |
| } |
| } |
| |
| dd.spsCacheEntryAdded(spsd); |
| try |
| { |
| spsd.loadGeneratedClass(); |
| } catch (StandardException e) |
| { |
| /* |
| ** We cannot throw an exception here, and although |
| ** we don't expect a problem, we'll put some debugging |
| ** under sanity just in case. Note that even if we |
| ** do get an exception here, everything else will work |
| ** ok -- subsequent attempts to access the generated |
| ** class for this sps will do a load themselves, and |
| ** they will throw their exception back to the user. |
| */ |
| if (SanityManager.DEBUG) |
| { |
| System.out.println("Error loading class for "+spsd.getName()); |
| System.out.println(e); |
| e.printStackTrace(); |
| } |
| } |
| return this; |
| } |
| else |
| { |
| return null; |
| } |
| } |
| |
| /* Cacheable interface */ |
| |
| /** @see Cacheable#clean */ |
| public void clean(boolean forRemove) |
| { |
| return; |
| } |
| |
| /** @see Cacheable#isDirty */ |
| public boolean isDirty() |
| { |
| return false; |
| } |
| |
| /** |
| * Get the sps descriptor that is associated with this Cacheable |
| */ |
| public SPSDescriptor getSPSDescriptor() |
| { |
| return spsd; |
| } |
| |
| // /** |
| // * Check the consistency of the table descriptor held by this TDCacheable |
| // * versus an uncached table descriptor. |
| // * |
| // * @param uncachedSpsd The uncached descriptor to compare to |
| // * @param identity The identity of the table descriptor |
| // * @param reportInconsistent A HeaderPrintWriter to send complaints to |
| // * |
| // * @return true if the descriptors are the same, false if they're different |
| // * |
| // * @exception StandardException Thrown on error |
| // */ |
| // private boolean checkConsistency(SPSDescriptor uncachedSpsd, |
| // Object identity, |
| // HeaderPrintWriter reportInconsistent) |
| // throws StandardException |
| // { |
| // boolean retval = true; |
| // |
| // if (SanityManager.DEBUG) |
| // { |
| // if (uncachedSpsd == null) |
| // { |
| // reportInconsistent.println( |
| // "Inconsistent SPSNameCacheable: identity = " + identity + |
| // ", uncached table descriptor not found."); |
| // retval = false; |
| // } |
| // else |
| // { |
| // if ( |
| // (!uncachedSpsd.getText().equals(spsd.getText())) || |
| // (!uncachedSpsd.getUsingText().equals(spsd.getUsingText())) || |
| // (!uncachedSpsd.getQualifiedName().equals(spsd.getQualifiedName())) |
| // ) |
| // { |
| // reportInconsistent.println( |
| // "Inconsistent SPSNameCacheable: identity = " + identity + |
| // ", cached SPS = " + |
| // spsd + |
| // ", uncached SPS = " + |
| // uncachedSpsd); |
| |
| // retval = false; |
| // } |
| // } |
| // } |
| // |
| // return retval; |
| // } |
| } |