/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 ro.nextreports.server.web.core; import org.apache.commons.lang.StringUtils; import org.apache.wicket.AttributeModifier; import org.apache.wicket.Component; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxFallbackLink; import org.apache.wicket.behavior.AttributeAppender; import org.apache.wicket.feedback.FeedbackMessage; import org.apache.wicket.markup.html.TransparentWebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.markup.html.panel.Panel; import org.apache.wicket.model.StringResourceModel; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.spring.injection.annot.SpringBean; import org.apache.wicket.util.time.Duration; import org.springframework.security.authentication.encoding.PasswordEncoder; import org.wicketstuff.push.AbstractPushEventHandler; import org.wicketstuff.push.IPushEventContext; import org.wicketstuff.push.IPushEventHandler; import org.wicketstuff.push.IPushNode; import org.wicketstuff.push.IPushService; import org.wicketstuff.push.timer.TimerPushService; import ro.nextreports.engine.util.DateUtil; import ro.nextreports.server.domain.ReportResultEvent; import ro.nextreports.server.report.ReportConstants; import ro.nextreports.server.service.ReportListener; import ro.nextreports.server.service.ReportService; import ro.nextreports.server.service.SecurityService; import ro.nextreports.server.service.StorageService; import ro.nextreports.server.util.AnalysisUtil; import ro.nextreports.server.web.NextServerSession; import ro.nextreports.server.web.common.behavior.FontAwesomeBehavior; import ro.nextreports.server.web.common.jgrowl.JGrowlAjaxBehavior; import ro.nextreports.server.web.common.slidebar.SlidebarBehavior; import ro.nextreports.server.web.common.util.PreferencesHelper; import ro.nextreports.server.web.core.section.Section; import ro.nextreports.server.web.core.section.SectionManager; import ro.nextreports.server.web.language.LanguageManager; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; /** * @author Decebal Suiu */ public class HomePage extends BasePage { private static final long serialVersionUID = 1L; public static final String surveyUrl = "http://www.next-reports.com/survey1"; private Label growlLabel; private JGrowlAjaxBehavior growlBehavior; private Panel sectionPanel; @SpringBean private SectionManager sectionManager; @SpringBean private ReportService reportService; @SpringBean private StorageService storageService; @SpringBean private SecurityService securityService; @SpringBean private PasswordEncoder passwordEncoder; public HomePage(PageParameters parameters) { super(parameters); // clear search context NextServerSession.get().setSearchContext(null); growlLabel = new Label("growl", ""); growlLabel.setOutputMarkupId(true); growlBehavior = new JGrowlAjaxBehavior(); growlLabel.add(growlBehavior); add(growlLabel); // add slidebar addSlidebar(); // add css /* add(new Behavior() { @Override public void renderHead(Component component, IHeaderResponse response) { super.renderHead(component, response); response.render(CssReferenceHeaderItem.forUrl("css/style.css")); response.render(CssReferenceHeaderItem.forUrl("css/table.css")); response.render(CssReferenceHeaderItem.forUrl("css/layout.css")); } }); */ } @Override protected void onInitialize() { super.onInitialize(); // obtain a reference to a Push service implementation final IPushService pushService = TimerPushService.get(); ((TimerPushService)pushService).setDefaultPollingInterval(Duration.seconds(storageService.getSettings().getPollingInterval())); // instantiate push event handler IPushEventHandler<Message> handler = new AbstractPushEventHandler<Message>() { private static final long serialVersionUID = 1L; @Override public void onEvent(AjaxRequestTarget target, Message event, IPushNode<Message> node, IPushEventContext<Message> context) { int messageType = event.isError() ? JGrowlAjaxBehavior.ERROR_STICKY : JGrowlAjaxBehavior.INFO_STICKY; getSession().getFeedbackMessages().add(new FeedbackMessage(null, event.getText(), messageType)); target.add(growlLabel); boolean autoOpen = storageService.getSettings().isAutoOpen(); String reportsUrl = storageService.getSettings().getReportsUrl(); if (autoOpen && StringUtils.contains(event.getText(), reportsUrl)) { growlBehavior.setAfterOpenJavaScript(getJGrowlAfterOpenJavaScript()); } } }; // install push node into this panel final IPushNode<Message> pushNode = pushService.installNode(this, handler); // push report result initPushReportResult(pushService, pushNode); // push survey initPushSurvey(pushService, pushNode); } private void addSlidebar() { add(new SlidebarBehavior()); add(new FontAwesomeBehavior()); // add(new Label("currentUser", NextServerSession.get().getUsername())); // add(new Label("realName", NextServerSession.get().getRealName())); // Link<String> logoutLink = new Link<String>("logout") { // // private static final long serialVersionUID = 1L; // // @Override // public void onClick() { // NextServerSession.get().signOut(); // // if (CasUtil.isCasUsed()) { // setResponsePage(new RedirectPage(CasUtil.getLogoutUrl())); // } else { // setResponsePage(getApplication().getHomePage()); // } // } // // }; // add(logoutLink); // // AjaxLink<String> changePassword = new AjaxLink<String>("changePassword") { // // private static final long serialVersionUID = 1L; // // @Override // public void onClick(AjaxRequestTarget target) { // dialog.setTitle(getString("ChangePassword.change")); // dialog.setInitialWidth(350); // dialog.setUseInitialHeight(false); // dialog.setContent(new ChangePasswordPanel(dialog.getContentId()) { // // private static final long serialVersionUID = 1L; // // @Override // public void onChange(AjaxRequestTarget target) { // ModalWindow.closeCurrent(target); // try { // User loggedUser = securityService.getUserByName(NextServerSession.get().getUsername()); // loggedUser.setPassword(passwordEncoder.encodePassword(confirmPassword, null)); // storageService.modifyEntity(loggedUser); // } catch (Exception e) { // e.printStackTrace(); // add(new AlertBehavior(e.getMessage())); // target.add(this); // } // } // // @Override // public void onCancel(AjaxRequestTarget target) { // ModalWindow.closeCurrent(target); // } // // }); // dialog.show(target); // } // }; // add(changePassword); // // if (NextServerSession.get().isDemo()) { // changePassword.setEnabled(false); // } // // ExternalLink surveyLink = new ExternalLink("survey", HomePage.surveyUrl) { // // protected void onComponentTag(ComponentTag componentTag) { // super.onComponentTag(componentTag); // componentTag.put("target", "_blank"); // } // // }; // add(surveyLink); List<String> sections = new ArrayList<String>(); for (Section section : sectionManager.getSections()) { if (section.isVisible()) { sections.add(section.getId()); } } ListView<String> view = new ListView<String>("section", sections) { @Override protected void populateItem(final ListItem<String> item) { // AbstractLink link = new ExternalLink("link", "http://wwww.google.com"); AjaxFallbackLink link = new AjaxFallbackLink("link") { @Override public void onClick(AjaxRequestTarget target) { onSlidebarClick(target, item.getModelObject()); } }; Section section = sectionManager.getSection(item.getModelObject()); link.add(new TransparentWebMarkupContainer("icon").add(AttributeModifier.append("class", "fa-" + section.getIcon()))); String key = "Section." + section.getTitle() + ".name"; String title = new StringResourceModel(key, null).getString(); // link.add(new Label("label", title).setRenderBodyOnly(true)); link.add(new Label("label", title)); item.setOutputMarkupId(true); item.add(link); item.add(new AttributeAppender("class", "active") { @Override public boolean isEnabled(Component component) { return sectionManager.getSelectedSectionId().equals(item.getModelObject()); } }.setSeparator(" ")); } }; add(view); Section selectedSection = sectionManager.getSelectedSection(); sectionPanel = selectedSection.createView("sectionPanel"); sectionPanel.setOutputMarkupId(true); add(sectionPanel); } private void onSlidebarClick(AjaxRequestTarget target, String sectionId) { String oldSectionId = sectionManager.getSelectedSectionId(); Section section = sectionManager.getSection(sectionId); sectionManager.setSelectedSectionId(sectionId); Panel newPanel = section.createView("sectionPanel"); newPanel.setOutputMarkupId(true); sectionPanel.replaceWith(newPanel); target.add(newPanel); sectionPanel = newPanel; // close slidebar target.appendJavaScript("closeSlidebar();"); // refresh active class ListView<String> view = (ListView<String>) get("section"); Iterator<Component> it= view.iterator(); while (it.hasNext()) { ListItem<String> item = (ListItem<String>) it.next(); String itemId = item.getModelObject(); if (itemId.equals(sectionId) || itemId.equals(oldSectionId)) { target.add(item); } } } private void initPushReportResult(final IPushService pushService, final IPushNode<Message> pushNode) { reportService.addReportListener(new ReportListener() { @Override public void onFinishRun(ReportResultEvent result) { if (pushService.isConnected(pushNode)) { pushService.publish(pushNode, createReportResultMessage(result)); } } }); } private Message createReportResultMessage(ReportResultEvent event) { StringBuilder sb = new StringBuilder(); Locale locale = LanguageManager.getInstance().getLocale(storageService.getSettings().getLanguage()); ResourceBundle bundle = ResourceBundle.getBundle("ro.nextreports.server.web.NextServerApplication", locale); String s = bundle.getString("ActionContributor.Run.finish"); String message = MessageFormat.format(s, event.getReportName()); sb.append(message); sb.append("<br>"); boolean error = false; if ("".equals(event.getReportUrl())) { sb.append(event.getResultMessage()); error = true; } else if (ReportConstants.ETL_FORMAT.equals(event.getReportUrl())) { sb.append(event.getResultMessage()); } else if (AnalysisUtil.FREEZE_ACTION.equals(event.getReportUrl())) { if (event.getResultMessage().startsWith(AnalysisUtil.FREEZE_FAILED)) { error = true; s = bundle.getString("Analysis.freezed.failed"); message = MessageFormat.format(s, event.getReportName()); sb = new StringBuilder(message + " " + event.getResultMessage().substring(AnalysisUtil.FREEZE_FAILED.length())); } else { sb = new StringBuilder(event.getResultMessage()); } } else if (AnalysisUtil.ANY_ACTION.equals(event.getReportUrl())) { if (event.getResultMessage().startsWith(AnalysisUtil.ANY_ACTION_FAILED)) { error = true; message = bundle.getString("Analysis.error"); sb = new StringBuilder(message + " " + event.getResultMessage().substring(AnalysisUtil.ANY_ACTION_FAILED.length())); } } else if (!event.getReportUrl().endsWith("/report")) { // indicator and alarm schedule alerts do not have a resulting report (url ends with /report) sb.append("<a href=\""). append(event.getReportUrl()). append("\" target=\"_blank\">"). append(bundle.getString("ActionContributor.Run.result")). append("</a>"); } else { sb.append(event.getResultMessage()); } return new Message(sb.toString(), error); } private String getJGrowlAfterOpenJavaScript() { // programatically click on link // http://stackoverflow.com/questions/1694595/can-i-call-jquery-click-to-follow-an-a-link-if-i-havent-bound-an-event-hand StringBuilder javaScript = new StringBuilder(); javaScript.append("function(e,m,o) {"); javaScript.append("var link = e.find('a');"); javaScript.append("if (link.size() > 0) {"); // javaScript.append("window.open(link.attr('href'), '_blank');"); javaScript.append("link[0].click();"); javaScript.append("}"); javaScript.append("}"); return javaScript.toString(); } private void initPushSurvey(IPushService pushService, IPushNode<Message> pushNode) { int[] surveyDays = new int[]{30, 180}; // show survey at 30, 180 days Map<String, String> preferences = NextServerSession.get().getPreferences(); int surveyDay = PreferencesHelper.getInt("survey.day", preferences); int surveyTestDay = surveyDay; if (surveyDay == 0) { surveyTestDay = surveyDays[0]; } else { for (int i=0, size=surveyDays.length; i<size; i++) { if (surveyDay == surveyDays[i]) { if (i == size-1) { return; } else { surveyTestDay = surveyDays[i+1]; } } } } Date firstUsageDate = PreferencesHelper.getDate("firstUsage.date", preferences); if (firstUsageDate == null) { firstUsageDate = new Date(); preferences.put("firstUsage.date", PreferencesHelper.sdf.format(firstUsageDate)); } int array[] = DateUtil.getElapsedTime(firstUsageDate, new Date()); boolean showSurvey = (array != null) && (array[0] >= surveyTestDay); if (showSurvey) { if (pushService.isConnected(pushNode)) { pushService.publish(pushNode, createSurveyMessage()); preferences.put("survey.day", String.valueOf(surveyTestDay)); } } NextServerSession.get().setPreferences(preferences); } private Message createSurveyMessage() { StringBuilder sb = new StringBuilder(); Locale locale = LanguageManager.getInstance().getLocale(storageService.getSettings().getLanguage()); ResourceBundle bundle = ResourceBundle.getBundle("ro.nextreports.server.web.NextServerApplication", locale); String s = bundle.getString("survey.message"); sb.append(s); sb.append("<br>"). append("<a class=\"go\" href=\""). append(surveyUrl). append("\" target=\"_blank\">"). append(bundle.getString("survey.go")). append("</a>"); return new Message(sb.toString(), false); } private class Message { private String text; private boolean error; public Message(String text, boolean error) { this.text = text; this.error = error; } public String getText() { return text; } public boolean isError() { return error; } } }