Java tutorial
/* * Copyright 2011-2015 CAST, Inc. * * This file is part of the UDL Curriculum Toolkit: * see <http://udl-toolkit.cast.org>. * * 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.Databinder; import net.databinder.hib.SessionUnit; import net.jeremybrooks.knicker.AccountApi; import net.jeremybrooks.knicker.KnickerException; import org.apache.commons.lang.StringUtils; import org.apache.wicket.Application; import org.apache.wicket.Component; import org.apache.wicket.Page; import org.apache.wicket.RuntimeConfigurationType; import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder; import org.apache.wicket.markup.html.IHeaderResponse; import org.apache.wicket.markup.html.PackageResourceGuard; import org.apache.wicket.markup.html.WebComponent; import org.apache.wicket.markup.html.WebMarkupContainer; 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.request.IRequestHandler; import org.apache.wicket.request.IRequestParameters; import org.apache.wicket.request.Request; import org.apache.wicket.request.Response; import org.apache.wicket.request.cycle.AbstractRequestCycleListener; import org.apache.wicket.request.cycle.RequestCycle; import org.apache.wicket.request.handler.PageProvider; import org.apache.wicket.request.handler.RenderPageRequestHandler; import org.apache.wicket.request.mapper.ICompoundRequestMapper; import org.apache.wicket.request.mapper.StalePageException; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.request.resource.ResourceReference; import org.apache.wicket.util.file.File; import org.apache.wicket.util.string.StringValue; import org.apache.wicket.util.string.Strings; import org.apache.wicket.util.time.Time; import org.cast.cwm.BinaryFileDataMapper; import org.cast.cwm.CwmApplication; import org.cast.cwm.CwmSession; import org.cast.cwm.IInputStreamProvider; import org.cast.cwm.ThemeDirectoryRequestMapper; import org.cast.cwm.UserResponseDataMapper; import org.cast.cwm.components.CwmPopupSettings; import org.cast.cwm.components.Icon; 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.ICwmSessionService; import org.cast.cwm.service.IEventService; import org.cast.cwm.service.IHighlightService; import org.cast.cwm.service.IResponseService; import org.cast.cwm.service.ISiteService; import org.cast.cwm.service.IUserPreferenceService; import org.cast.cwm.service.UserPreferenceServiceProvider; import org.cast.cwm.tag.TagService; import org.cast.cwm.wami.PlayerResponsePanel; import org.cast.cwm.xml.FileXmlDocumentSource; 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.mapper.ContentDirectoryMapper; import org.cast.isi.mapper.CustomThemeDirectoryRequestMapper; 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.DropDownNavBar; import org.cast.isi.panel.FooterPanel; import org.cast.isi.panel.FreeToolbar; import org.cast.isi.panel.GuestHeaderPanel; 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.IWordService; 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.cast.isi.service.WordServiceProvider; 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.AbstractModule; import com.google.inject.Inject; 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 sectionToggleImmediateScoreOn = false; // don't require teacher intervention for submitting sections (exams) @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 boolean guestAccessAllowed = false; @Getter protected String glossaryLinkType = DEFAULT_GLOSSARY_TYPE; @Getter protected boolean useAuthoredResponseType = false; // false for backwards compatibility @Getter protected String responseSortField = "createDate"; @Getter protected String mathJaxLocation = "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=MML_HTMLorMML"; @Getter protected SortOrder responseSortState = SortOrder.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; @Inject protected ISiteService siteService; @Inject protected ICwmSessionService cwmSessionService; @Inject protected IHighlightService highlightService; @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 AbstractModule() { protected void configure() { log.debug("Binding ISI Services"); // Temporary while we lose the singleton. bind(IXmlService.class).toInstance(xmlService); // Temporary while we lose the singleton. bind(IISIResponseService.class).toInstance(ISIResponseService.get()); //TODO: Deal with extended interfaces properly. bind(IResponseService.class).toInstance(ISIResponseService.get()); bind(ISectionService.class).to(SectionService.class).in(Scopes.SINGLETON); bind(IPageClassService.class).to(PageClassService.class).in(Scopes.SINGLETON); bind(IFeatureService.class).to(FeatureService.class).in(Scopes.SINGLETON); bind(ILinkPropertiesService.class).to(LinkPropertiesService.class).in(Scopes.SINGLETON); bind(IEventService.class).to(ISIEventService.class).in(Scopes.SINGLETON); bind(IQuestionService.class).to(QuestionService.class); bind(IHighlightService.class).to(HighlightService.class).in(Scopes.SINGLETON); // These get different implementations based on whether a user is a logged in or not bind(IWordService.class).toProvider(WordServiceProvider.class); bind(IUserPreferenceService.class).toProvider(UserPreferenceServiceProvider.class); log.debug("finished binding ISI Services"); } }); return modules; } @Override protected void authInit() { super.authInit(); // Set our custom authorization strategy, with needed bug fix. // TODO: should be able to remove this after wicket 6 migration. getSecuritySettings().setAuthorizationStrategy(new ISIAnnotationsRoleAuthorizationStrategy(this)); } protected void init() { log.debug("Starting ISI Application Init"); // TODO heikki find out which component requires this, and replace it with something empty in case this is not enabled getDebugSettings().setDevelopmentUtilitiesEnabled(true); // Set xml content Section and Page based on property file - these have to be set before // the super.init is called sectionElement = configuration.getProperty("isi.sectionElement"); pageElement = configuration.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 = configuration.getProperty("isi.defaultTags"); if (StringUtils.isEmpty(requestedTags)) { requestedTags = ""; } if (!Strings.isEmpty(requestedTags)) TagService.get().setDefaultTags(Arrays.asList(requestedTags.split("\\s*,\\s*"))); configureResponseTypes(); configureResponseSort(); // 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); // TODO heikki: SecurePackageResourceGuard subclasses cause errors for some resources. For the moment, use PackageResourceGuard. //getResourceSettings().setPackageResourceGuard(new ISIPackageResourceGuard()); //getResourceSettings().setPackageResourceGuard(new CwmPackageResourceGuard()); getResourceSettings().setPackageResourceGuard(new PackageResourceGuard()); this.getRequestCycleListeners().add(new AbstractRequestCycleListener() { @Override public IRequestHandler onException(RequestCycle cycle, Exception x) { if (x instanceof StalePageException) return null; // use normal exception processing for these PageParameters pageParameters = requestParameters2PageParameters( cycle.getRequest().getQueryParameters()); return new RenderPageRequestHandler( new PageProvider(new ExceptionPage(pageParameters, new RuntimeException(x)))); } }); if (highlightsPanelOn) registerHighlighters(); // Generally helpful log statement. if (!RuntimeConfigurationType.DEVELOPMENT.equals(getConfigurationType())) { log.warn("********************** Wicket is running in Deployment Mode **********************"); } log.debug("Finished ISI Application Init"); } /** * Converts requestParameters to PageParameters. * * @param requestParameters * @return */ private PageParameters requestParameters2PageParameters(IRequestParameters requestParameters) { PageParameters pageParameters = new PageParameters(); for (String name : requestParameters.getParameterNames()) { List<StringValue> values = requestParameters.getParameterValues(name); for (StringValue value : values) { pageParameters.add(name, value.toString()); } } return pageParameters; } 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.addHighlighter('Y', yHighlighterOn, yHighlighterEditable); highlightService.addHighlighter('B', bHighlighterOn, bHighlighterEditable); highlightService.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 link 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(Configuration 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); mathJaxLocation = setStringProperty("isi.mathJax.location", mathJaxLocation); sectionToggleTextLinksOn = setBooleanProperty("isi.sectionToggleTextLinks.isOn", sectionToggleTextLinksOn); sectionToggleImageLinksOn = setBooleanProperty("isi.sectionToggleImageLinks.isOn", sectionToggleImageLinksOn); sectionToggleImmediateScoreOn = setBooleanProperty("isi.sectionToggleImmediateScore.isOn", sectionToggleImmediateScoreOn); 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); guestAccessAllowed = setBooleanProperty("isi.guestAccess.isOn", guestAccessAllowed); navbarSectionIconsTeacher = setStringProperty("isi.navbar.sectionIcons.teacher", navbarSectionIconsTeacher); navbarSectionIconsStudent = setStringProperty("isi.navbar.sectionIcons.student", navbarSectionIconsStudent); String urlValue = configuration.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 = configuration.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 = configuration.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 = configuration.getProperty("isi.rssFeed.url").trim(); log.info("Using this URL for the RSS feed: {}", rssFeedUrl); maxRssFeedItems = Integer.parseInt(configuration.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 = configuration.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 = configuration.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 = configuration.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 = configuration.getProperty("isi.response.sortField"); String state = configuration.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 = SortOrder.ASCENDING; else if (state.equalsIgnoreCase("descending")) responseSortState = SortOrder.DESCENDING; else if (state.equalsIgnoreCase("none")) responseSortState = SortOrder.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 = configuration.getProperty("isi.davUser"); final String davPassword = configuration.getProperty("isi.davPassword"); DavClientManager manager = DavClientManager.get(); manager.setDefaultAuthentication(davUser, davPassword); manager.createClient(davServer, davServer, getContentDir()); } // Load glossary if there is one String glossaryFileName = configuration.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 final XmlDocument glossaryDoc; if (davServer != null) { IInputStreamProvider glossaryResource = new DavResource(davServer, getContentDir() + "/" + glossaryFileName); glossaryDoc = xmlService.loadXmlDocument("glossary", glossaryResource, new DtbookParser(), null); } else { File glossaryFile = new File(getContentDir(), glossaryFileName); glossaryDoc = xmlService.loadXmlDocument("glossary", glossaryFile, 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 = configuration.getProperty("isi.studentContentFiles"); if (StringUtils.isEmpty(fileList)) { fileList = DEFAULT_STUDENT_CONTENT_FILE_NAMES; } else { fileList = fileList.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) { XmlDocument doc; if (davServer != null) { log.debug("attempting to load DavResource file = {}", getContentDir() + "/" + file); log.debug("loading the DavResource on the Server = {}", davServer); IInputStreamProvider resource = new DavResource(davServer, getContentDir() + "/" + file); doc = xmlService.loadXmlDocument(file, resource, new DtbookParser(), documentObservers); } else { log.debug("attempting to load Resource file = {}", getContentDir() + "/" + file); File resource = new File(getContentDir(), file); doc = xmlService.loadXmlDocument(file, resource, new DtbookParser(), documentObservers); } studentContent.add(doc); } // Load email content files if (emailOn) { String emailFileName = EMAIL_FILE_NAME; if (davServer != null) { IInputStreamProvider emailResource = new DavResource(davServer, getContentDir() + "/" + emailFileName); emailContent = xmlService.loadXmlDocument("email", emailResource, new DtbookParser(), null); } else { File emailResource = 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()); //final File studentXslFileFinal = studentXslFile; // 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 FileXmlDocumentSource(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, guestAccessAllowed); } /* see getCustomRenderHead() @Override public AjaxRequestTarget newAjaxRequestTarget (final Page page) { AjaxRequestTarget target = super.newAjaxRequestTarget(page); target.appendJavaScript(SessionExpireWarningDialog.getResetJavascript()); return target; } */ @Override protected void configureMountPaths() { super.configureMountPaths(); // if the customSkinDir has been defined, use the custom mapper File themeDir = new File(ISIApplication.get().getSkinDir()); String customSkinDir = ISIApplication.get().getCustomSkinDir(); ICompoundRequestMapper requestMapper = getRootRequestMapperAsCompound(); if (customSkinDir != null) { File customThemeDir = new File(ISIApplication.get().getCustomSkinDir()); requestMapper.add(new CustomThemeDirectoryRequestMapper(themeDir, customThemeDir, "img", "css", "js")); } else { requestMapper.add(new ThemeDirectoryRequestMapper(themeDir, "img", "css", "js")); } // Mount authored content at expected URLs requestMapper.add(new ContentDirectoryMapper(getContentDir(), getDavServer())); // Mount audio data resources at expected URLs requestMapper.add(new BinaryFileDataMapper(PlayerResponsePanel.BINARY_FILE_DATA_MAPPER_PREFIX)); // Mount response data at expected URLs requestMapper.add(new UserResponseDataMapper(UserResponseDataMapper.USER_RESPONSE_DATA_MAPPER_PREFIX)); mountPage("login", getSignInPageClass()); mountPage("home", getStudentTOCPageClass()); mountPage("thome", getTeacherTOCPageClass()); mountPage("ahome", getAdminHomePageClass()); mountPage("reading", getStudentReadingPageClass()); mountPage("treading", getTeacherReadingPageClass()); mountPage("glossary", getGlossaryPageClass()); mountPage("notebook", getNotebookPageClass()); mountPage("tags", getTagsPageClass()); mountPage("questions", getMyQuestionsPageClass()); mountPage("questionp", getQuestionPopupPageClass()); mountPage("collections", getResponseCollectionsPageClass()); mountPage("whiteboard", getWhiteboardPageClass()); mountPage("compare", getPeriodResponsePageClass()); mountPage("tnotebook", getTeacherNotesPageClass()); mountPage("manage", getManageClassesPageClass()); mountPage("register", getRegisterPageClass()); mountPage("reset", getForgotPasswordPageClass()); mountPage("password", getPasswordPageClass()); mountPage("authoredp", getAuthoredPopupPageClass()); } @Override public Class<? extends WebPage> getHomePage(Role role) { if (role.equals(Role.ADMIN) || role.equals(Role.RESEARCHER)) return getAdminHomePageClass(); return getTocPageClass(role); } @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 (cwmSessionService.getUser() != null) role = cwmSessionService.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) { response.renderOnDomReadyJavaScript(SessionExpireWarningDialog.getResetJavascript()); } /** * 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.getPageParameters().add("loc", loc.getLocation()); } return link; } public String getContextPath() { return getServletContext().getContextPath(); } public String getContextDir() { return getServletContext().getRealPath("/"); } public String getContentDir() { return (configuration.getProperty("isi.contentDir")).trim(); } public String getSkinDir() { return (configuration.getProperty("isi.skinDir")).trim(); } public String getCustomSkinDir() { String csd = configuration.getProperty("isi.customSkinDir"); if (csd != null) { return (configuration.getProperty("isi.customSkinDir")).trim(); } return null; } public String getTransformationDir() { String td = configuration.getProperty("isi.transformationDir"); if (td != null) { return (configuration.getProperty("isi.transformationDir")).trim(); } return getSkinDir(); } public String getGlossaryTransformationFile() { String tf = configuration.getProperty("isi.xslGlossaryFile"); if (tf != null) { return (configuration.getProperty("isi.xslGlossaryFile")).trim(); } return "glossary.xsl"; } public String getStudentTransformationFile() { String tf = configuration.getProperty("isi.xslStudentFile"); if (tf != null) { return (configuration.getProperty("isi.xslStudentFile")).trim(); } return "student.xsl"; } public String getTocTransformationFile() { String tf = configuration.getProperty("isi.xslTocFile"); if (tf != null) { return (configuration.getProperty("isi.xslTocFile")).trim(); } return "toc.xsl"; } public String getEmailTransformationFile() { String tf = configuration.getProperty("isi.xslEmailFile"); if (tf != null) { return (configuration.getProperty("isi.xslEmailFile")).trim(); } return "email.xsl"; } public String getCustomTransformationDir() { // if there isn't any custom directory then use the default directory String ctd = configuration.getProperty("isi.customTransformationDir"); if (ctd != null) { return (configuration.getProperty("isi.customTransformationDir")).trim(); } return getTransformationDir(); } public String getDavServer() { String davServer = configuration.getProperty("isi.davServer"); if (davServer != null) { return (configuration.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<Period> getMDefaultPeriod() { // Set the default Period String periodName = configuration.getString("isi.defaultPeriod"); periodName = periodName.trim(); IModel<Period> mDefaultPeriod = siteService.getPeriodByName(periodName); if (mDefaultPeriod == null || mDefaultPeriod.getObject() == null) { log.error("No default period was found, creating new default"); mDefaultPeriod = siteService.newPeriod(periodName); } return mDefaultPeriod; } /** * 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. if (!session.isGuestUser()) { ISIEvent e = ISIResponseService.get().findLatestMatchingEvent(session.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) { // deal with whitespace or multi-word classes sectionClass = sectionClass == null ? "" : sectionClass.trim(); int space = sectionClass.indexOf(' '); if (space > 0) sectionClass = sectionClass.substring(0, space); 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(); getSession().bind(); 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) { User user = cwmSessionService.getUser(); switch (user.getRole()) { case TEACHER: return new TeacherHeaderPanel(id, parameters); case GUEST: return new GuestHeaderPanel(id, parameters); default: 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); } else if (alternateNavBar.equals("dropdown")) { return new DropDownNavBar(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); } /** * Return a component that asks users to login in to gain access to various features. * @param wicketId * @return */ public WebMarkupContainer getLoginMessageComponent(String wicketId) { return new org.cast.isi.panel.LoginMessageBox(wicketId); } }