private PersonFavourite addFavouriteSite(String userName, NodeRef nodeRef) {
    PersonFavourite favourite = null;

    SiteInfo siteInfo = siteService.getSite(nodeRef);
    if (siteInfo != null) {
      favourite = getFavouriteSite(userName, siteInfo);
      if (favourite == null) {
        Map<String, Serializable> preferences = new HashMap<String, Serializable>(1);

        String siteFavouritedKey = siteFavouritedKey(siteInfo);
        preferences.put(siteFavouritedKey, Boolean.TRUE);

        // ISO8601 string format: PreferenceService works with strings only for dates it seems
        String siteCreatedAtKey = siteCreatedAtKey(siteInfo);
        Date createdAt = new Date();
        String createdAtStr = ISO8601DateFormat.format(createdAt);
        preferences.put(siteCreatedAtKey, createdAtStr);

        preferenceService.setPreferences(userName, preferences);

        favourite =
            new PersonFavourite(
                userName, siteInfo.getNodeRef(), Type.SITE, siteInfo.getTitle(), createdAt);

        QName nodeClass = nodeService.getType(nodeRef);
        OnAddFavouritePolicy policy = onAddFavouriteDelegate.get(nodeRef, nodeClass);
        policy.onAddFavourite(userName, nodeRef);
      }
    } else {
      // shouldn't happen, getType recognizes it as a site or subtype
      logger.warn("Unable to get site for " + nodeRef);
    }

    return favourite;
  }
 /**
  * Invoke on cancel check out
  *
  * @param nodeRef
  */
 private void invokeOnCancelCheckOut(NodeRef nodeRef) {
   List<QName> classes = getInvokeClasses(nodeRef);
   for (QName invokeClass : classes) {
     Collection<OnCancelCheckOut> policies = onCancelCheckOut.getList(invokeClass);
     for (OnCancelCheckOut policy : policies) {
       policy.onCancelCheckOut(nodeRef);
     }
   }
 }
 /**
  * Invoke before cancel check out
  *
  * @param workingCopy
  */
 private void invokeBeforeCancelCheckOut(NodeRef workingCopy) {
   List<QName> classes = getInvokeClasses(workingCopy);
   for (QName invokeClass : classes) {
     Collection<BeforeCancelCheckOut> policies = beforeCancelCheckOut.getList(invokeClass);
     for (BeforeCancelCheckOut policy : policies) {
       policy.beforeCancelCheckOut(workingCopy);
     }
   }
 }
 /**
  * Invoke on check in policy
  *
  * @param nodeRef
  */
 private void invokeOnCheckIn(NodeRef nodeRef) {
   List<QName> classes = getInvokeClasses(nodeRef);
   for (QName invokeClass : classes) {
     Collection<OnCheckIn> policies = onCheckIn.getList(invokeClass);
     for (OnCheckIn policy : policies) {
       policy.onCheckIn(nodeRef);
     }
   }
 }
 /**
  * Invoke on the on check out policy
  *
  * @param workingCopy
  */
 private void invokeOnCheckOut(NodeRef workingCopy) {
   List<QName> classes = getInvokeClasses(workingCopy);
   for (QName invokeClass : classes) {
     Collection<OnCheckOut> policies = onCheckOut.getList(invokeClass);
     for (OnCheckOut policy : policies) {
       policy.onCheckOut(workingCopy);
     }
   }
 }
  public void notifyDynamicModelLoaded(DynamicModelInfo entry) {
    if (onLoadDynamicModelDelegate == null) {
      onLoadDynamicModelDelegate =
          policyComponent.registerClassPolicy(DynamicModelPolicies.OnLoadDynamicModel.class);
    }

    DynamicModelPolicies.OnLoadDynamicModel policy =
        onLoadDynamicModelDelegate.get(ContentModel.TYPE_CONTENT);
    policy.onLoadDynamicModel(entry.model, entry.nodeRef);
  }
 /**
  * Invoke before check in policy
  *
  * @param workingCopyNodeRef
  * @param versionProperties
  * @param contentUrl
  * @param keepCheckedOut
  */
 private void invokeBeforeCheckIn(
     NodeRef workingCopyNodeRef,
     Map<String, Serializable> versionProperties,
     String contentUrl,
     boolean keepCheckedOut) {
   List<QName> classes = getInvokeClasses(workingCopyNodeRef);
   for (QName invokeClass : classes) {
     Collection<BeforeCheckIn> policies = beforeCheckIn.getList(invokeClass);
     for (BeforeCheckIn policy : policies) {
       policy.beforeCheckIn(workingCopyNodeRef, versionProperties, contentUrl, keepCheckedOut);
     }
   }
 }
 /**
  * Invoke the before check out policy
  *
  * @param nodeRef
  * @param destinationParentNodeRef
  * @param destinationAssocTypeQName
  * @param destinationAssocQName
  */
 private void invokeBeforeCheckOut(
     NodeRef nodeRef,
     NodeRef destinationParentNodeRef,
     QName destinationAssocTypeQName,
     QName destinationAssocQName) {
   List<QName> classes = getInvokeClasses(nodeRef);
   for (QName invokeClass : classes) {
     Collection<BeforeCheckOut> policies = beforeCheckOut.getList(invokeClass);
     for (BeforeCheckOut policy : policies) {
       policy.beforeCheckOut(
           nodeRef, destinationParentNodeRef, destinationAssocTypeQName, destinationAssocQName);
     }
   }
 }
  private PersonFavourite addFavouriteDocumentOrFolder(
      String userName, Type type, NodeRef nodeRef) {
    Map<PersonFavouriteKey, PersonFavourite> personFavourites = getFavouriteNodes(userName, type);
    PersonFavourite personFavourite = getPersonFavourite(userName, type, nodeRef);
    if (personFavourite == null) {
      Date createdAt = new Date();
      final String name = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
      personFavourite = new PersonFavourite(userName, nodeRef, type, name, createdAt);
      personFavourites.put(personFavourite.getKey(), personFavourite);
      updateFavouriteNodes(userName, type, personFavourites);

      QName nodeClass = nodeService.getType(nodeRef);
      final String finalRef = nodeRef.getId();
      final QName nodeType = nodeClass;

      eventPublisher.publishEvent(
          new EventPreparator() {
            @Override
            public Event prepareEvent(String user, String networkId, String transactionId) {
              return new ActivityEvent(
                  "favorite.added",
                  transactionId,
                  networkId,
                  user,
                  finalRef,
                  null,
                  nodeType == null ? null : nodeType.toString(),
                  Client.asType(ClientType.script),
                  null,
                  name,
                  null,
                  0l,
                  null);
            }
          });

      OnAddFavouritePolicy policy = onAddFavouriteDelegate.get(nodeRef, nodeClass);
      policy.onAddFavourite(userName, nodeRef);
    }

    return personFavourite;
  }
  private boolean removeFavouriteNode(String userName, Type type, NodeRef nodeRef) {
    boolean exists = false;

    Map<PersonFavouriteKey, PersonFavourite> personFavourites = getFavouriteNodes(userName, type);

    PersonFavouriteKey personFavouriteKey = new PersonFavouriteKey(userName, null, type, nodeRef);
    PersonFavourite personFavourite = personFavourites.remove(personFavouriteKey);
    exists = personFavourite != null;
    updateFavouriteNodes(userName, type, personFavourites);

    QName nodeClass = nodeService.getType(nodeRef);
    final String finalRef = nodeRef.getId();
    final QName nodeType = nodeClass;

    eventPublisher.publishEvent(
        new EventPreparator() {
          @Override
          public Event prepareEvent(String user, String networkId, String transactionId) {
            return new ActivityEvent(
                "favorite.removed",
                transactionId,
                networkId,
                user,
                finalRef,
                null,
                nodeType == null ? null : nodeType.toString(),
                Client.asType(ClientType.script),
                null,
                null,
                null,
                0l,
                null);
          }
        });

    OnRemoveFavouritePolicy policy = onRemoveFavouriteDelegate.get(nodeRef, nodeClass);
    policy.onRemoveFavourite(userName, nodeRef);

    return exists;
  }