/** * Copyright (C) 2010 Asterios Raptis * * 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.alpharogroup.wicket.components.examples.basepage; import java.util.ArrayList; import java.util.List; import org.apache.wicket.Component; import org.apache.wicket.behavior.AttributeAppender; import org.apache.wicket.behavior.Behavior; import org.apache.wicket.markup.head.IHeaderResponse; import org.apache.wicket.markup.head.JavaScriptHeaderItem; import org.apache.wicket.markup.head.filter.HeaderResponseContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.link.AbstractLink; import org.apache.wicket.markup.html.link.ExternalLink; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.panel.FeedbackPanel; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.util.ListModel; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.settings.JavaScriptLibrarySettings; import org.apache.wicket.util.string.StringValue; import org.apache.wicket.util.time.Duration; import org.odlabs.wiquery.core.javascript.JsUtils; import de.agilecoders.wicket.core.Bootstrap; import de.agilecoders.wicket.core.markup.html.bootstrap.behavior.BootstrapBaseBehavior; import de.agilecoders.wicket.core.markup.html.bootstrap.block.Code; import de.agilecoders.wicket.core.markup.html.bootstrap.common.NotificationPanel; import de.agilecoders.wicket.core.markup.html.bootstrap.html.HtmlTag; import de.agilecoders.wicket.core.markup.html.bootstrap.html.IeEdgeMetaTag; import de.agilecoders.wicket.core.markup.html.bootstrap.html.OptimizedMobileViewportMetaTag; import de.agilecoders.wicket.core.settings.IBootstrapSettings; import de.alpharogroup.io.annotations.ImportResource; import de.alpharogroup.io.annotations.ImportResources; import de.alpharogroup.resourcebundle.locale.ResourceBundleKey; import de.alpharogroup.wicket.base.GenericBasePage; import de.alpharogroup.wicket.base.util.parameter.PageParametersExtensions; import de.alpharogroup.wicket.base.util.resource.ResourceModelFactory; import de.alpharogroup.wicket.behaviors.BuildableChainableStatement; import de.alpharogroup.wicket.behaviors.FaviconBehavior; import de.alpharogroup.wicket.behaviors.JavascriptAppenderBehavior; import de.alpharogroup.wicket.behaviors.JqueryStatementsBehavior; import de.alpharogroup.wicket.bootstrap3.application.WicketBootstrap3Application; import de.alpharogroup.wicket.components.examples.application.WicketApplication; import de.alpharogroup.wicket.components.examples.application.WicketSession; import de.alpharogroup.wicket.components.examples.imprint.ImprintPage; import de.alpharogroup.wicket.components.examples.termofuse.TermOfUsePage; import de.alpharogroup.wicket.components.footer.FooterMenuPanel; import de.alpharogroup.wicket.components.footer.FooterPanel; import de.alpharogroup.wicket.components.i18n.list.LinkListPanel; import de.alpharogroup.wicket.components.link.DefaultTargets; import de.alpharogroup.wicket.components.link.LinkItem; import de.alpharogroup.wicket.header.contributors.HeaderResponseExtensions; import de.alpharogroup.wicket.js.addon.sessiontimeout.BootstrapSessionTimeoutResourceReference; import de.alpharogroup.wicket.js.addon.sessiontimeout.SessionTimeoutJsGenerator; import de.alpharogroup.wicket.js.addon.sessiontimeout.SessionTimeoutSettings; import lombok.Getter; /** * The Class ApplicationBasePage. * * @param <T> * the generic type of the model */ @ImportResources(resources = { @ImportResource(resourceName = "main.css", resourceType = "css", index = 1), @ImportResource(resourceName = "bootstrap_alert.js", resourceType = "js", index = 2) }) public abstract class ApplicationBasePage<T> extends GenericBasePage<T> { /** The Constant serialVersionUID. */ private static final long serialVersionUID = 1L; /** The Constant COPYRIGHT_URL. */ protected static final String COPYRIGHT_URL = "http://www.alpharogroup.de/"; /** The Constant NAVBAR_PANEL_ID. */ protected static final String NAVBAR_PANEL_ID = "navbar"; /** The Constant CONTAINER_PANEL_ID. */ protected static final String CONTAINER_PANEL_ID = "container"; /** The Constant FOOTER_PANEL_ID. */ protected static final String FOOTER_PANEL_ID = "footer"; /** The Constant FEEDBACK_PANEL_ID. */ protected static final String FEEDBACK_PANEL_ID = "feedback"; /** The feedback. */ @Getter protected FeedbackPanel feedback; /** * Default constructor that instantiates a new {@link ApplicationBasePage}. */ public ApplicationBasePage() { this(new PageParameters()); } /** * Instantiates a new {@link ApplicationBasePage} with the given model. * * @param model * the model */ public ApplicationBasePage(final IModel<T> model) { super(model); } /** * Instantiates a new {@link ApplicationBasePage} with the given {@link PageParameters} object. * * @param parameters * the {@link PageParameters} object */ public ApplicationBasePage(final PageParameters parameters) { super(parameters); } /** * Change theme. * * @param themeParameter * the theme parameter */ protected void changeTheme(final String themeParameter) { if ((themeParameter != null) && !themeParameter.isEmpty()) { final IBootstrapSettings settings = Bootstrap.getSettings(getWicketApplication()); settings.getActiveThemeProvider().setActiveTheme(themeParameter); } } /** * sets the theme for the current user. * * @param pageParameters * current page parameters */ private void configureTheme(final PageParameters pageParameters) { newTheme(pageParameters.get("theme")); } /** * Gets the wicket application. * * @return the wicket application */ public WicketApplication getWicketApplication() { return WicketApplication.get(); } /** * Factory method for creating a new {@link Component} for the main container. This method is * invoked in the constructor from the derived classes and have to be overridden so users can * provide their own version of a new {@link Component} for the main container. * * @param id * the id * @param model * the model * @return the new {@link Component} for the main container */ public abstract Component newContainerPanel(final String id, final IModel<T> model); /** * Factory method for creating a new {@link FeedbackPanel}. This method is invoked in the * constructor from the derived classes and have to be overridden so users can provide their own * version of a new {@link FeedbackPanel}. * * @param id * the id * @param model * the model * @return the new {@link FeedbackPanel} */ protected FeedbackPanel newFeedbackPanel(final String id, final IModel<T> model) { final NotificationPanel notificationPanel = new NotificationPanel(id); notificationPanel.setOutputMarkupId(true); notificationPanel.setOutputMarkupPlaceholderTag(true); notificationPanel.hideAfter(Duration.seconds(5)); return notificationPanel; } /** * Factory method for creating a new list with the link items for the footer area. * * @return the new <code>{@link IModel}</code> with the link items for the footer area. */ protected IModel<List<LinkItem>> newFooterLinkItems() { final List<LinkItem> linkModel = new ArrayList<>(); linkModel .add(LinkItem.builder().url("http://www.alpharogroup.de/") .target(DefaultTargets.BLANK.getTarget()).linkClass(ExternalLink.class) // open in a new tab or window... .resourceModelKey(ResourceBundleKey.builder().key("main.footer.copyright.label") .defaultValue("\u0040 copyright 2012 Design by Alpha Ro Group").build()) .build()); linkModel .add(LinkItem.builder() .pageClass(ImprintPage.class).resourceModelKey(ResourceBundleKey.builder() .key("main.global.menu.masthead.label").defaultValue("Imprint").build()) .build()); linkModel .add(LinkItem.builder().pageClass(TermOfUsePage.class) .resourceModelKey(ResourceBundleKey.builder() .key("main.global.menu.term.of.use.label").defaultValue("AGBs").build()) .build()); final IModel<List<LinkItem>> listModel = new ListModel<>(linkModel); return listModel; } /** * Factory method for creating a new {@link Panel} for the footer area. This method is invoked * in the constructor from the derived classes and have to be overridden so users can provide * their own version of a new {@link Panel} for the footer area. * * @param id * the id * @param model * the model * @return the new {@link Panel} for the footer area */ protected Panel newFooterPanel(final String id, final IModel<T> model) { final FooterPanel<List<LinkItem>> footerPanel = new FooterPanel<List<LinkItem>>(id, newFooterLinkItems()) { private static final long serialVersionUID = 1L; /** * {@inheritDoc} */ @Override protected Component newFooterMenuPanel(final String id, final IModel<List<LinkItem>> model) { final FooterMenuPanel footerMenu = new FooterMenuPanel(id, model) { /** The Constant serialVersionUID. */ private static final long serialVersionUID = 1L; /** * {@inheritDoc} */ @Override protected Component newLinkListPanel(final String id, final IModel<List<LinkItem>> model) { final LinkListPanel listPanel = new LinkListPanel(id, model) { private static final long serialVersionUID = 1L; /** * {@inheritDoc} */ @Override protected String getCurrentPageCssClass() { return "active"; } /** * {@inheritDoc} */ @Override protected Component newListComponent(final String id, final ListItem<LinkItem> item) { final LinkItem model = item.getModelObject(); final Label itemLinkLabel = super.newItemLinkLabel("itemLinkLabel", model); itemLinkLabel.add(new AttributeAppender("class", " a")); final AbstractLink link = super.newAbstractLink(id, model); link.add(new AttributeAppender("class", " btn btn-default")); link.add(itemLinkLabel); return link; } }; listPanel.add(new AttributeAppender("class", " btn")); return listPanel; } }; // Add bootstrap class to ul element... add(new JqueryStatementsBehavior() .add(new BuildableChainableStatement.Builder().label("find") .args(JsUtils.quotes("ul")).build()) .add(new BuildableChainableStatement.Builder().label("addClass") .args(JsUtils.quotes("nav navbar-nav list-inline a")).build())); return footerMenu; } }; return footerPanel; } /** * Factory method that can be overwritten for new meta tag content for keywords. * * @return the new <code>{@link IModel}</code> for the keywords. */ @Override protected IModel<String> newKeywords() { return ResourceModelFactory.newResourceModel("page.meta.keywords", this, "wicket, components, examples"); } /** * Factory method for creating a new {@link Behavior} for the session timeout. This method is * invoked in the constructor from the derived classes and have to be overridden so users can * provide their own version of a new {@link Behavior} for the session timeout. */ protected void newSessionTimeoutBehavior() { final int sessionTimeout = WicketSession.get().getSessionTimeout(); if (0 < sessionTimeout) { add(newSessionTimeoutBehavior("sessionTimeoutNotification", newSessionTimeoutSettings())); } } /** * Factory method for creating a new {@link JavascriptAppenderBehavior}. This method is invoked * in the constructor from the derived classes and have to be overridden so users can provide * their own version of a new {@link JavascriptAppenderBehavior}. * * @param id * the id * @param settings * the settings * @return the new {@link JavascriptAppenderBehavior} */ protected JavascriptAppenderBehavior newSessionTimeoutBehavior(final String id, final SessionTimeoutSettings settings) { final SessionTimeoutJsGenerator generator = new SessionTimeoutJsGenerator(settings); final String jsCode = generator.generateJs(); return JavascriptAppenderBehavior.builder().id(id).javascript(jsCode).build(); } /** * Factory method for creating a new {@link SessionTimeoutSettings} for the session timeout. * This method is invoked in the constructor from the derived classes and have to be overridden * so users can provide their own version of a new {@link SessionTimeoutSettings} for the * session timeout. */ protected SessionTimeoutSettings newSessionTimeoutSettings() { final SessionTimeoutSettings settings; final int sessionTimeout = WicketSession.get().getSessionTimeout(); final int oneThirdOfWarnAfter; if (0 < sessionTimeout) { oneThirdOfWarnAfter = (sessionTimeout * 1000) / 3; } else { oneThirdOfWarnAfter = (300 * 1000) / 3; } final int twoThirdOfWarnAfter = oneThirdOfWarnAfter * 2; settings = SessionTimeoutSettings.builder().build(); settings.getTitle().setValue("Session timeout warning"); settings.getMessage().setValue("Your session will be timeouted..."); settings.getWarnAfter().setValue(oneThirdOfWarnAfter); settings.getRedirAfter().setValue(twoThirdOfWarnAfter); settings.getRedirUrl().setValue("/public/imprint"); settings.getLogoutUrl().setValue("/public/imprint"); return settings; } /** * Factory method for creating a new theme from the given {@link StringValue} that comes from * the page parameters. * * @param theme * the new theme to set. */ protected void newTheme(final StringValue theme) { changeTheme(PageParametersExtensions.getString(theme)); } /** * {@inheritDoc} */ @Override protected void onConfigure() { super.onConfigure(); configureTheme(getPageParameters()); } /** * {@inheritDoc} */ @Override protected void onInitialize() { super.onInitialize(); add(new HtmlTag("html")); add(new OptimizedMobileViewportMetaTag("viewport")); add(new IeEdgeMetaTag("ie-edge")); add(new FaviconBehavior()); add(new BootstrapBaseBehavior()); final HeaderResponseContainer headerResponseContainer = new HeaderResponseContainer( WicketBootstrap3Application.FOOTER_FILTER_NAME, WicketBootstrap3Application.FOOTER_FILTER_NAME); add(headerResponseContainer); add(new Code("code-internal")); } /** * {@inheritDoc} */ @Override public void renderHead(final IHeaderResponse response) { super.renderHead(response); final JavaScriptLibrarySettings javaScriptSettings = getApplication() .getJavaScriptLibrarySettings(); response.render(JavaScriptHeaderItem.forReference(javaScriptSettings.getJQueryReference())); Bootstrap.renderHead(response); HeaderResponseExtensions.renderHeaderResponse(response, ApplicationBasePage.class); response.render( JavaScriptHeaderItem.forReference(BootstrapSessionTimeoutResourceReference.get())); } }