Using MetaDataRetrievalFactory is missing addition
alesj Feb 4, 2010 2:52 PMWhen we use an explicit MetaDataRetrievalFactory to create MDRetrieval for scope level,
we never actually add the newly created retrieval to repository.
This results in retrieval override, since the factory is invoked for every lookup.
Just follow PreInstallAction and its MD::addMetaData invocation.
AbstractScopeInfo
public void addMetaData(MutableMetaDataRepository repository, ControllerContext context) { this.repository = repository; ScopeKey scope = getMutableScope(); MetaDataRetrieval retrieval = repository.getMetaDataRetrieval(scope); // HERE -- factory creates it MutableMetaDataLoader mutable; if (retrieval == null) { mutable = initMutableMetaDataRetrieval(repository, context, scope); repository.addMetaDataRetrieval(mutable); addedScopes.add(scope); } else { mutable = getMutableMetaDataLoader(retrieval); } if (mutable == null) { log.warn("MetaData context is not mutable: " + retrieval + " for " + context.toShortString()); return; } updateMetaData(repository, context, mutable, true); }
BasicMetaDataRepository
public MetaDataRetrieval getMetaDataRetrieval(ScopeKey key) { MetaDataRetrieval result = retrievals.get(key); if (result != null) return result; // Is this a single level? Collection<Scope> scopes = key.getScopes(); if (scopes.size() != 1) return null; // See if we have a factory Scope scope = scopes.iterator().next(); ScopeLevel scopeLevel = scope.getScopeLevel(); MetaDataRetrievalFactory factory = getMetaDataRetrievalFactory(scopeLevel); if (factory == null) return null; // We have a factory, use it return factory.getMetaDataRetrieval(scope); // HERE -- created, but never added }
I currently fixed it by adding the newly created retrieval in the MDRFactory itself.
But what should be the right place to do it? Or how?
Since AbstractKernelScopeInfo only cares about getting the MDRetrieval.
Perhaps a getOrCreateAndAdd method on MutableMetaDataRepository?