/* * Copyright 2012 * Ubiquitous Knowledge Processing (UKP) Lab and FG Language Technology * Technische Universität Darmstadt * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.tudarmstadt.ukp.clarin.webanno.ui.core.page; import java.util.Locale; import java.util.MissingResourceException; import java.util.Properties; import org.apache.commons.lang3.StringUtils; import org.apache.wicket.Application; import org.apache.wicket.AttributeModifier; import org.apache.wicket.RuntimeConfigurationType; import org.apache.wicket.Session; import org.apache.wicket.feedback.FeedbackMessage; import org.apache.wicket.feedback.IFeedbackMessageFilter; import org.apache.wicket.markup.head.CssHeaderItem; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.JavaScriptHeaderItem; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.link.ExternalLink; import org.apache.wicket.markup.html.link.PopupSettings; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.model.ResourceModel; import org.apache.wicket.protocol.http.ClientProperties; import org.apache.wicket.protocol.http.WebSession; import org.apache.wicket.protocol.http.request.WebClientInfo; import org.apache.wicket.request.cycle.RequestCycle; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.request.resource.caching.NoOpResourceCachingStrategy; import org.apache.wicket.spring.injection.annot.SpringBean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import com.googlecode.wicket.jquery.ui.settings.JQueryUILibrarySettings; import com.googlecode.wicket.kendo.ui.settings.KendoUILibrarySettings; import de.tudarmstadt.ukp.clarin.webanno.api.SettingsService; import de.tudarmstadt.ukp.clarin.webanno.fontawesome.FontAwesomeCssReference; import de.tudarmstadt.ukp.clarin.webanno.support.SettingsUtil; import de.tudarmstadt.ukp.clarin.webanno.ui.core.css.CssBrowserSelectorResourceReference; import de.tudarmstadt.ukp.clarin.webanno.ui.core.logout.LogoutPanel; public abstract class ApplicationPageBase extends WebPage { private final static Logger LOG = LoggerFactory.getLogger(ApplicationPageBase.class); private static final long serialVersionUID = -1690130604031181803L; private LogoutPanel logoutPanel; private FeedbackPanel feedbackPanel; private Label versionLabel; private Label embeddedDbWarning; private Label browserWarning; private ExternalLink helpLink; private @SpringBean SettingsService settingsService; protected ApplicationPageBase() { commonInit(); } protected ApplicationPageBase(final PageParameters parameters) { super(parameters); commonInit(); } @SuppressWarnings({ "serial" }) private void commonInit() { Properties settings = SettingsUtil.getSettings(); // Override locale to be used by application String locale = settings.getProperty(SettingsUtil.CFG_LOCALE, "en"); switch (locale) { case "auto": // Do nothing - locale is picked up from browser break; default: // Override the locale in the session getSession().setLocale(Locale.forLanguageTag(locale)); break; } logoutPanel = new LogoutPanel("logoutPanel"); feedbackPanel = new FeedbackPanel("feedbackPanel"); feedbackPanel.setOutputMarkupId(true); feedbackPanel.add(new AttributeModifier("class", "error")); feedbackPanel.setFilter(new IFeedbackMessageFilter() { @Override public boolean accept(FeedbackMessage aMessage) { Authentication auth = SecurityContextHolder.getContext().getAuthentication(); String username = auth != null ? auth.getName() : "SYSTEM"; if (aMessage.isFatal()) { LOG.error("{}: {}", username, aMessage.getMessage()); } else if (aMessage.isError()) { LOG.error("{}: {}", username, aMessage.getMessage()); } else if (aMessage.isWarning()) { LOG.warn("{}: {}", username, aMessage.getMessage()); } else if (aMessage.isInfo()) { LOG.info("{}: {}", username, aMessage.getMessage()); } else if (aMessage.isDebug()) { LOG.debug("{}: {}", username, aMessage.getMessage()); } return true; } }); versionLabel = new Label("version", SettingsUtil.getVersionString()); embeddedDbWarning = new Label("embeddedDbWarning", "USE THIS INSTALLATION FOR TESTING ONLY -- " + "AN EMBEDDED DATABASE IS NOT RECOMMENDED FOR PRODUCTION USE"); embeddedDbWarning.setVisible(false); try { String driver = settingsService.getDatabaseDriverName(); embeddedDbWarning.setVisible(StringUtils.contains(driver.toLowerCase(Locale.US), "hsql")); } catch (Throwable e) { LOG.warn("Unable to determine which database is being used", e); } // Override warning about embedded database. if ("false".equalsIgnoreCase( settings.getProperty(SettingsUtil.CFG_WARNINGS_EMBEDDED_DATABASE))) { embeddedDbWarning.setVisible(false); } // Display a warning when using an unsupported browser RequestCycle requestCycle = RequestCycle.get(); WebClientInfo clientInfo; if (Session.exists()) { WebSession session = WebSession.get(); clientInfo = session.getClientInfo(); } else { clientInfo = new WebClientInfo(requestCycle); } ClientProperties clientProperties = clientInfo.getProperties(); browserWarning = new Label("browserWarning", "THIS BROWSER IS NOT SUPPORTED -- " + "PLEASE USE CHROME OR SAFARI"); browserWarning.setVisible(!clientProperties.isBrowserSafari() && !clientProperties.isBrowserChrome()); // Override warning about browser. if ("false".equalsIgnoreCase( settings.getProperty(SettingsUtil.CFG_WARNINGS_UNSUPPORTED_BROWSER))) { browserWarning.setVisible(false); } boolean helpAvailable; try { Application.get().getResourceSettings().getLocalizer().getString("page.help.link", this); Application.get().getResourceSettings().getLocalizer().getString("page.help", this); helpAvailable = true; } catch (MissingResourceException e) { helpAvailable = false; } add(helpLink = new ExternalLink("helpLink", new ResourceModel("page.help.link", ""), new ResourceModel("page.help", ""))); helpLink.setPopupSettings(new PopupSettings("_blank")); helpLink.setVisible(helpAvailable); add(logoutPanel); add(feedbackPanel); add(versionLabel); add(embeddedDbWarning); add(browserWarning); } @Override protected void onConfigure() { super.onConfigure(); // Do not cache pages in development mode - allows us to make changes to the HMTL without // having to reload the application if (RuntimeConfigurationType.DEVELOPMENT.equals(getApplication().getConfigurationType())) { getApplication().getMarkupSettings().getMarkupFactory().getMarkupCache().clear(); getApplication().getResourceSettings().setCachingStrategy(NoOpResourceCachingStrategy.INSTANCE); } } public FeedbackPanel getFeedbackPanel() { return feedbackPanel; } @Override public void renderHead(IHeaderResponse aResponse) { super.renderHead(aResponse); // We also load the JQuery CSS always just to get a consistent look across the app JQueryUILibrarySettings jqueryCfg = JQueryUILibrarySettings.get(); if (jqueryCfg.getStyleSheetReference() != null) { aResponse.render(CssHeaderItem.forReference(jqueryCfg.getStyleSheetReference())); } // We use Kendo TextFields, but they do not automatically load the Kendo JS/CSS, so // we do it manually here and for all the pages. KendoUILibrarySettings kendoCfg = KendoUILibrarySettings.get(); if (kendoCfg.getCommonStyleSheetReference() != null) { aResponse.render(CssHeaderItem.forReference(kendoCfg.getCommonStyleSheetReference())); } if (kendoCfg.getThemeStyleSheetReference() != null) { aResponse.render(CssHeaderItem.forReference(kendoCfg.getThemeStyleSheetReference())); } if (kendoCfg.getJavaScriptReference() != null) { aResponse.render(JavaScriptHeaderItem.forReference(kendoCfg.getJavaScriptReference())); } aResponse.render(JavaScriptHeaderItem.forReference(CssBrowserSelectorResourceReference.get())); aResponse.render(CssHeaderItem.forReference(FontAwesomeCssReference.get())); // Loading WebAnno CSS here so it can override JQuery/Kendo CSS aResponse.render(CssHeaderItem.forReference(WebAnnoCssReference.get())); aResponse.render(JavaScriptHeaderItem.forReference(WebAnnoJavascriptReference.get())); } }