/**
   * Implementation of command pattern. Will be called by ScheduledInvocationManager for delayed
   * announcement notifications
   *
   * @param opaqueContext reference (context) for message
   */
  public void execute(String opaqueContext) {
    // get the message
    final Reference ref = entityManager.newReference(opaqueContext);

    // needed to access the message
    enableSecurityAdvisorToGetAnnouncement();

    final AnnouncementMessage msg = (AnnouncementMessage) ref.getEntity();
    final AnnouncementMessageHeader hdr = (AnnouncementMessageHeader) msg.getAnnouncementHeader();

    // read the notification options
    final String notification = msg.getProperties().getProperty("notificationLevel");

    int noti = NotificationService.NOTI_OPTIONAL;
    if ("r".equals(notification)) {
      noti = NotificationService.NOTI_REQUIRED;
    } else if ("n".equals(notification)) {
      noti = NotificationService.NOTI_NONE;
    }

    final Event delayedNotificationEvent =
        eventTrackingService.newEvent("annc.schInv.notify", msg.getReference(), true, noti);
    //		eventTrackingService.post(event);

    NotificationEdit notify = notificationService.addTransientNotification();

    super.notify(notify, delayedNotificationEvent);

    // since we build the notification by accessing the
    // message within the super class, can't remove the
    // SecurityAdvisor until this point
    // done with access, need to remove from stack
    disableSecurityAdvisor();
  }
  /** Disable the cache. */
  public void disable() {
    M_log.debug("disable()");

    m_disabled = true;
    m_eventTrackingService.deleteObserver(this);
    clear();
  } // disable
  /** Enable the cache. */
  public void enable() {
    M_log.debug("enable()");

    m_disabled = false;

    if (m_resourcePattern != null) {
      m_eventTrackingService.addPriorityObserver(this);
    }
  } // enable
  /**
   * @see
   *     org.sakaiproject.api.common.edu.person.SakaiPersonManager#delete(org.sakaiproject.api.common.edu.person.SakaiPerson)
   */
  public void delete(final SakaiPerson sakaiPerson) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("delete(SakaiPerson " + sakaiPerson + ")");
    }
    if (sakaiPerson == null)
      throw new IllegalArgumentException("Illegal sakaiPerson argument passed!");

    String ref = getReference(sakaiPerson);

    // only someone with the appropriate permissions can delete
    if (!SecurityService.unlock("user.del", ref)) {
      throw new SecurityException("You do not have permission to delete this sakaiPerson.");
    }

    LOG.debug("getHibernateTemplate().delete(sakaiPerson);");
    getHibernateTemplate().delete(sakaiPerson);
    eventTrackingService.post(eventTrackingService.newEvent("profile.delete", ref, true));
  }
  /** Clean up. */
  public void destroy() {
    cache.removeAll(); // TODO Do we boolean doNotNotifyCacheReplicators? Ian?
    cache.getStatistics().clearStatistics();

    // if we are not in a global shutdown
    if (!ComponentManager.hasBeenClosed()) {
      // remove my registration
      m_memoryService.unregisterCacher(this);

      // remove my event notification registration
      m_eventTrackingService.deleteObserver(this);
    }
  }
  /**
   * Construct the Cache. Event scanning if pattern not null - will expire entries.
   *
   * @param sleep The number of seconds to sleep between expiration checks.
   * @param pattern The "startsWith()" string for all resources that may be in this cache - if null,
   *     don't watch events for expiration.
   */
  public MemCache(
      BasicMemoryService memoryService,
      EventTrackingService eventTrackingService,
      String pattern,
      Ehcache cache) {
    this(memoryService, eventTrackingService, cache);
    m_resourcePattern = pattern;

    // register to get events - first, before others
    if (pattern != null) {
      m_eventTrackingService.addPriorityObserver(this);
    }
  }
  /**
   * @see org.sakaiproject.api.common.edu.person.SakaiPersonManager#create(java.lang.String,
   *     java.lang.String, org.sakaiproject.api.common.type.Type)
   */
  public SakaiPerson create(String userId, Type recordType) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("create(String " + userId + ",  Type " + recordType + ")");
    }
    if (userId == null || userId.length() < 1)
      throw new IllegalArgumentException("Illegal agentUuid argument passed!");
    ; // a null uid is valid
    if (!isSupportedType(recordType))
      throw new IllegalArgumentException("Illegal recordType argument passed!");

    SakaiPersonImpl spi = new SakaiPersonImpl();
    persistableHelper.createPersistableFields(spi);
    spi.setUuid(IdManager.createUuid());
    spi.setAgentUuid(userId);
    spi.setUid(userId);
    spi.setTypeUuid(recordType.getUuid());
    spi.setLocked(Boolean.valueOf(false));
    this.getHibernateTemplate().save(spi);

    // log the event
    String ref = getReference(spi);
    eventTrackingService.post(eventTrackingService.newEvent("profile.new", ref, true));

    // do not do this for system profiles
    if (serverConfigurationService.getBoolean("profile.updateUser", false)) {
      try {
        User u = userDirectoryService.getUser(userId);
        spi.setGivenName(u.getFirstName());
        spi.setSurname(u.getLastName());
        spi.setMail(u.getEmail());
      } catch (UserNotDefinedException uue) {
        LOG.error("User " + userId + "doesn't exist");
      }
    }

    LOG.debug("return spi;");
    return spi;
  }
 @Override
 public void destroy() {
   eventTrackingService.deleteObserver(observer);
   super.destroy();
 }
 public MyRecentChangesHandler() {
   observer = new MyRecentChangesObserver();
   eventTrackingService = Kernel.eventTrackingService();
   eventTrackingService.addLocalObserver(observer);
 }
  /** @see SakaiPersonManager#save(SakaiPerson) */
  public void save(SakaiPerson sakaiPerson) {
    if (LOG.isDebugEnabled()) {
      LOG.debug("save(SakaiPerson " + sakaiPerson + ")");
    }
    if (sakaiPerson == null)
      throw new IllegalArgumentException("Illegal sakaiPerson argument passed!");
    if (!isSupportedType(sakaiPerson.getTypeUuid()))
      throw new IllegalArgumentException("The sakaiPerson argument contains an invalid Type!");

    // AuthZ
    // Only superusers can update system records
    if (getSystemMutableType().getUuid().equals(sakaiPerson.getTypeUuid())
        && !SecurityService.isSuperUser()) {
      throw new IllegalAccessError("System mutable records cannot be updated.");
    }

    // if it is a user mutable record, ensure the user is updating their own record
    // this can be overriden with a security advisor so the admin user to allow access
    if (!SecurityService.unlock(
        UserDirectoryService.ADMIN_ID,
        SakaiPerson.PROFILE_SAVE_PERMISSION,
        sakaiPerson.getAgentUuid())) {

      if (!StringUtils.equals(SessionManager.getCurrentSessionUserId(), sakaiPerson.getAgentUuid())
          && !SecurityService.isSuperUser()) {
        // AuthZ - Ensure the current user is updating their own record
        if (!StringUtils.equals(
            SessionManager.getCurrentSessionUserId(), sakaiPerson.getAgentUuid())) {
          throw new IllegalAccessError("You do not have permissions to update this record!");
        }
      }
    }

    // store record
    if (!(sakaiPerson instanceof SakaiPersonImpl)) {
      // TODO support alternate implementations of SakaiPerson
      // copy bean properties into new SakaiPersonImpl with beanutils?
      throw new UnsupportedOperationException("Unknown SakaiPerson implementation found!");
    } else {
      // update lastModifiedDate
      SakaiPersonImpl spi = (SakaiPersonImpl) sakaiPerson;
      persistableHelper.modifyPersistableFields(spi);
      // if the repository path is set save if there
      if (photoService.overRidesDefault()) {
        photoService.savePhoto(spi.getJpegPhoto(), spi.getAgentUuid());
        spi.setJpegPhoto(null);
      }

      // use update(..) method to ensure someone does not try to insert a
      // prototype.
      getHibernateTemplate().update(spi);

      // set the event
      String ref = getReference(spi);
      LOG.debug("got ref of: " + ref + " about to set events");

      eventTrackingService.post(eventTrackingService.newEvent("profile.update", ref, true));

      LOG.debug("User record updated for Id :-" + spi.getAgentUuid());
      // update the account too -only if not system profile
      if (serverConfigurationService.getBoolean("profile.updateUser", false)
          && spi.getTypeUuid().equals(this.userMutableType.getUuid())) {
        try {
          UserEdit userEdit = null;
          userEdit = userDirectoryService.editUser(spi.getAgentUuid());
          userEdit.setFirstName(spi.getGivenName());
          userEdit.setLastName(spi.getSurname());
          userEdit.setEmail(spi.getMail());
          userDirectoryService.commitEdit(userEdit);
          LOG.debug("Saved user object");
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    }
  }
  /** Setup the velocity context and choose the template for options. */
  public String buildOptionsPanelContext(
      VelocityPortlet portlet, Context context, RunData data, SessionState state) {
    // provide the source, and let the user edit, if not special
    String special = (String) state.getAttribute(SPECIAL);
    String source = "";
    String siteId = "";
    if (special == null) {
      source = (String) state.getAttribute(SOURCE);
      if (source == null) source = "";
      context.put(SOURCE, source);
      context.put("heading", rb.getString("gen.custom"));
    }

    // set the heading based on special
    else {
      if (SPECIAL_SITE.equals(special)) {
        context.put("heading", rb.getString("gen.custom.site"));
      } else if (SPECIAL_WORKSPACE.equals(special)) {
        context.put("heading", rb.getString("gen.custom.workspace"));
      } else if (SPECIAL_WORKSITE.equals(special)) {
        context.put("heading", rb.getString("gen.custom.worksite"));

        // for worksite, also include the Site's infourl and description
        try {
          Site s = SiteService.getSite(ToolManager.getCurrentPlacement().getContext());
          siteId = s.getId();

          String infoUrl = StringUtils.trimToNull(s.getInfoUrl());
          if (infoUrl != null) {
            context.put("info_url", infoUrl);
          }

          String description = StringUtils.trimToNull(s.getDescription());
          if (description != null) {
            description = FormattedText.escapeHtmlFormattedTextarea(description);
            context.put("description", description);
          }
        } catch (Throwable e) {
        }
      } else if (SPECIAL_ANNOTATEDURL.equals(special)) {

        context.put("heading", rb.getString("gen.custom.annotatedurl"));

        // for Annotated URL Tool page, also include the description
        try {
          String desp = state.getAttribute(ANNOTATED_TEXT).toString();
          context.put("description", desp);

        } catch (Throwable e) {
        }
      } else {
        context.put("heading", rb.getString("gen.custom"));
      }
    }

    boolean selected = false;
    String height = state.getAttribute(HEIGHT).toString();
    for (int i = 0; i < ourPixels.length; i++) {
      if (height.equals(ourPixels[i])) {
        selected = true;
        continue;
      }
    }
    if (!selected) {
      String[] strings = height.trim().split("px");
      context.put("custom_height", strings[0]);
      height = rb.getString("gen.heisomelse");
    }
    context.put(HEIGHT, height);

    context.put(TITLE, state.getAttribute(TITLE));
    context.put("tlang", rb);

    context.put("doUpdate", BUTTON + "doConfigure_update");
    context.put("doCancel", BUTTON + "doCancel");

    context.put("form_tool_title", FORM_TOOL_TITLE);
    context.put("form_page_title", FORM_PAGE_TITLE);

    // if we are part of a site, and the only tool on the page, offer the popup to edit
    Placement placement = ToolManager.getCurrentPlacement();
    ToolConfiguration toolConfig = SiteService.findTool(placement.getId());
    if ((state.getAttribute(SPECIAL) == null) && (toolConfig != null)) {
      try {
        Site site = SiteService.getSite(toolConfig.getSiteId());
        siteId = site.getId();
        SitePage page = site.getPage(toolConfig.getPageId());

        // if this is the only tool on that page, update the page's title also
        if ((page.getTools() != null) && (page.getTools().size() == 1)) {
          context.put("showPopup", Boolean.TRUE);
          context.put("popup", Boolean.valueOf(page.isPopUp()));

          context.put("pageTitleEditable", Boolean.TRUE);
          context.put("page_title", (String) state.getAttribute(STATE_PAGE_TITLE));
        }
      } catch (Throwable e) {
      }
    }

    // pick the "-customize" template based on the standard template name
    String template = (String) getContext(data).get("template");

    // pick the site customize template if we are in that mode
    if (SPECIAL_WORKSITE.equals(special)) {
      template = template + "-site-customize";
    } else if (SPECIAL_WORKSPACE.equals(special)) {
      template = template + "-customize";
    } else if (SPECIAL_ANNOTATEDURL.equals(special)) {
      template = template + "-annotatedurl-customize";
    } else {
      template = template + "-customize";
    }

    // tracking event
    if (siteId.length() == 0) {
      try {
        Site s = SiteService.getSite(ToolManager.getCurrentPlacement().getContext());
        siteId = s.getId();
      } catch (Throwable e) {

      }
    }
    if (special == null) {
      if (state.getAttribute(EVENT_REVISE_WEB_CONTENT) == null) {

        // this is a Web Content tool
        m_eventTrackingService.post(
            m_eventTrackingService.newEvent(
                EVENT_REVISE_WEB_CONTENT, source, siteId, true, NotificationService.NOTI_NONE));
      } else {
        // event in tool registration file will be used
        m_eventTrackingService.post(
            m_eventTrackingService.newEvent(
                (String) state.getAttribute(EVENT_REVISE_WEB_CONTENT),
                source,
                siteId,
                true,
                NotificationService.NOTI_NONE));
      }
    } else {
      if (state.getAttribute(EVENT_REVISE_WEB_CONTENT) != null) {
        // special and event in tool registration file
        m_eventTrackingService.post(
            m_eventTrackingService.newEvent(
                (String) state.getAttribute(EVENT_REVISE_WEB_CONTENT),
                source,
                siteId,
                true,
                NotificationService.NOTI_NONE));
      }
    }

    // output the max limit
    context.put("max_length_title", MAX_TITLE_LENGTH);
    context.put("max_length_info_url", MAX_SITE_INFO_URL_LENGTH);

    return template;
  }
  /** Setup the velocity context and choose the template for the response. */
  public String buildMainPanelContext(
      VelocityPortlet portlet, Context context, RunData rundata, SessionState state) {
    // do options if we are in options mode
    if (MODE_OPTIONS.equals(state.getAttribute(STATE_MODE))) {
      return buildOptionsPanelContext(portlet, context, rundata, state);
    }

    // if we rely on state (like all the other tools), we won't pick up any changes others make to
    // the configuration till we are refreshed... -ggolden

    // set our configuration into the context for the vm
    String url = (String) state.getAttribute(URL);
    String special = (String) state.getAttribute(SPECIAL);
    context.put(URL, url);
    context.put(HEIGHT, state.getAttribute(HEIGHT));

    // for annotatedurl
    context.put(TARGETPAGE_URL, state.getAttribute(TARGETPAGE_URL));
    context.put(TARGETPAGE_NAME, state.getAttribute(TARGETPAGE_NAME));
    context.put(ANNOTATED_TEXT, state.getAttribute(ANNOTATED_TEXT));

    // set the resource bundle with our strings
    context.put("tlang", rb);

    // setup for the options menu if needed

    String hideOptions = (String) state.getAttribute(HIDE_OPTIONS);

    if (hideOptions != null && "true".equalsIgnoreCase(hideOptions)) {
      // always hide Options menu if hide.options is specified
    } else if (SiteService.allowUpdateSite(ToolManager.getCurrentPlacement().getContext())) {

      context.put(
          "options_title",
          ToolManager.getCurrentPlacement().getTitle() + " " + rb.getString("gen.options"));
    }

    // tracking event
    String siteId = "";
    try {
      Site s = SiteService.getSite(ToolManager.getCurrentPlacement().getContext());
      siteId = s.getId();
    } catch (Throwable e) {

    }
    if (special == null) {
      if (state.getAttribute(EVENT_ACCESS_WEB_CONTENT) == null) {

        // this is a Web Content tool
        m_eventTrackingService.post(
            m_eventTrackingService.newEvent(
                EVENT_ACCESS_WEB_CONTENT, url, siteId, false, NotificationService.NOTI_NONE));
      } else {

        // event in tool registration file will be used
        m_eventTrackingService.post(
            m_eventTrackingService.newEvent(
                (String) state.getAttribute(EVENT_ACCESS_WEB_CONTENT),
                url,
                siteId,
                false,
                NotificationService.NOTI_NONE));
      }
    } else {
      if (state.getAttribute(EVENT_ACCESS_WEB_CONTENT) != null) {

        // special and event in tool registration file
        m_eventTrackingService.post(
            m_eventTrackingService.newEvent(
                (String) state.getAttribute(EVENT_ACCESS_WEB_CONTENT),
                url,
                siteId,
                false,
                NotificationService.NOTI_NONE));
      }
    }

    return (String) getContext(rundata).get("template");
  }