/**
  * Access the component instance: special cover only method.
  *
  * <p>Automatically caches the instance if required.
  *
  * @return the component instance.
  */
 public static MetadataService getInstance() {
   if (ComponentManager.CACHE_COMPONENTS) {
     if (instance == null)
       instance = (MetadataService) ComponentManager.get(MetadataService.class);
     return instance;
   } else {
     return (MetadataService) ComponentManager.get(MetadataService.class);
   }
 }
Beispiel #2
0
 /**
  * Access the component instance: special cover only method.
  *
  * @return the component instance.
  */
 public static org.sakaiproject.db.api.SqlService getInstance() {
   if (ComponentManager.CACHE_COMPONENTS) {
     if (m_instance == null)
       m_instance =
           (org.sakaiproject.db.api.SqlService)
               ComponentManager.get(org.sakaiproject.db.api.SqlService.class);
     return m_instance;
   } else {
     return (org.sakaiproject.db.api.SqlService)
         ComponentManager.get(org.sakaiproject.db.api.SqlService.class);
   }
 }
 /**
  * Access the component instance: special cover only method.
  *
  * @return the component instance.
  */
 public static org.sakaiproject.tool.api.ActiveToolManager getInstance() {
   if (ComponentManager.CACHE_COMPONENTS) {
     if (m_instance == null)
       m_instance =
           (org.sakaiproject.tool.api.ActiveToolManager)
               ComponentManager.get(org.sakaiproject.tool.api.ActiveToolManager.class);
     return m_instance;
   } else {
     return (org.sakaiproject.tool.api.ActiveToolManager)
         ComponentManager.get(org.sakaiproject.tool.api.ActiveToolManager.class);
   }
 }
Beispiel #4
0
 public ArchiveAction() {
   super();
   courseManagementService = ComponentManager.get(CourseManagementService.class);
   siteService = ComponentManager.get(SiteService.class);
   sessionManager = ComponentManager.get(SessionManager.class);
   userDirectoryService = ComponentManager.get(UserDirectoryService.class);
   authzGroupService = ComponentManager.get(AuthzGroupService.class);
   serverConfigurationService = ComponentManager.get(ServerConfigurationService.class);
   archiveService = ComponentManager.get(ArchiveService.class);
   securityService = ComponentManager.get(SecurityService.class);
   idManager = ComponentManager.get(IdManager.class);
 }
Beispiel #5
0
 SecurityService getSecurityService() {
   // has to be lazy
   if (securityService == null) {
     securityService = (SecurityService) ComponentManager.get(SecurityService.class);
   }
   return securityService;
 }
  /** Final initialization, once all dependencies are set. */
  public void init() {
    try {
      m_relativeAccessPoint = REFERENCE_ROOT;

      // construct storage and read
      m_storage = newStorage();
      m_storage.open();

      // register as an entity producer
      entityManager().registerEntityProducer(this, REFERENCE_ROOT);

      // register functions
      functionManager().registerFunction(SECURE_ADD_AUTHZ_GROUP);
      functionManager().registerFunction(SECURE_REMOVE_AUTHZ_GROUP);
      functionManager().registerFunction(SECURE_UPDATE_AUTHZ_GROUP);
      functionManager().registerFunction(SECURE_UPDATE_OWN_AUTHZ_GROUP);

      // if no provider was set, see if we can find one
      if (m_provider == null) {
        m_provider = (GroupProvider) ComponentManager.get(GroupProvider.class.getName());
      }

      M_log.info(
          "init(): provider: " + ((m_provider == null) ? "none" : m_provider.getClass().getName()));
    } catch (Throwable t) {
      M_log.warn("init(); ", t);
    }
  }
  public void init() {
    logger.debug(APPLICATION + " init()");

    try {
      EntityManager.registerEntityProducer(this, REFERENCE_ROOT);
    } catch (Exception e) {
      logger.warn("Error registering " + APPLICATION + " Entity Producer", e);
    }

    try {
      ComponentManager.loadComponent(
          "org.sakaiproject.bbb.tool.entity.BBBMeetingEntityProducer", this);
    } catch (Exception e) {
      logger.warn(
          "Error registering "
              + APPLICATION
              + " Entity Producer with Spring. "
              + APPLICATION
              + " will work, but "
              + APPLICATION
              + " tools won't be imported from site archives. This normally happens only if you redeploy "
              + APPLICATION
              + ". Suggest restarting Sakai",
          e);
    }
  }
  /**
   * Determine whether the CitationsService is fully configured to enable this user to search
   * library resources and add search results as citations in the document in the rich-text editor.
   *
   * @return true if this user may use the resource-search plug-in in the editor to search library
   *     resources and add search results as citations in the document in the editor, false
   *     otherwise.
   */
  public static boolean enableResourceSearch() {
    Session session = SessionManager.getCurrentSession();
    Boolean showCitationsButton = (Boolean) session.getAttribute(ATTR_ENABLE_RESOURCE_SEARCH);

    if (showCitationsButton == null) {
      Object component = ComponentManager.get("org.sakaiproject.citation.api.ConfigurationService");
      if (component == null) {
        // if the service can't be found, return FALSE
        showCitationsButton = Boolean.FALSE;
      } else {
        try {
          Method method = component.getClass().getMethod("librarySearchEnabled", new Class[] {});

          if (method == null) {
            // if the method can't be invoked, return FALSE
            showCitationsButton = Boolean.FALSE;
          } else {
            showCitationsButton = (Boolean) method.invoke(component, null);
            session.setAttribute(ATTR_ENABLE_RESOURCE_SEARCH, showCitationsButton);
          }
        } catch (Exception e) {
          // if the method can't be invoked, return FALSE
          showCitationsButton = Boolean.FALSE;
        }
      }
    }

    return showCitationsButton.booleanValue();
  }
  public UrlResourceType() {
    this.userDirectoryService =
        (UserDirectoryService)
            ComponentManager.get("org.sakaiproject.user.api.UserDirectoryService");

    actions.put(ResourceToolAction.CREATE, new UrlResourceCreateAction());
    // actions.put(ResourceToolAction.ACCESS_CONTENT, new UrlResourceAccessAction());
    actions.put(ResourceToolAction.REVISE_CONTENT, new UrlResourceReviseAction());
    // actions.put(ResourceToolAction.REPLACE_CONTENT, new UrlResourceReplaceAction());
    actions.put(ResourceToolAction.ACCESS_PROPERTIES, new UrlResourceViewPropertiesAction());
    actions.put(ResourceToolAction.REVISE_METADATA, new UrlResourcePropertiesAction());
    actions.put(ResourceToolAction.DUPLICATE, new UrlResourceDuplicateAction());
    actions.put(ResourceToolAction.COPY, new UrlResourceCopyAction());
    actions.put(ResourceToolAction.MOVE, new UrlResourceMoveAction());
    actions.put(ResourceToolAction.DELETE, new UrlResourceDeleteAction());

    // initialize actionMap with an empty List for each ActionType
    for (ResourceToolAction.ActionType type : ResourceToolAction.ActionType.values()) {
      actionMap.put(type, new ArrayList<ResourceToolAction>());
    }

    // for each action in actions, add a link in actionMap
    Iterator<String> it = actions.keySet().iterator();
    while (it.hasNext()) {
      String id = it.next();
      ResourceToolAction action = actions.get(id);
      List<ResourceToolAction> list = actionMap.get(action.getActionType());
      if (list == null) {
        list = new ArrayList<ResourceToolAction>();
        actionMap.put(action.getActionType(), list);
      }
      list.add(action);
    }
  }
  public ExtendedTimeService(PublishedAssessmentFacade publishedAssessment) {
    PublishedAssessmentService assessmentService = new PublishedAssessmentService();
    PublishedAssessmentFacade metaPublishedAssessment =
        assessmentService.getPublishedAssessmentQuick(
            publishedAssessment.getPublishedAssessmentId().toString());
    if (!assessmentInitialized(publishedAssessment)) {
      publishedAssessment = metaPublishedAssessment;
    }
    authzGroupService = ComponentManager.get(AuthzGroupService.class);

    // Grab the site id from the publishedAssessment because the user may
    // not be in a site
    // if they're taking the test via url.
    PublishedAssessmentService publishedAssessmentService = new PublishedAssessmentService();
    String pubId = publishedAssessment.getPublishedAssessmentId().toString();
    siteId = publishedAssessmentService.getPublishedAssessmentSiteId(pubId);

    this.metaString = extractMetaString(metaPublishedAssessment);
    this.hasExtendedTime = (metaString != null);
    if (this.hasExtendedTime) {
      this.timeLimit = extractExtendedTime();
      this.startDate = determineDate(1, publishedAssessment.getStartDate(), publishedAssessment);
      this.dueDate = determineDate(2, publishedAssessment.getDueDate(), publishedAssessment);
      this.retractDate =
          determineDate(3, publishedAssessment.getRetractDate(), publishedAssessment);
    } else {
      this.timeLimit = 0;
      this.startDate = publishedAssessment.getStartDate();
      this.dueDate = publishedAssessment.getDueDate();
      this.retractDate = publishedAssessment.getRetractDate();
    }
  }
  /* (non-Javadoc)
   * @see org.hibernate.UserType#nullSafeGet(java.sql.ResultSet, java.lang.String[], java.lang.Object)
   */
  public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
      throws HibernateException, SQLException {
    byte[] bytes = rs.getBytes(names[0]);
    if (rs.wasNull()) {
      return null;
    }

    // TODO figure out how to inject this
    HomeFactory homeFactory = (HomeFactory) ComponentManager.getInstance().get("xmlHomeFactory");
    WritableObjectHome home = (WritableObjectHome) homeFactory.getHome("agent");

    StructuredArtifact artifact = (StructuredArtifact) home.createInstance();
    ByteArrayInputStream in = new ByteArrayInputStream(bytes);
    SAXBuilder saxBuilder = new SAXBuilder();
    saxBuilder.setFeature(
        "http://apache.org/xml/features/disallow-doctype-decl", true); // SAK-23245
    try {
      Document doc = saxBuilder.build(in);
      artifact.setBaseElement(doc.getRootElement());
    } catch (JDOMException e) {
      throw new HibernateException(e);
    } catch (IOException e) {
      throw new HibernateException(e);
    }
    return artifact;
  }
  protected void resolveTransientFields() {
    // These are spelled out instead of using imports, to be explicit
    org.sakaiproject.component.api.ComponentManager compMgr =
        org.sakaiproject.component.cover.ComponentManager.getInstance();

    usageSessionServiceAdaptor =
        (UsageSessionServiceAdaptor) compMgr.get("org.sakaiproject.event.api.UsageSessionService");
  }
 public Object getContext(Class<?> type) {
   try {
     return (Object) ComponentManager.get(type.getName());
   } catch (NoClassDefFoundError ncdfe) {
     log.warn("Failed to find Sakai component manager");
     return null;
   }
 }
 /** @return An instance of the ConfigurationService */
 public static org.sakaiproject.citation.api.ConfigurationService getInstance() {
   /*
    * Caching?
    */
   if (ComponentManager.CACHE_COMPONENTS) {
     if (m_instance == null) {
       m_instance =
           (org.sakaiproject.citation.api.ConfigurationService)
               ComponentManager.get(org.sakaiproject.citation.api.ConfigurationService.class);
     }
     return m_instance;
   }
   /*
    * No cache
    */
   return (org.sakaiproject.citation.api.ConfigurationService)
       ComponentManager.get(org.sakaiproject.citation.api.ConfigurationService.class);
 }
  /** Returns to uninitialized state. */
  public void destroy() {
    // if we are not in a global shutdown, remove my event notification registration
    if (!ComponentManager.hasBeenClosed()) {
      eventTrackingService().deleteObserver(this);
    }

    cacheManager.clearAll();

    M_log.info("destroy()");
  }
Beispiel #16
0
  /** 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);
    }
  }
/** BasicMultiFileUploadPipe */
public class BasicMultiFileUploadPipe extends BasicResourceToolActionPipe
    implements MultiFileUploadPipe {
  /*  */
  protected List<ResourceToolActionPipe> pipes = new ArrayList<ResourceToolActionPipe>();

  /*  */
  protected ResourceTypeRegistry registry =
      (ResourceTypeRegistry)
          ComponentManager.get("org.sakaiproject.content.api.ResourceTypeRegistry");

  /**
   * @param interactionId
   * @param action
   */
  public BasicMultiFileUploadPipe(String interactionId, ResourceToolAction action) {
    super(interactionId, action);
    pipes.add(this);
    // TODO Auto-generated constructor stub
  }

  /* (non-Javadoc)
   * @see org.sakaiproject.content.api.MultiFileUploadPipe#addFile()
   */
  public ResourceToolActionPipe addFile() {
    ResourceToolActionPipe newPipe = registry.newPipe(initializationId, action);
    pipes.add(newPipe);
    return newPipe;
  }

  /* (non-Javadoc)
   * @see org.sakaiproject.content.api.MultiFileUploadPipe#getPipes()
   */
  public List<ResourceToolActionPipe> getPipes() {
    return new ArrayList(pipes);
  }

  /* (non-Javadoc)
   * @see org.sakaiproject.content.api.MultiFileUploadPipe#setFileCount(int)
   */
  public void setFileCount(int count) {
    while (pipes.size() < count) {
      ResourceToolActionPipe newPipe = registry.newPipe(initializationId, action);
      pipes.add(newPipe);
    }

    while (pipes.size() > count) {
      pipes.remove(pipes.size() - 1);
    }
  }
}
  /** inject dependencies */
  public void init(ServletConfig config) throws ServletException {
    super.init(config);
    ComponentManager manager = org.sakaiproject.component.cover.ComponentManager.getInstance();

    if (securityService == null) {
      securityService = (SecurityService) manager.get(SecurityService.class.getName());
    }
    if (serverConfigurationService == null) {
      serverConfigurationService =
          (ServerConfigurationService) manager.get(ServerConfigurationService.class.getName());
    }
    if (sessionManager == null) {
      sessionManager = (SessionManager) manager.get(SessionManager.class.getName());
    }
  }
  private int getTotalChildNo(PrivateMessageDecoratedBean dmb, List beanList) {
    MessageForumsMessageManager messageManager =
        (MessageForumsMessageManager)
            ComponentManager.get(
                "org.sakaiproject.api.app.messageforums.MessageForumsMessageManager");
    List allChild = new ArrayList();
    messageManager.getChildMsgs(dmb.getMsg().getId(), allChild);
    int no = 0;

    for (int i = 0; i < beanList.size(); i++) {
      PrivateMessageDecoratedBean thisBean = (PrivateMessageDecoratedBean) beanList.get(i);
      for (int j = 0; j < allChild.size(); j++) {
        Message child = (Message) allChild.get(j);
        if (thisBean.getMsg().getId().equals(child.getId())) {
          no++;
          break;
        }
      }
    }
    return no;
  }
Beispiel #20
0
  protected String getValueFromBean(String propName) {
    String beanName = propName.trim().split("@")[1];
    Object bean = ComponentManager.get(beanName.trim());
    if (bean != null) {
      String methodName = propName.trim().split("@")[0];
      Class clazz = bean.getClass();
      String methodNameEnd = Character.toUpperCase(methodName.charAt(0)) + methodName.substring(1);
      Method method = null;

      try {
        method = clazz.getMethod("get" + methodNameEnd, null);
      } catch (NoSuchMethodException e) {

        LOG.info(
            "can't find method called " + " get" + methodNameEnd + " in class " + clazz.getName());
        try {

          method = clazz.getMethod("is" + methodNameEnd, null);
        } catch (NoSuchMethodException e1) {
          LOG.info(
              "can't find method called " + " is" + methodNameEnd + " in class " + clazz.getName());
        }
      }

      if (method != null) {
        try {
          Object returnValue = method.invoke(bean, null);
          return returnValue.toString();
        } catch (Exception e) {
          LOG.error("error calling accessor on bean :" + beanName + " msg: " + e.getMessage(), e);
        }
      }
      LOG.error("couldn't find config value for propName: " + propName);
    } else {
      LOG.error("can't find bean with id: " + beanName);
    }
    return null;
  }
  /**
   * 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);

    final NotificationService notificationService =
        (NotificationService)
            ComponentManager.get(org.sakaiproject.event.api.NotificationService.class);
    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();
  }
  /**
   * Convert the ContentEntity into its virtual shadow via its ContentHostingHandler bean. If no
   * bean is defined for the ContentEntity, no resolution is performed. If the ContentEntity is
   * null, no resolution is performed.
   *
   * @param ce
   * @return a resolved ContentEntity where appropriate, otherwise the orginal
   */
  public ContentEntity getVirtualEntity(ContentEntity ce, String finalId) {
    if (ce == null) {
      return null;
    }
    ResourceProperties p = ce.getProperties();
    String chhbeanname = p.getProperty(CHH_BEAN_NAME);

    if (chhbeanname != null && chhbeanname.length() > 0) {
      try {
        ContentHostingHandler chh = (ContentHostingHandler) ComponentManager.get(chhbeanname);
        return chh.getVirtualContentEntity(ce, finalId);

      } catch (Exception e) {
        // log and return null
        log.warn(
            "Failed to find CHH Bean "
                + chhbeanname
                + " or bean failed to resolve virtual entity ID",
            e);
        return ce;
      }
    }
    return ce;
  }
 public IdManager getIdManager() {
   if (idManager == null) {
     idManager = (IdManager) ComponentManager.getInstance().get("idManager");
   }
   return idManager;
 }
    /**
     * Run the maintenance thread. Every REFRESH seconds, re-register this app server as alive in
     * the cluster. Then check for any cluster entries that are more than EXPIRED seconds old,
     * indicating a failed app server, and remove that record, that server's sessions, generating
     * appropriate session events so the other app servers know what's going on. The "then" checks
     * need not be done each iteration - run them on 1 of n randomly choosen iterations. In a
     * clustered environment, this also distributes the work over the cluster better.
     */
    public void run() {
      // wait till things are rolling
      ComponentManager.waitTillConfigured();

      if (M_log.isDebugEnabled()) M_log.debug("run()");

      while (!m_maintenanceCheckerStop) {
        try {
          final String serverIdInstance = m_serverConfigurationService.getServerIdInstance();

          if (M_log.isDebugEnabled()) M_log.debug("checking...");

          // if we have been closed, reopen!
          String statement = clusterServiceSql.getReadServerSql();
          Object[] fields = new Object[1];
          fields[0] = serverIdInstance;
          List results = m_sqlService.dbRead(statement, fields, null);
          if (results.isEmpty()) {
            M_log.warn(
                "run(): server has been closed in cluster table, reopened: " + serverIdInstance);

            statement = clusterServiceSql.getInsertServerSql();
            fields[0] = serverIdInstance;
            boolean ok = m_sqlService.dbWrite(statement, fields);
            if (!ok) {
              M_log.warn("start(): dbWrite failed");
            }
          }

          // update our alive and well status
          else {
            // register that this app server is alive and well
            statement = clusterServiceSql.getUpdateServerSql();
            fields[0] = serverIdInstance;
            boolean ok = m_sqlService.dbWrite(statement, fields);
            if (!ok) {
              M_log.warn("run(): dbWrite failed: " + statement);
            }
          }

          // pick a random number, 0..99, to see if we want to do the full ghosting / cleanup
          // activities now
          int rand = (int) (Math.random() * 100.0);
          if (rand < m_ghostingPercent) {
            // get all expired open app servers not me
            statement = clusterServiceSql.getListExpiredServers(m_expired);
            // setup the fields to skip reading me!
            fields[0] = serverIdInstance;

            List instances = m_sqlService.dbRead(statement, fields, null);

            // close any severs found to be expired
            for (Iterator iInstances = instances.iterator(); iInstances.hasNext(); ) {
              String serverId = (String) iInstances.next();

              // close the server - delete the record
              statement = clusterServiceSql.getDeleteServerSql();
              fields[0] = serverId;
              boolean ok = m_sqlService.dbWrite(statement, fields);
              if (!ok) {
                M_log.warn("run(): dbWrite failed: " + statement);
              }

              M_log.warn(
                  "run(): ghost-busting server: " + serverId + " from : " + serverIdInstance);
            }

            // Close all sessions left over from deleted servers.
            int nbrClosed = m_usageSessionService.closeSessionsOnInvalidServers(getServers());
            if ((nbrClosed > 0) && M_log.isInfoEnabled())
              M_log.info("Closed " + nbrClosed + " orphaned usage session records");

            // Delete any orphaned locks from closed or missing sessions.
            statement = clusterServiceSql.getOrphanedLockSessionsSql();
            List sessions = m_sqlService.dbRead(statement);
            if (sessions.size() > 0) {
              if (M_log.isInfoEnabled())
                M_log.info(
                    "Found " + sessions.size() + " closed or deleted sessions in lock table");
              statement = clusterServiceSql.getDeleteLocksSql();
              for (Iterator iSessions = sessions.iterator(); iSessions.hasNext(); ) {
                fields[0] = (String) iSessions.next();
                boolean ok = m_sqlService.dbWrite(statement, fields);
                if (!ok) {
                  M_log.warn("run(): dbWrite failed: " + statement);
                }
              }
            }
          }
        } catch (Throwable e) {
          M_log.warn("exception: ", e);
        } finally {
          // clear out any current access bindings
          m_threadLocalManager.clear();
        }

        // cycle every REFRESH seconds
        if (!m_maintenanceCheckerStop) {
          try {
            Thread.sleep(m_refresh * 1000L);
          } catch (Exception ignore) {
          }
        }
      }

      if (M_log.isDebugEnabled()) M_log.debug("done");
    }
  protected void processRoster(
      HttpServletRequest request,
      HttpServletResponse response,
      String lti_message_type,
      Site site,
      String siteId,
      String placement_id,
      Properties pitch,
      String user_id,
      Map<String, Object> theMap)
      throws java.io.IOException {
    // Check for permission in placement
    String allowRoster = pitch.getProperty(LTIService.LTI_ALLOWROSTER);
    if (!"on".equals(allowRoster)) {
      doError(
          request,
          response,
          theMap,
          "outcomes.invalid",
          "lti_message_type=" + lti_message_type,
          null);
      return;
    }

    String roleMapProp = pitch.getProperty("rolemap");
    String releaseName = pitch.getProperty(LTIService.LTI_SENDNAME);
    String releaseEmail = pitch.getProperty(LTIService.LTI_SENDEMAILADDR);
    String assignment = pitch.getProperty("assignment");
    String allowOutcomes =
        ServerConfigurationService.getString(
            SakaiBLTIUtil.BASICLTI_OUTCOMES_ENABLED,
            SakaiBLTIUtil.BASICLTI_OUTCOMES_ENABLED_DEFAULT);
    if (!"true".equals(allowOutcomes)) allowOutcomes = null;

    String maintainRole = site.getMaintainRole();

    SakaiBLTIUtil.pushAdvisor();
    boolean success = false;
    try {
      List<Map<String, Object>> lm = new ArrayList<Map<String, Object>>();
      Set<Member> members = site.getMembers();
      Map<String, String> roleMap = SakaiBLTIUtil.convertRoleMapPropToMap(roleMapProp);
      for (Member member : members) {
        Map<String, Object> mm = new TreeMap<String, Object>();
        Role role = member.getRole();
        String ims_user_id = member.getUserId();
        mm.put("/user_id", ims_user_id);
        String ims_role = "Learner";

        // If there is a role mapping, it has precedence over site.update
        if (roleMap.containsKey(role.getId())) {
          ims_role = roleMap.get(role.getId());
        } else if (ComponentManager.get(AuthzGroupService.class)
            .isAllowed(ims_user_id, SiteService.SECURE_UPDATE_SITE, "/site/" + siteId)) {
          ims_role = "Instructor";
        }

        // Using "/role" is inconsistent with to
        // http://developers.imsglobal.org/ext_membership.html. It
        // should be roles. If we can determine that nobody is using
        // the role tag, we should remove it.

        mm.put("/role", ims_role);
        mm.put("/roles", ims_role);
        User user = null;
        if ("true".equals(allowOutcomes) && assignment != null) {
          user = UserDirectoryService.getUser(ims_user_id);
          String placement_secret = pitch.getProperty(LTIService.LTI_PLACEMENTSECRET);
          String result_sourcedid =
              SakaiBLTIUtil.getSourceDID(user, placement_id, placement_secret);
          if (result_sourcedid != null) mm.put("/lis_result_sourcedid", result_sourcedid);
        }

        if ("on".equals(releaseName) || "on".equals(releaseEmail)) {
          if (user == null) user = UserDirectoryService.getUser(ims_user_id);
          if ("on".equals(releaseName)) {
            mm.put("/person_name_given", user.getFirstName());
            mm.put("/person_name_family", user.getLastName());
            mm.put("/person_name_full", user.getDisplayName());
          }
          if ("on".equals(releaseEmail)) {
            mm.put("/person_contact_email_primary", user.getEmail());
            mm.put("/person_sourcedid", user.getEid());
          }
        }

        Collection groups = site.getGroupsWithMember(ims_user_id);

        if (groups.size() > 0) {
          List<Map<String, Object>> lgm = new ArrayList<Map<String, Object>>();
          for (Iterator i = groups.iterator(); i.hasNext(); ) {
            Group group = (Group) i.next();
            Map<String, Object> groupMap = new HashMap<String, Object>();
            groupMap.put("/id", group.getId());
            groupMap.put("/title", group.getTitle());
            groupMap.put("/set", new HashMap(groupMap));
            lgm.add(groupMap);
          }
          mm.put("/groups/group", lgm);
        }

        lm.add(mm);
      }
      theMap.put("/message_response/members/member", lm);
      success = true;
    } catch (Exception e) {
      doError(request, response, theMap, "memberships.fail", "", e);
    } finally {
      SakaiBLTIUtil.popAdvisor();
    }

    if (!success) return;

    theMap.put("/message_response/statusinfo/codemajor", "Success");
    theMap.put("/message_response/statusinfo/severity", "Status");
    theMap.put("/message_response/statusinfo/codeminor", "fullsuccess");
    String theXml = XMLMap.getXML(theMap, true);
    PrintWriter out = response.getWriter();
    out.println(theXml);
    M_log.debug(theXml);
  }
 @Override
 public void init(ServletConfig config) throws ServletException {
   super.init(config);
   if (ltiService == null)
     ltiService = (LTIService) ComponentManager.get("org.sakaiproject.lti.api.LTIService");
 }
  static void init() {
    // DEFAULT values to allow for testing and in case the resource loader values do not exist
    M_evilTags =
        "applet,base,body,bgsound,button,col,colgroup,comment, dfn,fieldset,form,frame,frameset,head,html,iframe,ilayer,inlineinput,isindex,input,keygen,label,layer,legend,link,listing,map,meta,multicol,nextid,noframes,nolayer,noscript,optgroup,option,plaintext,script,select,sound,spacer,spell,submit,textarea,title,wbr"
            .split(",");
    M_goodTags =
        "a,abbr,acronym,address,b,big,blockquote,br,center,cite,code,dd,del,dir,div,dl,dt,em,font,hr,h1,h2,h3,h4,h5,h6,i,ins,kbd,li,marquee,menu,nobr,noembed,ol,p,pre,q,rt,ruby,rbc,rb,rtc,rp,s,samp,small,span,strike,strong,sub,sup,tt,u,ul,var,xmp,img,embed,object,table,tr,td,th,tbody,caption,thead,tfoot,colgroup,col,param"
            .split(",");
    M_goodAttributes =
        "abbr,accept,accesskey,align,alink,alt,axis,background,bgcolor,border,cellpadding,cellspacing,char,charoff,charset,checked,cite,class,classid,clear,color,cols,colspan,compact,content,coords,datetime,dir,disabled,enctype,face,for,header,height,href,hreflang,hspace,id,ismap,label,lang,longdesc,maxlength,multiple,name,noshade,nowrap,profile,readonly,rel,rev,rows,rowspan,rules,scope,selected,shape,size,span,src,start,style,summary,tabindex,target,text,title,type,usemap,valign,value,vlink,vspace,width,pluginspage,play,loop,menu,codebase,data,pluginspace,wmode,allowscriptaccess,allowfullscreen"
            .split(",");
    M_evilValues = "javascript:,behavior:,vbscript:,mocha:,livescript:,expression".split(",");

    try {
      ResourceLoader properties =
          new ResourceLoader(
              RESOURCE_BUNDLE, ComponentManager.get(RESOURCE_CLASS).getClass().getClassLoader());
      M_evilTags = properties.getString("evilTags").split(",");
      M_goodTags = properties.getString("goodTags").split(",");
      M_goodAttributes = properties.getString("goodAttributes").split(",");
      M_evilValues = properties.getString("evilValues").split(",");
    } catch (Exception e) {
      // this is a failure and cannot really be recovered from
      M_log.error("Error collecting formattedtext.properties (using defaults)", e);
    }

    M_evilTagsPatterns = new Pattern[M_evilTags.length];
    for (int i = 0; i < M_evilTags.length; i++) {
      // matches the start of the particular evil tag "<" followed by whitespace,
      // followed by the tag name, followed by anything, followed by ">", case insensitive,
      // allowed to match over multiple lines.
      M_evilTagsPatterns[i] =
          Pattern.compile(
              ".*<\\s*" + M_evilTags[i] + ".*>.*",
              Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.DOTALL);
    }

    M_goodTagsPatterns = new Pattern[M_goodTags.length];
    M_goodCloseTagsPatterns = new Pattern[M_goodTags.length];
    for (int i = 0; i < M_goodTags.length; i++) {
      // matches the start of the particular good tag "<" followed by whitespace,
      // followed by the tag name, followed by anything, followed by ">", case insensitive,
      // allowed to match over multiple lines.
      M_goodTagsPatterns[i] =
          Pattern.compile(
              ".*<\\s*" + M_goodTags[i] + "(\\s+.*>|>|/>).*",
              Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.DOTALL);
      M_goodCloseTagsPatterns[i] =
          Pattern.compile(
              "<\\s*/\\s*" + M_goodTags[i] + "(\\s.*>|>)",
              Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.DOTALL);
    }

    M_goodAttributePatterns = new Pattern[M_goodAttributes.length];
    for (int i = 0; i < M_goodAttributes.length; i++) {
      M_goodAttributePatterns[i] =
          Pattern.compile(
              "\\s+" + M_goodAttributes[i] + "(\\s*=\\s*(?:\".*?\"|'.*?'|[^'\">\\s]+))",
              Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.DOTALL);
    }

    M_evilValuePatterns = new Pattern[M_evilValues.length];
    String pads = "(\\s)*?(?:/\\*.*\\*/|<!--.*-->|\0|)*?(\\s)*?";
    for (int i = 0; i < M_evilValues.length; i++) {
      StringBuilder complexPattern = new StringBuilder();
      complexPattern.append("\\s*");
      String value = M_evilValues[i];
      for (int j = 0; j < value.length(); j++) {
        complexPattern.append(value.charAt(j));
        complexPattern.append(pads);
      }
      M_evilValuePatterns[i] =
          Pattern.compile(
              complexPattern.toString(),
              Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.DOTALL);
    }
  }
 public TimeoutDialogHandler() {
   setUrlFragment(TimeoutDialogHandler.URL_FRAGMENT);
   serverConfigService =
       (ServerConfigurationService) ComponentManager.get(ServerConfigurationService.class);
 }
/** a simple SakaiIFrame Portlet */
public class SakaiIFrame extends GenericPortlet {

  private static final Log M_log = LogFactory.getLog(SakaiIFrame.class);

  private LTIService m_ltiService =
      (LTIService) ComponentManager.get("org.sakaiproject.lti.api.LTIService");

  // This is old-style internationalization (i.e. not dynamic based
  // on user preference) to do that would make this depend on
  // Sakai Unique APIs. :(
  // private static ResourceBundle rb =  ResourceBundle.getBundle("iframe");
  protected static ResourceLoader rb = new ResourceLoader("iframe");

  protected final FormattedText validator = new FormattedText();

  private final VelocityHelper vHelper = new VelocityHelper();

  VelocityEngine vengine = null;

  private PortletContext pContext;

  // TODO: Perhaps these constancts should come from portlet.xml

  /** The source URL, in state, config and context. */
  protected static final String SOURCE = "source";

  /**
   * The value in state and context for the source URL to actually used, as computed from special
   * and URL.
   */
  protected static final String URL = "url";

  /** The height, in state, config and context. */
  protected static final String HEIGHT = "height";

  /** The custom height from user input * */
  protected static final String CUSTOM_HEIGHT = "customNumberField";

  protected final String POPUP = "popup";
  protected final String MAXIMIZE = "sakai:maximize";

  protected static final String TITLE = "title";

  private static final String FORM_PAGE_TITLE = "title-of-page";

  private static final String FORM_TOOL_TITLE = "title-of-tool";

  private static final int MAX_TITLE_LENGTH = 99;

  private static String ALERT_MESSAGE = "sakai:alert-message";

  public static final String CURRENT_HTTP_REQUEST =
      "org.sakaiproject.util.RequestFilter.http_request";

  // If the property is final, the property wins.  If it is not final,
  // the portlet preferences take precedence.
  public String getTitleString(RenderRequest request) {
    Placement placement = ToolManager.getCurrentPlacement();
    return placement.getTitle();
  }

  public void init(PortletConfig config) throws PortletException {
    super.init(config);

    pContext = config.getPortletContext();
    try {
      vengine = vHelper.makeEngine(pContext);
    } catch (Exception e) {
      throw new PortletException("Cannot initialize Velocity ", e);
    }
    M_log.info("iFrame Portlet vengine=" + vengine + " rb=" + rb);
  }

  private void addAlert(ActionRequest request, String message) {
    PortletSession pSession = request.getPortletSession(true);
    pSession.setAttribute(ALERT_MESSAGE, message);
  }

  private void sendAlert(RenderRequest request, Context context) {
    PortletSession pSession = request.getPortletSession(true);
    String str = (String) pSession.getAttribute(ALERT_MESSAGE);
    pSession.removeAttribute(ALERT_MESSAGE);
    if (str != null && str.length() > 0)
      context.put("alertMessage", validator.escapeHtml(str, false));
  }

  // Render the portlet - this is not supposed to change the state of the portlet
  // Render may be called many times so if it changes the state - that is tacky
  // Render will be called when someone presses "refresh" or when another portlet
  // onthe same page is handed an Action.
  public void doView(RenderRequest request, RenderResponse response)
      throws PortletException, IOException {
    response.setContentType("text/html");

    // System.out.println("==== doView called ====");

    // Grab that underlying request to get a GET parameter
    ServletRequest req = (ServletRequest) ThreadLocalManager.get(CURRENT_HTTP_REQUEST);
    String popupDone = req.getParameter("sakai.popup");

    PrintWriter out = response.getWriter();
    Placement placement = ToolManager.getCurrentPlacement();
    response.setTitle(placement.getTitle());
    String source = placement.getPlacementConfig().getProperty(SOURCE);
    if (source == null) source = "";
    String height = placement.getPlacementConfig().getProperty(HEIGHT);
    if (height == null) height = "1200px";
    boolean maximize = "true".equals(placement.getPlacementConfig().getProperty(MAXIMIZE));

    boolean popup = false; // Comes from content item
    boolean oldPopup = "true".equals(placement.getPlacementConfig().getProperty(POPUP));

    // Retrieve the corresponding content item and tool to check the launch
    Map<String, Object> content = null;
    Map<String, Object> tool = null;
    Long key = getContentIdFromSource(source);
    if (key == null) {
      out.println(rb.getString("get.info.notconfig"));
      M_log.warn("Cannot find content id placement=" + placement.getId() + " source=" + source);
      return;
    }
    try {
      content = m_ltiService.getContent(key);
      // If we are supposed to popup (per the content), do so and optionally
      // copy the calue into the placement to communicate with the portal
      popup = getLongNull(content.get("newpage")) == 1;
      if (oldPopup != popup) {
        placement.getPlacementConfig().setProperty(POPUP, popup ? "true" : "false");
        placement.save();
      }
      String launch = (String) content.get("launch");
      Long tool_id = getLongNull(content.get("tool_id"));
      if (launch == null && tool_id != null) {
        tool = m_ltiService.getTool(tool_id);
        launch = (String) tool.get("launch");
      }

      // Force http:// to pop-up if we are https://
      String serverUrl = ServerConfigurationService.getServerUrl();
      if (request.isSecure() || (serverUrl != null && serverUrl.startsWith("https://"))) {
        if (launch != null && launch.startsWith("http://")) popup = true;
      }
    } catch (Exception e) {
      out.println(rb.getString("get.info.notconfig"));
      e.printStackTrace();
      return;
    }

    if (source != null && source.trim().length() > 0) {

      Context context = new VelocityContext();
      context.put("tlang", rb);
      context.put("validator", validator);
      context.put("source", source);
      context.put("height", height);
      sendAlert(request, context);
      context.put("popupdone", Boolean.valueOf(popupDone != null));
      context.put("popup", Boolean.valueOf(popup));
      context.put("maximize", Boolean.valueOf(maximize));

      vHelper.doTemplate(vengine, "/vm/main.vm", context, out);
    } else {
      out.println(rb.getString("get.info.notconfig"));
    }

    // System.out.println("==== doView complete ====");
  }

  public void doEdit(RenderRequest request, RenderResponse response)
      throws PortletException, IOException {

    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    String title = getTitleString(request);
    if (title != null) response.setTitle(title);

    Context context = new VelocityContext();
    context.put("tlang", rb);
    context.put("validator", validator);
    sendAlert(request, context);

    PortletURL url = response.createActionURL();
    context.put("actionUrl", url.toString());
    context.put("doCancel", "sakai.cancel");
    context.put("doUpdate", "sakai.update");

    // get current site
    Placement placement = ToolManager.getCurrentPlacement();
    String siteId = "";

    // find the right LTIContent object for this page
    String source = placement.getPlacementConfig().getProperty(SOURCE);
    Long key = getContentIdFromSource(source);
    if (key == null) {
      out.println(rb.getString("get.info.notconfig"));
      M_log.warn("Cannot find content id placement=" + placement.getId() + " source=" + source);
      return;
    }

    Map<String, Object> content = m_ltiService.getContent(key);
    if (content == null) {
      out.println(rb.getString("get.info.notconfig"));
      M_log.warn("Cannot find content item placement=" + placement.getId() + " key=" + key);
      return;
    }

    // attach the ltiToolId to each model attribute, so that we could have the tool configuration
    // page for multiple tools
    String foundLtiToolId = content.get(m_ltiService.LTI_TOOL_ID).toString();
    Map<String, Object> tool = m_ltiService.getTool(Long.valueOf(foundLtiToolId));
    if (tool == null) {
      out.println(rb.getString("get.info.notconfig"));
      M_log.warn("Cannot find tool placement=" + placement.getId() + " key=" + foundLtiToolId);
      return;
    }

    String[] contentToolModel = m_ltiService.getContentModel(Long.valueOf(foundLtiToolId));
    String formInput = m_ltiService.formInput(content, contentToolModel);
    context.put("formInput", formInput);

    vHelper.doTemplate(vengine, "/vm/edit.vm", context, out);
  }

  public void doHelp(RenderRequest request, RenderResponse response)
      throws PortletException, IOException {
    // System.out.println("==== doHelp called ====");
    // sendToJSP(request, response, "/help.jsp");
    JSPHelper.sendToJSP(pContext, request, response, "/help.jsp");
    // System.out.println("==== doHelp done ====");
  }

  // Process action is called for action URLs / form posts, etc
  // Process action is called once for each click - doView may be called many times
  // Hence an obsession in process action with putting things in session to
  // Send to the render process.
  public void processAction(ActionRequest request, ActionResponse response)
      throws PortletException, IOException {

    // System.out.println("==== processAction called ====");

    PortletSession pSession = request.getPortletSession(true);

    // Our first challenge is to figure out which action we want to take
    // The view selects the "next action" either as a URL parameter
    // or as a hidden field in the POST data - we check both

    String doCancel = request.getParameter("sakai.cancel");
    String doUpdate = request.getParameter("sakai.update");

    // Our next challenge is to pick which action the previous view
    // has told us to do.  Note that the view may place several actions
    // on the screen and the user may have an option to pick between
    // them.  Make sure we handle the "no action" fall-through.

    pSession.removeAttribute("error.message");

    if (doCancel != null) {
      response.setPortletMode(PortletMode.VIEW);
    } else if (doUpdate != null) {
      processActionEdit(request, response);
    } else {
      // System.out.println("Unknown action");
      response.setPortletMode(PortletMode.VIEW);
    }

    // System.out.println("==== End of ProcessAction  ====");
  }

  public void processActionEdit(ActionRequest request, ActionResponse response)
      throws PortletException, IOException {
    // TODO: Check Role

    // Stay in EDIT mode unless we are successful
    response.setPortletMode(PortletMode.EDIT);

    Placement placement = ToolManager.getCurrentPlacement();
    // get the site toolConfiguration, if this is part of a site.
    ToolConfiguration toolConfig = SiteService.findTool(placement.getId());
    String id = request.getParameter(LTIService.LTI_ID);
    String toolId = request.getParameter(LTIService.LTI_TOOL_ID);
    Properties reqProps = new Properties();
    Enumeration names = request.getParameterNames();
    while (names.hasMoreElements()) {
      String name = (String) names.nextElement();
      reqProps.setProperty(name, request.getParameter(name));
    }
    Object retval = m_ltiService.updateContent(Long.parseLong(id), reqProps);
    placement.save();

    response.setPortletMode(PortletMode.VIEW);
  }

  /** Valid digits for custom height from user input * */
  protected static final String VALID_DIGITS = "0123456789";

  /* Parse the source URL to extract the content identifier */
  private Long getContentIdFromSource(String source) {
    int pos = source.indexOf("/content:");
    if (pos < 1) return null;
    pos = pos + "/content:".length();
    if (pos < source.length()) {
      String sContentId = source.substring(pos);
      try {
        Long key = new Long(sContentId);
        return key;
      } catch (Exception e) {
        return null;
      }
    }
    return null;
  }

  /**
   * Check if the string from user input contains any characters other than digits
   *
   * @param height String from user input
   * @return True if all are digits. Or False if any is not digit.
   */
  private boolean checkDigits(String height) {
    for (int i = 0; i < height.length(); i++) {
      if (VALID_DIGITS.indexOf(height.charAt(i)) == -1) return false;
    }
    return true;
  }

  private Long getLongNull(Object key) {
    if (key == null) return null;

    if (key instanceof Number) return new Long(((Number) key).longValue());

    if (key instanceof String) {
      try {
        return new Long((String) key);
      } catch (Exception e) {
        return null;
      }
    }
    return null;
  }
}
public class ReportXMLReader extends AbstractObjectReader {
  /** Resource bundle */
  private ResourceLoader msgs = new ResourceLoader("Messages");

  /** Date formatters. */
  private SimpleDateFormat dateMonthFrmt = new SimpleDateFormat("yyyy-MM");

  private SimpleDateFormat dateYearFrmt = new SimpleDateFormat("yyyy");

  /** Sakai services */
  private TimeService M_ts = (TimeService) ComponentManager.get(TimeService.class.getName());

  private SiteService M_ss = (SiteService) ComponentManager.get(SiteService.class.getName());
  private UserDirectoryService M_uds =
      (UserDirectoryService) ComponentManager.get(UserDirectoryService.class.getName());
  private StatsManager M_sm = (StatsManager) ComponentManager.get(StatsManager.class.getName());
  private EventRegistryService M_ers =
      (EventRegistryService) ComponentManager.get(EventRegistryService.class.getName());
  private ReportManager M_rm = (ReportManager) ComponentManager.get(ReportManager.class.getName());
  private ChartService M_cs = (ChartService) ComponentManager.get(ChartService.class.getName());

  @Override
  public void parse(InputSource input) throws IOException, SAXException {
    if (input instanceof ReportInputSource) {
      parse(((ReportInputSource) input).getReport());
    } else {
      throw new SAXException("Unsupported InputSource specified. " + "Must be a ReportInputSource");
    }
  }

  public void parse(Report report) throws SAXException {
    if (report == null) {
      throw new NullPointerException("Parameter report must not be null");
    }
    if (handler == null) {
      throw new IllegalStateException("ContentHandler not set");
    }

    // Start the document
    handler.startDocument();

    // Generate SAX events for the Report
    generateReport(report);

    // End the document
    handler.endDocument();
  }

  protected void generateReport(Report report) throws SAXException {
    if (report == null) {
      throw new NullPointerException("Parameter report must not be null");
    }
    if (handler == null) {
      throw new IllegalStateException("ContentHandler not set");
    }

    handler.startElement("report");

    String reportTitle = M_rm.getReportFormattedParams().getReportTitle(report);
    if (reportTitle != null && reportTitle.trim().length() != 0) {
      reportTitle =
          msgs.getString("reportres_title_detailed").replaceAll("\\$\\{title\\}", reportTitle);
    } else {
      reportTitle = msgs.getString("reportres_title");
    }
    handler.element("title", reportTitle);

    // description
    String reportDescription = M_rm.getReportFormattedParams().getReportDescription(report);
    if (reportDescription != null) {
      generateReportSummaryHeaderRow(
          msgs.getString("reportres_summ_description"), reportDescription);
    }
    // site
    String reportSite = M_rm.getReportFormattedParams().getReportSite(report);
    if (reportSite != null) {
      generateReportSummaryHeaderRow(msgs.getString("reportres_summ_site"), reportSite);
    }
    // activity based on
    generateReportSummaryHeaderRow(
        msgs.getString("reportres_summ_act_basedon"),
        M_rm.getReportFormattedParams().getReportActivityBasedOn(report));
    String reportResourceAction = M_rm.getReportFormattedParams().getReportResourceAction(report);
    // resources action
    if (reportResourceAction != null)
      generateReportSummaryHeaderRow(
          M_rm.getReportFormattedParams().getReportResourceActionTitle(report),
          reportResourceAction);
    // activity selection
    String reportActivitySelection =
        M_rm.getReportFormattedParams().getReportActivitySelection(report);
    if (reportActivitySelection != null)
      generateReportSummaryHeaderRow(
          M_rm.getReportFormattedParams().getReportActivitySelectionTitle(report),
          reportActivitySelection);
    // time period
    generateReportSummaryHeaderRow(
        msgs.getString("reportres_summ_timeperiod"),
        M_rm.getReportFormattedParams().getReportTimePeriod(report));
    // user selection type
    generateReportSummaryHeaderRow(
        msgs.getString("reportres_summ_usr_selectiontype"),
        M_rm.getReportFormattedParams().getReportUserSelectionType(report));
    // user selection
    String reportUserSelection = M_rm.getReportFormattedParams().getReportUserSelection(report);
    if (reportUserSelection != null)
      generateReportSummaryHeaderRow(
          M_rm.getReportFormattedParams().getReportUserSelectionTitle(report), reportUserSelection);
    // report timestamp
    generateReportSummaryHeaderRow(
        msgs.getString("reportres_summ_generatedon"),
        M_rm.getReportFormattedParams().getReportGenerationDate(report));

    // set column display info
    setColumnDisplayInfo(report.getReportDefinition().getReportParams());

    // display chart and/or table?
    /*ReportParams params = report.getReportDefinition().getReportParams();
        boolean showChart = ReportManager.HOW_PRESENTATION_BOTH.equals(params.getHowPresentationMode())
    || ReportManager.HOW_PRESENTATION_CHART.equals(params.getHowPresentationMode());
        boolean showTable = ReportManager.HOW_PRESENTATION_BOTH.equals(params.getHowPresentationMode())
    || ReportManager.HOW_PRESENTATION_TABLE.equals(params.getHowPresentationMode());*/
    boolean showChart = false;
    boolean showTable = true;
    handler.element("showChart", String.valueOf(showChart));
    handler.element("showTable", String.valueOf(showTable));

    // report chart
    if (showChart) {
      // TODO Embbed image in fop
      generateReportChart(report);
    }

    // report table
    if (showTable) {
      generateReportDataHeader(report.getReportDefinition().getReportParams());
      generateReportTable(report.getReportData(), report.getReportDefinition().getReportParams());
    }

    handler.endElement("report");
  }

  protected void generateReportSummaryHeaderRow(String label, String value) throws SAXException {
    if (label == null || value == null) {
      throw new NullPointerException("Parameter label and value must not be null");
    }
    if (handler == null) {
      throw new IllegalStateException("ContentHandler not set");
    }

    handler.startElement("summaryheader");
    handler.element("label", label);
    handler.element("value", value);
    handler.endElement("summaryheader");
  }

  private void generateReportDataHeader(ReportParams params) throws SAXException {
    if (params == null) {
      throw new NullPointerException("Parameter 'params' must not be null");
    }
    if (handler == null) {
      throw new IllegalStateException("ContentHandler not set");
    }

    handler.startElement("datarowheader");

    // set column display info
    setColumnDisplayInfo(params);

    handler.element("th_site", msgs.getString("th_site"));
    handler.element("th_id", msgs.getString("th_id"));
    handler.element("th_user", msgs.getString("th_user"));
    handler.element("th_resource", msgs.getString("th_resource"));
    handler.element("th_action", msgs.getString("th_action"));
    handler.element("th_tool", msgs.getString("th_tool"));
    handler.element("th_event", msgs.getString("th_event"));
    handler.element("th_date", msgs.getString("th_date"));
    handler.element("th_lastdate", msgs.getString("th_date"));
    handler.element("th_total", msgs.getString("th_total"));
    handler.element("th_visits", msgs.getString("th_visits"));
    handler.element("th_uniquevisitors", msgs.getString("th_uniquevisitors"));
    handler.element(
        "th_duration", msgs.getString("th_duration") + " (" + msgs.getString("minutes_abbr") + ")");

    handler.endElement("datarowheader");
  }

  private void setColumnDisplayInfo(ReportParams params) throws SAXException {
    if (handler == null) {
      throw new IllegalStateException("ContentHandler not set");
    }
    handler.element("what", params.getWhat());
    handler.element("who", params.getWho());
    handler.element(
        "showSite", String.valueOf(M_rm.isReportColumnAvailable(params, StatsManager.T_SITE)));
    handler.element(
        "showUser", String.valueOf(M_rm.isReportColumnAvailable(params, StatsManager.T_USER)));
    handler.element(
        "showTool", String.valueOf(M_rm.isReportColumnAvailable(params, StatsManager.T_TOOL)));
    handler.element(
        "showEvent", String.valueOf(M_rm.isReportColumnAvailable(params, StatsManager.T_EVENT)));
    handler.element(
        "showResource",
        String.valueOf(M_rm.isReportColumnAvailable(params, StatsManager.T_RESOURCE)));
    handler.element(
        "showResourceAction",
        String.valueOf(M_rm.isReportColumnAvailable(params, StatsManager.T_RESOURCE_ACTION)));
    handler.element(
        "showDate",
        String.valueOf(
            M_rm.isReportColumnAvailable(params, StatsManager.T_DATE)
                || M_rm.isReportColumnAvailable(params, StatsManager.T_DATEMONTH)
                || M_rm.isReportColumnAvailable(params, StatsManager.T_DATEYEAR)));
    handler.element(
        "showLastDate",
        String.valueOf(M_rm.isReportColumnAvailable(params, StatsManager.T_LASTDATE)));
    handler.element(
        "showTotal", String.valueOf(M_rm.isReportColumnAvailable(params, StatsManager.T_TOTAL)));
    handler.element(
        "showTotalVisits",
        String.valueOf(M_rm.isReportColumnAvailable(params, StatsManager.T_VISITS)));
    handler.element(
        "showTotalUnique",
        String.valueOf(M_rm.isReportColumnAvailable(params, StatsManager.T_UNIQUEVISITS)));
    handler.element(
        "showDuration",
        String.valueOf(M_rm.isReportColumnAvailable(params, StatsManager.T_DURATION)));
  }

  private void generateReportChart(Report report) throws SAXException {
    if (report == null) {
      throw new NullPointerException("Parameter 'report'must not be null");
    }
    if (handler == null) {
      throw new IllegalStateException("ContentHandler not set");
    }

    // generate chart
    /*PrefsData prefsData = M_sm.getPreferences(report.getReportDefinition().getReportParams().getSiteId(), false);
    int width = 1024;
    int height = 768;
    BufferedImage img = M_cs.generateChart(
    		report, width, height,
    		prefsData.isChartIn3D(), prefsData.getChartTransparency(),
    		prefsData.isItemLabelsVisible()
    );*/
    // handler.element("chart", "sitestats://" + M_ers.getToolIcon(toolId));
  }

  private void generateReportTable(List<Stat> data, ReportParams params) throws SAXException {
    if (data == null || params == null) {
      throw new NullPointerException("Parameter 'data', 'params' must not be null");
    }
    if (handler == null) {
      throw new IllegalStateException("ContentHandler not set");
    }

    final Map<String, ToolInfo> eventIdToolMap = M_ers.getEventIdToolMap();

    boolean showSite = M_rm.isReportColumnAvailable(params, StatsManager.T_SITE);
    boolean showUser = M_rm.isReportColumnAvailable(params, StatsManager.T_USER);
    boolean showTool = M_rm.isReportColumnAvailable(params, StatsManager.T_TOOL);
    boolean showEvent = M_rm.isReportColumnAvailable(params, StatsManager.T_EVENT);
    boolean showResource = M_rm.isReportColumnAvailable(params, StatsManager.T_RESOURCE);
    boolean showResourceAction =
        M_rm.isReportColumnAvailable(params, StatsManager.T_RESOURCE_ACTION);
    boolean showDate =
        M_rm.isReportColumnAvailable(params, StatsManager.T_DATE)
            || M_rm.isReportColumnAvailable(params, StatsManager.T_DATEMONTH)
            || M_rm.isReportColumnAvailable(params, StatsManager.T_DATEYEAR);
    boolean showLastDate = M_rm.isReportColumnAvailable(params, StatsManager.T_LASTDATE);
    boolean showTotal = M_rm.isReportColumnAvailable(params, StatsManager.T_TOTAL);
    boolean showTotalVisits = M_rm.isReportColumnAvailable(params, StatsManager.T_VISITS);
    boolean showTotalUnique = M_rm.isReportColumnAvailable(params, StatsManager.T_UNIQUEVISITS);
    boolean showDuration = M_rm.isReportColumnAvailable(params, StatsManager.T_DURATION);

    Iterator<Stat> i = data.iterator();
    while (i.hasNext()) {
      Stat cs = i.next();
      handler.startElement("datarow");

      // set column display info
      setColumnDisplayInfo(params);

      if (showSite) {
        String siteId = cs.getSiteId();
        String site = null;
        try {
          site = M_ss.getSite(siteId).getTitle();
        } catch (IdUnusedException e) {
          site = msgs.getString("site_unknown");
        }
        handler.element("site", site);
      }
      if (showUser) {
        String userId = null;
        String userName = null;
        String id = cs.getUserId();
        if (id != null) {
          if (("-").equals(id)) {
            userId = "-";
            userName = msgs.getString("user_anonymous");
          } else if (("?").equals(id)) {
            userId = "-";
            userName = msgs.getString("user_anonymous_access");
          } else {
            try {
              User user = M_uds.getUser(id);
              userId = user.getDisplayId();
              userName = M_sm.getUserNameForDisplay(user);
            } catch (UserNotDefinedException e1) {
              userId = id;
              userName = msgs.getString("user_unknown");
            }
          }
        } else {
          userName = msgs.getString("user_unknown");
        }
        handler.element("userid", userId);
        handler.element("username", userName);
      }
      if (showTool) {
        EventStat es = (EventStat) cs;
        String toolId = es.getToolId();
        handler.element("tool", M_ers.getToolName(toolId == null ? "" : toolId));
        handler.element("showToolIcon", "true");
        handler.element("toolicon", "sitestats://" + M_ers.getToolIcon(toolId));
      }
      if (showEvent) {
        EventStat es = (EventStat) cs;
        String eventRef = es.getEventId();
        handler.element("event", M_ers.getEventName(eventRef == null ? "" : eventRef));
        ToolInfo toolInfo = eventIdToolMap.get(eventRef);
        if (toolInfo != null && !showTool) {
          handler.element("showToolEventIcon", "true");
          String toolId = toolInfo.getToolId();
          handler.element("tooleventicon", "sitestats://" + M_ers.getToolIcon(toolId));
        } else {
          handler.element("showToolEventIcon", "false");
        }
      }
      if (showResource) {
        ResourceStat rs = (ResourceStat) cs;
        String resName = M_sm.getResourceName(rs.getResourceRef());
        handler.element("resource", resName == null ? "" : resName);
        handler.element(
            "resourceimg",
            "library://" + M_sm.getResourceImageLibraryRelativePath(rs.getResourceRef()));
      }
      if (showResourceAction) {
        ResourceStat rs = (ResourceStat) cs;
        String resAction = rs.getResourceAction();
        handler.element("action", resAction == null ? "" : msgs.getString("action_" + resAction));
      }
      if (showDate) {
        java.util.Date date = cs.getDate();
        if (M_rm.isReportColumnAvailable(params, StatsManager.T_DATE)) {
          handler.element(
              "date", date == null ? "" : M_ts.newTime(date.getTime()).toStringLocalDate());
        } else if (M_rm.isReportColumnAvailable(params, StatsManager.T_DATEMONTH)) {
          handler.element("date", date == null ? "" : dateMonthFrmt.format(date));
        } else if (M_rm.isReportColumnAvailable(params, StatsManager.T_DATEYEAR)) {
          handler.element("date", date == null ? "" : dateYearFrmt.format(date));
        }
      }
      if (showLastDate) {
        java.util.Date date = cs.getDate();
        handler.element(
            "lastdate", date == null ? "" : M_ts.newTime(date.getTime()).toStringLocalDate());
      }
      if (showTotal) {
        handler.element("total", String.valueOf(cs.getCount()));
      }
      if (showTotalVisits) {
        SiteVisits ss = (SiteVisits) cs;
        handler.element("totalVisits", String.valueOf(ss.getTotalVisits()));
      }
      if (showTotalUnique) {
        SiteVisits ss = (SiteVisits) cs;
        handler.element("totalUnique", String.valueOf(ss.getTotalUnique()));
      }
      if (showDuration) {
        SitePresence ss = (SitePresence) cs;
        double durationInMin =
            ss.getDuration() == 0
                ? 0
                : Util.round((double) ss.getDuration() / 1000 / 60, 1); // in minutes
        handler.element("duration", String.valueOf(durationInMin));
      }

      handler.endElement("datarow");
    }

    // empty report
    if (data.size() == 0) {
      String messageNoData = msgs.getString("no_data");

      handler.startElement("datarow");
      // set column display info
      setColumnDisplayInfo(params);

      if (showSite) {
        handler.element("site", messageNoData);
        messageNoData = "";
      }
      if (showUser) {
        handler.element("userid", messageNoData);
        messageNoData = "";
        handler.element("username", messageNoData);
      }
      if (showTool) {
        handler.element("tool", messageNoData);
        messageNoData = "";
        handler.element("showToolIcon", "");
        handler.element("toolicon", "");
      }
      if (showEvent) {
        handler.element("event", messageNoData);
        messageNoData = "";
        handler.element("showToolEventIcon", "false");
      }
      if (showResource) {
        handler.element("resource", messageNoData);
        messageNoData = "";
        handler.element("resourceimg", "");
      }
      if (showResourceAction) {
        handler.element("action", messageNoData);
        messageNoData = "";
      }
      if (showDate) {
        handler.element("date", messageNoData);
        messageNoData = "";
      }
      if (showLastDate) {
        handler.element("lastdate", messageNoData);
        messageNoData = "";
      }
      if (showTotal) {
        handler.element("total", messageNoData);
        messageNoData = "";
      }
      if (showTotalVisits) {
        handler.element("totalVisits", messageNoData);
        messageNoData = "";
      }
      if (showTotalUnique) {
        handler.element("totalUnique", messageNoData);
        messageNoData = "";
      }
      if (showDuration) {
        handler.element("duration", messageNoData);
        messageNoData = "";
      }
      handler.endElement("datarow");
    }
  }
}