package fr.openwide.core.basicapp.web.application.common.template; import static fr.openwide.core.basicapp.web.application.property.BasicApplicationWebappPropertyIds.MAINTENANCE_URL; import static fr.openwide.core.jpa.more.property.JpaMorePropertyIds.MAINTENANCE; import static fr.openwide.core.spring.property.SpringPropertyIds.OWSI_CORE_VERSION; import static fr.openwide.core.spring.property.SpringPropertyIds.VERSION; import java.util.List; import org.apache.wicket.AttributeModifier; import org.apache.wicket.Component; import org.apache.wicket.Session; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.behavior.AttributeAppender; 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.TransparentWebMarkupContainer; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.link.AbstractLink; import org.apache.wicket.markup.html.link.BookmarkablePageLink; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.model.Model; import org.apache.wicket.model.ResourceModel; import org.apache.wicket.model.StringResourceModel; import org.apache.wicket.request.flow.RedirectToUrlException; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.spring.injection.annot.SpringBean; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableList; import fr.openwide.core.basicapp.core.security.service.ISecurityManagementService; import fr.openwide.core.basicapp.core.util.binding.Bindings; import fr.openwide.core.basicapp.web.application.BasicApplicationApplication; import fr.openwide.core.basicapp.web.application.BasicApplicationSession; import fr.openwide.core.basicapp.web.application.administration.page.AdministrationUserGroupPortfolioPage; import fr.openwide.core.basicapp.web.application.common.component.EnvironmentPanel; import fr.openwide.core.basicapp.web.application.common.template.styles.StylesLessCssResourceReference; import fr.openwide.core.basicapp.web.application.common.typedescriptor.user.AdministrationUserTypeDescriptor; import fr.openwide.core.basicapp.web.application.common.typedescriptor.user.UserTypeDescriptor; import fr.openwide.core.basicapp.web.application.profile.page.ProfilePage; import fr.openwide.core.basicapp.web.application.referencedata.page.ReferenceDataPage; import fr.openwide.core.jpa.security.service.IAuthenticationService; import fr.openwide.core.spring.property.service.IPropertyService; import fr.openwide.core.wicket.behavior.ClassAttributeAppender; import fr.openwide.core.wicket.markup.html.basic.CoreLabel; import fr.openwide.core.wicket.markup.html.panel.InvisiblePanel; import fr.openwide.core.wicket.more.condition.Condition; import fr.openwide.core.wicket.more.markup.html.basic.EnclosureContainer; import fr.openwide.core.wicket.more.markup.html.feedback.AnimatedGlobalFeedbackPanel; import fr.openwide.core.wicket.more.markup.html.template.AbstractWebPageTemplate; import fr.openwide.core.wicket.more.markup.html.template.component.BodyBreadCrumbPanel; import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstrap.collapse.BootstrapCollapseJavaScriptResourceReference; import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstrap.dropdown.BootstrapDropdownBehavior; import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstrap.tooltip.BootstrapTooltip; import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstrap.tooltip.BootstrapTooltipDocumentBehavior; import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstraphoverdropdown.BootstrapHoverDropdownBehavior; import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.scrolltotop.ScrollToTopBehavior; import fr.openwide.core.wicket.more.markup.html.template.model.BreadCrumbElement; import fr.openwide.core.wicket.more.markup.html.template.model.NavigationMenuItem; import fr.openwide.core.wicket.more.model.ApplicationPropertyModel; import fr.openwide.core.wicket.more.model.BindingModel; import fr.openwide.core.wicket.more.security.page.LoginSuccessPage; import fr.openwide.core.wicket.more.security.page.LogoutPage; public abstract class MainTemplate extends AbstractWebPageTemplate { private static final long serialVersionUID = -1312989780696228848L; private static final Logger LOGGER = LoggerFactory.getLogger(MainTemplate.class); @SpringBean private IPropertyService propertyService; @SpringBean private ISecurityManagementService securityManagementService; @SpringBean private IAuthenticationService authenticationService; public MainTemplate(PageParameters parameters) { super(parameters); if (Boolean.TRUE.equals(propertyService.get(MAINTENANCE)) && !authenticationService.hasAdminRole()) { throw new RedirectToUrlException(propertyService.get(MAINTENANCE_URL)); } if (securityManagementService.isPasswordExpired(BasicApplicationSession.get().getUser())) { throw UserTypeDescriptor.get(BasicApplicationSession.get().getUser()) .securityTypeDescriptor() .passwordExpirationPageLinkDescriptor() .newRestartResponseException(); } add(new TransparentWebMarkupContainer("htmlRootElement") .add(AttributeAppender.append("lang", BasicApplicationSession.get().getLocale().getLanguage()))); add(new AnimatedGlobalFeedbackPanel("animatedGlobalFeedbackPanel")); // Page title addHeadPageTitlePrependedElement(new BreadCrumbElement(new ResourceModel("common.rootPageTitle"))); add(createHeadPageTitle("headPageTitle")); // Bread crumb Component breadCrumb; if (isBreadCrumbDisplayed()) { breadCrumb = createBodyBreadCrumb("breadCrumb"); } else { breadCrumb = new InvisiblePanel("breadCrumb"); } add(breadCrumb); // Environment add(new EnvironmentPanel("environment")); // Main navigation bar add(new ListView<NavigationMenuItem>("mainNav", getMainNav()) { private static final long serialVersionUID = -2257358650754295013L; @Override protected void populateItem(ListItem<NavigationMenuItem> item) { NavigationMenuItem navItem = item.getModelObject(); AbstractLink navLink = navItem.linkHidingIfInvalid("navLink"); navLink.add(new ClassAttributeAppender(navItem.getCssClassesModel())); navLink.add( new Label("label", navItem.getLabelModel()), new EnclosureContainer("icon").condition(Condition.modelNotNull(navItem.getIconClassesModel())) .add(new ClassAttributeAppender(navItem.getIconClassesModel())) ); if (navItem.isActive(MainTemplate.this.getFirstMenuPage())) { item.add(new ClassAttributeAppender("active")); } item.add(navLink); List<NavigationMenuItem> subMenuItems = navItem.getSubMenuItems(); if (!subMenuItems.isEmpty()) { item.add(new ClassAttributeAppender("dropdown")); navLink.add(new ClassAttributeAppender("dropdown-toggle")); navLink.add(new AttributeModifier("data-toggle", "dropdown")); navLink.add(new AttributeModifier("data-hover", "dropdown")); } item.add(new ListView<NavigationMenuItem>("subNav", subMenuItems) { private static final long serialVersionUID = -2257358650754295013L; @Override protected void populateItem(ListItem<NavigationMenuItem> item) { NavigationMenuItem navItem = item.getModelObject(); AbstractLink navLink = navItem.linkHidingIfInvalid("navLink"); navLink.add(new ClassAttributeAppender(navItem.getCssClassesModel())); navLink.add( new Label("label", navItem.getLabelModel()), new EnclosureContainer("icon").condition(Condition.modelNotNull(navItem.getIconClassesModel())) .add(new ClassAttributeAppender(navItem.getIconClassesModel())) ); if (navItem.isActive(MainTemplate.this.getSecondMenuPage())) { item.add(new ClassAttributeAppender("active")); } item.add(navLink); } @Override protected void onDetach() { super.onDetach(); for (NavigationMenuItem item : getModelObject()) { item.detach(); } } }); } @Override protected void onDetach() { super.onDetach(); for (NavigationMenuItem item : getModelObject()) { item.detach(); } } }); // User menu add( new Label( "originalAuthentication", new StringResourceModel("console.authentication.originalAuthentication.help") .setParameters(BasicApplicationSession.get().getOriginalAuthentication() != null ? BasicApplicationSession.get().getOriginalAuthentication().getName() : null) .getObject() ) { private static final long serialVersionUID = -5789260462449121142L; @Override protected void onConfigure() { super.onConfigure(); setVisible(BasicApplicationSession.get().getOriginalAuthentication() != null); } }, ProfilePage.linkDescriptor() .link("profileLink") .add( new CoreLabel("userFullName", BindingModel.of(BasicApplicationSession.get().getUserModel(), Bindings.user().fullName())) .hideIfEmpty() ), new AjaxLink<Void>("reconnexionLink") { private static final long serialVersionUID = 1L; @Override public void onClick(AjaxRequestTarget target) { try { BasicApplicationSession.get().signInAsMe(); BasicApplicationSession.get().success(getString("console.authentication.back.success")); } catch (Exception e) { LOGGER.error("Erreur lors de la reconnexion de l'utilisateur", e); Session.get().error(getString("signIn.error.unknown")); } throw LoginSuccessPage.linkDescriptor().newRestartResponseException(); } @Override protected void onConfigure() { super.onConfigure(); setVisible(BasicApplicationSession.get().getOriginalAuthentication() != null); } }, new BookmarkablePageLink<Void>("logoutLink", LogoutPage.class) ); // Footer add( new Label("version", propertyService.get(VERSION)) .add(new AttributeModifier("title", new StringResourceModel("common.version.full") .setParameters(ApplicationPropertyModel.of(VERSION), ApplicationPropertyModel.of(OWSI_CORE_VERSION)) )) ); // Tooltip add(new BootstrapTooltipDocumentBehavior(getBootstrapTooltip())); // Dropdown add(new BootstrapDropdownBehavior()); add(new BootstrapHoverDropdownBehavior()); // Scroll to top add(new WebMarkupContainer("scrollToTop").add(new ScrollToTopBehavior())); } protected List<NavigationMenuItem> getMainNav() { return ImmutableList.of( BasicApplicationApplication.get().getHomePageLinkDescriptor().navigationMenuItem(new ResourceModel("navigation.home")) .setCssClassesModel(Model.of("home")), ReferenceDataPage.linkDescriptor().navigationMenuItem(new ResourceModel("navigation.referenceData")) .setCssClassesModel(Model.of("referenceData")), AdministrationUserTypeDescriptor.BASIC_USER.portfolio().navigationMenuItem(new ResourceModel("navigation.administration")) .setCssClassesModel(Model.of("administration")) .setSubMenuItems(ImmutableList.of( AdministrationUserTypeDescriptor.BASIC_USER.portfolio().navigationMenuItem(new ResourceModel("navigation.administration.user.basic")), AdministrationUserTypeDescriptor.TECHNICAL_USER.portfolio().navigationMenuItem(new ResourceModel("navigation.administration.user.technical")), AdministrationUserGroupPortfolioPage.linkDescriptor().navigationMenuItem(new ResourceModel("navigation.administration.usergroup")) )) ); } @Override protected Class<? extends WebPage> getSecondMenuPage() { return null; } @Override protected Component createBodyBreadCrumb(String wicketId) { // By default, we remove one element from the breadcrumb as it is usually also used to generate the page title. // The last element is usually the title of the current page and shouldn't be displayed in the breadcrumb. return new BodyBreadCrumbPanel(wicketId, bodyBreadCrumbPrependedElementsModel, breadCrumbElementsModel, 1) .setDividerModel(Model.of("")) .setTrailingSeparator(true); } protected boolean isBreadCrumbDisplayed() { return true; } @Override public void renderHead(IHeaderResponse response) { super.renderHead(response); response.render(CssHeaderItem.forReference(StylesLessCssResourceReference.get())); response.render(JavaScriptHeaderItem.forReference(BootstrapCollapseJavaScriptResourceReference.get())); } @Override public String getVariation() { return BOOTSTRAP3_VARIATION; } protected BootstrapTooltip getBootstrapTooltip() { BootstrapTooltip bootstrapTooltip = new BootstrapTooltip(); bootstrapTooltip.setSelector("[title],[data-original-title]"); bootstrapTooltip.setAnimation(true); bootstrapTooltip.setContainer("body"); return bootstrapTooltip; } }