0 Replies Latest reply on Feb 4, 2010 2:52 PM by Ales Justin

    Using MetaDataRetrievalFactory is missing addition

    Ales Justin Master

      When 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?