Package org.cast.isi

Source Code of org.cast.isi.ISIApplication

/*
* Copyright 2011 CAST, Inc.
*
* This file is part of the UDL Curriculum Toolkit:
* see <http://code.google.com/p/udl-curriculum-toolkit>.
*
* The UDL Curriculum Toolkit is free software: you can redistribute and/or
* modify it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* The UDL Curriculum Toolkit is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this software.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.cast.isi;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import lombok.Getter;
import lombok.Setter;
import net.databinder.auth.hib.AuthDataSession;
import net.databinder.hib.DataRequestCycle;
import net.databinder.hib.Databinder;
import net.databinder.hib.SessionUnit;
import net.jeremybrooks.knicker.AccountApi;
import net.jeremybrooks.knicker.KnickerException;

import org.apache.wicket.Application;
import org.apache.wicket.Component;
import org.apache.wicket.Page;
import org.apache.wicket.PageParameters;
import org.apache.wicket.Request;
import org.apache.wicket.RequestCycle;
import org.apache.wicket.Resource;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.Response;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.ISortState;
import org.apache.wicket.markup.html.IHeaderResponse;
import org.apache.wicket.markup.html.WebComponent;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.link.PopupSettings;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.protocol.http.WebRequest;
import org.apache.wicket.protocol.http.WebResponse;
import org.apache.wicket.request.target.coding.QueryStringUrlCodingStrategy;
import org.apache.wicket.util.file.File;
import org.apache.wicket.util.string.Strings;
import org.apache.wicket.util.time.Time;
import org.cast.cwm.CwmApplication;
import org.cast.cwm.CwmSession;
import org.cast.cwm.components.CwmPopupSettings;
import org.cast.cwm.components.Icon;
import org.cast.cwm.components.ImageUrlCodingStrategy;
import org.cast.cwm.data.IResponseType;
import org.cast.cwm.data.Period;
import org.cast.cwm.data.ResponseMetadata;
import org.cast.cwm.data.Role;
import org.cast.cwm.data.User;
import org.cast.cwm.data.component.DialogBorder;
import org.cast.cwm.data.component.SessionExpireWarningDialog;
import org.cast.cwm.dav.DavClientManager;
import org.cast.cwm.dav.DavResource;
import org.cast.cwm.glossary.Glossary;
import org.cast.cwm.glossary.GlossaryService;
import org.cast.cwm.glossary.GlossaryTransformer;
import org.cast.cwm.service.HighlightService;
import org.cast.cwm.service.IEventService;
import org.cast.cwm.service.IResponseService;
import org.cast.cwm.service.IUserPreferenceService;
import org.cast.cwm.service.SiteService;
import org.cast.cwm.service.UserPreferenceService;
import org.cast.cwm.tag.TagService;
import org.cast.cwm.xml.FileResource;
import org.cast.cwm.xml.IDocumentObserver;
import org.cast.cwm.xml.XmlDocument;
import org.cast.cwm.xml.XmlDocumentList;
import org.cast.cwm.xml.XmlSection;
import org.cast.cwm.xml.parser.DtbookParser;
import org.cast.cwm.xml.service.IXmlService;
import org.cast.cwm.xml.service.XmlService;
import org.cast.cwm.xml.transform.EnsureUniqueWicketIds;
import org.cast.cwm.xml.transform.FilterElements;
import org.cast.cwm.xml.transform.TransformChain;
import org.cast.cwm.xml.transform.XslTransformer;
import org.cast.isi.data.ContentElement;
import org.cast.isi.data.ContentLoc;
import org.cast.isi.data.ISIEvent;
import org.cast.isi.data.SectionStatus;
import org.cast.isi.page.AuthoredPopup;
import org.cast.isi.page.ExceptionPage;
import org.cast.isi.page.GlossaryPage;
import org.cast.isi.page.ISIStandardPage;
import org.cast.isi.page.Login;
import org.cast.isi.page.Notebook;
import org.cast.isi.page.PeriodResponsePage;
import org.cast.isi.page.TeacherNotesPopup;
import org.cast.isi.page.Whiteboard;
import org.cast.isi.panel.AbstractNavBar;
import org.cast.isi.panel.AlternateNavBar1;
import org.cast.isi.panel.DefaultHeaderPanel;
import org.cast.isi.panel.DefaultNavBar;
import org.cast.isi.panel.FooterPanel;
import org.cast.isi.panel.FreeToolbar;
import org.cast.isi.panel.HeaderPanel;
import org.cast.isi.panel.PageNavPanel;
import org.cast.isi.panel.TeacherHeaderPanel;
import org.cast.isi.service.FeatureService;
import org.cast.isi.service.IFeatureService;
import org.cast.isi.service.IISIResponseService;
import org.cast.isi.service.ILinkPropertiesService;
import org.cast.isi.service.IPageClassService;
import org.cast.isi.service.IQuestionService;
import org.cast.isi.service.ISIEmailService;
import org.cast.isi.service.ISIEventService;
import org.cast.isi.service.ISIResponseService;
import org.cast.isi.service.ISectionService;
import org.cast.isi.service.LinkPropertiesService;
import org.cast.isi.service.PageClassService;
import org.cast.isi.service.QuestionService;
import org.cast.isi.service.SectionService;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import wicket.contrib.tinymce.settings.TinyMCESettings;
import wicket.contrib.tinymce.settings.TinyMCESettings.Theme;

import com.google.inject.Binder;
import com.google.inject.Module;
import com.google.inject.Scopes;

public abstract class ISIApplication extends CwmApplication {
 
  private static final Logger log = LoggerFactory.getLogger(ISIApplication.class);
 
  // Constants
  public static final String PAGE_NOTES_EVENT_TYPE = "post:pagenotes";
  public static final String NOTEBOOK_NOTES_EVENT_TYPE = "post:notebooknotes";
  protected static final String DEFAULT_STUDENT_CONTENT_FILE_NAMES = "student";
  protected static final String DEFAULT_GLOSSARY_TYPE = "modal";
  protected static final String GLOSSARY_TYPE_INLINE = "inline";
  protected static final String GLOSSARY_TYPE_MODAL = "modal";
  protected static final String GLOSSARY_TYPE_MAIN = "main";
 
  // Popup settings
  protected static final int POPUP_WIDTH = 800;
  protected static final int POPUP_HEIGHT = 600;
  protected static final int POPUP_FLAGS = PopupSettings.RESIZABLE+PopupSettings.SCROLLBARS;
 
  @Getter protected static final PopupSettings glossaryPopupSettings = new CwmPopupSettings ("glossary", POPUP_FLAGS).setWidth(POPUP_WIDTH).setHeight(POPUP_HEIGHT);
  @Getter protected static final PopupSettings whiteboardPopupSettings = new CwmPopupSettings ("whiteboard", POPUP_FLAGS).setWidth(POPUP_WIDTH).setHeight(POPUP_HEIGHT);
  @Getter protected static final PopupSettings notebookPopupSettings = new CwmPopupSettings ("notebook", POPUP_FLAGS).setWidth(POPUP_WIDTH).setHeight(POPUP_HEIGHT);
  @Getter protected static final PopupSettings periodResponsePopupSettings = new CwmPopupSettings ("compare", POPUP_FLAGS).setWidth(POPUP_WIDTH).setHeight(POPUP_HEIGHT);
  @Getter public static final PopupSettings teacherNotesPopupSettings = new CwmPopupSettings ("tnotebook", POPUP_FLAGS).setWidth(POPUP_WIDTH).setHeight(POPUP_HEIGHT);
  @Getter public static final PopupSettings questionPopupSettings = new CwmPopupSettings ("questionp", POPUP_FLAGS).setWidth(POPUP_WIDTH).setHeight(POPUP_HEIGHT);
  @Getter public static final PopupSettings authoredPopupSettings = new CwmPopupSettings ("authoredp", POPUP_FLAGS).setWidth(POPUP_WIDTH).setHeight(POPUP_HEIGHT);
 
  // These settings are generally overridden by applications in the configuration file
  @Getter @Setter protected String sectionElement = "level3"; // XML element that is one section, usually
  @Getter @Setter protected String pageElement    = "level4";    // XML element that is one page, usually
  @Getter protected String alternateNavBar = null;
  @Getter protected String readingAgentName = "the Penguin";
  @Getter protected String responseAgentName = "the Gecko";
  @Getter protected boolean ratePanelIncludesDone = true;
  @Getter protected boolean notebookOn = true;
  @Getter protected boolean whiteboardOn = true;
  @Getter protected boolean glossaryOn = true;
  @Getter protected boolean myQuestionsOn = true;
  @Getter protected boolean responseCollectionsOn = true;
  @Getter protected boolean tagsOn = true;   
  @Getter protected boolean pageNotesOn = true// margin notes
  @Getter protected boolean classMessageOn = true;
  @Getter protected boolean pageNumbersOn = true// ALL page numbers FIXME need one for TOC only-ldm
  @Getter protected boolean toolBarOn = true; // text help, dictionary
  @Getter protected boolean mathMLOn = false;
  @Getter protected boolean sectionToggleTextLinksOn = false;
  @Getter protected boolean sectionToggleImageLinksOn = true;
  @Getter protected boolean tocSectionTogglesOn = true;
  @Getter protected boolean tocSectionCompleteIconsOn = false;
  @Getter protected boolean tocSectionIncompleteIconsOn = false;
  @Getter protected boolean collectionsScoreSummaryOn = false;
  @Getter protected boolean compareScoreSummaryOn = false;

 
  @Getter protected String glossaryLinkType = DEFAULT_GLOSSARY_TYPE;
  @Getter protected boolean useAuthoredResponseType = false; // false for backwards compatibility
  @Getter protected String responseSortField = "createDate";
  @Getter protected int responseSortState = ISortState.DESCENDING;
  @Getter protected ResponseMetadata responseMetadata; // the default type of responses
  @Getter protected ArrayList<IResponseType> defaultResponseTypes = new ArrayList<IResponseType>();
  protected TinyMCESettings tinyMCESettings = null;

  // highlighter settings from the config file
  @Getter protected boolean highlightsPanelOn = true;

  // rss feed info from the config file
  @Getter protected boolean rssFeedOn = false;
  @Getter protected String rssFeedUrl;
  @Getter protected int maxRssFeedItems;
 
  // navbar section icons types from the config file
  @Getter protected String navbarSectionIconsTeacher = "status";
  @Getter protected String navbarSectionIconsStudent = "class";


  // Service Classes and Plugins
  @Getter @Setter protected Glossary glossary;
  @Getter @Setter protected ISITagLinkBuilder tagLinkBuilder = new ISITagLinkBuilder();
  @Getter @Setter protected ISITagLinkBuilder tagPopupLinkBuilder = null;
 
  protected String[] studentContentFiles;
  @Getter protected XmlDocumentList studentContent = new XmlDocumentList();
 
  //email related
  @Getter protected boolean emailOn = false;      // ability to email, includes password reminder
  @Getter protected boolean selfRegisterOn = false;   // users can create their own logins
  @Getter protected String EMAIL_FILE_NAME = "email.xml";
  @Getter protected String EMAIL_TRANSFORMER = "email";

  // Application URL - needed for email links
  @Getter protected String url;
  @Getter protected XmlDocument emailContent;
 
  protected List<IDocumentObserver> documentObservers = new ArrayList<IDocumentObserver>();
  protected static Time lastFileCheck;
  protected List<String> enabledFeatures = new ArrayList<String>();

  protected IXmlService xmlService;

  @Override
  public void loadAppProperties() {
    super.loadAppProperties();
    // get the configuration from the properties file
    configureApplicationProperties();
  }
 
  @Override
  protected void loadServices() {
    log.debug("Loading XML Service");
    super.loadServices();
    xmlService = XmlService.get();
    xmlService.setXmlSectionClass(getXmlSectionClass());
    log.debug("Finished loading XML Service");
    log.debug("Loading Response Service");
    ISIResponseService.useAsServiceInstance();
    ISIResponseService.get().setResponseClass(getResponseClass());
    log.debug("Finished loading Response Service");
  }

  @Override
  protected List<Module> getInjectionModules() {
    List<Module> modules = super.getInjectionModules();
    modules.add(new Module() {
        public void configure(Binder binder) {
        log.debug("Binding ISI Services");
      // Temporary while we lose the singleton.
         binder.bind(IXmlService.class).toInstance(xmlService);
      // Temporary while we lose the singleton.
      binder.bind(IISIResponseService.class).toInstance(ISIResponseService.get());
      //TODO: Deal with extended interfaces properly.
      binder.bind(IResponseService.class).toInstance(ISIResponseService.get());
         binder.bind(ISectionService.class).to(SectionService.class).in(Scopes.SINGLETON);
         binder.bind(IPageClassService.class).to(PageClassService.class).in(Scopes.SINGLETON);
         binder.bind(IFeatureService.class).to(FeatureService.class).in(Scopes.SINGLETON);
         binder.bind(ILinkPropertiesService.class).to(LinkPropertiesService.class).in(Scopes.SINGLETON);
         binder.bind(IEventService.class).to(ISIEventService.class).in(Scopes.SINGLETON);
         binder.bind(IQuestionService.class).to(QuestionService.class);
         binder.bind(IUserPreferenceService.class).to(UserPreferenceService.class).in(Scopes.SINGLETON);
         log.debug("finished binding ISI Services");
        }
        });
        return modules;
  }
 
  protected void init() {
    log.debug("Starting ISI Application Init");

    // Set xml content Section and Page based on property file - these have to be set before
    // the super.init is called
    sectionElement = appProperties.getProperty("isi.sectionElement");
    pageElement = appProperties.getProperty("isi.pageElement");
    super.init();
   
    ISIEmailService.useAsServiceInstance();
    responseMetadata  = new ResponseMetadata();   
   
    getMarkupSettings().setDefaultBeforeDisabledLink( "" );
    getMarkupSettings().setDefaultAfterDisabledLink( "" );
   
    // Strip tags so that jQuery traversal doesn't break
    getMarkupSettings().setStripWicketTags(true);
       
    // Tells ResourceFinder to look in skin directory before looking in context dir.
    if (getCustomSkinDir() != null)
      getResourceSettings().addResourceFolder(getCustomSkinDir());
    getResourceSettings().addResourceFolder(getSkinDir());
   
    // Content elements are taggable
    TagService.get().configureTaggableClass('P', ContentElement.class);
    String requestedTags = appProperties.getProperty("isi.defaultTags", "");
    if (!Strings.isEmpty(requestedTags))
      TagService.get().setDefaultTags(Arrays.asList(requestedTags.split("\\s*,\\s*")));

    configureResponseTypes();
    configureResponseSort();
    if (highlightsPanelOn)
      registerHighlighters();   
   
    // load the xml documents and xsl transformers
    loadXmlFiles();
    loadXslFiles();

    // Tell dialog border to not use it's css
    List<ResourceReference> noStylesheets = Collections.emptyList();
    DialogBorder.setStyleReferences(noStylesheets);

    getResourceSettings().setPackageResourceGuard(new ISIPackageResourceGuard());

    // Generally helpful log statement.
    if (!DEVELOPMENT.equalsIgnoreCase(getConfigurationType())) {
      log.warn("********************** Wicket is running in Deployment Mode **********************");
    }
    log.debug("Finished ISI Application Init");
  }

  protected void registerHighlighters() {
    // These letters are the same as used in the markup.  Don't change one without changing the other
    // or just change the css and leave these alone.
    boolean yHighlighterOn = setBooleanProperty("isi.highlighter.yellow.isOn", true);
    boolean yHighlighterEditable = setBooleanProperty("isi.highlighter.yellow.nameEditable", true);

    boolean bHighlighterOn = setBooleanProperty("isi.highlighter.blue.isOn", true);
    boolean bHighlighterEditable = setBooleanProperty("isi.highlighter.blue.nameEditable", true);

    boolean gHighlighterOn = setBooleanProperty("isi.highlighter.green.isOn", true);
    boolean gHighlighterEditable = setBooleanProperty("isi.highlighter.green.nameEditable", true);

    HighlightService.get().addHighlighter('Y', yHighlighterOn, yHighlighterEditable);
    HighlightService.get().addHighlighter('B', bHighlighterOn, bHighlighterEditable);
    HighlightService.get().addHighlighter('G', gHighlighterOn, gHighlighterEditable);   
  }

 
  /**
   * Method to call with any BookmarkablePageLink that will set appropriate PopupSettings
   * (or it can be extended to do other link configuration if necessary).
   *
   * @param the BookmarkablePageLink
   */ 
  public void setLinkProperties (BookmarkablePageLink<?> link) {
    if (GlossaryPage.class.isAssignableFrom(link.getPageClass())) {
      link.setPopupSettings(glossaryPopupSettings);
    } else if (Notebook.class.isAssignableFrom(link.getPageClass())) {
      link.setPopupSettings(notebookPopupSettings);
    } else if (Whiteboard.class.isAssignableFrom(link.getPageClass())) {
      link.setPopupSettings(whiteboardPopupSettings);
    } else if (TeacherNotesPopup.class.isAssignableFrom(link.getPageClass())) {
      link.setPopupSettings(teacherNotesPopupSettings);
    } else if (PeriodResponsePage.class.isAssignableFrom(link.getPageClass())) {
      link.setPopupSettings(periodResponsePopupSettings);
    } else if (AuthoredPopup.class.isAssignableFrom(link.getPageClass())) {
      link.setPopupSettings(authoredPopupSettings);
    }
  }
 
  @Override
  protected void configureHibernate(@SuppressWarnings("deprecation") org.hibernate.cfg.AnnotationConfiguration ac) {
    super.configureHibernate(ac);
   
    Configuration c = ac;
    TagService.configureTagClasses(c);
    c.addAnnotatedClass(org.cast.isi.data.ISIEvent.class);
    c.addAnnotatedClass(org.cast.isi.data.ISIResponse.class);
    c.addAnnotatedClass(org.cast.isi.data.SectionStatus.class);
    c.addAnnotatedClass(org.cast.isi.data.ClassMessage.class);
    c.addAnnotatedClass(org.cast.isi.data.StudentFlag.class);
    c.addAnnotatedClass(org.cast.isi.data.FeedbackMessage.class);
    c.addAnnotatedClass(org.cast.isi.data.WordCard.class);
    c.addAnnotatedClass(org.cast.isi.data.ISIPrompt.class);
    c.addAnnotatedClass(org.cast.isi.data.ContentElement.class);
    c.addAnnotatedClass(org.cast.isi.data.Question.class);
  }
 
  protected void configureApplicationProperties() {
    log.debug("Configuring ISI Application Properties");
    // Set Application settings based on property file
    notebookOn = setBooleanProperty("isi.notebook.isOn", notebookOn);
    whiteboardOn = setBooleanProperty("isi.whiteboard.isOn", whiteboardOn);
    glossaryOn = setBooleanProperty("isi.glossary.isOn", glossaryOn);
    myQuestionsOn = setBooleanProperty("isi.myQuestion.isOn", myQuestionsOn);
    responseCollectionsOn = setBooleanProperty("isi.responseCollection.isOn", responseCollectionsOn);
    tagsOn = setBooleanProperty("isi.tag.isOn", tagsOn);
    highlightsPanelOn = setBooleanProperty("isi.highlightsPanel.isOn", highlightsPanelOn);
    pageNotesOn = setBooleanProperty("isi.pageNotes.isOn", pageNotesOn);
    pageNumbersOn = setBooleanProperty("isi.pageNumbers.isOn", pageNumbersOn);
    classMessageOn = setBooleanProperty("isi.classMessage.isOn", classMessageOn);
    toolBarOn = setBooleanProperty("isi.toolBar.isOn", toolBarOn);
    mathMLOn = setBooleanProperty("isi.mathML.isOn", mathMLOn);
    sectionToggleTextLinksOn = setBooleanProperty("isi.sectionToggleTextLinks.isOn", sectionToggleTextLinksOn);
    sectionToggleImageLinksOn = setBooleanProperty("isi.sectionToggleImageLinks.isOn", sectionToggleImageLinksOn);
    tocSectionTogglesOn = setBooleanProperty("isi.tocSectionToggles.isOn", tocSectionTogglesOn);
    tocSectionCompleteIconsOn = setBooleanProperty("isi.tocSectionCompleteIcons.isOn", tocSectionCompleteIconsOn);
    tocSectionIncompleteIconsOn = setBooleanProperty("isi.tocSectionIncompleteIcons.isOn", tocSectionIncompleteIconsOn);
    useAuthoredResponseType = setBooleanProperty("isi.useAuthoredResponseType.isOn", useAuthoredResponseType)
    rssFeedOn = setBooleanProperty("isi.rssFeed.isOn", rssFeedOn);
    emailOn = setBooleanProperty("isi.email.isOn", emailOn);
    selfRegisterOn = setBooleanProperty("isi.selfRegister.isOn", selfRegisterOn);
    collectionsScoreSummaryOn = setBooleanProperty("isi.collectionsScoreSummary.isOn", collectionsScoreSummaryOn);
    compareScoreSummaryOn = setBooleanProperty("isi.compareScoreSummary.isOn", compareScoreSummaryOn);
    alternateNavBar = setStringProperty("isi.navBarType", alternateNavBar);
   
    navbarSectionIconsTeacher = setStringProperty("isi.navbar.sectionIcons.teacher", navbarSectionIconsTeacher);
    navbarSectionIconsStudent = setStringProperty("isi.navbar.sectionIcons.student", navbarSectionIconsStudent);

    String urlValue = appProperties.getProperty("app.url");
    if (urlValue != null) {
      url = urlValue.trim();
      log.info("using this URL starter for email links: {}", url);
    }
   

    /* if the glossary is on, decide what type of glossary link is used */
    if (glossaryOn == true) {
      String glossaryTypeProperty =  appProperties.getProperty("isi.glossary.type");
      if (glossaryTypeProperty != null &&
          (glossaryTypeProperty.trim().equals(GLOSSARY_TYPE_INLINE) ||
              glossaryTypeProperty.trim().equals(GLOSSARY_TYPE_MAIN) ||
              glossaryTypeProperty.trim().equals(GLOSSARY_TYPE_MODAL))) {
        glossaryLinkType = glossaryTypeProperty.trim();
      }
      log.info("Type of of glossary link is  = {}", glossaryLinkType);
    }

    // Wordnik API key, used if available for free dictionary
    String wordnikKey = appProperties.getProperty("isi.wordnikApiKey");
    if (wordnikKey != null) {
      System.setProperty("WORDNIK_API_KEY", wordnikKey);
      try {
        if (AccountApi.apiTokenStatus().isValid())
          log.info("Valid Wordnik API key confirmed");
        else
          log.warn("Wordnik API key is not valid");
      } catch (KnickerException e) {
        log.error("Wordnik API failure");
        e.printStackTrace();
      }
    } else {
      log.info("Wordnik will not be used");
    }

    if (rssFeedOn == true) {
      rssFeedUrl =  appProperties.getProperty("isi.rssFeed.url").trim();
      log.info("Using this URL for the RSS feed: {}", rssFeedUrl);
      maxRssFeedItems =  Integer.parseInt(appProperties.getProperty("isi.rssFeed.maxItems").trim());
      log.info("The RSS feed will have at most {} items displayed.", maxRssFeedItems);
    }

    log.debug("Finished configuring ISI Application Properties");
  }

  private String setStringProperty(String property, String defaultPropertyValue) {
    String propertyValue =  appProperties.getProperty(property);
    if (propertyValue != null) {
      log.info("Value of {} is  = {}", property, propertyValue);
      return propertyValue.trim();
    }
    log.info("Value of {} is = {}", property, defaultPropertyValue);
    return defaultPropertyValue;
  }
 
  protected Boolean setBooleanProperty(String property, boolean defaultPropertyValue) {
    String propertyValue =  appProperties.getProperty(property);
    if (propertyValue != null) {
      log.info("Value of {} is  = {}", property, propertyValue);
      return Boolean.valueOf(propertyValue.trim());
    }
    log.info("Value of {} is = {}", property, defaultPropertyValue);
    return defaultPropertyValue;
  }

  /**
   * determine what the default response types are used
   */
  public void configureResponseTypes() {
    log.debug("Configuring ISI Response Types");
    // Set default response types based on comma separated values in the property file
    String responseTypeList = appProperties.getProperty("isi.defaultResponse.type");
    String[] responseTypes = null;
    if (responseTypeList != null) {
      responseTypes = responseTypeList.split("\\s*,\\s*")
    }
    if (responseTypes == null) {
      log.info("No Response Types Set - using the Defaults: text, image, audio, file and table");
      defaultResponseTypes.add(getResponseType("HTML"));
      defaultResponseTypes.add(getResponseType("AUDIO"));
      defaultResponseTypes.add(getResponseType("SVG"));
      defaultResponseTypes.add(getResponseType("UPLOAD"));
      defaultResponseTypes.add(getResponseType("TABLE"));
    } else {
      for (String responseType : responseTypes) {
        log.info("Adding the application Response type {}", responseType);
        if (responseType.toLowerCase().trim().equals("text"))
          defaultResponseTypes.add(getResponseType("HTML"));       
        else if (responseType.toLowerCase().trim().equals("image"))
          defaultResponseTypes.add(getResponseType("SVG"));
        else if (responseType.toLowerCase().trim().equals("audio"))
          defaultResponseTypes.add(getResponseType("AUDIO"));
        else if (responseType.toLowerCase().trim().equals("file"))
          defaultResponseTypes.add(getResponseType("UPLOAD"));
        else if (responseType.toLowerCase().trim().equals("table"))
          defaultResponseTypes.add(getResponseType("TABLE"));
        else log.error("This Response Type {} is NOT valid and will NOT be added", responseType);
      }
    }
    if (defaultResponseTypes.isEmpty())
      log.error("There are no valid response types defined");
   
    for (IResponseType rt : defaultResponseTypes) {
      responseMetadata.addType(rt);
    }
    log.debug("Finished configuring ISI Response Types");
  }

  /**
   * determine any custom response sorting
   */
  public void configureResponseSort() {
    String field = appProperties.getProperty("isi.response.sortField");
    String state = appProperties.getProperty("isi.response.sort");

    if (field != null) {
      responseSortField = field.trim();
      log.info("The Response will be sorted by: {}", responseSortField);
    }
    if (state != null) {
      state = state.trim();
      if (state.equalsIgnoreCase("ascending"))
        responseSortState = ISortState.ASCENDING;
      else if (state.equalsIgnoreCase("descending"))
        responseSortState = ISortState.DESCENDING;
      else if (state.equalsIgnoreCase("none"))
        responseSortState = ISortState.NONE;
      log.info("The Response have a sort order: {}", state);
    }
  }
 
  /**
   * Load XML documents
   */
  protected void loadXmlFiles() {
    log.debug("Loading ISI XML Files");
   
    String davServer  = getDavServer();
    if (davServer != null) {
      final String davUser = appProperties.getProperty("isi.davUser");
      final String davPassword = appProperties.getProperty("isi.davPassword");
     
      DavClientManager manager = DavClientManager.get();
      manager.setDefaultAuthentication (davUser, davPassword);
      manager.createClient (davServer, davServer, getContentDir());
    }
   
    // Load glossary if there is one
    String glossaryFileName = appProperties.getProperty("isi.glossaryFile");
    if (glossaryOn == false) {
      log.debug("Glossary is turned off");
    } else if (Strings.isEmpty(glossaryFileName)) {
      log.debug("No glossary file");
    } else { // when the glossary is on
      Resource glossaryResource;
      if (davServer != null) {
        glossaryResource = new DavResource(davServer, getContentDir() + "/" + glossaryFileName);
      } else {
        glossaryResource = new FileResource(new File(getContentDir(), glossaryFileName));
      }
      final XmlDocument glossaryDoc = xmlService.loadXmlDocument("glossary", glossaryResource, new DtbookParser(), null);
     
      // Set up Glossary
      Databinder.ensureSession(new SessionUnit() {
        public Object run(Session sess) {
          glossary = GlossaryService.get().parseXmlGlossaryDocument(glossaryDoc);
          return null;
        }
      });
    }
       
    // Load student content files
    String fileList = appProperties.getProperty("isi.studentContentFiles", DEFAULT_STUDENT_CONTENT_FILE_NAMES).trim();
    studentContentFiles = fileList.split("\\s*,\\s*");   
    documentObservers.add(new XmlDocumentObserver(getSectionElement(), getPageElement())); // Use set so sub-classed applications can add to it as well
    for (String file : studentContentFiles) {
      Resource resource;
      if (davServer != null) {
        log.debug("attempting to load DavResource file = {}", getContentDir() + "/" + file);
        log.debug("loading the DavResource on the Server = {}", davServer);
        resource = new DavResource(davServer, getContentDir() + "/" + file);
      } else {
        log.debug("attempting to load Resource file = {}", getContentDir() + "/" + file);
        resource = new FileResource(new File(getContentDir(), file));
      }
      XmlDocument doc = xmlService.loadXmlDocument(file, resource, new DtbookParser(), documentObservers);
      studentContent.add(doc);
    }
   
    // Load email content files
    if (emailOn) {
      String emailFileName = EMAIL_FILE_NAME;         
      Resource emailResource;
      if (davServer != null) {
        emailResource = new DavResource(davServer, getContentDir() + "/" + emailFileName);
      } else {
        emailResource = new FileResource(new File(getContentDir(), emailFileName));
      }
      emailContent = xmlService.loadXmlDocument("email", emailResource, new DtbookParser(), null);         
    }
    log.debug("Finished loading ISI XML Files");
  }

  /**
   * Load XSL transformer files
   */
  protected void loadXslFiles() {
    log.debug("Loading ISI XSL Files");
    // load the transformation directories into the list managed by XmlService
    // load the custom directory first, then the base directory (if they are different)
    xmlService.addTransformerDirectory(getCustomTransformationDir());
    if (!getCustomTransformationDir().equals(getTransformationDir()))
      xmlService.addTransformerDirectory(getTransformationDir());

    // Transformers
    xmlService.loadXSLTransformer("glossary", getGlossaryTransformationFile(), true);
    xmlService.loadXSLTransformer("toc", getTocTransformationFile(), true);
   
    // check for the student transformation file in the custom dir first then base dir
    File studentXslFile = new File(getCustomTransformationDir(), getStudentTransformationFile());
    if (!studentXslFile.exists())
      studentXslFile = new File(getTransformationDir(), getStudentTransformationFile());
   
    // For comparing responses, need to filter down to a single response area and invoke custom XSL
    TransformChain compareChain = new TransformChain(
        new FilterElements(),
        new XslTransformer(xmlService.findXslResource("compare-responses.xsl")),
        new EnsureUniqueWicketIds());
    xmlService.registerTransformer("compare-responses", compareChain);

    // For viewing single-select response in whiteboard or notebook, need to filter down to a single response area and invoke custom XSL
    TransformChain viewChain = new TransformChain(
        new FilterElements(),
        new XslTransformer(xmlService.findXslResource("view-response.xsl")),
        new EnsureUniqueWicketIds());
    xmlService.registerTransformer("view-response", viewChain);
   
    // Construct transformation pipeline for student content: glossary -> XSL -> unique wicket:ids
    TransformChain transformchain = new TransformChain(
        new XslTransformer(xmlService.findXslResource("strip-class.xsl")),
        new GlossaryTransformer(glossary),
        new FilterElements(),
        new XslTransformer(new FileResource(studentXslFile)),
        new EnsureUniqueWicketIds());
    xmlService.registerTransformer("student", transformchain)
   
    if (emailOn) {
      // For sending emails to users
      xmlService.loadXSLTransformer("email", getEmailTransformationFile(), true);
    }
    log.debug("Finished loading ISI XSL Files");

  }

 
  public static ISIApplication get() {
    return (ISIApplication) Application.get();
  }

 
  @Override
  public org.apache.wicket.Session newSession(Request request, Response response) {
    return new ISISession(request);
  }
 
  @Override
  public RequestCycle newRequestCycle (final Request request, final Response response) {
    return new DataRequestCycle (this, (WebRequest) request, (WebResponse) response) {
     
      @Override
      public Page onRuntimeException(final Page cause, final RuntimeException e) {
        super.onRuntimeException(cause, e)// Executes some methods
        return new ExceptionPage(cause != null ? cause.getPageParameters() : null, e);
      }
    };
  }
 
  @Override
  public AjaxRequestTarget newAjaxRequestTarget (final Page page) {
    AjaxRequestTarget target = super.newAjaxRequestTarget(page);
    target.appendJavascript(SessionExpireWarningDialog.getResetJavascript());
    return target;
  }

  // TODO: When shifting to the Cwm-Data 0.8-Snapshot, swap to the CwmApplication method
  @Override
  protected void configureMountPaths() {
    super.configureMountPaths();
   
    mount(new ImageUrlCodingStrategy("css"));
    mount(new ImageUrlCodingStrategy("img"));
    mount(new ImageUrlCodingStrategy("js"));

    mount(new QueryStringUrlCodingStrategy("login", getSignInPageClass()));
    mount(new QueryStringUrlCodingStrategy("home", getStudentTOCPageClass()));
    mount(new QueryStringUrlCodingStrategy("thome", getTeacherTOCPageClass()));
    mount(new QueryStringUrlCodingStrategy("ahome", getAdminHomePageClass()));
    mount(new QueryStringUrlCodingStrategy("reading", getStudentReadingPageClass()));
    mount(new QueryStringUrlCodingStrategy("treading", getTeacherReadingPageClass()));
    mount(new QueryStringUrlCodingStrategy("glossary", getGlossaryPageClass()));
    mount(new QueryStringUrlCodingStrategy("notebook", getNotebookPageClass()));
    mount(new QueryStringUrlCodingStrategy("tags", getTagsPageClass()));
    mount(new QueryStringUrlCodingStrategy("questions", getMyQuestionsPageClass()));
    mount(new QueryStringUrlCodingStrategy("questionp", getQuestionPopupPageClass()));
    mount(new QueryStringUrlCodingStrategy("collections", getResponseCollectionsPageClass()));
    mount(new QueryStringUrlCodingStrategy("whiteboard", getWhiteboardPageClass()));
    mount(new QueryStringUrlCodingStrategy("compare", getPeriodResponsePageClass()));
    mount(new QueryStringUrlCodingStrategy("tnotebook", getTeacherNotesPageClass()));
    mount(new QueryStringUrlCodingStrategy("manage", getManageClassesPageClass()));
    mount(new QueryStringUrlCodingStrategy("register", getRegisterPageClass()));
    mount(new QueryStringUrlCodingStrategy("reset", getForgotPasswordPageClass()));
    mount(new QueryStringUrlCodingStrategy("password", getPasswordPageClass()));
    mount(new QueryStringUrlCodingStrategy("authoredp", getAuthoredPopupPageClass()));
  }
 
 
  @Override
  public Class<? extends WebPage> getHomePage(Role role) {
    if (role.equals(Role.ADMIN) || role.equals(Role.RESEARCHER))
      return getAdminHomePageClass();
    if (role.equals(Role.TEACHER) || role.equals(Role.STUDENT))
      return getTocPageClass(role);
    return getSignInPageClass();
  }

  @Override
  public Class<? extends WebPage> getSignInPageClass() {
    return Login.class;
  }

  @Override
  public Class<? extends WebPage> getHomePage() {
    ISISession s = ISISession.get();
    if (s != null && s.getUser() != null)
      return getHomePage(s.getUser().getRole());
    else
      return getSignInPageClass();
  }

  /**
   * Get the Class for the Table of Contents for the given role.  If the role
   * is null, attempts to determine the role from the currently logged in user.  If
   * there is no user, returns null.
   *
   * @return
   */
  public Class<? extends WebPage> getTocPageClass(Role role) {
    if (role == null) {
      if (ISISession.get().getUser() != null)
        role = ISISession.get().getUser().getRole();
      else
        return null;
    }
    if (role.subsumes(Role.TEACHER))
      return getTeacherTOCPageClass();
    return getStudentTOCPageClass();
  }
  public Class<? extends ISIStandardPage> getReadingPageClass() {
    User user = CwmSession.get().getUser();
    if (user!=null && Role.TEACHER.equals(user.getRole()))
      return getTeacherReadingPageClass();
    else
      return getStudentReadingPageClass();
  }

  public Class<? extends WebPage> getStudentTOCPageClass() {
    return org.cast.isi.page.StudentToc.class;
  }
  public Class<? extends WebPage> getTeacherTOCPageClass() {
    return org.cast.isi.page.TeacherToc.class;
  }
  public Class<? extends WebPage> getAdminHomePageClass() {
    return org.cast.isi.page.AdminHome.class;
  }
  public Class<? extends WebPage> getGlossaryPageClass() {
    return org.cast.isi.page.GlossaryPage.class;
  }
  public Class<? extends WebPage> getNotebookPageClass() {
    return org.cast.isi.page.Notebook.class;
  }
  public Class<? extends WebPage> getResponseCollectionsPageClass() {
    return org.cast.isi.page.ResponseCollections.class;
  }
  public Class<? extends WebPage> getWhiteboardPageClass() {
    return org.cast.isi.page.Whiteboard.class;
  }
  public Class<? extends WebPage> getTagsPageClass() {
    return org.cast.isi.page.Tags.class;
  }
  public Class<? extends WebPage> getMyQuestionsPageClass() {
    return org.cast.isi.page.MyQuestions.class;
  }
  public Class<? extends WebPage> getQuestionPopupPageClass() {
    return org.cast.isi.page.QuestionPopup.class;
  }
  public Class<? extends WebPage> getPeriodResponsePageClass() {
    return org.cast.isi.page.PeriodResponsePage.class;
  }
  public Class<? extends WebPage> getTeacherNotesPageClass() {
    return org.cast.isi.page.TeacherNotesPopup.class;
  }
  public Class<? extends ISIStandardPage> getStudentReadingPageClass() {
    return org.cast.isi.page.Reading.class;
  }
  public Class<? extends ISIStandardPage> getTeacherReadingPageClass() {
    return org.cast.isi.page.TeacherReading.class;
  }
  public Class<? extends ISIStandardPage> getManageClassesPageClass() {
    return org.cast.isi.page.ManageClasses.class;
  }
  public Class<? extends WebPage> getRegisterPageClass() {
    return org.cast.isi.page.Register.class;
  }
  public Class<? extends WebPage> getForgotPasswordPageClass() {
    return org.cast.isi.page.ForgotPassword.class;
  }
  public Class<? extends WebPage> getPasswordPageClass() {
    return org.cast.isi.page.Password.class;
  }
  public Class<? extends WebPage> getAuthoredPopupPageClass() {
    return org.cast.isi.page.AuthoredPopup.class;
  }

  public Class<? extends org.cast.cwm.data.Response> getResponseClass() {
    return org.cast.isi.data.ISIResponse.class;
  }
 
  public Class<? extends org.cast.cwm.xml.XmlSection> getXmlSectionClass() {
    return org.cast.isi.ISIXmlSection.class;
  }

  public Component getToolbar (String id, Page page) {
    return (new FreeToolbar("tht")).setVisible(isToolBarOn());
  }

  // TODO change context from type string to enum
  public TinyMCESettings getTinyMCESettings(String context) {
    if (tinyMCESettings == null) {
      tinyMCESettings = new ISITinyMCESettings(Theme.advanced);
    }
    return tinyMCESettings;
  }

  // over ride this class to add custom js, css that is needed by the entire application
  public void getCustomRenderHead(IHeaderResponse response) {
  }


  /**
   * Get a link to this application's Table of Contents, based on the currently
   * logged in user.
   *
   * @param id wicket id of the link
   * @return
   */
  public BookmarkablePageLink<ISIStandardPage> getTocLink(String id) {
    return getTocLink(id, null);
  }
 
  /**
   * Get a link to this application's Table of Contents, based on the currently
   * logged in user.  Setting a valid {@link ContentLoc} will jump to that
   * spot in the TOC.
   *
   * @param id wicket id of the link
   * @param loc location to open in the TOC.
   * @return
   */
  public BookmarkablePageLink<ISIStandardPage> getTocLink(String id, ContentLoc loc) {

    Class<? extends WebPage> clazz = getTocPageClass(null);
    BookmarkablePageLink<ISIStandardPage> link;
    if (clazz != null) {
      link = new BookmarkablePageLink<ISIStandardPage>(id, getTocPageClass(null));
    } else {
      link = new BookmarkablePageLink<ISIStandardPage>(id, ISIApplication.get().getSignInPageClass());
    }
   
    if (loc != null) {
      link.setParameter("loc", loc.getLocation());
    }
   
    return link;
  }
 
  public String getContextPath() {
    return getServletContext().getContextPath();
  }
 
  public String getContextDir() {
    return getServletContext().getRealPath("/");
  }

  public String getContentDir() {
    return (appProperties.getProperty("isi.contentDir")).trim();
  }
   
  public String getSkinDir() {
    return (appProperties.getProperty("isi.skinDir")).trim();
  }

  public String getCustomSkinDir() {
    String csd =  appProperties.getProperty("isi.customSkinDir");
    if (csd != null) {
      return (appProperties.getProperty("isi.customSkinDir")).trim();
    }
    return null
  }
 
  public String getTransformationDir() {
    String td =  appProperties.getProperty("isi.transformationDir");
    if (td != null) {
      return (appProperties.getProperty("isi.transformationDir")).trim();
    }
    return getSkinDir();
  }

  public String getGlossaryTransformationFile() {
    String tf =  appProperties.getProperty("isi.xslGlossaryFile");
    if (tf != null) {
      return (appProperties.getProperty("isi.xslGlossaryFile")).trim();
    }
    return "glossary.xsl";
  }

  public String getStudentTransformationFile() {
    String tf =  appProperties.getProperty("isi.xslStudentFile");
    if (tf != null) {
      return (appProperties.getProperty("isi.xslStudentFile")).trim();
    }
    return "student.xsl";
  }

  public String getTocTransformationFile() {
    String tf =  appProperties.getProperty("isi.xslTocFile");
    if (tf != null) {
      return (appProperties.getProperty("isi.xslTocFile")).trim();
    }
    return "toc.xsl";
  }

  public String getEmailTransformationFile() {
    String tf =  appProperties.getProperty("isi.xslEmailFile");
    if (tf != null) {
      return (appProperties.getProperty("isi.xslEmailFile")).trim();
    }
    return "email.xsl";
  }

  public String getCustomTransformationDir() {
    // if there isn't any custom directory then use the default directory
    String ctd =  appProperties.getProperty("isi.customTransformationDir");
    if (ctd != null) {
      return (appProperties.getProperty("isi.customTransformationDir")).trim();
    }
    return getTransformationDir();
  }
 
  public String getDavServer() {
    String davServer = appProperties.getProperty("isi.davServer");
    if (davServer != null) {
      return (appProperties.getProperty("isi.davServer")).trim();
    }
    return null;
  }
 
  /**
   * Return the ISIXMLSection correspoding to a page number.
   * @param num the 1-based page number
   * @return corresponding ISIXMLSection, or null if page number is out of range.
   */
  public ISIXmlSection getPageNum(int num) {
    return (ISIXmlSection) studentContent.getByLabel(ISIXmlSection.SectionType.PAGE, num);
  }
 
  /**
   * Return the number of pages of content.  Page numbers range from 0 to the given number - 1.
   * @return
   */
  public int getPageCount() {
    return studentContent.getLabelCount(ISIXmlSection.SectionType.PAGE);
  }

 
  /**
   * Configure the default period
   */
  public IModel<? extends Period> getMDefaultPeriod() {
    // Set the default Period
    String periodName =  appProperties.getProperty("isi.defaultPeriod");
    if (periodName != null) {
      periodName = periodName.trim();
      return SiteService.get().getPeriodByName(periodName);   
    } else {
      // error if this period doesn't exist
      log.error("No default period was found");
    }   
    return null;
  }


  /**
   * Return the ContentLoc of the most recent page the user visited.
   * @return the ContentLoc, or null if it can't be determined.
   */
  public ContentLoc getBookmarkLoc() {
    ISISession session = ISISession.get();
    ContentLoc bookmark = session.getBookmark();
    if (bookmark!= null)
      return bookmark;
   
    // Not in session, need to do query.
    ISIEvent e = ISIResponseService.get().findLatestMatchingEvent(ISISession.get().getUser(), "pageview:reading");
    if (e != null && e.getPage() != null) {
      bookmark = new ContentLoc(e.getPage());
      session.setBookmark(bookmark);
      return bookmark;
    }

    // User has never visited a page before.  Set bookmark to first page.
    ISIXmlSection section = getPageNum(1);
    if (section != null)
      bookmark = new ContentLoc(section);
    session.setBookmark(bookmark);
    return bookmark;
  }
 
 
  public String getPageTitleBase() {
    return "ISI";
  }
   
  /**
   * Return an icon to use for a given XmlSection.
   * This will be based on the class attribute of the section, e.g. "reading" or "activity" or "overview".
   * It will have alt and title set as the title of the section.
   */
  public WebComponent iconFor(XmlSection section) {
    Icon icon = makeIcon("icon", section.getClassName());
    icon.setmAltText(Model.of(section.getTitle()));
    return icon;
  }
 
  /**
   * Return basic icon component for a given class of section.
   * This method should be customized to match naming convention of the images,
   * and arrange for a default image if the one suggested by the section class
   * does not exist.
   * @param wicketId to use for the image
   * @param sectionClass the class attribute of the section, which determines which image to use
   * @return an image component
   */
  public Icon makeIcon (String wicketId, String sectionClass) {
    return new Icon(wicketId, iconPathForSectionClassName(sectionClass));
  }
 
  /**
   * What image to use as the icon for a section, based on the section's class attribute.
   * TODO: assumes that the image exists; there should be some way to configure this more flexibly.
   * @param sectionClassName
   * @return
   */
  protected String iconPathForSectionClassName (String sectionClassName) {
    if (!Strings.isEmpty(sectionClassName))
      return "img/icons/activity_" + sectionClassName + ".png";
    else
      return "img/icons/activity_reading.png";
  }
 
  public WebComponent teacherStatusIconFor(ISIXmlSection section, SectionStatus sectionStatus) {
    String imageName = "";
    IModel<String> mAlt;
    IModel<ISIXmlSection> sectionModel = new Model<ISIXmlSection>(section);
   
    // if there is no sectionStatus record then student hasn't finished this section
    if (sectionStatus == null) {
      imageName = "status_incomplete";
      mAlt = formatAltString(
          "isi.sectionStatusIconAlt.incomplete",
          "%s is incomplete",
          sectionModel);
    } else if (sectionStatus.getUnreadStudentMessages() > 0) {
      imageName = "status_message";
      mAlt = formatAltString(
          "isi.sectionStatusIconAlt.newfeedback",
          "%s has new feedback from student",
          sectionModel);
    } else if (!sectionStatus.getCompleted()) {
      imageName = "status_incomplete";
      mAlt = formatAltString(
          "isi.sectionStatusIconAlt.incomplete",
          "%s is incomplete",
          sectionModel);
    } else if (sectionStatus.getReviewed()) {
      imageName = "status_reviewed";
      mAlt = formatAltString(
          "isi.sectionStatusIconAlt.reviewed",
          "%s has been reviewed",
          sectionModel);
    } else {
      imageName = "status_ready";
      mAlt = formatAltString(
          "isi.sectionStatusIconAlt.ready",
          "%s is ready for review",
          sectionModel);
    }
    return new Icon("icon", "img/icons/" + imageName + ".png", mAlt, mAlt);
  }
 
  public WebComponent studentStatusIconFor(ISIXmlSection section, SectionStatus sectionStatus) {
    String imageName = "";
    IModel<String> mAlt;
    IModel<ISIXmlSection> sectionModel = new Model<ISIXmlSection>(section);
   
    if ((sectionStatus == null) || (!sectionStatus.getCompleted())) {
      imageName = "status_incomplete";
      mAlt = formatAltString(
          "isi.sectionStatusIconAlt.incomplete",
          "%s is incomplete",
          sectionModel);
    } else {
      imageName = "status_complete";
      mAlt = formatAltString(
          "isi.sectionStatusIconAlt.complete",
          "%s is completed",
          sectionModel);
    }
    return new Icon("icon", "img/icons/" + imageName + ".png", mAlt, mAlt);
  }
 
  private IModel<String> formatAltString(String propertyKey, String defaultFormat, IModel<ISIXmlSection> sectionModel) {
    return new StringResourceModel(
        propertyKey,
        sectionModel,
        String.format(
            defaultFormat,
            sectionModel.getObject().getTitle())
        );
  }

  /*=========================
   *== Static Link Classes ==
   *=========================
   */

  public static class ContentsLink extends Link<ContentLoc> {
    private static final long serialVersionUID = 1L;

    private ContentLoc bookmark = null;
   
    public ContentsLink (String id) {
      super(id);
    }
   
    public ContentsLink (String id, ContentLoc bookmark) {
      this(id);
      this.bookmark = bookmark;
    }
   
    @Override
    public void onClick() {
      if (bookmark == null)
        bookmark = ISIApplication.get().getBookmarkLoc();
      PageParameters ppar = new PageParameters();
      ppar.add("loc", bookmark.getLocation());
      setResponsePage(ISIApplication.get().getReadingPageClass(), ppar);
    }
  }

  public static class LogoutLink extends Link<Page> {
    private static final long serialVersionUID = 1L;
    public LogoutLink(String name) {
      super(name);
    }
    @Override
    public void onClick() {
      AuthDataSession.get().signOut();
      getRequestCycle().setRedirect(true);
      setResponsePage(ISIApplication.get().getSignInPageClass());
    }
  }
 
  /**
   * This is a link that, when clicked, will throw an exception.  Used for testing.
   *
   * @author jbrookover
   *
   */
  public static class ExceptionLink extends Link<Exception> {

    private static final long serialVersionUID = 1L;

    public ExceptionLink(String id) {
      super(id);
    }

    @Override
    public void onClick() {
      throw new IllegalStateException("Testing Exceptions")
    }
  }
 
  /**
   * Returns the header and footer panel to be used on pages for this application.
   * @return
   */
  public HeaderPanel getHeaderPanel(String id, PageParameters parameters) {
//    the header panel expects the application to add buttons   
    if (Role.TEACHER.equals(CwmSession.get().getUser().getRole()))
      return new TeacherHeaderPanel(id, parameters);
    else
      return new DefaultHeaderPanel(id, parameters);
  }

  public FooterPanel getFooterPanel(String id, PageParameters parameters) {
    return new FooterPanel(id, parameters);
  }

  public AbstractNavBar<? extends XmlSection> getTopNavigation(String id, IModel<XmlSection> sec, boolean teacher) {
    if (alternateNavBar != null) {
      if (alternateNavBar.equals("alternate1")) {
        return new AlternateNavBar1(id, sec, teacher);
      }
    }
    return new DefaultNavBar(id, sec, teacher);
  }

  public AbstractNavBar<? extends XmlSection> getBottomNavigation (String id, IModel<XmlSection> mSection, boolean teacher) {
    return new PageNavPanel("pageNavPanelBottom", mSection);
  }
}
TOP

Related Classes of org.cast.isi.ISIApplication

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.