Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ atlassian-ide-plugin.xml

# OSX
.DS_Store
/.nb-gradle/private/
/.nb-gradle/private/
/bin/
.classpath
11 changes: 8 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'eclipse'
apply plugin: 'eclipse-wtp'
apply plugin: 'sonar-runner'

sourceCompatibility = 1.8
version = '1.0'
project.ext {
springVersion = '4.0.5.RELEASE'
springSecurityVersion = '3.2.3.RELEASE'
jacksonVersion ='2.4.2'
}
compileJava.options.encoding = 'UTF-8'
eclipse.classpath.downloadJavadoc = true

repositories {
mavenCentral()
Expand Down Expand Up @@ -47,8 +51,8 @@ dependencies {

//web
compile "org.springframework:spring-webmvc:$project.springVersion"
compile "com.fasterxml.jackson.core:jackson-databind:2.3.1"
compile "org.codehaus.jackson:jackson-core-asl:1.9.13"
compile "com.fasterxml.jackson.core:jackson-databind:$project.jacksonVersion"
compile "com.fasterxml.jackson.core:jackson-core:$project.jacksonVersion"
compile "javax.servlet:jstl:1.2"
compile "org.springframework.data:spring-data-rest-webmvc:2.1.0.RELEASE"
compile "org.webjars:bootstrap:3.1.1"
Expand Down Expand Up @@ -80,7 +84,7 @@ dependencies {
compile "postgresql:postgresql:9.1-901.jdbc4"
compile "org.springframework.data:spring-data-jpa:1.6.0.RELEASE"
compile "org.springframework:spring-orm:$project.springVersion"
compile "org.hibernate:hibernate-entitymanager:4.1.8.Final"
compile "org.hibernate:hibernate-entitymanager:4.3.6.Final"
compile "org.hibernate:hibernate-validator:4.3.1.Final"
//needed because java 8 compability
compile "org.javassist:javassist:3.18.1-GA"
Expand All @@ -97,6 +101,7 @@ dependencies {
testCompile("org.echocat.jomon:testing:1.4.3") {
exclude group: "org.mockito"
}
testCompile "org.hamcrest:hamcrest-all:1.3"
testCompile "org.mockito:mockito-core:1.9.5"
testCompile "com.jayway.jsonpath:json-path:0.9.1"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.Map;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,14 @@
package de.techdev.trackr.core.web.api;

import de.techdev.trackr.core.web.converters.DateConverter;
import de.techdev.trackr.domain.ApiBeansConfiguration;
import de.techdev.trackr.domain.common.StringToEntityConverter;
import de.techdev.trackr.domain.common.TrackrUserLocaleResolver;
import de.techdev.trackr.domain.company.Address;
import de.techdev.trackr.domain.company.Company;
import de.techdev.trackr.domain.company.ContactPerson;
import de.techdev.trackr.domain.employee.Employee;
import de.techdev.trackr.domain.employee.expenses.TravelExpense;
import de.techdev.trackr.domain.employee.expenses.reports.Report;
import de.techdev.trackr.domain.employee.expenses.reports.comments.Comment;
import de.techdev.trackr.domain.employee.login.Authority;
import de.techdev.trackr.domain.employee.login.Credential;
import de.techdev.trackr.domain.employee.sickdays.SickDays;
import de.techdev.trackr.domain.employee.vacation.VacationRequest;
import de.techdev.trackr.domain.project.billtimes.BillableTime;
import de.techdev.trackr.domain.project.Project;
import de.techdev.trackr.domain.project.worktimes.WorkTime;
import de.techdev.trackr.domain.project.invoice.Invoice;
import java.time.LocalDate;
import java.util.List;

import org.springframework.context.MessageSource;
import org.springframework.context.annotation.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.Import;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.support.ConfigurableConversionService;
Expand All @@ -37,7 +25,29 @@
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;

import de.techdev.trackr.core.web.converters.DateConverter;
import de.techdev.trackr.core.web.converters.LocalDateConverter;
import de.techdev.trackr.core.web.converters.TimePropertiesToJson;
import de.techdev.trackr.domain.ApiBeansConfiguration;
import de.techdev.trackr.domain.common.StringToEntityConverter;
import de.techdev.trackr.domain.common.TrackrUserLocaleResolver;
import de.techdev.trackr.domain.company.Address;
import de.techdev.trackr.domain.company.Company;
import de.techdev.trackr.domain.company.ContactPerson;
import de.techdev.trackr.domain.employee.Employee;
import de.techdev.trackr.domain.employee.expenses.TravelExpense;
import de.techdev.trackr.domain.employee.expenses.reports.Report;
import de.techdev.trackr.domain.employee.expenses.reports.comments.Comment;
import de.techdev.trackr.domain.employee.login.Authority;
import de.techdev.trackr.domain.employee.login.Credential;
import de.techdev.trackr.domain.employee.sickdays.SickDays;
import de.techdev.trackr.domain.employee.vacation.VacationRequest;
import de.techdev.trackr.domain.project.Project;
import de.techdev.trackr.domain.project.billtimes.BillableTime;
import de.techdev.trackr.domain.project.invoice.Invoice;
import de.techdev.trackr.domain.project.worktimes.WorkTime;

/**
* @author Moritz Schulze
Expand Down Expand Up @@ -69,12 +79,15 @@ protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration
public EntityLinks entityLinks() {
return new RepositoryEntityLinksWithoutProjection(repositories(), resourceMappings(), config(), pageableResolver(), backendIdConverterRegistry());
}



@Bean
public LocaleResolver localeResolver() {
return new TrackrUserLocaleResolver();
}



@Bean
public ExceptionHandlers exceptionHandlers() {
return new ExceptionHandlers();
Expand All @@ -84,6 +97,11 @@ public ExceptionHandlers exceptionHandlers() {
public DateConverter dateConverter() {
return new DateConverter();
}

@Bean
public Converter<String, LocalDate> localDateConverter() {
return new LocalDateConverter();
}

@Bean
public Converter<String, Invoice> stringInvoiceConverter() {
Expand All @@ -109,13 +127,15 @@ public Converter<String, Employee> employeeConverter() {
protected void configureConversionService(ConfigurableConversionService conversionService) {
super.configureConversionService(conversionService);
conversionService.addConverter(dateConverter());
conversionService.addConverter(localDateConverter());
}

/**
* Somehow the "normal" Spring MVC (not spring-data-rest) does not use the converter registered in {@link #configureConversionService} so we have to register it again.
*/
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(localDateConverter());
registry.addConverter(dateConverter());
registry.addConverter(stringInvoiceConverter());
registry.addConverter(vacationRequestConverter());
Expand Down Expand Up @@ -153,6 +173,18 @@ protected void configureValidatingRepositoryEventListener(ValidatingRepositoryEv
validatingListener.addValidator("beforeCreate", validator());
}


@Override
protected void configureJacksonObjectMapper(ObjectMapper objectMapper) {
super.configureJacksonObjectMapper(objectMapper);
objectMapper.registerModule(localDateTimeModule());
}

@Bean
public TimePropertiesToJson localDateTimeModule() {
return new TimePropertiesToJson();
}

/**
* Custom validator that extracts messages with locale. Used by spring-data-rest.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package de.techdev.trackr.core.web.converters;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;


public class JsonModuleSupport extends SimpleModule {

/**
*
*/
private static final long serialVersionUID = 1L;

public interface SerializeInterface<T> {
public void serialize(T value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonGenerationException;
}

public interface DeserializerInterface<T> {
public T deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException;
}

public JsonModuleSupport() {
super();
}

public JsonModuleSupport(String name) {
super(name);
}

public JsonModuleSupport(Version version) {
super(version);
}

public JsonModuleSupport(String name, Version version) {
super(name, version);
}

public JsonModuleSupport(String name, Version version,
Map<Class<?>, JsonDeserializer<?>> deserializers) {
super(name, version, deserializers);
}

public JsonModuleSupport(String name, Version version,
List<JsonSerializer<?>> serializers) {
super(name, version, serializers);
}

public JsonModuleSupport(String name, Version version,
Map<Class<?>, JsonDeserializer<?>> deserializers,
List<JsonSerializer<?>> serializers) {
super(name, version, deserializers, serializers);
}

public <T> void addSerializer(Class<T> type, SerializeInterface<T> serializer) {
addSerializer(translateToSerializer(type, serializer));
}

public <T> void addDeserializer(Class<T> type, DeserializerInterface<T> deserializer) {
addDeserializer(type, translateToDeserializer(type, deserializer));
}

private <T> JsonSerializer<T> translateToSerializer(Class<T> type, SerializeInterface<T> serializer) {
return new StdSerializer<T>(type) {

@Override
public void serialize(T value, JsonGenerator jgen,
SerializerProvider provider) throws IOException,
JsonGenerationException {
serializer.serialize(value, jgen, provider);

}
};
}

private <T> JsonDeserializer<T> translateToDeserializer(Class<T> type, DeserializerInterface<T> deserializer) {
return new StdDeserializer<T>(type) {

/**
* auto generated
*/
private static final long serialVersionUID = 1L;

@Override
public T deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
return deserializer.deserialize(jp, ctxt);
}

};
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package de.techdev.trackr.core.web.converters;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

import org.springframework.core.convert.converter.Converter;

/**
* A {@link java.util.Date} converter that supports the formats yyyy-MM-dd and yyyy-MM-dd HH:mm:ss.
*
* @author Moritz Schulze
*/
public class LocalDateConverter implements Converter<String, LocalDate> {

private DateTimeFormatter date10;

private DateTimeFormatter date19;

public LocalDateConverter() {
date10 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
date19 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
}

@Override
public LocalDate convert(String source) {
if(source == null) {
return null;
}
LocalDate date;
try {
Long milliSeconds = Long.valueOf(source);
Instant instant = Instant.ofEpochMilli(milliSeconds);
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).toLocalDate();
} catch (NumberFormatException e) {
//Continue with other formats
}
if(source.length() == 10) {
try {
date = LocalDate.parse(source,date10);
} catch (DateTimeParseException e) {
throw new IllegalArgumentException(String.format("%s is not a valid yyyy-MM-dd date.", source));
}
} else if(source.length() == 19) {
try {
date = LocalDate.parse(source,date19);
} catch (DateTimeParseException e) {
throw new IllegalArgumentException(String.format("%s is not a valid yyyy-MM-dd HH:mm:ss date.", source));
}
} else {
throw new IllegalArgumentException(String.format("%s is not convertible by this Date converter", source));
}
return date;
}
}
Loading