diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/PersonDao.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/PersonDao.java index b2ecfa8..07be91e 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/PersonDao.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/PersonDao.java @@ -1,7 +1,18 @@ package de.kreth.vaadin.clubhelper.vaadinclubhelper.dao; +import javax.persistence.NoResultException; + import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.Person; public interface PersonDao extends IDao { + /** + * Returns Person from Storage by username and (encrypted) password. + * + * @param username login username + * @param password encrypted password + * @return + * @throws NoResultException if no result is found. + */ + Person findLoginUser(String username, String password) throws NoResultException; } diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/PersonDaoImpl.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/PersonDaoImpl.java index 524e04f..13093e5 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/PersonDaoImpl.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/PersonDaoImpl.java @@ -1,16 +1,24 @@ package de.kreth.vaadin.clubhelper.vaadinclubhelper.dao; +import javax.persistence.TypedQuery; + import org.springframework.stereotype.Repository; import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.Person; @Repository -public class PersonDaoImpl extends AbstractDaoImpl - implements - PersonDao { +public class PersonDaoImpl extends AbstractDaoImpl implements PersonDao { public PersonDaoImpl() { super(Person.class); } + @Override + public Person findLoginUser(String username, String password) { + TypedQuery query = em.createNamedQuery(Person.QUERY_FINDLOGIN, Person.class); + query.setParameter("username", username); + query.setParameter("password", password); + return query.getSingleResult(); + } + } diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/Person.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/Person.java index 6c1b907..d6adc71 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/Person.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/data/Person.java @@ -26,9 +26,13 @@ import javax.persistence.Table; @Table(name = "person") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @NamedQuery(name = Person.QUERY_FINDALL, query = "SELECT p FROM Person p") +@NamedQuery(name = Person.QUERY_FINDLOGIN, query = "FROM Person WHERE username = :username AND password = :password") public class Person extends BaseEntity implements Serializable { + public static final String SESSION_LOGIN = "SESSION_LOGIN_USER"; + public static final String QUERY_FINDALL = "Person.findAll"; + public static final String QUERY_FINDLOGIN = "Person.findLogin"; private static final long serialVersionUID = -8361264400619997123L; diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/LoginUI.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/LoginUI.java new file mode 100644 index 0000000..05c73ba --- /dev/null +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/LoginUI.java @@ -0,0 +1,52 @@ +package de.kreth.vaadin.clubhelper.vaadinclubhelper.ui; + +import com.vaadin.navigator.Navigator; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.ui.Alignment; +import com.vaadin.ui.LoginForm; +import com.vaadin.ui.Notification; +import com.vaadin.ui.VerticalLayout; + +import de.kreth.vaadin.clubhelper.vaadinclubhelper.dao.PersonDao; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.Person; + +public class LoginUI extends VerticalLayout implements View { + + private static final long serialVersionUID = 4339018452507960084L; + public static final String VIEW_NAME = "LoginUI"; + + private Navigator navigator; + private String parameters; + + public LoginUI(PersonDao personDao) { + + LoginForm lf = new LoginForm(); + lf.addLoginListener(e -> { + + String username = e.getLoginParameter("username"); + String password = e.getLoginParameter("password"); + + try { + Person loggedin = personDao.findLoginUser(username, password); + this.getSession().setAttribute(Person.SESSION_LOGIN, loggedin); + navigator.navigateTo(MainView.VIEW_NAME + '/' + parameters); + } catch (final Exception ex) { + String message = "Incorrect user or password:" + ex.getMessage() + e.getLoginParameter("username") + ":" + + e.getLoginParameter("password"); + Notification.show(message, Notification.Type.ERROR_MESSAGE); + } + }); + addComponent(lf); + setComponentAlignment(lf, Alignment.MIDDLE_CENTER); + setSizeFull(); + + } + + @Override + public void enter(ViewChangeEvent event) { + View.super.enter(event); + navigator = event.getNavigator(); + parameters = event.getParameters(); + } +} diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/MainUi.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/MainUi.java index 3d541e6..9e12857 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/MainUi.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/MainUi.java @@ -1,36 +1,26 @@ package de.kreth.vaadin.clubhelper.vaadinclubhelper.ui; -import java.util.List; -import java.util.Set; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.vaadin.addon.calendar.ui.CalendarComponentEvents; +import com.vaadin.annotations.PreserveOnRefresh; import com.vaadin.annotations.Push; import com.vaadin.annotations.Theme; -import com.vaadin.event.selection.SelectionEvent; +import com.vaadin.navigator.Navigator; import com.vaadin.server.VaadinRequest; import com.vaadin.shared.communication.PushMode; import com.vaadin.spring.annotation.SpringUI; -import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.UI; import de.kreth.vaadin.clubhelper.vaadinclubhelper.business.EventBusiness; import de.kreth.vaadin.clubhelper.vaadinclubhelper.dao.GroupDao; import de.kreth.vaadin.clubhelper.vaadinclubhelper.dao.PersonDao; -import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.ClubEvent; -import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.Person; -import de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.components.CalendarComponent; -import de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.components.PersonEditDialog; -import de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.components.PersonGrid; @Theme("vaadin-clubhelpertheme") @SpringUI @Push(value = PushMode.MANUAL) +@PreserveOnRefresh public class MainUi extends UI { private static final long serialVersionUID = 7581634188909841919L; @@ -45,80 +35,20 @@ public class MainUi extends UI { @Autowired EventBusiness eventBusiness; - private PersonGrid personGrid; - - private CalendarComponent calendar; - - private HorizontalLayout contentLayout; - @Override protected void init(VaadinRequest request) { LOGGER.debug("Starting Vaadin UI with {}", getClass().getName()); - personGrid = new PersonGrid(groupDao, personDao); - personGrid.setId("main.person"); - personGrid.setCaption("Personen"); - personGrid.onClosedFunction(() -> detailClosed()); - personGrid.onPersonSelect(ev -> personSelectionChange(ev)); - personGrid.onPersonEdit(p -> onPersonEdit(p)); - - this.calendar = new CalendarComponent(); - calendar.setId("main.calendar"); - calendar.setHandler(this::onItemClick); - - contentLayout = new HorizontalLayout(); - contentLayout.setSizeFull(); - contentLayout.addComponents(calendar); - - setContent(contentLayout); - setSizeFull(); - - ExecutorService exec = Executors.newSingleThreadExecutor(); - exec.execute(() -> { + getPage().setTitle("Vereinshelfer"); - final List events = eventBusiness.loadEvents(); - LOGGER.info("Loaded events: {}", events); - final UI ui = calendar.getUI(); - ui.access(() -> { - calendar.setItems(events); - ui.push(); - }); - - }); - exec.shutdown(); - LOGGER.info("Loaded UI and started fetch of Events"); - } - - private void onPersonEdit(Person p) { - PersonEditDialog dlg = new PersonEditDialog(groupDao.listAll(), p, personDao); - getUI().addWindow(dlg); - } - - private void personSelectionChange(SelectionEvent ev) { - Set selected = ev.getAllSelectedItems(); - LOGGER.debug("Selection changed to: {}", selected); - eventBusiness.changePersons(selected); - } - - private void detailClosed() { - LOGGER.debug("Closing detail view."); - contentLayout.removeComponent(personGrid); - } + // Create a navigator to control the views + Navigator navigator = new Navigator(this, this); - private void onItemClick(CalendarComponentEvents.ItemClickEvent event) { -// ClubEvent ev = (ClubEvent) event.getCalendarItem(); -// LOGGER.debug("Opening detail view for {}", ev); -// -// contentLayout.removeComponent(personGrid); -// contentLayout.addComponent(personGrid); -// -// eventBusiness.setSelected(null); -// personGrid.setEnabled(false); -// personGrid.setEvent(ev); -// personGrid.setEnabled(true); -// personGrid.setVisible(true); -// eventBusiness.setSelected(ev); + // Create and register the views + navigator.addView(MainView.VIEW_NAME, new MainView(personDao, groupDao, eventBusiness)); + navigator.addView(LoginUI.VIEW_NAME, new LoginUI(personDao)); + navigator.navigateTo(MainView.VIEW_NAME); } } diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/MainView.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/MainView.java new file mode 100644 index 0000000..ab2fe22 --- /dev/null +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/MainView.java @@ -0,0 +1,139 @@ +package de.kreth.vaadin.clubhelper.vaadinclubhelper.ui; + +import java.util.List; +import java.util.Set; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.vaadin.addon.calendar.ui.CalendarComponentEvents; + +import com.vaadin.event.selection.SelectionEvent; +import com.vaadin.navigator.Navigator; +import com.vaadin.navigator.View; +import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.UI; + +import de.kreth.vaadin.clubhelper.vaadinclubhelper.business.EventBusiness; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.dao.GroupDao; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.dao.PersonDao; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.ClubEvent; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.Person; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.components.CalendarComponent; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.components.PersonEditDialog; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.components.PersonGrid; + +public class MainView extends HorizontalLayout implements View { + + public static final String VIEW_NAME = ""; + + private static final long serialVersionUID = 4831071242146146399L; + private final Logger LOGGER = LoggerFactory.getLogger(getClass()); + + private PersonGrid personGrid; + + private CalendarComponent calendar; + + private Person loggedinPerson; + private PersonDao personDao; + private GroupDao groupDao; + private EventBusiness eventBusiness; + private Navigator navigator; + + public MainView(PersonDao personDao, GroupDao groupDao, EventBusiness eventBusiness) { + + this.personDao = personDao; + this.groupDao = groupDao; + this.eventBusiness = eventBusiness; + + } + + @Override + public void enter(ViewChangeEvent event) { + View.super.enter(event); + if (this.navigator == null) { + + navigator = event.getNavigator(); + + personGrid = new PersonGrid(groupDao, personDao); + personGrid.setId("main.person"); + personGrid.setCaption("Personen"); + personGrid.onClosedFunction(() -> detailClosed()); + personGrid.onPersonSelect(ev -> personSelectionChange(ev)); + personGrid.onPersonEdit(p -> onPersonEdit(p)); + + calendar = new CalendarComponent(); + calendar.setId("main.calendar"); + calendar.setHandler(this::onItemClick); + + setSizeFull(); + addComponents(calendar); + + setSizeFull(); + + ExecutorService exec = Executors.newSingleThreadExecutor(); + exec.execute(() -> { + + final List events = eventBusiness.loadEvents(); + LOGGER.info("Loaded events: {}", events); + final UI ui = calendar.getUI(); + ui.access(() -> { + calendar.setItems(events); + ui.push(); + }); + + }); + exec.shutdown(); + LOGGER.info("Loaded UI and started fetch of Events"); + } else { + LOGGER.info("{} already initialized - opening Person View."); + openPersonViewForEvent(eventBusiness.getCurrent()); + calendar.setToday(eventBusiness.getCurrent().getStart()); + } + } + + private void onPersonEdit(Person p) { + PersonEditDialog dlg = new PersonEditDialog(groupDao.listAll(), p, personDao); + getUI().addWindow(dlg); + } + + private void personSelectionChange(SelectionEvent ev) { + Set selected = ev.getAllSelectedItems(); + LOGGER.debug("Selection changed to: {}", selected); + eventBusiness.changePersons(selected); + } + + private void detailClosed() { + LOGGER.debug("Closing detail view."); + removeComponent(personGrid); + } + + private void onItemClick(CalendarComponentEvents.ItemClickEvent event) { + + loggedinPerson = (Person) getSession().getAttribute(Person.SESSION_LOGIN); + ClubEvent ev = (ClubEvent) event.getCalendarItem(); + if (loggedinPerson != null) { + openPersonViewForEvent(ev); + } else { + eventBusiness.setSelected(ev); + navigator.navigateTo(LoginUI.VIEW_NAME + '/' + ev.getId()); + } + } + + public void openPersonViewForEvent(ClubEvent ev) { + LOGGER.debug("Opening detail view for {}", ev); + + removeComponent(personGrid); + addComponent(personGrid); + + eventBusiness.setSelected(null); + personGrid.setEnabled(false); + personGrid.setEvent(ev); + personGrid.setEnabled(true); + personGrid.setVisible(true); + eventBusiness.setSelected(ev); + } + +} diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/CalendarComponent.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/CalendarComponent.java index 7a8b9f2..8c02a9a 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/CalendarComponent.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/CalendarComponent.java @@ -1,20 +1,9 @@ package de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.components; -import java.io.IOException; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; -import java.time.LocalDate; import java.time.LocalDateTime; import java.time.Month; import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,50 +13,23 @@ import org.vaadin.addon.calendar.ui.CalendarComponentEvents.BackwardEvent; import org.vaadin.addon.calendar.ui.CalendarComponentEvents.ForwardEvent; import org.vaadin.addon.calendar.ui.CalendarComponentEvents.ItemClickHandler; -import com.vaadin.contextmenu.ContextMenu; -import com.vaadin.server.StreamResource; import com.vaadin.shared.Registration; -import com.vaadin.ui.AbstractComponent; -import com.vaadin.ui.BrowserFrame; -import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.CustomComponent; -import com.vaadin.ui.HorizontalLayout; -import com.vaadin.ui.Label; -import com.vaadin.ui.MenuBar.MenuItem; -import com.vaadin.ui.Notification; import com.vaadin.ui.VerticalLayout; -import com.vaadin.ui.Window; import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.ClubEvent; -import net.sf.jasperreports.engine.JRException; -import net.sf.jasperreports.engine.JasperExportManager; -import net.sf.jasperreports.engine.JasperPrint; public class CalendarComponent extends CustomComponent { private static final long serialVersionUID = -9152173211931554059L; private transient final Logger log = LoggerFactory.getLogger(getClass()); - private transient DateTimeFormatter dfMonth = DateTimeFormatter.ofPattern("MMMM uuuu"); - - private Label monthName; - private ClubEventProvider dataProvider; private Calendar calendar; + private HeadComponent head; public CalendarComponent() { - monthName = new Label(); - monthName.setId("calendar.month"); - monthName.setStyleName("title_label"); - - Button popupButton = new Button("Menu"); - popupButton.setId("calendar.menu"); - popupButton.addClickListener(ev -> openPopupMenu(ev)); - - HorizontalLayout head = new HorizontalLayout(monthName, popupButton); - dataProvider = new ClubEventProvider(); calendar = new Calendar<>(dataProvider).withMonth(Month.from(LocalDateTime.now())); calendar.setId("calendar.calendar"); @@ -75,8 +37,8 @@ public class CalendarComponent extends CustomComponent { calendar.setCaption("Events"); calendar.setSizeFull(); calendar.addListener(ev -> calendarEvent(ev)); - - updateMonthText(calendar.getStartDate()); + head = new HeadComponent(() -> calendar.getStartDate(), () -> calendar.getEndDate(), dataProvider); + head.updateMonthText(calendar.getStartDate()); VerticalLayout layout = new VerticalLayout(head, calendar); layout.setSizeFull(); @@ -86,130 +48,16 @@ public class CalendarComponent extends CustomComponent { private void calendarEvent(Event ev) { log.debug("Event on calendar: {}", ev); if (ev instanceof BackwardEvent || ev instanceof ForwardEvent) { - updateMonthText(calendar.getStartDate()); - } - } - - public Registration setHandler(ItemClickHandler listener) { - return calendar.setHandler(listener); - } - - private void openPopupMenu(ClickEvent ev) { - ContextMenu contextMenu = new ContextMenu(ev.getButton(), true); - contextMenu.addItem("Export Monat", ev1 -> calendarExport(ev1)); - contextMenu.addItem("Export Jahr", ev1 -> calendarExport(ev1)); - contextMenu.open(210, 40); - } - - private void calendarExport(MenuItem ev1) { - - boolean monthOnly = ev1.getText().contains("Monat"); - List items; - ZonedDateTime start; - if (monthOnly) { - start = calendar.getStartDate(); - ZonedDateTime end = calendar.getEndDate(); - log.debug("exporting Calendar from {} to {}", start, end); - items = dataProvider.getItems(start, end); - } else { - - start = calendar.getStartDate().withDayOfYear(1); - ZonedDateTime end = start.withMonth(12).withDayOfMonth(31); - log.debug("exporting Calendar from {} to {}", start, end); - items = dataProvider.getItems(start, end); - } - - Map values = new HashMap<>(); - List holidays = CalendarCreator.filterHolidays(items); - - for (ClubEvent ev : items) { - - ZonedDateTime evStart = ev.getStart(); - ZonedDateTime evEnd = ev.getEnd(); - - log.trace("Added to eventsd: {}", ev); - - CalendarCreator.iterateDays(evStart.toLocalDate(), evEnd.toLocalDate(), day -> { - - StringBuilder content; - if (values.containsKey(day)) { - content = values.get(day); - content.append("\n"); - } else { - content = new StringBuilder(); - values.put(day, content); - } - content.append(ev.getCaption()); - }); - } - - String calendarMonth; - if (monthOnly) { - calendarMonth = dfMonth.format(start); - } else { - calendarMonth = "Jahr " + start.getYear(); - } - - try { - JasperPrint print; - if (monthOnly) { - print = CalendarCreator.createCalendar(new Date(start.toInstant().toEpochMilli()), values, holidays); - } else { - print = CalendarCreator.createYearCalendar(start.getYear(), values, holidays); - } - log.trace("Created Jasper print for {}", calendarMonth); - Window window = new Window(); - window.setCaption("View PDF"); - AbstractComponent e = createEmbedded(calendarMonth, print); - window.setContent(e); - window.setModal(true); - window.setWidth("50%"); - window.setHeight("90%"); - monthName.getUI().addWindow(window); - log.trace("Added pdf window for {}", calendarMonth); - } catch (JRException e) { - log.error("Error Creating Jasper Report for {}", calendarMonth, e); - Notification.show("Fehler bei PDF: " + e); - } catch (IOException e1) { - log.error("Error Creating Jasper Report for {}", calendarMonth, e1); - Notification.show("Fehler bei PDF: " + e1); + head.updateMonthText(calendar.getStartDate()); } } - private AbstractComponent createEmbedded(String title, JasperPrint print) throws IOException { - - PipedInputStream in = new PipedInputStream(); - final PipedOutputStream out = new PipedOutputStream(in); - - final StreamResource resource = new StreamResource(() -> in, title); - resource.setMIMEType("application/pdf"); - - BrowserFrame c = new BrowserFrame("PDF invoice", resource); - c.setSizeFull(); - - ExecutorService exec = Executors.newSingleThreadExecutor(); - exec.execute(() -> { - try { - JasperExportManager.exportReportToPdfStream(print, out); - } catch (JRException e) { - log.error("Error on Export to Pdf.", e); - throw new RuntimeException(e); - } finally { - try { - out.close(); - } catch (IOException e) { - log.warn("Error closing Jasper output stream.", e); - } - } - }); - exec.shutdown(); - return c; + public void setToday(ZonedDateTime date) { + calendar.withDayInMonth(date); } - private void updateMonthText(ZonedDateTime startDate) { - String monthValue = dfMonth.format(startDate); - log.debug("Changed Month title to {}", monthValue); - monthName.setValue(monthValue); + public Registration setHandler(ItemClickHandler listener) { + return calendar.setHandler(listener); } public void setItems(Collection items) { @@ -217,7 +65,7 @@ public class CalendarComponent extends CustomComponent { calendar.markAsDirty(); } - static class ClubEventProvider extends BasicItemProvider { + public static class ClubEventProvider extends BasicItemProvider { private static final long serialVersionUID = -5415397258827236704L; diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/HeadComponent.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/HeadComponent.java new file mode 100644 index 0000000..8c40be4 --- /dev/null +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/HeadComponent.java @@ -0,0 +1,187 @@ +package de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.components; + +import java.io.IOException; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; +import java.time.LocalDate; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.function.Supplier; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.vaadin.contextmenu.ContextMenu; +import com.vaadin.icons.VaadinIcons; +import com.vaadin.server.StreamResource; +import com.vaadin.ui.AbstractComponent; +import com.vaadin.ui.BrowserFrame; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.HorizontalLayout; +import com.vaadin.ui.Label; +import com.vaadin.ui.MenuBar.MenuItem; +import com.vaadin.ui.Notification; +import com.vaadin.ui.Window; + +import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.ClubEvent; +import de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.components.CalendarComponent.ClubEventProvider; +import net.sf.jasperreports.engine.JRException; +import net.sf.jasperreports.engine.JasperExportManager; +import net.sf.jasperreports.engine.JasperPrint; + +public class HeadComponent extends HorizontalLayout { + + private static final long serialVersionUID = -7915475211371903028L; + + private transient final Logger log = LoggerFactory.getLogger(getClass()); + private transient DateTimeFormatter dfMonth = DateTimeFormatter.ofPattern("MMMM uuuu"); + + private Label monthName; + + private final Supplier startTime; + private final Supplier endTime; + + private ClubEventProvider dataProvider; + + public HeadComponent(Supplier startTime, Supplier endTime, + ClubEventProvider dataProvider) { + + monthName = new Label(); + monthName.setId("calendar.month"); + monthName.setStyleName("title_label"); + + Button popupButton = new Button(VaadinIcons.MENU); + popupButton.setId("calendar.menu"); + popupButton.addClickListener(ev -> openPopupMenu(ev)); + this.addComponent(monthName); + this.addComponent(popupButton); + this.startTime = startTime; + this.endTime = endTime; + this.dataProvider = dataProvider; + } + + public void updateMonthText(ZonedDateTime startDate) { + String monthValue = dfMonth.format(startDate); + log.debug("Changed Month title to {}", monthValue); + monthName.setValue(monthValue); + } + + private void openPopupMenu(ClickEvent ev) { + ContextMenu contextMenu = new ContextMenu(ev.getButton(), true); + contextMenu.addItem("Export Monat", ev1 -> calendarExport(ev1)); + contextMenu.addItem("Export Jahr", ev1 -> calendarExport(ev1)); + contextMenu.open(210, 40); + } + + private void calendarExport(MenuItem ev1) { + + boolean monthOnly = ev1.getText().contains("Monat"); + List items; + ZonedDateTime start; + if (monthOnly) { + start = startTime.get(); + ZonedDateTime end = endTime.get(); + log.debug("exporting Calendar from {} to {}", start, end); + items = dataProvider.getItems(start, end); + } else { + start = startTime.get().withDayOfYear(1); + ZonedDateTime end = start.withMonth(12).withDayOfMonth(31); + log.debug("exporting Calendar from {} to {}", start, end); + items = dataProvider.getItems(start, end); + } + + Map values = new HashMap<>(); + List holidays = CalendarCreator.filterHolidays(items); + + for (ClubEvent ev : items) { + + ZonedDateTime evStart = ev.getStart(); + ZonedDateTime evEnd = ev.getEnd(); + + log.trace("Added to eventsd: {}", ev); + + CalendarCreator.iterateDays(evStart.toLocalDate(), evEnd.toLocalDate(), day -> { + + StringBuilder content; + if (values.containsKey(day)) { + content = values.get(day); + content.append("\n"); + } else { + content = new StringBuilder(); + values.put(day, content); + } + content.append(ev.getCaption()); + }); + } + + String calendarMonth; + if (monthOnly) { + calendarMonth = dfMonth.format(start); + } else { + calendarMonth = "Jahr " + start.getYear(); + } + + try { + JasperPrint print; + if (monthOnly) { + print = CalendarCreator.createCalendar(new Date(start.toInstant().toEpochMilli()), values, holidays); + } else { + print = CalendarCreator.createYearCalendar(start.getYear(), values, holidays); + } + log.trace("Created Jasper print for {}", calendarMonth); + Window window = new Window(); + window.setCaption("View PDF"); + AbstractComponent e = createEmbedded(calendarMonth, print); + window.setContent(e); + window.setModal(true); + window.setWidth("50%"); + window.setHeight("90%"); + monthName.getUI().addWindow(window); + log.trace("Added pdf window for {}", calendarMonth); + } catch (JRException e) { + log.error("Error Creating Jasper Report for {}", calendarMonth, e); + Notification.show("Fehler bei PDF: " + e); + } catch (IOException e1) { + log.error("Error Creating Jasper Report for {}", calendarMonth, e1); + Notification.show("Fehler bei PDF: " + e1); + } + } + + private AbstractComponent createEmbedded(String title, JasperPrint print) throws IOException { + + PipedInputStream in = new PipedInputStream(); + final PipedOutputStream out = new PipedOutputStream(in); + + final StreamResource resource = new StreamResource(() -> in, title); + resource.setMIMEType("application/pdf"); + + BrowserFrame c = new BrowserFrame("PDF invoice", resource); + c.setSizeFull(); + + ExecutorService exec = Executors.newSingleThreadExecutor(); + exec.execute(() -> { + try { + JasperExportManager.exportReportToPdfStream(print, out); + } catch (JRException e) { + log.error("Error on Export to Pdf.", e); + throw new RuntimeException(e); + } finally { + try { + out.close(); + } catch (IOException e) { + log.warn("Error closing Jasper output stream.", e); + } + } + }); + exec.shutdown(); + return c; + } + +} diff --git a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/calendar/Year.java b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/calendar/Year.java index f67681e..1ba5cdf 100644 --- a/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/calendar/Year.java +++ b/src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/calendar/Year.java @@ -10,8 +10,11 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.Set; +import javax.annotation.Nonnull; + public class Year { private final LocalDate date; @@ -24,16 +27,20 @@ public class Year { this(year, Collections.emptyMap(), Collections.emptyList(), Locale.getDefault()); } - public Year(int year, Map values, Collection holidays) { + public Year(int year, @Nonnull Map values, @Nonnull Collection holidays) { this(year, values, holidays, Locale.getDefault()); } - public Year(int year, Map values, Collection holidays, Locale locale) { + public Year(int year, @Nonnull Map values, @Nonnull Collection holidays, + Locale locale) { if (year < 1900 || year > 2100) { throw new IllegalArgumentException("Year value must be between 1900 and 2100"); } + Objects.requireNonNull(values); + Objects.requireNonNull(holidays); + this.date = LocalDate.of(year, 1, 1); - this.locale = locale; + this.locale = locale == null ? Locale.getDefault() : locale; this.holidays = new HashSet<>(holidays); this.monthWeeks = new HashMap<>(); for (Month m : Month.values()) { diff --git a/src/test/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/YearlyCalendarCreatorTest.java b/src/test/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/YearlyCalendarCreatorTest.java new file mode 100644 index 0000000..7042cfd --- /dev/null +++ b/src/test/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/components/YearlyCalendarCreatorTest.java @@ -0,0 +1,19 @@ +package de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.components; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class YearlyCalendarCreatorTest { + + @BeforeEach + void setUp() throws Exception { + } + + @Test + void testYearlyCalendarCreatorIntMapOfLocalDateCharSequenceCollectionOfLocalDate() { + assertThrows(NullPointerException.class, () -> new YearlyCalendarCreator(2018, null, null)); + } + +}