Package com.secretpal.model

Source Code of com.secretpal.model.SPEvent

package com.secretpal.model;

import java.security.SecureRandom;

import org.apache.log4j.Logger;

import com.webobjects.eocontrol.EOEditingContext;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSMutableArray;

import er.extensions.eof.ERXEC;
import er.extensions.eof.ERXEOControlUtilities;

public class SPEvent extends _SPEvent {
  private static Logger log = Logger.getLogger(SPEvent.class);

  public boolean hasAssignedSecretPals() {
    return secretPals().count() > 0;
  }
 
  public boolean hasNotAssignedSecretPals() {
    return !hasAssignedSecretPals();
  }
 
  public void reassignSecretPals() {
    // MS: deleting all the existing pals means that this implementation can be a lot easier, but it was originally
    // written to NOT do this, which is why it's so weird and non-deterministic.
    deleteAllSecretPalsRelationships();

    NSArray<SPPerson> allPeople = SPMembership.PERSON.arrayValueInObject(group().memberships());
    NSArray<SPPerson> eligibleGivers = _eligibleGivers(allPeople);
    NSMutableArray<SPPerson> consumedReceivers = new NSMutableArray<SPPerson>();
   
    log.info(eligibleGivers.count() + " eligible givers out of " + allPeople.count() + " people");

    SecureRandom random = new SecureRandom();
    long a = System.currentTimeMillis();
    int numberOfAttempts = 0;
    int maxNumberOfAttempts = 100;
    boolean doneWithSecretPals = false;
    while (!doneWithSecretPals && numberOfAttempts < maxNumberOfAttempts) {
      log.info("attempt #" + numberOfAttempts + " of " + maxNumberOfAttempts);
      EOEditingContext nestedEditingContext = ERXEC.newEditingContext(editingContext());
      nestedEditingContext.lock();
      SPEvent localEvent = localInstanceIn(nestedEditingContext);
      try {
        for (SPPerson selectedGiver : eligibleGivers) {
          NSArray<SPPerson> eligibleReceivers = _eligibleReceiversForPerson(selectedGiver, allPeople, consumedReceivers);
          if (eligibleReceivers.count() == 0) {
            throw new IllegalStateException("  Try again -- no receivers for " + selectedGiver.name());
          }
          int selectedReceiverNum = Math.abs(random.nextInt()) % eligibleReceivers.count();
          SPPerson selectedReceiver = eligibleReceivers.objectAtIndex(selectedReceiverNum);
          log.info("   " + selectedGiver.name() + "=>" + selectedReceiver.name() + ", " +selectedGiver + "," + selectedReceiver);
          SPSecretPal.createSPSecretPal(nestedEditingContext, localEvent, selectedGiver.localInstanceIn(nestedEditingContext), selectedReceiver.localInstanceIn(nestedEditingContext));
          consumedReceivers.addObject(selectedReceiver);
        }
        nestedEditingContext.saveChanges();
        doneWithSecretPals = true;
      }
      catch (IllegalStateException e) {
        numberOfAttempts ++;
      }
      finally {
        nestedEditingContext.unlock();
        nestedEditingContext.dispose();
      }
    }
    log.info("done in " + (System.currentTimeMillis() - a) + "ms");
    if (!doneWithSecretPals) {
      throw new IllegalStateException("Failed to assign secret pals after " + numberOfAttempts + " attempts.");
    }
  }

  public boolean canEdit(SPPerson currentPerson) {
    return currentPerson.admin().booleanValue() || ERXEOControlUtilities.eoEquals(group().owner(), currentPerson);
  }

  public NSArray<SPPerson> _eligibleGivers(NSArray<SPPerson> allPeople) {
    NSMutableArray<SPPerson> eligibleGivers = new NSMutableArray<SPPerson>();
    for (SPPerson possibleGiver : allPeople) {
      NSArray<SPPerson> noNoPeople = SPNoNoPal.RECEIVER.arrayValueInObject(noNoPalsForPerson(possibleGiver));
      // If someone has NO possible receivers right at the start, just leave them out ... This is to support
      // defining babies that can't buy for anyone
      if (noNoPeople.count() != allPeople.count() - 1) {
        eligibleGivers.addObject(possibleGiver);
      }
    }
    return eligibleGivers;
  }
 
  public NSArray<SPPerson> _eligibleReceiversForPerson(SPPerson giver, NSArray<SPPerson> allPeople, NSArray<SPPerson> consumedReceivers) {
    NSMutableArray<SPPerson> eligibleReceivers = new NSMutableArray<SPPerson>();
    NSArray<SPPerson> noNoPeople = SPNoNoPal.RECEIVER.arrayValueInObject(noNoPalsForPerson(giver));
    for (SPPerson possibleReceiver : allPeople) {
      if (!giver.equals(possibleReceiver) && !consumedReceivers.containsObject(possibleReceiver) && !noNoPeople.containsObject(possibleReceiver)) {
        eligibleReceivers.addObject(possibleReceiver);
      }
    }
    return eligibleReceivers;
  }
 
  public NSArray<SPSecretPal> secretPalsForPerson(SPPerson person) {
    return SPSecretPal.GIVER.is(person).filtered(secretPals());
  }
 
  public NSArray<SPNoNoPal> noNoPalsForPerson(SPPerson person) {
    return SPNoNoPal.GIVER.is(person).filtered(noNoPals());
  }
 
  public NSArray<SPPerson> noNoPersonPossibilitiesForPerson(SPPerson person) {
    NSMutableArray<SPPerson> noNoPalPossibilities = new NSMutableArray<SPPerson>();
    NSArray<SPPerson> noNoPals = SPNoNoPal.RECEIVER.arrayValueInObject(noNoPalsForPerson(person));
    for (SPMembership membership : group().memberships()) {
      if (!membership.person().equals(person) && !noNoPals.containsObject(membership.person())) {
        noNoPalPossibilities.addObject(membership.person());
      }
    }
    return noNoPalPossibilities;
  }

}
TOP

Related Classes of com.secretpal.model.SPEvent

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.