Package org.eclipse.persistence.internal.oxm

Source Code of org.eclipse.persistence.internal.oxm.ReferenceResolver

/*******************************************************************************
* Copyright (c) 1998, 2008 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*     Oracle - initial API and implementation from Oracle TopLink
******************************************************************************/
package org.eclipse.persistence.internal.oxm;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Vector;

import org.eclipse.persistence.internal.queries.ContainerPolicy;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.oxm.mappings.XMLCollectionReferenceMapping;
import org.eclipse.persistence.oxm.mappings.XMLObjectReferenceMapping;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.UnitOfWork;

public class ReferenceResolver {
    public static final String KEY = "REFERENCE_RESOLVER";
    private ArrayList references;

    /**
     * Return an instance of this class for a given unit of work.
     *
     * @param uow
     * @return
     */
    public static ReferenceResolver getInstance(Session unitOfWork) {
        if (unitOfWork == null) {
            return null;
        }
        return (ReferenceResolver) unitOfWork.getProperty(KEY);
    }

    /**
     * The default constructor initializes the list of References.
     */
    public ReferenceResolver() {
        references = new ArrayList();
    }
   
    /**
     * Add a Reference object to the list - these References will
     * be resolved after unmarshalling is complete.
     *
     * @param ref
     */
    public void addReference(Reference ref) {
        references.add(ref);
    }

    /**
     * INTERNAL:
     * Create vectors of primary key values to be used for cache lookup.  The map
     * of vectors on the reference is keyed on the reference descriptors primary
     * key field names.  Each of these vectors contains all of the values for a
     * particular key - in the order that they we read in from the document.  For
     * example, if the key field names are A, B, and C, and there are three reference
     * object instances, then the hashmap would have the following: 
     * (A=[1,2,3], B=[X,Y,Z], C=[Jim, Joe, Jane]).  If the primary key field names on
     * the reference descriptor contained [B, C, A], then the result of this method call
     * would be reference.primaryKeys=([X, Jim, 1], [Y, Joe, 2], [Z, Jane, 3]).
     * 
     * @param reference
     */
    private void createPKVectorsFromMap(Reference reference) {
      XMLCollectionReferenceMapping mapping = (XMLCollectionReferenceMapping) reference.getMapping()
      Vector pks = new Vector();
   
      Vector pkFields = mapping.getReferenceDescriptor().getPrimaryKeyFieldNames();
      if (pkFields.size() <= 0) {
        return;
      }
     
      Vector pkVals;
      boolean init = true;
     
      // for each primary key field name
      for (Iterator pkFieldNameIt = pkFields.iterator(); pkFieldNameIt.hasNext(); ) {
        pkVals = (Vector) reference.getPrimaryKeyMap().get(pkFieldNameIt.next());
       
        if (pkVals == null) {
          return;
        }
        // initialize the list of pk vectors once and only once
        if (init) {
          for (int i=0; i<pkVals.size(); i++) {
            pks.add(new Vector());
          }
          init = false;
        }
       
        // now add each value for the current target key to it's own vector
          for (int i=0; i<pkVals.size(); i++) {
          Object val = pkVals.get(i);
        ((Vector) pks.get(i)).add(val);
        }
      }
      reference.primaryKeys = pks;
    }   

    /**
     * Retrieve the reference for a given mapping instance.
     * 
     * @param mapping
     */
    public Reference getReference(XMLObjectReferenceMapping mapping, Object sourceObject) {
        for (int x = 0; x < references.size(); x++) {
            Reference reference = (Reference) references.get(x);
            if (reference.getMapping() == mapping && reference.getSourceObject() == sourceObject) {
              return reference;
            }
        }     
        return null;
    }

    /**
     * INTERNAL:
     * @param session typically will be a unit of work
     */
    public void resolveReferences(AbstractSession session) {
        for (int x = 0; x < references.size(); x++) {
            Reference reference = (Reference) references.get(x);

            if (reference.getMapping() instanceof XMLCollectionReferenceMapping) {
              XMLCollectionReferenceMapping mapping = (XMLCollectionReferenceMapping) reference.getMapping();
              ContainerPolicy cPolicy = mapping.getContainerPolicy();
              Object container = cPolicy.containerInstance();
              // create vectors of primary key values - one vector per reference instance
                createPKVectorsFromMap(reference);
              // loop over each pk vector and get object from cache - then add to collection and set on object
              for (Iterator pkIt = reference.getPrimaryKeys().iterator(); pkIt.hasNext();) {
                Vector pkVector = (Vector) pkIt.next();
                    Object value = session.getIdentityMapAccessor().getFromIdentityMap(pkVector, reference.getTargetClass());
               
                    if (value != null) {
                      cPolicy.addInto(value, container,  session);
                    }
              }
              // for each reference, get the source object and add it to the container policy
              // when finished, set the policy on the mapping
              mapping.setAttributeValueInObject(reference.getSourceObject(), container);
          } else if (reference.getMapping() instanceof XMLObjectReferenceMapping) {
              Object value = session.getIdentityMapAccessor().getFromIdentityMap(reference.getPrimaryKeys(), reference.getTargetClass());
              if (value != null) {
                  ((XMLObjectReferenceMapping)reference.getMapping()).setAttributeValueInObject(reference.getSourceObject(), value);
                }
              if(null != reference.getSetting()) {
                  reference.getSetting().setValue(value);
              }
          }
        }
        // release the unit of work, if required
        if (session.isUnitOfWork()) {
            ((UnitOfWork) session).release();
        }
       
        // reset the references list
        references = new ArrayList();
    }
}
TOP

Related Classes of org.eclipse.persistence.internal.oxm.ReferenceResolver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.