From f089457f2a6d712f1bf92c4d3ffc4866f54f5ec1 Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" <bronee@gmail.com> Date: Sun, 3 Jun 2007 01:39:33 +0000 Subject: Prevent premature uncaching of StorableInfo. --- .../carbonado/info/StorableIntrospector.java | 43 ++++++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java b/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java index 0fd427d..ce704e3 100644 --- a/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java +++ b/src/main/java/com/amazon/carbonado/info/StorableIntrospector.java @@ -223,15 +223,24 @@ public class StorableIntrospector { primaryKey, alternateKeys, type.getAnnotation(Independent.class) != null, type.getAnnotation(Authoritative.class) != null); + cCache.put(type, new SoftReference<StorableInfo<?>>(info)); + // Now that the StorableInfo object has been constructed, assign it + // to all properties to prevent it from being prematurely uncached. + for (StorableProperty property : properties.values()) { + if (property instanceof SimpleProperty) { + ((SimpleProperty)property).setEnclosingInfo(info); + } + } + // Finish resolving join properties, after properties have been // added to cache. This makes it possible for joins to (directly or // indirectly) reference their own enclosing type. If not resolved // late, then there would be a stack overflow. for (StorableProperty property : properties.values()) { if (property instanceof JoinProperty) { - ((JoinProperty)property).resolveJoin(errorMessages, info); + ((JoinProperty)property).resolveJoin(errorMessages); } } @@ -241,7 +250,7 @@ public class StorableIntrospector { for (StorableProperty<S> property : properties.values()) { if (property instanceof SimpleProperty && property.isDerived()) { anyDerived = true; - ((SimpleProperty)property).resolveDerivedFrom(errorMessages, info); + ((SimpleProperty)property).resolveDerivedFrom(errorMessages); } } @@ -1573,6 +1582,11 @@ public class StorableIntrospector { // Resolved derived to properties. private ChainedProperty<S>[] mDerivedTo; + // Reference to enclosing StorableInfo. This reference exists to + // prevent the StorableInfo from being uncached so as long as a + // reference from a property exists. + protected StorableInfo<S> mEnclosingInfo; + SimpleProperty(BeanProperty property, Class<S> enclosing, boolean nullable, boolean primaryKey, boolean alternateKey, String[] aliases, StorablePropertyConstraint[] constraints, @@ -1822,7 +1836,11 @@ public class StorableIntrospector { app.append('}'); } - void resolveDerivedFrom(List<String> errorMessages, StorableInfo<S> info) { + void setEnclosingInfo(StorableInfo<S> info) { + mEnclosingInfo = info; + } + + void resolveDerivedFrom(List<String> errorMessages) { Derived derived = mDerived; // Don't need this anymore. mDerived = null; @@ -1840,7 +1858,7 @@ public class StorableIntrospector { for (String fromName : fromNames) { ChainedProperty<S> from; try { - from = ChainedProperty.parse(info, fromName); + from = ChainedProperty.parse(mEnclosingInfo, fromName); } catch (IllegalArgumentException e) { errorMessages.add ("Cannot find derived-from property: \"" + @@ -1885,8 +1903,7 @@ public class StorableIntrospector { if (lastInChain.isDerived()) { // Expand derived dependencies. - ((SimpleProperty) lastInChain) - .resolveDerivedFrom(errorMessages, examine(lastInChain.getEnclosingType())); + ((SimpleProperty) lastInChain).resolveDerivedFrom(errorMessages); for (ChainedProperty<?> lastFrom : lastInChain.getDerivedFromProperties()) { ChainedProperty<S> dep; if (trimmed == null) { @@ -2109,7 +2126,7 @@ public class StorableIntrospector { * Finishes the definition of this join property. Can only be called once. */ @SuppressWarnings("unchecked") - void resolveJoin(List<String> errorMessages, StorableInfo<S> info) { + void resolveJoin(List<String> errorMessages) { StorableInfo<?> joinedInfo; try { joinedInfo = examine(getJoinedType()); @@ -2150,7 +2167,7 @@ public class StorableIntrospector { // Verify that internal properties exist and are not themselves joins. for (int i=0; i<mInternalNames.length; i++) { String internalName = mInternalNames[i]; - StorableProperty property = info.getAllProperties().get(internalName); + StorableProperty property = mEnclosingInfo.getAllProperties().get(internalName); if (property == null) { errorMessages.add ("Cannot find internal join element: \"" + @@ -2452,8 +2469,8 @@ public class StorableIntrospector { boolean oneToOne = false; oneToOneCheck: { - Set<StorableProperty> internalPrimaryKey = - new HashSet<StorableProperty>(info.getPrimaryKeyProperties().values()); + Set<StorableProperty> internalPrimaryKey = new HashSet<StorableProperty> + (mEnclosingInfo.getPrimaryKeyProperties().values()); for (int i=0; i<mInternal.length; i++) { internalPrimaryKey.remove(getInternalJoinElement(i)); @@ -2464,10 +2481,12 @@ public class StorableIntrospector { } altKeyScan: - for (int i=0; i<info.getAlternateKeyCount(); i++) { + for (int i=0; i<mEnclosingInfo.getAlternateKeyCount(); i++) { Set<StorableProperty> altKey = new HashSet<StorableProperty>(); - for (OrderedProperty op : info.getAlternateKey(i).getProperties()) { + for (OrderedProperty op : + mEnclosingInfo.getAlternateKey(i).getProperties()) + { ChainedProperty chained = op.getChainedProperty(); if (chained.getChainCount() > 0) { // Funny alt key. Pretend it does not exist. -- cgit v1.2.3