Code Search for Developers
 
 
  

DomainEntityLoaderBean.java from Texai at Krugle


Show DomainEntityLoaderBean.java syntax highlighted

/*
 * DomainEntityLoaderBean.java
 *
 * Created on October 31, 2006, 11:22 AM
 *
 * Description: This stateless session bean loads domain entities from the knowledge base,
 * mapping KB propositions onto domain entity associations.
 *
 * Copyright (C) 2006 Stephen L. Reed.
 *
 * This program is free software; you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this program;
 * if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

package org.texai.kb.ejb.session;

import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.Stack;
import java.util.UUID;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.FetchType;
import javax.persistence.OrderBy;
import javax.persistence.Transient;
import net.sf.cglib.proxy.Enhancer;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import org.apache.log4j.Logger;
import org.texai.kb.Constants;
import org.texai.kb.ejb.session.shared.AssociationFinderLocal;
import org.texai.kb.ejb.session.shared.TermDefinitionAccessorLocal;
import org.texai.kb.ejb.session.shared.TermFinderFacadeLocal;
import org.texai.kb.entity.AtomicTerm;
import org.texai.kb.entity.Formula;
import org.texai.kb.entity.NonAtomicTerm;
import org.texai.kb.entity.PDate;
import org.texai.kb.entity.PDouble;
import org.texai.kb.entity.PLong;
import org.texai.kb.entity.PString;
import org.texai.kb.entity.AbstractReifiedTerm;
import org.texai.kb.entity.AbstractTerm;
import org.texai.kb.persistence.DomainProperty;
import org.texai.kb.persistence.lazy.DomainEntityLazyLoader;
import org.texai.kb.persistence.lazy.LazyList;
import org.texai.kb.persistence.lazy.LazySet;
import org.texai.util.ByteUtils;
import org.texai.util.TexaiException;

/**
 *
 * @author reed
 */
@Stateless
public class DomainEntityLoaderBean extends AbstractDomainEntityAccessor implements DomainEntityLoaderLocal {   // NOPMD
  
  /** the term finder, which is injected by the container */
  @EJB
  private TermFinderFacadeLocal termFinderFacade;          // NOPMD
  
  /** the association finder, which is injected by the container */
  @EJB
  private AssociationFinderLocal associationFinder;        // NOPMD
  
  /** the term definition accessor, which is injected by the container */
  @EJB
  private TermDefinitionAccessorLocal termDefinitionAccessor;        // NOPMD
  
  /** the logger */
  @Transient
  private Logger logger;               // NOPMD
  
  /** the dictionary of connected domain entities, term --> domain instance */
  @Transient
  private Map<AtomicTerm, Object> connectedDomainEntityDictionary = new HashMap<AtomicTerm, Object>();
  
  /** the stack of domain entity information that allows the session bean to perform recursive method calls */
  @Transient
  private final Stack<DomainEntityInfo> domainEntityInfoStack = new Stack<DomainEntityInfo>();
  
  
  /** Creates a new instance of DomainEntityLoaderBean */
  public DomainEntityLoaderBean() {
    super();
  }
  
  /** Injects the shared session bean dependencies when executed out of the container. */
  public void injectSharedBeanDependencies() {
    if (termFinderFacade != null) {
      termFinderFacade.setTermDefinitionAccessor(termDefinitionAccessor);
    }
    if (associationFinder != null) {
      associationFinder.setTermFinderFacade(termFinderFacade);
    }
    if (termDefinitionAccessor != null) {
      termDefinitionAccessor.setTermFinderFacade(termFinderFacade);
      termDefinitionAccessor.setAssociationFinder(associationFinder);
    }
  }
  
  /** Loads the domain entity from propositions in the knowledge base given its term id.
   *
   * @param termId the id of the atomic term that represents the domain entity
   * @return the domain entity
   */
  public Object loadDomainEntity(final UUID termId) {
    //Preconditions
    assert termId != null : "termId must not be null";
    
    return loadDomainEntity(termId, false);
  }
  
  /** Loads the domain entity from propositions in the knowledge base given its term id.
   *
   * @param termId the id of the atomic term that represents the domain entity
   * @param isLoadableFromDomainEntityCache the indicator that domain entities can be loaded from the cache
   * @return the domain entity
   */
  public Object loadDomainEntity(final UUID termId, final boolean isLoadableFromDomainEntityCache) {
    //Preconditions
    assert termId != null : "termId must not be null";
    
    getLogger().debug(stackLevel() + "loading domain entity with term id: " + termId);
    final AtomicTerm instanceTerm = termFinderFacade.findAtomicTermByTermId(ByteUtils.toBytes(termId));
    if (instanceTerm == null) {
      throw new IllegalArgumentException("no domain entity instance term found for term id " + termId);
    }
    return loadDomainEntity(instanceTerm, isLoadableFromDomainEntityCache);
  }
  
  /** Loads the domain entity from propositions in the knowledge base given its instance term.
   *
   * @param instanceTerm the atomic term that represents the domain entity
   * @return the domain entity
   */
  public Object loadDomainEntity(final AtomicTerm instanceTerm) {
    //Preconditions
    assert instanceTerm != null : "instanceTerm must not be null";
    
    return loadDomainEntity(instanceTerm, false);
  }
  
  /** Loads the domain entity from propositions in the knowledge base given its term id.
   *
   * @param instanceTerm the atomic term that represents the domain entity
   * @param isLoadableFromDomainEntityCache the indicator that domain entities can be loaded from the cache
   * @return the domain entity
   */
  public Object loadDomainEntity(final AtomicTerm instanceTerm, final boolean isLoadableFromDomainEntityCache) {
    //Preconditions
    assert instanceTerm != null : "instanceTerm must not be null";
    
    connectedDomainEntityDictionary.clear();
    return loadDomainEntityInternal(instanceTerm, isLoadableFromDomainEntityCache);
  }
  
  /** Loads domain entities having the given property and value.
   *
   * @param property the given property
   * @param value the value of the property
   * @param domainEntityClass the class of the desired domain entity
   * @return the domain entities having the given property and value
   */
  public Set<Object> loadDomainEntitiesByPropertyValue(
          final AtomicTerm property,
          final Object value,
          final Class domainEntityClass) {
    //Preconditions
    assert property != null : "property must not be null";
    assert value != null : "value must not be null";
    assert domainEntityClass != null : "domainEntityClass must not be null";
    
    final Set<Object> domainEntities = new HashSet<Object>();
    connectedDomainEntityDictionary.clear();
    initializeAbstractSessionState();
    final Set<AtomicTerm> instanceTerms = findInstanceTermsByPropertyValue(property, value, domainEntityClass);
    for (final AtomicTerm instanceTerm : instanceTerms) {
      domainEntities.add(loadDomainEntity(instanceTerm, false));
    }
    return domainEntities;
  }
  
  /** Loads the domain entity from propositions in the knowledge base given an identifying property and value, or null if
   * not found.
   *
   * @param property the identifying property
   * @param value the value of the property which identifies the desired domain entity
   * @param domainEntityClass the class of the desired domain entity
   * @return the domain entity having the given property and value, or null if not found
   */
  public Object loadDomainEntityByIndentifyingPropertyValue(
          final AtomicTerm property,
          final Object value,
          final Class domainEntityClass) {
    //Preconditions
    assert property != null : "property must not be null";
    assert value != null : "value must not be null";
    assert domainEntityClass != null : "domainEntityClass must not be null";
    
    return loadDomainEntityByIndentifyingPropertyValue(property, value, domainEntityClass, false);
  }
  
  /** Loads the domain entity from propositions in the knowledge base given an identifying property and value, or null if
   * not found.
   *
   * @param property the identifying property
   * @param value the value of the property which identifies the desired domain entity
   * @param domainEntityClass the class of the desired domain entity
   * @param isLoadableFromDomainEntityCache the indicator that domain entities can be loaded from the cache
   * @return the domain entity having the given property and value, or null if not found
   */
  public Object loadDomainEntityByIndentifyingPropertyValue(
          final AtomicTerm property,
          final Object value,
          final Class domainEntityClass,
          final boolean isLoadableFromDomainEntityCache) {
    //Preconditions
    assert property != null : "property must not be null";
    assert value != null : "value must not be null";
    assert domainEntityClass != null : "domainEntityClass must not be null";
    
    loadDomainEntityShellByIndentifyingPropertyValue(property, value, domainEntityClass);
    if (getInstanceTerm() == null) {
      return null;
    }
    loadFields(isLoadableFromDomainEntityCache);
    return getDomainEntity();
  }
  
  /** Loads the domain entity from propositions in the knowledge base given an identifying property and value.
   *
   * @param property the identifying property
   * @param value the value of the property which identifies the desired domain entity
   * @param ClassPersistenceContext the context from which the class-scoped associations are loaded
   * @return the domain entity having the given property and value, or null if not found
   */
  public Object loadDomainEntityByIndentifyingPropertyValue(
          final AtomicTerm property,
          final Object value,
          final AbstractReifiedTerm ClassPersistenceContext) {
    //Preconditions
    assert property != null : "property must not be null";
    assert value != null : "value must not be null";
    assert ClassPersistenceContext != null : "ClassPersistenceContext must not be null";
    
    return loadDomainEntityByIndentifyingPropertyValue(property, value, ClassPersistenceContext, false);
  }
  
  /** Loads the domain entity from propositions in the knowledge base given an identifying property and value.
   *
   * @param property the identifying property
   * @param value the value of the property which identifies the desired domain entity
   * @param ClassPersistenceContext the context from which the class-scoped associations are loaded
   * @param isLoadableFromDomainEntityCache the indicator that domain entities can be loaded from the cache
   * @return the domain entity having the given property and value, or null if not found
   */
  public Object loadDomainEntityByIndentifyingPropertyValue(
          final AtomicTerm property,
          final Object value,
          final AbstractReifiedTerm ClassPersistenceContext,
          final boolean isLoadableFromDomainEntityCache) {
    //Preconditions
    assert property != null : "property must not be null";
    assert value != null : "value must not be null";
    assert ClassPersistenceContext != null : "ClassPersistenceContext must not be null";
    
    getLogger().debug(stackLevel() + "loading domain entity by identifying property: "
            + property + "\n  and value: " + value
            + "\n  context: " + ClassPersistenceContext);
    final AbstractTerm arg2 = termFinderFacade.findTermByValue(value);
    if (arg2 == null) {
      return null;
    }
    final Set<AbstractTerm> arg1s = associationFinder.gatherArg1TermsFromBinaryGAFs(
            property,
            arg2,
            ClassPersistenceContext);
    
    if (arg1s.isEmpty()) {
      return null;
    }
    if (arg1s.size() > 1) {
      throw new TexaiException("expected only one domain entity, found " + arg1s + "\n  property: "
              + property + "\n  and value: " + value
              + "\n  context: " + ClassPersistenceContext);
    }
    return loadDomainEntity((AtomicTerm) arg1s.toArray()[0], isLoadableFromDomainEntityCache);
  }
  
  /** Loads the domain entity shell, which is the @Id field only, from propositions in the knowledge base
   * given an identifying property and value, or null if not found.
   *
   * @param property the identifying property
   * @param value the value of the property which identifies the desired domain entity
   * @param domainEntityClass the class of the desired domain entity
   * @return the domain entity shell having the given property and value, or null if not found
   */
  public Object loadDomainEntityShellByIndentifyingPropertyValue(
          final AtomicTerm property,
          final Object value,
          final Class domainEntityClass) {
    //Preconditions
    assert property != null : "property must not be null";
    assert value != null : "value must not be null";
    assert domainEntityClass != null : "domainEntityClass must not be null";
    
    getLogger().debug(stackLevel() + "loading domain entity shell by identifying property: "
            + property + "\n  and value: " + value
            + "\n  domain enitity class: " + domainEntityClass);
    connectedDomainEntityDictionary.clear();
    initializeAbstractSessionState();
    if (!findInstanceTermByIndentifyingPropertyValue(property, value, domainEntityClass)) {
      return null;
    }
    instantiateDomainEntity();
    loadIdField();
    final Cache cache = CacheManager.getInstance().getCache(Constants.CACHE_CONNECTED_DOMAIN_ENTITY_TERM_IDS);
    assert cache != null : "cache not found for: " + Constants.CACHE_CONNECTED_DOMAIN_ENTITY_TERM_IDS;
    final Element element = new Element(getDomainEntity(), getInstanceTerm().getTermId());
    cache.put(element);
    return getDomainEntity();
  }
  
  
  /** Loads the domain entity field.
   *
   * @param domainEntity the domain entity
   * @param field the field to be loaded
   * @param domainProperty the domain property the associates field value(s) in the knowledge base
   * @param isLoadableFromDomainEntityCache the indicator that domain entities can be loaded from the cache
   * @return the value of the loaded field
   */
  public Object loadDomainEntityField(
          final Object domainEntity,
          final Field field,
          final DomainProperty domainProperty,
          final boolean isLoadableFromDomainEntityCache) {
    //Preconditions
    assert domainEntity != null : "domainInstance must not be null";
    assert field != null : "field must not be null";
    assert domainProperty != null : "domainProperty must not be null";
    
    getLogger().debug(stackLevel() + "loading domain entity entity " + domainEntity.getClass().getName()
    + "\n  field: " + field
            + "\n  domainProperty: " + domainProperty);
    saveAbstractSessionState();
    initializeAbstractSessionState();
    setDomainEntityClass(domainEntity.getClass());
    setDomainEntity(domainEntity);
    gatherAnnotationsForDomainEntityClass();
    configureDomainContextSettings();
    setClassPersistenceContext(termFinderFacade.findAtomicTermByTermName(getClassPersistenceContextName()));
    setInstanceTermFromIdField();
    final Object value = loadField(field, domainProperty, isLoadableFromDomainEntityCache);
    restoreAbstractSessionState();
    return value;
  }
  
  /** Finds the instance term by the given identifying property value.
   *
   * @param property the identifying property
   * @param value the value of the property which identifies the desired domain entity
   * @param domainEntityClass the class of the desired domain entity
   * @return true if the term is found
   */
  private boolean findInstanceTermByIndentifyingPropertyValue(
          final AtomicTerm property,
          final Object value,
          final Class domainEntityClass) {
    //Preconditions
    assert property != null : "property must not be null";
    assert value != null : "value must not be null";
    assert domainEntityClass != null : "domainEntityClass must not be null";
    
    final AbstractTerm arg2 = termFinderFacade.findTermByValue(value);
    if (arg2 == null) {
      return false;
    }
    setDomainEntityClass(domainEntityClass);
    gatherAnnotationsForDomainEntityClass();
    configureDomainContextSettings();
    setClassPersistenceContext(termFinderFacade.findAtomicTermByTermName(getClassPersistenceContextName()));
    
    final Set<AbstractTerm> arg1s = associationFinder.gatherArg1TermsFromBinaryGAFs(
            property,
            arg2,
            getClassPersistenceContext());
    
    if (arg1s.isEmpty()) {
      return false;
    }
    if (arg1s.size() > 1) {
      throw new TexaiException("expected only one domain entity, found " + arg1s + "\n  property: "
              + property + "\n  and value: " + value
              + "\n  domain enitity class: " + domainEntityClass);
    }
    final AtomicTerm instanceTerm = (AtomicTerm) arg1s.toArray()[0];
    setInstanceTerm(instanceTerm);
    return true;
  }
  
  /** Returns the set of instance terms having the given property and value.
   *
   * @param property the identifying property
   * @param value the value of the property which identifies the desired domain entity
   * @param domainEntityClass the class of the desired domain entity
   * @return true if the term is found
   */
  private Set<AtomicTerm> findInstanceTermsByPropertyValue(
          final AtomicTerm property,
          final Object value,
          final Class domainEntityClass) {
    //Preconditions
    assert property != null : "property must not be null";
    assert value != null : "value must not be null";
    assert domainEntityClass != null : "domainEntityClass must not be null";
    
    final Set<AtomicTerm> instanceTerms = new HashSet<AtomicTerm>();
    final AbstractTerm arg2 = termFinderFacade.findTermByValue(value);
    if (arg2 == null) {
      return instanceTerms;
    }
    setDomainEntityClass(domainEntityClass);
    gatherAnnotationsForDomainEntityClass();
    configureDomainContextSettings();
    setClassPersistenceContext(termFinderFacade.findAtomicTermByTermName(getClassPersistenceContextName()));
    final Set<AbstractTerm> arg1s = associationFinder.gatherArg1TermsFromBinaryGAFs(
            property,
            arg2,
            getClassPersistenceContext());
    for (final AbstractTerm arg1 : arg1s) {
      instanceTerms.add((AtomicTerm) arg1);
    }
    return instanceTerms;
  }
  
  /** Loads the domain entity from propositions in the knowledge base given its instance term, without clearing
   * the dictionary of connected domain entities.
   *
   * @param instanceTerm the atomic term that represents the domain entity
   * @param isLoadableFromDomainEntityCache the indicator that domain entities can be loaded from the cache
   * @return the domain entity
   */
  private Object loadDomainEntityInternal(final AtomicTerm instanceTerm, boolean isLoadableFromDomainEntityCache) {
    //Preconditions
    assert instanceTerm != null : "instanceTerm must not be null";
    
    getLogger().debug(stackLevel() + "loading domain entity instance term: " + instanceTerm);
    initializeAbstractSessionState();
    setInstanceTerm(instanceTerm);
    final Cache cache = CacheManager.getInstance().getCache(Constants.CACHE_CONNECTED_DOMAIN_ENTITY_TERM_IDS);
    assert cache != null : "cache not found for: " + Constants.CACHE_CONNECTED_DOMAIN_ENTITY_TERM_IDS;
    if (isLoadableFromDomainEntityCache) {
      final Element element = cache.get(instanceTerm.getTermId());
      if (element != null) {
        setDomainEntity(element.getObjectValue());
      }
    } else {
      instantiateDomainEntity();
      gatherAnnotationsForDomainEntityClass();
      configureDomainContextSettings();
      loadIdField();
      loadFields(isLoadableFromDomainEntityCache);
      getLogger().debug(stackLevel() + "caching connected domain entity: " + getDomainEntity().getClass().getName() + "-->" + instanceTerm);
      final Element element = new Element(getDomainEntity(), instanceTerm.getTermId());
      cache.put(element);
    }
    
    //Postconditions
    assert getDomainEntity() != null : "domainEntity must not be null";
    
    return getDomainEntity();
  }
  
  /** Sets the instance term from the term id field contained in the domain entity. */
  private void setInstanceTermFromIdField() {
    //Preconditions
    assert getFieldAnnotationDictionary() != null : "fieldAnnotationDictionary must not be null";
    assert !getFieldAnnotationDictionary().isEmpty() : "fieldAnnotationDictionary must not be empty";
    assert getDomainEntity() != null : "domainEntity() must not be null";
    
    getLogger().debug(stackLevel() + "  finding ID field for domainEntity " + getDomainEntity().getClass().getName());
    boolean isIdFound = false;
    Object value = null;
    for (final Field field : getFieldAnnotationDictionary().keySet()) {
      if (!field.isAccessible()) {
        field.setAccessible(true);
      }
      try {
        value = field.get(getDomainEntity());
      } catch (final IllegalArgumentException ex) {
        throw new TexaiException(ex);
      } catch (final IllegalAccessException ex) {
        throw new TexaiException(ex);
      }
      final Annotation annotation = getFieldAnnotationDictionary().get(field);
      getLogger().debug(stackLevel() + "    field: " + field + ", annotation: " + annotation);
      if ("@javax.persistence.Id()".equals(annotation.toString())) {
        getLogger().debug(stackLevel() + "  found ID field");
        isIdFound = true;
        break;
      }
    }
    if (!isIdFound) {
      throw new TexaiException("Id field not found for domain entity " + getDomainEntity().getClass().getName());
    }
    if (!(value instanceof UUID)) {
      throw new TexaiException("Id field must be type UUID " + getDomainEntity() + ", is type " + value.getClass());
    }
    setInstanceTerm(termFinderFacade.findAtomicTermByTermId(ByteUtils.toBytes((UUID) value)));
    getLogger().debug(stackLevel() + "  found existing instance " + getInstanceTerm());
  }
  
  /** Returns an iterator over the set of domain entity terms that represent instances of the given domain entity class.
   *
   * @param domainEntityClass the given domain entity class
   */
  public Iterator<Object> domainEntityIterator(final Class domainEntityClass) {
    //Preconditions
    assert domainEntityClass != null : "domainEntityClass must not be null";
    
    return new DomainEntityIterator<Object>(domainEntityClass);
  }
  
  /** Provides an iterator over the instances of the specified domain entity class. */
  public class DomainEntityIterator<E> implements Iterator<E> {
    
    /** the domain entity class name */
    private final String domainEntityClassName;
    
    /** the iterator over the set of domain entity terms that represent instances of the given domain entity class */
    private final Iterator<AbstractTerm> domainEntityTermSetIter;
    
    /** Constructs a new DomainEntityIterator instance.
     *
     * @param domainEntityClass the given domain entity class
     */
    public DomainEntityIterator(final Class domainEntityClass) {
      //Preconditions
      assert domainEntityClass != null : "domainEntityClass must not be null";
      
      domainEntityClassName = domainEntityClass.getName();
      saveAbstractSessionState();
      saveSessionState();
      connectedDomainEntityDictionary.clear();
      initializeAbstractSessionState();
      setDomainEntityClass(domainEntityClass);
      gatherAnnotationsForDomainEntityClass();
      configureDomainContextSettings();
      setClassPersistenceContext(termFinderFacade.findAtomicTermByTermName(getClassPersistenceContextName()));
      configureDomainEntitySettings();
      final AtomicTerm domainEntityClassTerm = termFinderFacade.findAtomicTermByTermName(getClassTermName());
      if (domainEntityClassTerm == null) {
        throw new TexaiException("cannot find class term for " + domainEntityClass);
      }
      final Set<AbstractTerm> domainEntityTermSet = associationFinder.gatherArg1TermsFromBinaryGAFs(
              termFinderFacade.findAtomicTermByTermName(Constants.TERM_NAME_ISA),
              domainEntityClassTerm,
              getClassPersistenceContext());
      restoreAbstractSessionState();
      restoreSessionState();
      domainEntityTermSetIter = domainEntityTermSet.iterator();
    }
    
    /** Returns <tt>true</tt> if the iteration has more elements. (In other
     * words, returns <tt>true</tt> if <tt>next</tt> would return an element
     * rather than throwing an exception.)
     *
     * @return <tt>true</tt> if the iterator has more elements.
     */
    public boolean hasNext() {
      return domainEntityTermSetIter.hasNext();
    }
    
    /** Returns the next element in the iteration.  Calling this method
     * repeatedly until the {@link #hasNext()} method returns false will
     * return each element in the underlying collection exactly once.
     *
     * @return the next element in the iteration.
     * @exception NoSuchElementException iteration has no more elements.
     */
    @SuppressWarnings("unchecked")
    public E next() {
      if (!domainEntityTermSetIter.hasNext()) {
        throw new NoSuchElementException("iterator is empty and cannot return the next element");
      }
      final AtomicTerm domainEntityTerm = (AtomicTerm) domainEntityTermSetIter.next();
      saveAbstractSessionState();
      connectedDomainEntityDictionary.clear();
      final Object domainEntity = loadDomainEntityInternal(domainEntityTerm, false);
      restoreAbstractSessionState();
      return (E) domainEntity;
    }
    
    /** Removes from the underlying collection the last element returned by the
     * iterator (optional operation).  This method can be called only once per
     * call to <tt>next</tt>.  The behavior of an iterator is unspecified if
     * the underlying collection is modified while the iteration is in
     * progress in any way other than by calling this method.
     *
     * @exception UnsupportedOperationException if the <tt>remove</tt>
     *		  operation is not supported by this Iterator.
     *
     * @exception IllegalStateException if the <tt>next</tt> method has not
     *		  yet been called, or the <tt>remove</tt> method has already
     *		  been called after the last call to the <tt>next</tt>
     *		  method.
     */
    public void remove() {
      domainEntityTermSetIter.remove();
    }
    
    /** Returns a string representation of this object.
     *
     * @return a string representation of this object
     */
    @Override
    public String toString() {
      return "[iterator over instances of " + domainEntityClassName + "]";
    }
  }
  
  /** Sets the term finder during out-of-the-container unit testing.
   *
   * @param termFinderFacade the term finder
   */
  public void setTermFinderFacade(final TermFinderFacadeLocal termFinderFacade) {
    //Preconditions
    assert termFinderFacade != null : "termFinderFacade must not be null";
    
    this.termFinderFacade = termFinderFacade;
  }
  
  /** Sets the association finder during out-of-the-container unit testing.
   *
   * @param associationFinder the association finder
   */
  public void setAssociationFinder(final AssociationFinderLocal associationFinder) {
    //Preconditions
    assert associationFinder != null : "associationFinder must not be null";
    
    this.associationFinder = associationFinder;
  }
  
  /** Sets the term definition accessor during out-of-the-container unit testing.
   *
   * @param termDefinitionAccessor the term definition accessor
   */
  public void setTermDefinitionAccessor(final TermDefinitionAccessorLocal termDefinitionAccessor) {
    //Preconditions
    assert termDefinitionAccessor != null : "termDefinitionAccessor must not be null";
    
    this.termDefinitionAccessor = termDefinitionAccessor;
  }
  
  /** Gets the logger.
   *
   * @return the logger
   */
  protected Logger getLogger() {
    if (logger == null) {
      logger = Logger.getLogger(DomainEntityLoaderBean.class.getName());
    }
    return logger;
  }
  
  /** Instantiates the domain entity. */
  private void instantiateDomainEntity() {
    //Preconditions
    assert getInstanceTerm() != null : "instanceTerm must not be null";
    
    Object domainEntity = null;
    try {
      if (getDomainEntityClass() == null) {
        setDomainEntityClass(Class.forName(queryDomainEntityClassName()));
      }
      assert getDomainEntityClass() != null : "domainEntityClass must not be null";
      getLogger().debug(stackLevel() + "instantiating: " + getDomainEntityClass().getName() + " for " + getInstanceTerm());
      domainEntity = getDomainEntityClass().newInstance();
    } catch (final IllegalAccessException ex) {
      throw new TexaiException(ex);
    } catch (final InstantiationException ex) {
      throw new TexaiException("instantiating: " + getDomainEntityClass().getName() + " for " + getInstanceTerm(), ex);
    } catch (final ClassNotFoundException ex) {
      throw new TexaiException(ex.getMessage()
      + "\ninstance term: " + getInstanceTerm()
      + "\nprettyName: "+  getInstanceTerm().getPrettyName(), ex);
    }
    assert domainEntity != null : Constants.DOMAIN_ENTITY_ERR;
    setDomainEntity(domainEntity);
    connectedDomainEntityDictionary.put(getInstanceTerm(), getDomainEntity());
  }
  
  /** Returns the domain entity class name for the instance term via KB lookup.
   *
   * @return the domain entity class name for the instance term
   */
  private String queryDomainEntityClassName() {
    //Preconditions
    assert getInstanceTerm() != null : "instanceTerm must not be null";
    
    final PString classNameTerm = (PString) associationFinder.getArg2TermFromBinaryGAF(
            termFinderFacade.findAtomicTermByTermName(Constants.TERM_NAME_DOMAIN_ENTITY_CLASS_NAME),
            getInstanceTerm(),
            termFinderFacade.findAtomicTermByTermName(Constants.TERM_NAME_UNIVERSAL_VOCABULARY_MT));
    assert classNameTerm != null : "cannot find class name term for instance term " + getInstanceTerm();
    final String domainEntityClassName = classNameTerm.getStringValue();
    
    //Postconditions
    assert domainEntityClassName != null : "domainEntityClassName must not be null";
    assert !domainEntityClassName.isEmpty() : "domainEntityClassName must not be an empty string";
    
    return domainEntityClassName;
  }
  
  /** Loads the id field of the domain entity. */
  private void loadIdField() {
    //Preconditions
    assert getFieldAnnotationDictionary() != null : "fieldAnnotationDictionary must not be null";
    assert !getFieldAnnotationDictionary().isEmpty() : "fieldAnnotationDictionary must not be empty";
    assert getDomainEntity() != null :Constants.DOMAIN_ENTITY_ERR;
    
    Field idField = null;
    for (final Field field : getFieldAnnotationDictionary().keySet()) {
      if (!field.isAccessible()) {
        field.setAccessible(true);
      }
      final Annotation annotation = getFieldAnnotationDictionary().get(field);
      getLogger().debug(stackLevel() + "field: " + field + ", annotation: " + annotation);
      if ("@javax.persistence.Id()".equals(annotation.toString())) {
        getLogger().debug(stackLevel() + "  found ID field");
        idField = field;
        break;
      }
    }
    if (idField == null) {
      throw new TexaiException("ID field not found for domain entity " + getDomainEntity());
    }
    try {
      idField.set(getDomainEntity(), getInstanceTerm().getTermId());
    } catch (final IllegalArgumentException ex) {
      throw new TexaiException(ex.getMessage()
      + "\n  domainEntity: " + getDomainEntity()
      + "\n  instanceTerm: " + getInstanceTerm()
      + "\n  termId: " + getInstanceTerm().getTermId(), ex);
    } catch (final IllegalAccessException ex) {
      throw new TexaiException(ex);
    }
  }
  
  /** Loads the domain entity fields from propositions in the knowledge base.
   *
   * @param isLoadableFromDomainEntityCache the indicator that domain entities can be loaded from the cache
   */
  private void loadFields(final boolean isLoadableFromDomainEntityCache) {
    //Preconditions
    assert getInstanceTerm() != null : "instanceTerm must not be null";
    
    setClassPersistenceContext(termFinderFacade.findAtomicTermByTermName(getClassPersistenceContextName()));
    if (getClassPersistenceContext() == null) {
      throw new TexaiException("cannot find loadFromContext term for " + getClassPersistenceContextName());
    }
    for (final Field field : getFieldAnnotationDictionary().keySet()) {
      final Annotation annotation = getFieldAnnotationDictionary().get(field);
      getLogger().debug(stackLevel() + "field: " + field + ", annotation: " + annotation);
      if ("@javax.persistence.Id()".equals(annotation.toString())) {
        getLogger().debug(stackLevel() + "  skipping Id field");
        continue;
      } else {
        if (annotation instanceof DomainProperty) {
          final Class fieldType = field.getType();
          final DomainProperty domainProperty = (DomainProperty) annotation;
          if (domainProperty.fetch().equals(FetchType.EAGER)) {
            loadField(field, domainProperty, isLoadableFromDomainEntityCache);
          } else {
            // default behavior is lazy loading
            if (fieldType.equals(Set.class)) {
              getLogger().debug(stackLevel() + "  lazySet for field: " + field);
              final LazySet lazySet = new LazySet(
                      this,
                      getDomainEntity(),
                      field,
                      domainProperty,
                      isLoadableFromDomainEntityCache);
              setFieldValue(field, lazySet, fieldType);
            } else if (fieldType.equals(List.class)) {
              getLogger().debug(stackLevel() + "  lazyList for field: " + field);
              final LazyList lazyList = new LazyList(
                      this,
                      getDomainEntity(),
                      field,
                      domainProperty,
                      isLoadableFromDomainEntityCache);
              setFieldValue(field, lazyList, fieldType);
            } else if (isDomainEntityClass(fieldType)) {
              final List<List<Object>> valueAndStrengthPairs =
                      getValueStrengthPairs(field, domainProperty, isLoadableFromDomainEntityCache);
              if (!valueAndStrengthPairs.isEmpty()) {
                getLogger().debug(stackLevel() + "  lazyily loaded proxy for field: " + field);
                //  load the value upon first access to the associated proxy
                final DomainEntityLazyLoader domainEntityLazyLoader = new DomainEntityLazyLoader(
                        this,
                        getDomainEntity(),
                        field,
                        domainProperty,
                        isLoadableFromDomainEntityCache);
                // dynamically create the proxy using cglib
                final Object lazyObjectProxy = Enhancer.create(fieldType, domainEntityLazyLoader);
                setFieldValue(field, lazyObjectProxy, fieldType);
              }
            } else {
              // otherwise rely on Hibernate proxy features when they can apply
              loadField(field, domainProperty, isLoadableFromDomainEntityCache);
            }
          }
        }
      }
    }
  }
  
  /** Loads the given field according to the given domain property.
   *
   * @param field the given domain entity instance field
   * @param domainProperty the property annotation associated with the field
   * @param isLoadableFromDomainEntityCache the indicator that domain entities can be loaded from the cache
   * @return the loaded value
   */
  @SuppressWarnings("unchecked")
  private Object loadField(
          final Field field,
          final DomainProperty domainProperty,
          final boolean isLoadableFromDomainEntityCache) {
    //Preconditions
    assert field != null : "field must not be null";
    assert domainProperty != null : "domainProperty must not be null";
    
    // obtain field and strength field attributes
    final Class fieldType = field.getType();
    getLogger().debug(stackLevel() + "  field: " + field);
    getLogger().debug(stackLevel() + "  field type: " + fieldType.getName());
    final List<List<Object>> valueAndStrengthPairs =
            getValueStrengthPairs(field, domainProperty, isLoadableFromDomainEntityCache);
    final int valueAndStrengthPairsSize = valueAndStrengthPairs.size();
    final Field strengthField = getStrengthFieldDictionary().get(field);
    Class strengthFieldType = null;
    if (strengthField != null) {
      strengthFieldType = strengthField.getType();
      getLogger().debug(stackLevel() + "  strengthField: " + strengthField);
      getLogger().debug(stackLevel() + "  strengthField type: " + strengthFieldType.getName());
    }
    // load the value according to its field type
    Object loadedValue = null;
    if (fieldType.isArray()) {
      // load an array field and array of strengths
      final Object array = Array.newInstance(fieldType.getComponentType(), valueAndStrengthPairsSize);
      Object strengthFieldArray = null;
      if (strengthField != null) {
        if (!strengthFieldType.isArray()) {
          throw new TexaiException("strengthField " + strengthField + " must be an Array");
        }
        strengthFieldArray = Array.newInstance(strengthFieldType.getComponentType(), valueAndStrengthPairsSize);
      }
      for (int i = 0; i < valueAndStrengthPairsSize; i++) {
        final List<Object> valueAndStrengthPair = valueAndStrengthPairs.get(i);
        Array.set(array, i, valueAndStrengthPair.get(0));
        if (strengthField != null) {
          Array.set(strengthFieldArray, i, valueAndStrengthPair.get(1));
        }
      }
      loadedValue = array;
      setFieldValue(
              field,
              loadedValue,
              fieldType);
      if (strengthField != null) {
        setFieldValue(
                strengthField,
                strengthFieldArray,
                strengthFieldType);
      }
    } else if (fieldType.equals(List.class)) {
      // load a List field and list of strengths
      final OrderBy orderBy = getOrderByDictionary().get(field);
      final List list = new ArrayList();
      List<Double> strengthList = null;
      if (strengthField != null) {
        if (fieldType.equals(List.class)) {
          strengthList = new ArrayList<Double>(valueAndStrengthPairsSize);
        } else {
          throw new TexaiException("strengthField must be a List");
        }
      }
      if (orderBy != null) {
        final ValueAndStrengthPairsComparator valueAndStrengthPairsComparator = new ValueAndStrengthPairsComparator(orderBy);
        Collections.sort(valueAndStrengthPairs, valueAndStrengthPairsComparator);
        getLogger().debug(stackLevel() + "  ordered valueAndStrengthPairs: " + valueAndStrengthPairs);
      }
      for (List<Object> valueAndStrengthPair : valueAndStrengthPairs) {
        list.add(valueAndStrengthPair.get(0));
        if (strengthField != null) {
          strengthList.add((Double) valueAndStrengthPair.get(1));
        }
      }
      loadedValue = list;
      setFieldValue(field, loadedValue, fieldType);
      if (strengthField != null) {
        setFieldValue(
                strengthField,
                strengthList,
                strengthFieldType);
      }
    } else if (Collection.class.isAssignableFrom(fieldType)) {
      // load a Collection field
      Collection collection = null;
      Class concreteFieldType = null;
      if (fieldType.equals(Collection.class)) {
        concreteFieldType = ArrayList.class;
      } else if (fieldType.equals(Set.class)) {
        concreteFieldType = HashSet.class;
      } else {
        concreteFieldType = fieldType;
      }
      try {
        collection = (Collection) concreteFieldType.newInstance();
      } catch (final InstantiationException ex) {
        throw new TexaiException(ex);
      } catch (final IllegalAccessException ex) {
        throw new TexaiException(ex);
      }
      for (List<Object> valueAndStrengthPair : valueAndStrengthPairs) {
        collection.add(valueAndStrengthPair.get(0));
      }
      loadedValue = collection;
      setFieldValue(field, loadedValue, fieldType);
    } else {
      // load a single value field and single strength field
      if (valueAndStrengthPairsSize > 1) {
        getLogger().info(stackLevel() + "expected only one value/strength pair for field " + field + " but found\n  " + valueAndStrengthPairs);
      }
      if (!valueAndStrengthPairs.isEmpty()) {
        final List<Object> valueAndStrengthPair = valueAndStrengthPairs.get(0);
        loadedValue = valueAndStrengthPair.get(0);
        setFieldValue(field, loadedValue, fieldType);
        if (strengthField != null) {
          setFieldValue(
                  strengthField,
                  valueAndStrengthPair.get(1),
                  strengthFieldType);
        }
      }
    }
    return loadedValue;
  }
  
  /** Gets the values and GAF strengths for loading the given field, sorted by value termId.
   *
   * @param field the given domain entity instance field
   * @param domainProperty the property annotation associated with the field
   * @param isLoadableFromDomainEntityCache the indicator that domain entities can be loaded from the cache
   * @return the ordered list of value/strength pairs for the field
   */
  private List<List<Object>> getValueStrengthPairs(
          final Field field,
          final DomainProperty domainProperty,
          final boolean isLoadableFromDomainEntityCache) {
    //Preconditions
    assert field != null : "field must not be null";
    assert domainProperty != null : "domainProperty must not be null";
    
    getLogger().debug(stackLevel() + "  processing domain property: " + domainProperty);
    final boolean isBooleanField = "boolean".equals(field.getType().getName());
    String predicateName = null;
    if (isBooleanField) {
      predicateName = Constants.TERM_NAME_ISA;
    } else {
      predicateName = domainProperty.name();
    }
    if (predicateName.length() == 0) {
      predicateName = field.getName();
    }
    AtomicTerm predicate = null;
    final Cache cache = CacheManager.getInstance().getCache(Constants.CACHE_LOADED_DOMAIN_ENTITY_PREDICATES);
    assert cache != null : "cache not found: " + Constants.CACHE_LOADED_DOMAIN_ENTITY_PREDICATES;
    final Element element = cache.get(predicateName);
    if (element == null) {
      predicate = termFinderFacade.findAtomicTermByTermName(predicateName);
      if (predicate != null) {
        cache.put(new Element(predicateName, predicate));
      }
    } else {
      predicate = (AtomicTerm) element.getObjectValue();
    }
    if (predicate == null) {
      getLogger().debug(stackLevel() + "new property: " + predicateName);
      return new ArrayList<List<Object>>(0);
    }
    if (!field.isAccessible()) {
      field.setAccessible(true);
    }
    final List<List<Object>> valueAndStrengthPairs = queryForValuesAndStrengths(
            predicate,
            field.getType(),
            domainProperty.inverse(),
            isLoadableFromDomainEntityCache);
    if (isBooleanField) {
      getLogger().debug(stackLevel() + "  boolean field: " + field.getName());
      // for boolean values, return a true value if the trueClass is among the queried values, otherwise return a false value with
      // its associated strength
      final String trueClassName = domainProperty.trueClass();
      if (trueClassName.isEmpty()) {
        throw new TexaiException("trueClass must be specified for boolean field " + field.getName());
      }
      final AtomicTerm trueClass = termFinderFacade.findAtomicTermByTermName(trueClassName);
      if (trueClass == null) {
        return new ArrayList<List<Object>>(0);
      }
      // note that there will only be one boolean value and strength pair returned
      final List<List<Object>> booleanValueAndStrengthPairs = new ArrayList<List<Object>>(1);
      for (final List<Object> valueAndStrengthPair : valueAndStrengthPairs) {
        getLogger().debug(stackLevel() + "    " + valueAndStrengthPair.get(0) + " equals " + trueClass + " ?");
        if (valueAndStrengthPair.get(0).equals(trueClass)) {
          final List<Object> booleanValueAndStrengthPair = new ArrayList<Object>(2);
          booleanValueAndStrengthPair.add(Boolean.valueOf(true));
          booleanValueAndStrengthPair.add(valueAndStrengthPair.get(1));
          booleanValueAndStrengthPairs.add(booleanValueAndStrengthPair);
          return booleanValueAndStrengthPairs;
        }
      }
      final String falseClassName = domainProperty.falseClass();
      if (falseClassName.isEmpty()) {
        throw new TexaiException("trueClass must be specified for boolean field " + field.getName());
      }
      final AtomicTerm falseClass = termFinderFacade.findAtomicTermByTermName(falseClassName);
      if (falseClass == null) {
        return new ArrayList<List<Object>>(0);
      }
      for (final List<Object> valueAndStrengthPair : valueAndStrengthPairs) {
        getLogger().debug(stackLevel() + "    " + valueAndStrengthPair.get(0) + " equals " + falseClass + " ?");
        if (valueAndStrengthPair.get(0).equals(falseClass)) {
          final List<Object> booleanValueAndStrengthPair = new ArrayList<Object>(2);
          booleanValueAndStrengthPair.add(Boolean.valueOf(false));
          booleanValueAndStrengthPair.add(valueAndStrengthPair.get(1));
          booleanValueAndStrengthPairs.add(booleanValueAndStrengthPair);
          return booleanValueAndStrengthPairs;
        }
      }
      getLogger().debug(stackLevel() + "  boolean field true/false class not found for : " + field.getName() + ", defaulting to false");
      final List<Object> booleanValueAndStrengthPair = new ArrayList<Object>(2);
      booleanValueAndStrengthPair.add(Boolean.valueOf(false));
      booleanValueAndStrengthPair.add(Constants.STRENGTH_MONOTONIC);
      booleanValueAndStrengthPairs.add(booleanValueAndStrengthPair);
      return booleanValueAndStrengthPairs;
    }
    return valueAndStrengthPairs;
  }
  
  /** Sets the given field to the given value if the value is not null.
   *
   * @param field the given field to be set
   * @param value the field value
   * @param fieldType the field type
   */
  private void setFieldValue(final Field field, final Object value, final Class fieldType) {
    //Preconditions
    assert field != null : "field must not be null";
    assert fieldType != null : "fieldType must not be null";
    
    if (value == null) {
      getLogger().debug(stackLevel() + "  value is null");
    } else {
      getLogger().debug(stackLevel() + "  load value (" + value.getClass().getName() + ") into fieldType " + fieldType.getName());
      if (!field.isAccessible()) {
        field.setAccessible(true);
      }
      try {
        field.set(getDomainEntity(), value);
      } catch (final IllegalArgumentException ex) {
        throw new TexaiException(
                ex.getMessage()
                + "\nfield: " + field
                + "\nvalue: " + value
                + "\nfieldType: " + fieldType, ex);
      } catch (final IllegalAccessException ex) {
        throw new TexaiException(
                ex.getMessage()
                + "\nfield: " + field
                + "\nvalue: " + value
                + "\nfieldType: " + fieldType, ex);
      }
    }
  }
  
  /** Queries for the value terms filling the arg2 position of matching gafs having the
   * given predicate, arg1 position filled by the instanceTerm and found in relevant contexts from
   * the class load-from context.  The value terms are translated into domain objects.
   *
   * @param predicate the predicate that relates the value for the domain entity field
   * @param fieldType the field type
   * @param isInverseProperty the indicator that the property is to be inverted with respect to treatment of arg1 and arg2
   * @param isLoadableFromDomainEntityCache the indicator that domain entities can be loaded from the cache
   * @return the ordered list by value termId of value and gaf strength pairs
   */
  private List<List<Object>> queryForValuesAndStrengths(
          final AtomicTerm predicate,
          final Class fieldType,
          final boolean isInverseProperty,
          final boolean isLoadableFromDomainEntityCache) {
    //Preconditions
    assert predicate != null : "predicate must not be null";
    assert fieldType != null : "fieldType must not be null";
    
    List<List<Object>> valueTermAndStrengthTerms = null;
    if (isInverseProperty) {
      valueTermAndStrengthTerms = associationFinder.gatherArg1TermsAndStrengthsFromBinaryGAFs(
              predicate,
              getInstanceTerm(),
              getClassPersistenceContext());
    } else {
      valueTermAndStrengthTerms = associationFinder.gatherArg2TermsAndStrengthsFromBinaryGAFs(
              predicate,
              getInstanceTerm(),
              getClassPersistenceContext());
    }
    final List<List<Object>> valuesAndStrengths = new ArrayList<List<Object>>();
    for (List<Object> valueTermAndStrengthTerm : valueTermAndStrengthTerms) {
      final List<Object> valueAndStrength = new ArrayList<Object>(2);
      final AbstractTerm valueTerm = (AbstractTerm) valueTermAndStrengthTerm.get(0);
      valueAndStrength.add(getValueFromTerm(valueTerm, fieldType, isLoadableFromDomainEntityCache));
      final Double strength = (Double) valueTermAndStrengthTerm.get(1);
      valueAndStrength.add(strength);
      valuesAndStrengths.add(valueAndStrength);
    }
    return valuesAndStrengths;
  }
  
  /** Gets the domain value from the given value term.  In case of domain entities,
   * state is saved and a recursive domain entity load is performed.
   *
   * @param valueTerm the value term
   * @param fieldType the field type
   * @param isLoadableFromDomainEntityCache the indicator that domain entities can be loaded from the cache
   * @return the domain value from the given value term
   */
  private Object getValueFromTerm(
          final AbstractTerm valueTerm,
          final Class fieldType,
          final boolean isLoadableFromDomainEntityCache) {   // NOPMD
    //Preconditions
    assert valueTerm != null : "valueTerm must not be null";
    
    Object value = null;
    if (valueTerm instanceof PString) {
      value = ((PString) valueTerm).getStringValue();
    } else if (valueTerm instanceof PLong) {
      final Long longValue = ((PLong) valueTerm).getLongValue();
      if (fieldType.equals(Integer.class) || ("int").equals(fieldType.getName())) {
        value = Integer.valueOf(longValue.intValue());
      } else {
        value = longValue;
      }
    } else if (valueTerm instanceof PDouble) {
      final Double doubleValue = ((PDouble) valueTerm).getDoubleValue();
      if (fieldType.equals(Float.class) || ("float").equals(fieldType.getName())) {
        value = Float.valueOf(doubleValue.floatValue());
      } else {
        value = doubleValue;
      }
    } else if (valueTerm instanceof PDate) {
      value = ((PDate) valueTerm).getDateValue();
    } else if (valueTerm instanceof Formula) {
      value = valueTerm;
    } else if (valueTerm instanceof NonAtomicTerm) {
      value = valueTerm;
    } else if (valueTerm instanceof AtomicTerm) {
      value = connectedDomainEntityDictionary.get(valueTerm);
      if (value == null) {
        if (isAtomicTermDomainEntity((AtomicTerm) valueTerm)) {
          getLogger().debug(stackLevel() + "  domain entity AtomicTerm valueTerm: " + valueTerm);
          // save this session state before the recursive method call because session beans cannot
          // create a new session bean instance
          saveAbstractSessionState();
          value = loadDomainEntityInternal((AtomicTerm) valueTerm, isLoadableFromDomainEntityCache);
          restoreAbstractSessionState();
        } else {
          // value term is an atomic term but not a domain entity
          getLogger().debug(stackLevel() + "  AtomicTerm valueTerm: " + valueTerm);
          value = valueTerm;
          connectedDomainEntityDictionary.put((AtomicTerm) valueTerm, value);
        }
      } else {
        getLogger().debug(stackLevel() + "  previously loaded value: " + value);
      }
    } else {
      throw new TexaiException("unhandled valueTerm " + valueTerm);
    }
    getLogger().debug(stackLevel() + "  value from term " + valueTerm + " = " + value);
    
    return value;
  }
  
  /** Returns true if the given atomic term value represents a domain entity.
   *
   * @param atomicTerm the value term
   * @return true if the given value term represents a domain entity
   */
  private boolean isAtomicTermDomainEntity(final AtomicTerm atomicTerm) {
    //Preconditions
    assert atomicTerm != null : "atomicTerm must not be null";
    
    final PString classNameTerm = (PString) associationFinder.getArg2TermFromBinaryGAF(
            termFinderFacade.findAtomicTermByTermName(Constants.TERM_NAME_DOMAIN_ENTITY_CLASS_NAME),
            atomicTerm,
            termFinderFacade.findAtomicTermByTermName(Constants.TERM_NAME_UNIVERSAL_VOCABULARY_MT));
    return classNameTerm != null;
  }
  
  /** Pushes the current session bean state onto a stack and then intitializes the session state. */
  public void saveSessionState() {
    //Preconditions
    assert domainEntityInfoStack != null : "domainEntityInfoStack must not be null";
    
    getLogger().debug(stackLevel() + "saving session state");
    domainEntityInfoStack.push(new DomainEntityInfo(connectedDomainEntityDictionary));
  }
  
  /** Restores the session state following a recursive method call. */
  public void restoreSessionState() {
    //Preconditions
    assert domainEntityInfoStack != null : "domainEntityInfoStack must not be null";
    
    final DomainEntityInfo domainEntityInfo = domainEntityInfoStack.pop();
    connectedDomainEntityDictionary = domainEntityInfo.connectedDomainEntityDictionary;
    getLogger().debug(stackLevel() + "restored session state");
  }
  
  /** Contains the session bean state for recursive method calls. */
  private class DomainEntityInfo {
    
    /** the dictionary of connected domain entities, term --> domain instance */
    private Map<AtomicTerm, Object> connectedDomainEntityDictionary;
    
    /** Creates a new DomainEntityInfo instance.
     *
     * @param connectedDomainEntityDictionary the dictionary of connected domain entities, term --> domain instance
     */
    protected DomainEntityInfo(final Map<AtomicTerm, Object> connectedDomainEntityDictionary) {
      //Preconditions
      assert connectedDomainEntityDictionary != null : "connectedDomainEntityDictionary must not be null";
      
      this.connectedDomainEntityDictionary = connectedDomainEntityDictionary;
    }
  }
  
  /** This comparator class orders value and strength pairs by the field specified in an OrderBy annotation. */
  public class ValueAndStrengthPairsComparator implements Comparator {
    
    /** the name of the field by which to order the values */
    private String orderByFieldName;
    
    /**
     * Creates a new instance of ValueAndStrengthPairsComparator.
     */
    public ValueAndStrengthPairsComparator(final OrderBy orderBy) {
      //Preconditions
      assert orderBy != null : "orderBy must not be null";
      
      orderByFieldName = orderBy.value();
      getLogger().debug(stackLevel() + " orderByFieldName: " + orderByFieldName);
    }
    
    /**
     * Compares its two arguments for order.  Returns a negative integer,
     * zero, or a positive integer as the first argument is less than, equal
     * to, or greater than the second.<p>
     *
     *
     * @param o1 the first object to be compared.
     * @param o2 the second object to be compared.
     * @return a negative integer, zero, or a positive integer as the
     * 	       first argument is less than, equal to, or greater than the
     *	       second.
     * @throws ClassCastException if the arguments' types prevent them from
     * 	       being compared by this comparator.
     */
    @SuppressWarnings("unchecked")
    public int compare(final Object o1, final Object o2) {
      final List<Object> valueAndStrengthPair1 = (List<Object>) o1;
      final Object value1 = valueAndStrengthPair1.get(0);
      final Class clazz1 = value1.getClass();
      final Field compareField1 = findCompareField(value1);
      Object compareValue1 = null;
      try {
        compareField1.setAccessible(true);
        compareValue1 = compareField1.get(value1);
      } catch (final IllegalArgumentException ex) {
        throw new TexaiException(ex);
      } catch (final IllegalAccessException ex) {
        throw new TexaiException(ex);
      }
      
      final List<Object> valueAndStrengthPair2 = (List<Object>) o2;
      final Object value2 = valueAndStrengthPair2.get(0);
      final Class clazz2 = value2.getClass();
      final Field compareField2 = findCompareField(value2);
      Object compareValue2 = null;
      try {
        compareField2.setAccessible(true);
        compareValue2 = compareField2.get(value2);
      } catch (final IllegalArgumentException ex) {
        throw new TexaiException(ex);
      } catch (final IllegalAccessException ex) {
        throw new TexaiException(ex);
      }
      getLogger().debug(stackLevel() + " comparing " + o1 + " / " + compareValue1
              + " with " + o2 + " / " + compareValue2);
      
      return ((Comparable) compareValue1).compareTo(((Comparable) compareValue2));
    }
    
    /** Finds the orderBy field in the given domain entity.
     *
     * @param domainEntity the domain entity having an orderBy field
     * @return the orderBy field in the given domain entity
     */
    private Field findCompareField(final Object domainEntity) {
      //Preconditions
      assert domainEntity != null : "domainEntity must not be null";
      
      return findCompareField(domainEntity, domainEntity.getClass());
    }
    
    /** Finds the orderBy field in the given domain entity.
     *
     * @param domainEntity the domain entity having an orderBy field
     * @param clazz the class or super class of the domain entity
     * @return the orderBy field in the given domain entity
     */
    private Field findCompareField(final Object domainEntity, final Class clazz) {
      //Preconditions
      assert domainEntity != null : "domainEntity must not be null";
      assert clazz != null : "clazz must not be null";
      
      Field compareField = null;
      try {
        compareField = clazz.getDeclaredField(orderByFieldName);
      } catch (final NoSuchFieldException ex) {
        if (clazz.equals(Object.class)) {
          throw new TexaiException("OrderBy field [" + orderByFieldName + "] not found in " + domainEntity + " having class " + clazz, ex);
        }
      }
      if (compareField == null) {
        return findCompareField(domainEntity, clazz.getSuperclass());
      } else {
        return compareField;
      }
    }
    
    /**
     *
     * Indicates whether some other object is &quot;equal to&quot; this
     * comparator.
     *
     * @param   obj   the reference object with which to compare.
     * @return  <code>true</code> only if the specified object is also
     *		a comparator and it imposes the same ordering as this
     *		comparator.
     */
    public boolean equals(final Object obj) {
      if (!(obj instanceof ValueAndStrengthPairsComparator)) {
        return false;
      }
      final ValueAndStrengthPairsComparator that = (ValueAndStrengthPairsComparator) obj;
      return this.orderByFieldName.equals(that.orderByFieldName);
    }
  }
}




See more files for this project here

Texai

Texai is an chatbot that intelligently seeks to acquire knowledge and friendly behaviors.

Project homepage: http://sourceforge.net/projects/texai
Programming language(s): Java,Shell Script,XML
License: other

  shared/
    AssociationEditorBean.java
    AssociationEditorLocal.java
    AssociationFinderBean.java
    AssociationFinderLocal.java
    KBPartitionFacadeBean.java
    KBPartitionFacadeLocal.java
    KBShardFacadeBean.java
    TermDeleterFacadeBean.java
    TermDeleterFacadeLocal.java
    TermFinderFacadeBean.java
    TermFinderFacadeLocal.java
    TermManagerBean.java
    TermManagerLocal.java
  AbstractDomainEntityAccessor.java
  DomainEntityDeleterBean.java
  DomainEntityDeleterLocal.java
  DomainEntityLoaderBean.java
  DomainEntityLoaderLocal.java
  DomainEntityManagerBean.java
  DomainEntityManagerLocal.java
  DomainEntityPersisterBean.java
  DomainEntityPersisterLocal.java
  package.html