Package er.modern.directtoweb.components.relationships

Source Code of er.modern.directtoweb.components.relationships.ERMD2WEditToOneTypeAhead

package er.modern.directtoweb.components.relationships;

import org.apache.log4j.Logger;

import com.webobjects.appserver.WOActionResults;
import com.webobjects.appserver.WOContext;
import com.webobjects.directtoweb.D2W;
import com.webobjects.directtoweb.EditPageInterface;
import com.webobjects.eoaccess.EOEntity;
import com.webobjects.eoaccess.EOModelGroup;
import com.webobjects.eoaccess.EORelationship;
import com.webobjects.eoaccess.EOUtilities;
import com.webobjects.eocontrol.EODataSource;
import com.webobjects.eocontrol.EOEditingContext;
import com.webobjects.eocontrol.EOEnterpriseObject;
import com.webobjects.eocontrol.EOFetchSpecification;
import com.webobjects.eocontrol.EOQualifier;
import com.webobjects.eocontrol.EOSortOrdering;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSNotification;
import com.webobjects.foundation.NSNotificationCenter;
import com.webobjects.foundation.NSSelector;

import er.directtoweb.ERDirectToWeb;
import er.directtoweb.components.ERDCustomEditComponent;
import er.extensions.eof.ERXConstant;
import er.extensions.eof.ERXEC;
import er.extensions.eof.ERXEOControlUtilities;
import er.extensions.eof.ERXGenericRecord;
import er.extensions.eof.ERXQ;
import er.extensions.eof.ERXS;
import er.extensions.foundation.ERXSimpleTemplateParser;
import er.extensions.foundation.ERXStringUtilities;
import er.extensions.foundation.ERXUtilities;
import er.extensions.foundation.ERXValueUtilities;
import er.modern.directtoweb.components.buttons.ERMDActionButton;

/**
* <p>A to-one relationship edit component that allows a user to select from a list by typing in the text field</p>
*
* <p>It uses the 'keyWhenRelationship' from the d2w rules for this relationship to display and query. Because it uses an AjaxAutoComplet
* the keyWhenRelationshp must be able to uniquely identify the found entity. It can either be a string attribute or a helper
* method that returns a constructed unique string.</p>
*
* <p>If the keyWhenRelationship represents an attribute, this component will qualify the list of possible matches via a
* fetch. Otherwise it will load ALL of the available destinationEntities and qualify in memory. Keep this in mind when
* deciding how to use this component.</p>
*
* @d2wKey restrictedChoiceKey - keypath off the component that returns a list of objects to be searched from (only used when keyWhenRelationship is NOT an attribute)
* @d2wKey restrictingFetchSpecification - name of the model FetchSpec supplies the list of objects to be searched from (keyWhenRelationship is NOT an attribute) or that additionally qualifies the fetch
* @d2wKey extraRestrictingQualifier - an additional qualifier (defined in the rules) that additionally qualifies the search
* @d2wKey typeAheadSearchTemplate - a template that wraps the searchValue (for the inclusion of pre/post wildcards: i.e: "*@@searchValue@@*" )
* @d2wKey typeAheadMinimumCharaceterCount - minimum number of characters before a search is performed
* @d2wKey sortKey
* @d2wKey isMandatory
* @d2wKey propertyKey
* @d2wKey destinationEntityName
* @d2wKey sortCaseInsensitive
* @d2wKey pageConfiguration
* @d2wKey createConfigurationName
* @d2wKey keyWhenRelationship
* @d2wKey newButtonLabel
*
* @author davidleber
*/

public class ERMD2WEditToOneTypeAhead extends ERDCustomEditComponent {
 
  public interface Keys extends ERDCustomEditComponent.Keys {
    public static final String newButtonLabel = "newButtonLabel";
    public static final String classForNewObjButton = "classForNewObjButton";
    public static final String pageConfiguration = "pageConfiguration";
    public static final String createConfigurationName = "createConfigurationName";
    public static final String propertyKey = "propertyKey";
    public static final String sortKey = "sortKey";
    public static final String destinationEntityName = "destinationEntityName";
    public static final String restrictedChoiceKey = "restrictedChoiceKey";
    public static final String restrictingFetchSpecification = "restrictingFetchSpecification";
    public static final String typeAheadSearchTemplate = "typeAheadSearchTemplate";
    public static final String extraRestrictingQualifier = "extraRestrictingQualifier";
    public static final String keyWhenRelationship = "keyWhenRelationship";
    public static final String typeAheadMinimumCharaceterCount = "typeAheadMinimumCharaceterCount";
  }
 
  public static Logger log = Logger.getLogger(ERMD2WEditToOneTypeAhead.class);
  private String _searchValue;
  private String _destinationEntityName;
  private String _sortKey;
  private String _propertyKey;
  private String _keyWhenRelationship;
  private String _safeElementID;
  private EOFetchSpecification _restrictingFetchSpec;
  private String _restrictedChoiceKey;
  private String _restrictingFetchSpecification;
  private NSArray<EOEnterpriseObject> _allItems;
  private String _template;
  private EOQualifier _extraQualifier;
  private Integer _minimumCharacterCount;
  private EOEnterpriseObject _currentSelection;
  private String _newButtonClass;
  private String _newButtonLabel;
 
  public EOEnterpriseObject item;
 
    public ERMD2WEditToOneTypeAhead(WOContext context) {
        super(context);
    }
 
    @Override
    public void awake() {
      NSNotificationCenter.defaultCenter().addObserver(this, new NSSelector("relatedObjectDidChange", ERXConstant.NotificationClassArray), ERMDActionButton.BUTTON_PERFORMED_DELETE_ACTION, null);
      super.awake();
    }
   
    @Override
    public void sleep() {
      NSNotificationCenter.defaultCenter().removeObserver(this, ERMDActionButton.BUTTON_PERFORMED_DELETE_ACTION, null);
      super.sleep();
    }
   
  /**
   * Called when an {@link ERMDActionButton} changes the related object. Nulls
   * {@link #_searchValue} which in turn lets it rebuild on the next display
   */
  @SuppressWarnings("unchecked")
  public void relatedObjectDidChange(NSNotification notif) {
    NSDictionary<String, Object>userInfo = notif.userInfo();
    if (userInfo != null) {
      Object key = userInfo.valueForKey("propertyKey");
      EOEnterpriseObject obj = (EOEnterpriseObject)userInfo.valueForKey("object");
      if (propertyKey() != null && propertyKey().equals(key) && ERXEOControlUtilities.eoEquals(object(), obj)) {
        _searchValue = null;
        _currentSelection = null;
      }
    }
  }
 
   
    @Override
    public boolean synchronizesVariablesWithBindings() {
      return false;
    }
   
    /**
     * Value displayed by the AjaxAutoFill field, if nothing is entered in the
     * field it will return either the kvc value of 'keyWhenRelationship' on the related
     * entity or the kvc value of 'userPresentableDescription'
     */
    public String searchValue() {
      if (ERXStringUtilities.stringIsNullOrEmpty(_searchValue) && currentSelection() != null) {
        _searchValue = currentSelection().valueForKey(keyWhenRelationship()).toString();
      }
    return _searchValue;
  }
   
    /**
     * Sets the searchValue
     *
     * @param value
     */
  public void setSearchValue(String value) {
    _searchValue = value;
  }
 
  /**
   * Returns the currently selected destination entity
   */
  public EOEnterpriseObject currentSelection() {
    if (_currentSelection == null)
//      NSLog.out.appendln("***ERMD2WEditToOneTypeAhead.currentSelection: "
//          + _currentSelection + " ***");
      _currentSelection = (EOEnterpriseObject)objectPropertyValue();
    return _currentSelection;
  }
 
  /**
   * Returns the array of available matching destination entities
   */
    public NSArray<EOEnterpriseObject> currentObjects() {
    NSArray<EOEnterpriseObject> result = null;
    String value = searchValue();
      if (value != null) {
        if (searchTemplate() != null) {
          value = ERXSimpleTemplateParser.parseTemplatedStringWithObject(searchTemplate(), this);
        }
        EOQualifier qual = ERXQ.likeInsensitive(keyWhenRelationship(), value);
        result = destinationObjectsWithQualifier(qual);
      }
      return result;
    }
 
    /**
     * Returns the display value for the available matching destination entities in the
     * drop down list.
     */
  public String itemDisplayString() {
    return (String)item.valueForKey(keyWhenRelationship());
  }
 
  /**
   * Action called when the user makes a selection from the AjaxAutoComplete
   */
  public WOActionResults selectObject() {
//    log.debug("selectobject called: " + item);
    EOQualifier qual = ERXQ.equals(keyWhenRelationship(), searchValue());
    NSArray<EOEnterpriseObject> objs = destinationObjectsWithQualifier(qual);
    if (objs != null && objs.count() > 0) {
      EOEnterpriseObject localEO = ERXEOControlUtilities.localInstanceOfObject(object().editingContext(), objs.objectAtIndex(0));
      object().addObjectToBothSidesOfRelationshipWithKey(localEO, propertyKey());
    } else {
      EOEnterpriseObject existingObj = (EOEnterpriseObject)object().valueForKey(propertyKey());
      if (existingObj != null) {
        object().removeObjectFromBothSidesOfRelationshipWithKey(existingObj, propertyKey());
      }
    }
//    NSLog.out.appendln("Select Object Called: " + object().valueForKey(propertyKey()) + " " + searchValue());
    return null;
  }
 
  /**
   * Action called when user clicks the Add button
   */
  @SuppressWarnings("unchecked")
  public WOActionResults addObject() {
    String currentPageConfiguration = stringValueForBinding(Keys.pageConfiguration);
   
    NSDictionary extraValues = currentPageConfiguration != null ? new NSDictionary(currentPageConfiguration, Keys.pageConfiguration) : null;
        String createPageConfigurationName = (String)ERDirectToWeb.d2wContextValueForKey(Keys.createConfigurationName, destinationEntityName(), extraValues);
       
    EditPageInterface epi = (EditPageInterface)D2W.factory().pageForConfigurationNamed(createPageConfigurationName, session());
    EOEditingContext newEc = ERXEC.newEditingContext(object().editingContext());
    EOEnterpriseObject relatedObject = EOUtilities.createAndInsertInstance(newEc, destinationEntityName());
    EOEnterpriseObject localObj = ERXEOControlUtilities.localInstanceOfObject(relatedObject.editingContext(), object());
    if (localObj instanceof ERXGenericRecord) {
      ((ERXGenericRecord)localObj).setValidatedWhenNested(false);
    }
    localObj.addObjectToBothSidesOfRelationshipWithKey(relatedObject, propertyKey());
   
    epi.setNextPage(context().page());
    epi.setObject(relatedObject);
   
    // Null out the current searchValue so when we come back, it regenerates
    _searchValue = null;
   
    return (WOActionResults) epi;
  }
 
  public EODataSource dataSource() {
    return ERXEOControlUtilities.dataSourceForObjectAndKey(object(), propertyKey());
  }
 
  /**
   * Should this component use a fetch to qualify the list of available destination entities
   *
   * @return true if the 'keyWhenRelationship' is the name of an attribute
   */
  public boolean useFetch() {
    EOEntity entity = EOUtilities.entityNamed(ec(), destinationEntityName());
    return (entity.attributeNamed(keyWhenRelationship()) != null);
  }
 
  @SuppressWarnings("unchecked")
  public NSArray<EOEnterpriseObject> destinationObjectsWithQualifier(EOQualifier qual) {
    NSArray<EOEnterpriseObject> result = null;
    NSArray<EOSortOrdering> orderings = null;
    if (!ERXStringUtilities.stringIsNullOrEmpty(sortKey())) {
      orderings = ERXS.ascs(sortKey());
    }
    if (extraQualifier() != null) {
      qual = ERXQ.and(qual, extraQualifier());
    }
    if (useFetch() && ERXStringUtilities.stringIsNullOrEmpty(restrictedChoiceKey())) {
          if(restrictingFetchSpecificationName() != null) {
            qual = ERXQ.and(qual, restrictingFetchSpec().qualifier());
          }
          EOFetchSpecification fetchSpec = new EOFetchSpecification(destinationEntityName(), qual, orderings);
      fetchSpec.setIsDeep(true);
      EOEditingContext ec = ERXEC.newEditingContext();
      result = ec.objectsWithFetchSpecification(fetchSpec);
    } else {
      result = ERXQ.filtered(allItems(), qual);
    }
    return result;
  }
 
  private EOEditingContext ec() {
      return object().editingContext();
    }
 
  // ACCESSORS
 
  public String destinationEntityName() {
    if (_destinationEntityName == null) {
      _destinationEntityName = stringValueForBinding(Keys.destinationEntityName);
     
    }
    return _destinationEntityName;
  }

  public String sortKey() {
    if (_sortKey == null) {
      _sortKey = stringValueForBinding(Keys.sortKey);
    }
    return _sortKey;
  }

  public String propertyKey() {
    if (_propertyKey == null) {
      _propertyKey = stringValueForBinding(Keys.propertyKey);
    }
    return _propertyKey;
  }

  public void setPropertyKey(String key) {
    _propertyKey = key;
  }
 
  @SuppressWarnings("unchecked")
    public NSArray<EOEnterpriseObject> allItems() {
      if (_allItems == null) {
        _allItems = (NSArray<EOEnterpriseObject>)restrictedChoiceList();
        if (_allItems == null) {
          EOFetchSpecification fetchSpec = new EOFetchSpecification(destinationEntityName(), null, null);
          _allItems = ec().objectsWithFetchSpecification(fetchSpec);
        }
    }
    return _allItems;
  }
 
  public EOFetchSpecification restrictingFetchSpec() {
    if (_restrictingFetchSpec == null) {
     
      _restrictingFetchSpec = EOModelGroup.defaultGroup().fetchSpecificationNamed(restrictingFetchSpecificationName(), destinationEntityName());;
    }
    return _restrictingFetchSpec;
  }

  public String restrictedChoiceKey() {
    if (_restrictedChoiceKey == null) {
      _restrictedChoiceKey = stringValueForBinding(Keys.restrictedChoiceKey);
    }
    return _restrictedChoiceKey;
  }

  public String restrictingFetchSpecificationName() {
    if (_restrictingFetchSpecification == null) {
      _restrictingFetchSpecification = stringValueForBinding(Keys.restrictingFetchSpecification);
    }
    return _restrictingFetchSpecification;
  }

  public String searchTemplate() {
    if (_template == null) {
      _template = stringValueForBinding(Keys.typeAheadSearchTemplate);
    }
    return _template;
  }

  public EOQualifier extraQualifier() {
    if (_extraQualifier == null) {
      _extraQualifier = (EOQualifier)valueForBinding(Keys.extraRestrictingQualifier);
    }
    return _extraQualifier;
  }

  public Integer minimumCharacterCount() {
    if (_minimumCharacterCount == null) {
      _minimumCharacterCount = ERXValueUtilities.IntegerValueWithDefault(stringValueForBinding(Keys.typeAheadMinimumCharaceterCount), 1);
    }
    return _minimumCharacterCount;
  }

  public String keyWhenRelationship() {
    if (_keyWhenRelationship == null) {
      _keyWhenRelationship = stringValueForBinding(Keys.keyWhenRelationship);
    }
    return _keyWhenRelationship;
  }
 
    public Object restrictedChoiceList() {
        String restrictedChoiceKey = stringValueForBinding(Keys.restrictedChoiceKey);
        if( restrictedChoiceKey!=null &&  restrictedChoiceKey.length()>0 )
            return valueForKeyPath(restrictedChoiceKey);
        String fetchSpecName = stringValueForBinding(Keys.restrictingFetchSpecification);
        if(fetchSpecName != null) {
            EORelationship relationship = ERXUtilities.relationshipWithObjectAndKeyPath(object(),
                                                                                        (String)d2wContext().valueForKey(Keys.propertyKey));
            return EOUtilities.objectsWithFetchSpecificationAndBindings(object().editingContext(), relationship.destinationEntity().name(),fetchSpecName,null);
        }
        return null;
    }
   
  public String newButtonClass() {
    if (_newButtonClass == null) {
      _newButtonClass = stringValueForBinding(Keys.classForNewObjButton, "Button ObjButton NewObjButton");
    }
    return _newButtonClass;
  }
 
  public String newButtonLabel() {
    if (_newButtonLabel == null) {
      _newButtonLabel = stringValueForBinding(Keys.newButtonLabel, "New");
    }
    return _newButtonLabel;
  }

  // AJAX IDs
 
  public String searchTermSelectedFunctionName() {
    if (_safeElementID == null) {
      _safeElementID =ERXStringUtilities.safeIdentifierName(context().elementID());
    }
    return "ermdtorlu_" + _safeElementID + "CompleteFunction";
  }

  public String searchTermSelectedFunction() {
    return "function(e) { " + searchTermSelectedFunctionName() + "(); }";
  }
   
  /** Should the 'new' button be displayed? */
  public boolean isEntityCreatable() {
    return ERXValueUtilities.booleanValueWithDefault(d2wContext()
        .valueForKey("isDestinationEntityCreatable"), true);
  }

  /** Should the 'inspect' button be displayed? */
  public boolean isEntityInspectable() {
    return ERXValueUtilities.booleanValueWithDefault(d2wContext()
        .valueForKey("isDestinationEntityInspectable"), true);
  }
}
TOP

Related Classes of er.modern.directtoweb.components.relationships.ERMD2WEditToOneTypeAhead

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.