private void updateFavouriteNodes(
      String userName, Type type, Map<PersonFavouriteKey, PersonFavourite> favouriteNodes) {
    PrefKeys prefKeys = getPrefKeys(type);

    Map<String, Serializable> preferences = new HashMap<String, Serializable>(1);

    StringBuilder values = new StringBuilder();
    for (PersonFavourite node : favouriteNodes.values()) {
      NodeRef nodeRef = node.getNodeRef();

      values.append(nodeRef.toString());
      values.append(",");

      // ISO8601 string format: PreferenceService works with strings only for dates it seems
      StringBuilder sb = new StringBuilder(prefKeys.getAlfrescoPrefKey());
      sb.append(nodeRef.toString());
      sb.append(".createdAt");
      String createdAtKey = sb.toString();
      Date createdAt = node.getCreatedAt();
      if (createdAt != null) {
        String createdAtStr = ISO8601DateFormat.format(createdAt);
        preferences.put(createdAtKey, createdAtStr);
      }
    }

    if (values.length() > 1) {
      values.delete(values.length() - 1, values.length());
    }

    preferences.put(prefKeys.getSharePrefKey(), values.toString());
    preferenceService.setPreferences(userName, preferences);
  }
  private String siteCreatedAtKey(SiteInfo siteInfo) {
    PrefKeys prefKeys = getPrefKeys(Type.SITE);

    StringBuilder sitePrefKeyBuilder = new StringBuilder(prefKeys.getAlfrescoPrefKey());
    sitePrefKeyBuilder.append(siteInfo.getShortName());
    String sitePrefKey = sitePrefKeyBuilder.toString();

    StringBuilder createdAtKeyBuilder = new StringBuilder(sitePrefKey);
    createdAtKeyBuilder.append(".createdAt");
    String createdAtKey = createdAtKeyBuilder.toString();
    return createdAtKey;
  }
  /*
   * Extract favourite nodes of the given type from the comma-separated list in "nodes".
   */
  private Map<PersonFavouriteKey, PersonFavourite> extractFavouriteNodes(
      String userName, Type type, String nodes) {
    PrefKeys prefKeys = getPrefKeys(type);
    Map<PersonFavouriteKey, PersonFavourite> favouriteNodes =
        new HashMap<PersonFavouriteKey, PersonFavourite>();

    StringTokenizer st = new StringTokenizer(nodes, ",");
    while (st.hasMoreTokens()) {
      String nodeRefStr = st.nextToken();
      nodeRefStr = nodeRefStr.trim();
      if (!NodeRef.isNodeRef((String) nodeRefStr)) {
        continue;
      }

      NodeRef nodeRef = new NodeRef((String) nodeRefStr);

      if (!nodeService.exists(nodeRef)) {
        continue;
      }

      if (permissionService.hasPermission(nodeRef, PermissionService.READ_PROPERTIES)
          == AccessStatus.DENIED) {
        continue;
      }

      // get createdAt for this favourited node
      // use ISO8601
      StringBuilder builder = new StringBuilder(prefKeys.getAlfrescoPrefKey());
      builder.append(nodeRef.toString());
      builder.append(".createdAt");
      String prefKey = builder.toString();
      String createdAtStr = (String) preferenceService.getPreference(userName, prefKey);
      Date createdAt = (createdAtStr != null ? ISO8601DateFormat.parse(createdAtStr) : null);

      String name = (String) nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);

      PersonFavourite personFavourite =
          new PersonFavourite(userName, nodeRef, type, name, createdAt);
      PersonFavouriteKey key = personFavourite.getKey();
      favouriteNodes.put(key, personFavourite);
    }

    return favouriteNodes;
  }
  private void extractFavouriteSite(
      String userName,
      Type type,
      Map<PersonFavouriteKey, PersonFavourite> sortedFavouriteNodes,
      Map<String, Serializable> preferences,
      String key) {
    // preference value indicates whether the site has been favourited
    Serializable pref = preferences.get(key);
    Boolean isFavourite = (Boolean) pref;
    if (isFavourite) {
      PrefKeys sitePrefKeys = getPrefKeys(Type.SITE);
      int length = sitePrefKeys.getSharePrefKey().length();
      String siteId = key.substring(length);

      try {
        SiteInfo siteInfo = siteService.getSite(siteId);
        if (siteInfo != null) {
          StringBuilder builder = new StringBuilder(sitePrefKeys.getAlfrescoPrefKey());
          builder.append(siteId);
          builder.append(".createdAt");
          String createdAtPrefKey = builder.toString();
          String createdAtStr = (String) preferences.get(createdAtPrefKey);
          Date createdAt = null;
          if (createdAtStr != null) {
            createdAt = (createdAtStr != null ? ISO8601DateFormat.parse(createdAtStr) : null);
          }
          PersonFavourite personFavourite =
              new PersonFavourite(userName, siteInfo.getNodeRef(), Type.SITE, siteId, createdAt);
          sortedFavouriteNodes.put(personFavourite.getKey(), personFavourite);
        }
      } catch (AccessDeniedException ex) {
        // the user no longer has access to this site, skip over the favourite
        // TODO remove the favourite preference
        return;
      }
    }
  }