Calendar shown, events loaded.

master
Markus Kreth 7 years ago
parent 28647d3643
commit 42727d01d5
  1. 11
      .classpath
  2. 8
      .settings/org.eclipse.wst.common.component
  3. 2
      .settings/org.eclipse.wst.common.project.facet.core.xml
  4. 2
      .settings/org.eclipse.wst.validation.prefs
  5. 65
      pom.xml
  6. 147
      src/main/java/de/kreth/clubhelperbackend/google/GoogleBaseAdapter.java
  7. 182
      src/main/java/de/kreth/clubhelperbackend/google/calendar/CalendarAdapter.java
  8. 81
      src/main/java/de/kreth/clubhelperbackend/google/calendar/CalendarResource.java
  9. 83
      src/main/java/de/kreth/clubhelperbackend/google/calendar/ClubEvent.java
  10. 46
      src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/dao/EventBusiness.java
  11. 51
      src/main/java/de/kreth/vaadin/clubhelper/vaadinclubhelper/ui/MainUi.java
  12. 3
      src/main/resources/application.properties
  13. 6
      src/main/resources/calendars.properties
  14. 13
      src/main/resources/client_secret.json

@ -13,9 +13,9 @@
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
@ -28,13 +28,12 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Hibernate">
<classpathentry kind="src" output="target/classes" path="target/generated-resources/gwt">
<attributes>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
<attribute name="owner.project.facets" value="jpt.jpa"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.web.container"/>
<classpathentry kind="con" path="org.eclipse.jst.j2ee.internal.module.container"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

@ -1,9 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="vaadin-clubhelper">
<wb-resource deploy-path="/" source-path="/WebContent" tag="defaultRootSource"/>
<wb-module deploy-name="vaadin-clubhelper-0.0.1-SNAPSHOT">
<wb-resource deploy-path="/" source-path="/WebContent"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/test/java"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/target/generated-resources/gwt"/>
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<property name="context-root" value="vaadin-clubhelper"/>
<property name="java-output-path" value="/vaadin-clubhelper/target/classes"/>
</wb-module>

@ -3,6 +3,6 @@
<fixed facet="wst.jsdt.web"/>
<installed facet="java" version="1.8"/>
<installed facet="jpt.jpa" version="2.1"/>
<installed facet="jst.web" version="3.0"/>
<installed facet="wst.jsdt.web" version="1.0"/>
<installed facet="jst.web" version="3.1"/>
</faceted-project>

@ -0,0 +1,2 @@
disabled=06target
eclipse.preferences.version=1

@ -24,18 +24,20 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<vaadin.version>8.4.4</vaadin.version>
<google-api-version>1.23.0</google-api-version>
<google-api-sheets-version>v4-rev488-1.23.0</google-api-sheets-version>
<google-api-calendar-version>v3-rev271-1.23.0</google-api-calendar-version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- <dependency> -->
<!-- <groupId>org.springframework.boot</groupId> -->
<!-- <artifactId>spring-boot-starter-security</artifactId> -->
<!-- </dependency> -->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
@ -67,6 +69,37 @@
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.vaadin.blackbluegl</groupId>
<artifactId>calendar-component</artifactId>
<version>2.0-BETA4</version>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-calendar</artifactId>
<version>${google-api-calendar-version}</version>
</dependency>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client-appengine</artifactId>
<version>${google-api-version}</version>
</dependency>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client-gson</artifactId>
<version>${google-api-version}</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-java6</artifactId>
<version>${google-api-version}</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-jetty</artifactId>
<version>${google-api-version}</version>
</dependency>
</dependencies>
<dependencyManagement>
@ -87,8 +120,34 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<version>${vaadin.version}</version>
<executions>
<execution>
<goals>
<goal>update-theme</goal>
<goal>update-widgetset</goal>
<goal>compile</goal>
<!-- Comment out compile-theme goal to use on-the-fly theme compilation -->
<goal>compile-theme</goal>
</goals>
</execution>
</executions>
<configuration>
<gwtSdkFirstInClasspath>true</gwtSdkFirstInClasspath>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>vaadin-addons</id>
<url>http://maven.vaadin.com/vaadin-addons</url>
</repository>
</repositories>
</project>

@ -0,0 +1,147 @@
package de.kreth.clubhelperbackend.google;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.calendar.CalendarScopes;
public abstract class GoogleBaseAdapter {
private static final int GOOGLE_SECRET_PORT = 59431;
/** Application name. */
protected static final String APPLICATION_NAME = "ClubHelperVaadin";
/** Directory to store user credentials for this application. */
protected static final File DATA_STORE_DIR = new File(
System.getProperty("catalina.base"), ".credentials");
/** Global instance of the JSON factory. */
protected static final JsonFactory JSON_FACTORY = JacksonFactory
.getDefaultInstance();
/**
* Global instance of the scopes required by this quickstart.
*
* If modifying these scopes, delete your previously saved credentials
*/
static final List<String> SCOPES = Arrays.asList(CalendarScopes.CALENDAR);
protected static Credential credential;
protected static final Logger log = LoggerFactory
.getLogger(GoogleBaseAdapter.class);
/** Global instance of the {@link FileDataStoreFactory}. */
protected final FileDataStoreFactory DATA_STORE_FACTORY;
/** Global instance of the HTTP transport. */
protected final HttpTransport HTTP_TRANSPORT;
public GoogleBaseAdapter() throws GeneralSecurityException, IOException {
super();
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
DATA_STORE_DIR.mkdirs();
}
protected void checkRefreshToken(String serverName) throws IOException {
if (credential == null) {
credential = authorize(serverName);
}
if ((credential.getExpiresInSeconds() != null
&& credential.getExpiresInSeconds() < 3600)) {
if (log.isDebugEnabled()) {
log.debug("Security needs refresh, trying.");
}
boolean result = credential.refreshToken();
if (log.isDebugEnabled()) {
log.debug("Token refresh "
+ (result ? "successfull." : "failed."));
}
}
}
/**
* Creates an authorized Credential object.
*
* @param request
*
* @return an authorized Credential object.
* @throws IOException
*/
private synchronized Credential authorize(String serverName)
throws IOException {
if (credential != null && (credential.getExpiresInSeconds() != null
&& credential.getExpiresInSeconds() < 3600)) {
credential.refreshToken();
return credential;
}
// Load client secrets.
InputStream in = getClass().getResourceAsStream("/client_secret.json");
if (in == null) {
File inHome = new File(System.getProperty("user.home"),
"client_secret.json");
if (inHome.exists()) {
if (log.isInfoEnabled()) {
log.info(
"Google secret not found as Resource, using user Home file.");
}
in = new FileInputStream(inHome);
} else {
log.error(
"Failed to load client_secret.json. Download from google console.");
return null;
}
}
GoogleClientSecrets clientSecrets = GoogleClientSecrets
.load(JSON_FACTORY, new InputStreamReader(in));
if (log.isTraceEnabled()) {
log.trace("client secret json resource loaded.");
}
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(DATA_STORE_FACTORY)
.setAccessType("offline").setApprovalPrompt("force")
.build();
if (log.isDebugEnabled()) {
log.debug("Configuring google LocalServerReceiver on " + serverName
+ ":" + GOOGLE_SECRET_PORT);
}
LocalServerReceiver localServerReceiver = new LocalServerReceiver.Builder()
.setHost(serverName).setPort(GOOGLE_SECRET_PORT).build();
Credential credential = new AuthorizationCodeInstalledApp(flow,
localServerReceiver).authorize("user");
if (log.isDebugEnabled()) {
log.debug(
"Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
}
credential.setExpiresInSeconds(Long.valueOf(691200L));
return credential;
}
}

@ -0,0 +1,182 @@
package de.kreth.clubhelperbackend.google.calendar;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import com.google.api.client.util.DateTime;
import com.google.api.services.calendar.model.Calendar;
import com.google.api.services.calendar.model.CalendarList;
import com.google.api.services.calendar.model.CalendarListEntry;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.EventAttendee;
import de.kreth.clubhelperbackend.google.GoogleBaseAdapter;
import de.kreth.clubhelperbackend.google.calendar.CalendarResource.CalendarKonfig;
public class CalendarAdapter extends GoogleBaseAdapter {
com.google.api.services.calendar.Calendar service;
private Lock lock = new ReentrantLock();
private CalendarResource res;
public CalendarAdapter() throws GeneralSecurityException, IOException {
super();
res = new CalendarResource();
}
@Override
protected void checkRefreshToken(String serverName) throws IOException {
try {
if (lock.tryLock(10, TimeUnit.SECONDS)) {
try {
super.checkRefreshToken(serverName);
if (service == null && credential != null) {
service = new com.google.api.services.calendar.Calendar.Builder(
HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
}
} finally {
lock.unlock();
}
}
} catch (InterruptedException e) {
if (log.isWarnEnabled()) {
log.warn("Lock interrupted", e);
}
}
if (service == null) {
throw new IllegalStateException(
"Calendar Service not instanciated!");
}
}
Calendar getCalendarBySummaryName(List<CalendarListEntry> items,
String calendarSummary) throws IOException {
String calendarId = null;
for (CalendarListEntry e : items) {
if (calendarSummary.equals(e.getSummary())) {
calendarId = e.getId();
break;
}
}
if (calendarId == null) {
throw new IllegalStateException(
"Calendar " + calendarSummary + " not found!");
}
Calendar cal = service.calendars().get(calendarId).execute();
return cal;
}
public List<Event> getAllEvents(String serverName)
throws IOException, InterruptedException {
final List<Event> events = new ArrayList<>();
List<CalendarListEntry> items = getCalendarList(serverName);
final long oldest = getOldest();
List<CalendarKonfig> configs = res.getConfigs();
ExecutorService exec = Executors.newFixedThreadPool(configs.size());
for (CalendarKonfig c : configs) {
exec.execute(new FetchEventsRunner(items, c.getName(), events,
oldest, c.getColor()));
}
exec.shutdown();
try {
exec.awaitTermination(20, TimeUnit.SECONDS);
} catch (InterruptedException e) {
log.error("Thread terminated - event list may be incomplete.", e);
}
return events;
}
private long getOldest() {
GregorianCalendar oldestCal = new GregorianCalendar();
oldestCal.set(java.util.Calendar.DAY_OF_MONTH, 1);
oldestCal.set(java.util.Calendar.HOUR_OF_DAY, 0);
oldestCal.set(java.util.Calendar.MINUTE, 0);
oldestCal.add(java.util.Calendar.MONTH, -1);
oldestCal.add(java.util.Calendar.YEAR, -1);
oldestCal.add(java.util.Calendar.HOUR_OF_DAY, -1);
final long oldest = oldestCal.getTimeInMillis();
return oldest;
}
List<CalendarListEntry> getCalendarList(String serverName)
throws IOException {
checkRefreshToken(serverName);
CalendarList calendarList;
try {
calendarList = service.calendarList().list().execute();
} catch (IOException e) {
if (log.isWarnEnabled()) {
log.warn("Error fetching Calendar List, trying token refresh",
e);
}
credential.refreshToken();
if (log.isInfoEnabled()) {
log.info("Successfully refreshed Google Security Token.");
}
calendarList = service.calendarList().list().execute();
}
return calendarList.getItems();
}
private final class FetchEventsRunner implements Runnable {
private final List<Event> events;
private final long oldest;
private String colorClass;
private List<CalendarListEntry> items;
private String summary;
private FetchEventsRunner(List<CalendarListEntry> items, String summary,
List<Event> events, long oldest, String colorClass) {
this.events = events;
this.oldest = oldest;
this.items = items;
this.summary = summary;
this.colorClass = colorClass;
}
@Override
public void run() {
try {
log.debug("Fetching events of calendar \"" + summary + "\"");
Calendar calendar = getCalendarBySummaryName(items, summary);
DateTime timeMin = new DateTime(oldest);
List<Event> items = service.events().list(calendar.getId())
.setTimeMin(timeMin).execute().getItems();
items.forEach(item -> item.set("colorClass", colorClass));
events.addAll(items);
log.debug("Added " + items.size() + " Events for \"" + summary
+ "\"");
} catch (IOException e) {
log.error("Unable to fetch Events from " + summary, e);
}
}
}
static Event createDefaultEvent(String summary) {
Event ev = new Event().setGuestsCanInviteOthers(false)
.setGuestsCanModify(false).setGuestsCanSeeOtherGuests(true)
.setSummary(summary);
List<EventAttendee> attendees = new ArrayList<>();
ev.setAttendees(attendees);
return ev;
}
}

@ -0,0 +1,81 @@
package de.kreth.clubhelperbackend.google.calendar;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
public class CalendarResource {
private Map<String, CalendarKonfig> configs;
public CalendarResource() throws IOException {
configs = new HashMap<>();
InputStream resStream = getClass()
.getResourceAsStream("/calendars.properties");
Properties prop = new Properties();
prop.load(resStream);
Enumeration<Object> keys = prop.keys();
String className = getClass().getName();
String packageName = className.substring(0, className.lastIndexOf('.'));
while (keys.hasMoreElements()) {
String key = keys.nextElement().toString();
String name = key.substring(packageName.length());
String value = prop.getProperty(key);
StringTokenizer tok = new StringTokenizer(name, ".");
name = tok.nextToken();
String type = tok.nextToken();
CalendarKonfig conf;
if (configs.containsKey(name)) {
conf = configs.get(name);
} else {
conf = new CalendarKonfig(null, null);
configs.put(name, conf);
}
switch (type) {
case "name" :
conf.name = value;
break;
case "color" :
conf.color = value;
default :
break;
}
}
}
public List<CalendarKonfig> getConfigs() {
return new ArrayList<>(configs.values());
}
public class CalendarKonfig {
private String name;
private String color;
CalendarKonfig(String name, String color) {
super();
this.name = name;
this.color = color;
}
public String getName() {
return name;
}
public String getColor() {
return color;
}
}
}

@ -0,0 +1,83 @@
package de.kreth.clubhelperbackend.google.calendar;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import org.vaadin.addon.calendar.item.BasicItem;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.EventDateTime;
public class ClubEvent extends BasicItem {
private static final long serialVersionUID = -3600971939167437577L;
ClubEvent() {
}
public static ClubEvent parse(Event ev) {
ClubEvent clubEvent = new ClubEvent();
clubEvent.setCaption(ev.getSummary());
clubEvent.setStart(toZoned(parse(ev.getStart())));
if (clubEvent.getStart() == null) {
clubEvent.setStart(toZoned(parse(ev.getOriginalStartTime())));
}
clubEvent.setEnd(toZoned(adjustExcludedEndDate(ev)));
clubEvent.setDescription(ev.getDescription());
return clubEvent;
}
private static ZonedDateTime toZoned(Date parse) {
if (parse != null) {
Instant instant = parse.toInstant();
return ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
} else {
return null;
}
}
public static Date parse(EventDateTime date) {
if (date != null) {
if (date.getDateTime() != null) {
return new Date(date.getDateTime().getValue());
} else if (date.getDate() != null) {
return new Date(date.getDate().getValue());
}
}
return null;
}
public static Date adjustExcludedEndDate(
com.google.api.services.calendar.model.Event e) {
if (e.isEndTimeUnspecified() == false) {
EventDateTime end = e.getEnd();
GregorianCalendar calendar = new GregorianCalendar();
calendar.setTimeInMillis(end.getDate() != null
? end.getDate().getValue()
: end.getDateTime().getValue());
if (startIsDateOnly(e)) {
calendar.add(Calendar.DAY_OF_MONTH, -1);
}
return calendar.getTime();
}
return null;
}
public static boolean startIsDateOnly(
com.google.api.services.calendar.model.Event e) {
EventDateTime start = e.getStart();
if (start == null) {
start = e.getOriginalStartTime();
}
return (start.getDate() != null || (start.getDateTime() != null
&& start.getDateTime().isDateOnly()));
}
}

@ -0,0 +1,46 @@
package de.kreth.vaadin.clubhelper.vaadinclubhelper.dao;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.vaadin.server.VaadinRequest;
import de.kreth.clubhelperbackend.google.calendar.CalendarAdapter;
import de.kreth.clubhelperbackend.google.calendar.ClubEvent;
public class EventBusiness {
private final List<ClubEvent> cache = new ArrayList<>();
public List<ClubEvent> loadEvents(VaadinRequest request) {
if (cache.isEmpty() == false) {
return Collections.unmodifiableList(cache);
}
cache.clear();
try {
// String remoteHost = request.getRemoteHost();
String remoteHost = "localhost";
CalendarAdapter adapter = new CalendarAdapter();
List<com.google.api.services.calendar.model.Event> events = adapter
.getAllEvents(remoteHost);
for (com.google.api.services.calendar.model.Event ev : events) {
if ("cancelled".equals(ev.getStatus()) == false) {
cache.add(ClubEvent.parse(ev));
} else {
System.out.println("Cancelled: " + ev.getSummary());
}
}
} catch (GeneralSecurityException | IOException
| InterruptedException e) {
e.printStackTrace();
}
return Collections.unmodifiableList(cache);
}
}

@ -1,15 +1,26 @@
package de.kreth.vaadin.clubhelper.vaadinclubhelper.ui;
import java.time.LocalDateTime;
import java.time.Month;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.springframework.beans.factory.annotation.Autowired;
import org.vaadin.addon.calendar.Calendar;
import org.vaadin.addon.calendar.item.BasicItemProvider;
import org.vaadin.addon.calendar.ui.CalendarComponentEvents;
import com.vaadin.server.VaadinRequest;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Notification;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import de.kreth.clubhelperbackend.google.calendar.ClubEvent;
import de.kreth.vaadin.clubhelper.vaadinclubhelper.dao.EventBusiness;
import de.kreth.vaadin.clubhelper.vaadinclubhelper.dao.PersonDao;
import de.kreth.vaadin.clubhelper.vaadinclubhelper.data.Person;
import de.kreth.vaadin.clubhelper.vaadinclubhelper.ui.components.PersonGrid;
@ -20,10 +31,12 @@ public class MainUi extends UI {
private static final long serialVersionUID = 7581634188909841919L;
@Autowired
PersonDao dao;
private ClubEventProvider dataProvider;
@Override
protected void init(VaadinRequest request) {
VerticalLayout layout = new VerticalLayout();
HorizontalLayout layout = new HorizontalLayout();
layout.addComponent(new Label("Persons found:"));
List<Person> persons = dao.list();
@ -31,8 +44,40 @@ public class MainUi extends UI {
grid.setItems(persons);
grid.setCaption("Person Grid");
layout.addComponent(grid);
dataProvider = new ClubEventProvider();
Calendar<ClubEvent> calendar = new Calendar<>(dataProvider)
.withMonth(Month.from(LocalDateTime.now()));
calendar.setCaption("Events");
calendar.setHandler(this::onItemClick);
layout.addComponents(grid, calendar);
setContent(layout);
ExecutorService exec = Executors.newSingleThreadExecutor();
exec.execute(() -> {
EventBusiness business = new EventBusiness();
List<ClubEvent> events = business.loadEvents(request);
dataProvider.setItems(events);
System.out.println("Updated data: " + events);
});
exec.shutdown();
}
private void onItemClick(CalendarComponentEvents.ItemClickEvent event) {
ClubEvent ev = (ClubEvent) event.getCalendarItem();
Notification.show("Clicked: " + ev);
}
class ClubEventProvider extends BasicItemProvider<ClubEvent> {
private static final long serialVersionUID = -5415397258827236704L;
@Override
public void setItems(Collection<ClubEvent> items) {
super.setItems(items);
fireItemSetChanged();
}
}
}

@ -1,3 +1,6 @@
spring.datasource.url=jdbc:mysql://192.168.0.8:3306/clubhelper
spring.datasource.username=markus
spring.datasource.password=0773
security.ignored=/**
security.basic.enable: false
management.security.enabled: false

@ -0,0 +1,6 @@
de.kreth.clubhelperbackend.google.calendar.1.name=mtv_wettkampf
de.kreth.clubhelperbackend.google.calendar.1.color=color1
de.kreth.clubhelperbackend.google.calendar.2.name=mtv_allgemein
de.kreth.clubhelperbackend.google.calendar.2.color=color2
de.kreth.clubhelperbackend.google.calendar.3.name=Schulferien
de.kreth.clubhelperbackend.google.calendar.3.color=color3

@ -0,0 +1,13 @@
{
"web": {
"client_id": "18873888282-iptk63468sf4to7ajihqmq1l5ggkq54o.apps.googleusercontent.com",
"project_id": "clubhelper",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "RxtsmNfj6CmQOX_4enrOl9aM",
"redirect_uris": [
"http://localhost:59431/Callback"
]
}
}
Loading…
Cancel
Save