Embed dropwizard jersey module. Add jackson

serialization/deserialization support for Hibernate.
This commit is contained in:
robin shine 2013-10-11 23:35:58 +08:00
parent d7c32e3d4f
commit 26535f960a
51 changed files with 1210 additions and 163 deletions

View File

@ -24,6 +24,10 @@
<module>../commons.wicket</module>
<module>../gitop.product</module>
<module>../gitop.web</module>
<module>../commons.jackson</module>
<module>../commons.metrics</module>
<module>../commons.validation</module>
<module>../gitop.rest</module>
</modules>
<repositories>
<repository>

View File

@ -34,19 +34,9 @@
<version>1.0.29</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.0.1.Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
<version>2.2.1-b04</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>el-impl</artifactId>
<version>2.2.1-b05</version>
<groupId>com.pmease</groupId>
<artifactId>commons.validation</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>

View File

@ -1,8 +1,5 @@
package com.pmease.commons.editable;
import javax.validation.Validation;
import javax.validation.Validator;
import com.pmease.commons.loader.AbstractPluginModule;
/**
@ -15,8 +12,6 @@ public class EditableModule extends AbstractPluginModule {
protected void configure() {
super.configure();
bind(Validator.class).toInstance(Validation.buildDefaultValidatorFactory().getValidator());
// put your guice bindings here
}

View File

@ -76,6 +76,16 @@
<artifactId>jtds</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>commons.jackson</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate4</artifactId>
<version>${jacksonVersion}</version>
</dependency>
</dependencies>
<repositories>
<repository>

View File

@ -13,6 +13,7 @@ import com.google.inject.name.Names;
import com.google.inject.util.Providers;
import com.pmease.commons.hibernate.dao.DefaultGeneralDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.commons.jackson.ObjectMapperConfigurator;
import com.pmease.commons.loader.AbstractPlugin;
import com.pmease.commons.loader.AbstractPluginModule;
@ -38,18 +39,15 @@ public class HibernateModule extends AbstractPluginModule {
TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
requestInjection(transactionInterceptor);
bindInterceptor(
Matchers.any(),
Matchers.annotatedWith(Transactional.class),
transactionInterceptor);
bindInterceptor(Matchers.any(), Matchers.annotatedWith(Transactional.class), transactionInterceptor);
SessionInterceptor sessionInterceptor = new SessionInterceptor();
requestInjection(sessionInterceptor);
bindInterceptor(
Matchers.any(),
Matchers.annotatedWith(Sessional.class),
sessionInterceptor);
bindInterceptor(Matchers.any(), Matchers.annotatedWith(Sessional.class), sessionInterceptor);
contribute(ObjectMapperConfigurator.class, HibernateObjectMapperConfigurator.class);
}
@Override

View File

@ -0,0 +1,24 @@
package com.pmease.commons.hibernate;
import javax.inject.Inject;
import javax.inject.Singleton;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pmease.commons.jackson.ObjectMapperConfigurator;
@Singleton
public class HibernateObjectMapperConfigurator implements ObjectMapperConfigurator {
private final HibernateObjectMapperModule module;
@Inject
public HibernateObjectMapperConfigurator(HibernateObjectMapperModule module) {
this.module = module;
}
@Override
public void configure(ObjectMapper objectMapper) {
objectMapper.registerModule(module);
}
}

View File

@ -0,0 +1,43 @@
package com.pmease.commons.hibernate;
import javax.inject.Singleton;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.datatype.hibernate4.Hibernate4Module;
@Singleton
public class HibernateObjectMapperModule extends Hibernate4Module {
@SuppressWarnings("serial")
@Override
protected AnnotationIntrospector annotationIntrospector() {
return new AnnotationIntrospector() {
@Override
public Version version() {
return Version.unknownVersion();
}
@Override
public boolean hasIgnoreMarker(AnnotatedMember m) {
return super.hasIgnoreMarker(m) || m.hasAnnotation(OneToMany.class);
}
@Override
public Object findDeserializer(Annotated am) {
if (am.hasAnnotation(ManyToOne.class)) {
return new ManyToOneDeserializer(am.getRawType());
} else {
return super.findDeserializer(am);
}
}
};
}
}

View File

@ -0,0 +1,32 @@
package com.pmease.commons.hibernate;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.commons.loader.AppLoader;
@SuppressWarnings("serial")
public final class ManyToOneDeserializer extends StdDeserializer<AbstractEntity> {
public ManyToOneDeserializer(Class<?> entityClass) {
super(entityClass);
}
@Override
public AbstractEntity getNullValue() {
return null;
}
@SuppressWarnings("unchecked")
@Override
public AbstractEntity deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
JsonProcessingException {
String entityId = jp.readValueAsTree().get("id").toString();
Class<? extends AbstractEntity> valueClass = (Class<? extends AbstractEntity>)getValueClass();
return (AbstractEntity) AppLoader.getInstance(GeneralDao.class).load(valueClass, Long.valueOf(entityId));
}
}

76
commons.jackson/pom.xml Normal file
View File

@ -0,0 +1,76 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>commons.jackson</artifactId>
<version>1.0.0</version>
<parent>
<groupId>com.pmease</groupId>
<artifactId>parent.general</artifactId>
<version>1.0.28</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>com.pmease</groupId>
<artifactId>plugin.maven</artifactId>
</plugin>
<!-- Uncomment below if you'd like to publish an archetype based on your
plugin -->
<!--plugin> <artifactId>maven-archetype-plugin</artifactId> </plugin -->
<plugin>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>commons.loader</artifactId>
<version>1.0.29</version>
</dependency>
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-jackson</artifactId>
<version>${dropwizardVersion}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>pmeaseRepo</id>
<name>PMEase Repository</name>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
<url>http://artifact.pmease.com/</url>
</repository>
<repository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<properties>
<moduleClass>com.pmease.commons.jackson.JacksonModule</moduleClass>
</properties>
</project>

View File

@ -0,0 +1,30 @@
package com.pmease.commons.jackson;
import javax.inject.Singleton;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pmease.commons.loader.AbstractPluginModule;
/**
* NOTE: Do not forget to rename moduleClass property defined in the pom if you've renamed this class.
*
*/
public class JacksonModule extends AbstractPluginModule {
@Override
protected void configure() {
super.configure();
bind(ObjectMapper.class).toProvider(ObjectMapperProvider.class).in(Singleton.class);
// Add a dummy contribution to avoid error if no other contributions
contribute(ObjectMapperConfigurator.class, new ObjectMapperConfigurator() {
@Override
public void configure(ObjectMapper objectMapper) {
}
});
}
}

View File

@ -0,0 +1,7 @@
package com.pmease.commons.jackson;
import com.fasterxml.jackson.databind.ObjectMapper;
public interface ObjectMapperConfigurator {
void configure(ObjectMapper objectMapper);
}

View File

@ -0,0 +1,44 @@
package com.pmease.commons.jackson;
import io.dropwizard.jackson.Jackson;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
@Singleton
public class ObjectMapperProvider implements Provider<ObjectMapper> {
private final Set<ObjectMapperConfigurator> configurators;
@Inject
public ObjectMapperProvider(Set<ObjectMapperConfigurator> configurators) {
this.configurators = configurators;
}
@Override
public ObjectMapper get() {
ObjectMapper mapper = Jackson.newObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.setVisibilityChecker(mapper.getSerializationConfig().getDefaultVisibilityChecker()
.withFieldVisibility(JsonAutoDetect.Visibility.ANY)
.withGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withSetterVisibility(JsonAutoDetect.Visibility.NONE)
.withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
for (ObjectMapperConfigurator each: configurators)
each.configure(mapper);
return mapper;
}
}

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor name="archetype.plugin">
<fileSets>
<fileSet filtered="true" packaged="true">
<directory>src/main/java</directory>
</fileSet>
<fileSet filtered="false" packaged="false">
<directory>src/main/resources</directory>
</fileSet>
<fileSet filtered="false" packaged="false">
<directory>src/test/java</directory>
</fileSet>
<fileSet filtered="false" packaged="false">
<directory>src/test/resources</directory>
</fileSet>
</fileSets>
</archetype-descriptor>

View File

@ -0,0 +1,60 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
#if (\${groupId} != "com.pmease")
<groupId>\${groupId}</groupId>
#end
<artifactId>\${artifactId}</artifactId>
<version>\${version}</version>
<parent>
<groupId>com.pmease</groupId>
<artifactId>parent.general</artifactId>
<version>1.0.28</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>com.pmease</groupId>
<artifactId>plugin.maven</artifactId>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>pmeaseRepo</id>
<name>PMEase Repository</name>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
<url>http://artifact.pmease.com/</url>
</repository>
</repositories>
<properties>
<moduleClass>\${package}.PluginModule</moduleClass>
</properties>
</project>

View File

@ -0,0 +1,13 @@
package ${package};
import java.util.Collection;
import com.pmease.commons.loader.AbstractPlugin;
public class Plugin extends AbstractPlugin {
@Override
public Collection<?> getExtensions() {
return null;
}
}

View File

@ -0,0 +1,24 @@
package ${package};
import com.pmease.commons.loader.AbstractPlugin;
import com.pmease.commons.loader.AbstractPluginModule;
/**
* NOTE: Do not forget to rename moduleClass property defined in the pom if you've renamed this class.
*
*/
public class PluginModule extends AbstractPluginModule {
@Override
protected void configure() {
super.configure();
// put your guice bindings here
}
@Override
protected Class<? extends AbstractPlugin> getPluginClass() {
return Plugin.class;
}
}

View File

@ -1,69 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>commons.jersey</artifactId>
<version>1.0.0</version>
<parent>
<groupId>com.pmease</groupId>
<artifactId>parent.general</artifactId>
<version>1.0.28</version>
</parent>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>commons.jersey</artifactId>
<parent>
<groupId>com.pmease</groupId>
<artifactId>parent.general</artifactId>
<version>1.0.28</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>com.pmease</groupId>
<artifactId>plugin.maven</artifactId>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>commons.loader</artifactId>
<version>1.0.29</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>${jerseyVersion}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>${jerseyVersion}</version>
</dependency>
<build>
<plugins>
<plugin>
<groupId>com.pmease</groupId>
<artifactId>plugin.maven</artifactId>
</plugin>
<!-- Uncomment below if you'd like to publish an archetype based on your plugin -->
<!--plugin>
<artifactId>maven-archetype-plugin</artifactId>
</plugin-->
<plugin>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>commons.loader</artifactId>
<version>1.0.29</version>
</dependency>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>commons.validation</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>commons.jackson</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-jersey</artifactId>
<version>${dropwizardVersion}</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-guice</artifactId>
<artifactId>jersey-multipart</artifactId>
<version>${jerseyVersion}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>pmeaseRepo</id>
<name>PMEase Repository</name>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
<url>http://artifact.pmease.com/</url>
</repository>
</repositories>
<properties>
<moduleClass>com.pmease.commons.jersey.JerseyModule</moduleClass>
<jerseyVersion>1.17</jerseyVersion>
</properties>
<version>1.0.30</version>
</dependency>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>commons.metrics</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>pmeaseRepo</id>
<name>PMEase Repository</name>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
<url>http://artifact.pmease.com/</url>
</repository>
<repository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<properties>
<moduleClass>com.pmease.commons.jersey.JerseyModule</moduleClass>
<jerseyVersion>1.17</jerseyVersion>
</properties>
</project>

View File

@ -0,0 +1,5 @@
package com.pmease.commons.jersey;
public interface JerseyConfigurator {
void configure(JerseyEnvironment environment);
}

View File

@ -0,0 +1,55 @@
package com.pmease.commons.jersey;
import io.dropwizard.jersey.DropwizardResourceConfig;
import io.dropwizard.jersey.jackson.JacksonMessageBodyProvider;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import javax.validation.Validator;
import com.codahale.metrics.MetricRegistry;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.inject.Injector;
import com.pmease.commons.util.ClassUtils;
import com.sun.jersey.api.core.DefaultResourceConfig;
import com.sun.jersey.api.core.ResourceConfig;
@Singleton
public class JerseyEnvironment implements Provider<ResourceConfig> {
private final Injector injector;
private final DefaultResourceConfig resourceConfig;
@Inject
public JerseyEnvironment(Injector injector, MetricRegistry metricRegistry, Validator validator,
ObjectMapper objectMapper, Set<JerseyConfigurator> configurators) {
this.injector = injector;
resourceConfig = new DropwizardResourceConfig(metricRegistry);
resourceConfig.getSingletons().add(new JacksonMessageBodyProvider(objectMapper, validator));
for (JerseyConfigurator configurator: configurators)
configurator.configure(this);
}
public void addComponent(Class<?> componentClass) {
resourceConfig.getSingletons().add(injector.getInstance(componentClass));
}
public void addComponentFromPackage(Class<?> packageLocator) {
for (Class<?> each: ClassUtils.findImplementations(Object.class, packageLocator)) {
if (DefaultResourceConfig.isProviderClass(each) || DefaultResourceConfig.isRootResourceClass(each))
addComponent(each);
}
}
@Override
public ResourceConfig get() {
return resourceConfig;
}
}

View File

@ -1,18 +1,28 @@
package com.pmease.commons.jersey;
import com.pmease.commons.loader.AbstractPluginModule;
import com.sun.jersey.api.core.ResourceConfig;
/**
* NOTE: Do not forget to rename moduleClass property defined in the pom if
* you've renamed this class.
*
* NOTE: Do not forget to rename moduleClass property defined in the pom if you've renamed this class.
*
*/
public class JerseyModule extends AbstractPluginModule {
@Override
protected void configure() {
super.configure();
contribute(JerseyConfigurator.class, new JerseyConfigurator() {
@Override
public void configure(JerseyEnvironment app) {
}
});
bind(JerseyEnvironment.class);
bind(ResourceConfig.class).toProvider(JerseyEnvironment.class);
}
}

109
commons.metrics/pom.xml Normal file
View File

@ -0,0 +1,109 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>commons.metrics</artifactId>
<version>1.0.0</version>
<parent>
<groupId>com.pmease</groupId>
<artifactId>parent.general</artifactId>
<version>1.0.28</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>com.pmease</groupId>
<artifactId>plugin.maven</artifactId>
</plugin>
<!-- Uncomment below if you'd like to publish an archetype based on your plugin -->
<!--plugin>
<artifactId>maven-archetype-plugin</artifactId>
</plugin-->
<plugin>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.codahale.metrics</groupId>
<artifactId>metrics-core</artifactId>
<version>${metricsVersion}</version>
</dependency>
<dependency>
<groupId>com.codahale.metrics</groupId>
<artifactId>metrics-jvm</artifactId>
<version>${metricsVersion}</version>
</dependency>
<dependency>
<groupId>com.codahale.metrics</groupId>
<artifactId>metrics-servlets</artifactId>
<version>${metricsVersion}</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.codahale.metrics</groupId>
<artifactId>metrics-healthchecks</artifactId>
<version>${metricsVersion}</version>
</dependency>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>commons.loader</artifactId>
<version>1.0.29</version>
</dependency>
<dependency>
<groupId>com.pmease </groupId>
<artifactId>commons.validation</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-metrics</artifactId>
<version>${dropwizardVersion}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>pmeaseRepo</id>
<name>PMEase Repository</name>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
<url>http://artifact.pmease.com/</url>
</repository>
<repository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<properties>
<moduleClass>com.pmease.commons.metrics.MetricsModule</moduleClass>
<metricsVersion>3.0.1</metricsVersion>
</properties>
</project>

View File

@ -0,0 +1,28 @@
package com.pmease.commons.metrics;
import java.lang.management.ManagementFactory;
import javax.inject.Provider;
import javax.inject.Singleton;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.jvm.BufferPoolMetricSet;
import com.codahale.metrics.jvm.GarbageCollectorMetricSet;
import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
import com.codahale.metrics.jvm.ThreadStatesGaugeSet;
@Singleton
public class MetricRegistryProvider implements Provider<MetricRegistry> {
@Override
public MetricRegistry get() {
MetricRegistry registry = new MetricRegistry();
registry.register("jvm.buffers", new BufferPoolMetricSet(ManagementFactory.getPlatformMBeanServer()));
registry.register("jvm.gc", new GarbageCollectorMetricSet());
registry.register("jvm.memory", new MemoryUsageGaugeSet());
registry.register("jvm.threads", new ThreadStatesGaugeSet());
return registry;
}
}

View File

@ -0,0 +1,22 @@
package com.pmease.commons.metrics;
import javax.inject.Singleton;
import com.codahale.metrics.MetricRegistry;
import com.pmease.commons.loader.AbstractPluginModule;
/**
* NOTE: Do not forget to rename moduleClass property defined in the pom if you've renamed this class.
*
*/
public class MetricsModule extends AbstractPluginModule {
@Override
protected void configure() {
super.configure();
// put your guice bindings here
bind(MetricRegistry.class).toProvider(MetricRegistryProvider.class).in(Singleton.class);
}
}

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor name="archetype.plugin">
<fileSets>
<fileSet filtered="true" packaged="true">
<directory>src/main/java</directory>
</fileSet>
<fileSet filtered="false" packaged="false">
<directory>src/main/resources</directory>
</fileSet>
<fileSet filtered="false" packaged="false">
<directory>src/test/java</directory>
</fileSet>
<fileSet filtered="false" packaged="false">
<directory>src/test/resources</directory>
</fileSet>
</fileSets>
</archetype-descriptor>

View File

@ -0,0 +1,60 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
#if (\${groupId} != "com.pmease")
<groupId>\${groupId}</groupId>
#end
<artifactId>\${artifactId}</artifactId>
<version>\${version}</version>
<parent>
<groupId>com.pmease</groupId>
<artifactId>parent.general</artifactId>
<version>1.0.28</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>com.pmease</groupId>
<artifactId>plugin.maven</artifactId>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>pmeaseRepo</id>
<name>PMEase Repository</name>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
<url>http://artifact.pmease.com/</url>
</repository>
</repositories>
<properties>
<moduleClass>\${package}.PluginModule</moduleClass>
</properties>
</project>

View File

@ -0,0 +1,13 @@
package ${package};
import java.util.Collection;
import com.pmease.commons.loader.AbstractPlugin;
public class Plugin extends AbstractPlugin {
@Override
public Collection<?> getExtensions() {
return null;
}
}

View File

@ -0,0 +1,24 @@
package ${package};
import com.pmease.commons.loader.AbstractPlugin;
import com.pmease.commons.loader.AbstractPluginModule;
/**
* NOTE: Do not forget to rename moduleClass property defined in the pom if you've renamed this class.
*
*/
public class PluginModule extends AbstractPluginModule {
@Override
protected void configure() {
super.configure();
// put your guice bindings here
}
@Override
protected Class<? extends AbstractPlugin> getPluginClass() {
return Plugin.class;
}
}

View File

@ -74,7 +74,11 @@ public class ClassUtils extends org.apache.commons.lang3.ClassUtils {
packageDir.getAbsolutePath());
String className = packageLocator.getPackage().getName() +
StringUtils.substringBeforeLast(relativePath.replace('/', '.'), ".");
clazz = (Class<T>) superClass.getClassLoader().loadClass(className);
ClassLoader classLoader = superClass.getClassLoader();
if (classLoader == null)
classLoader = packageLocator.getClassLoader();
Preconditions.checkNotNull(classLoader);
clazz = (Class<T>) classLoader.loadClass(className);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}

View File

@ -0,0 +1,77 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>commons.validation</artifactId>
<version>1.0.0</version>
<parent>
<groupId>com.pmease</groupId>
<artifactId>parent.general</artifactId>
<version>1.0.28</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>com.pmease</groupId>
<artifactId>plugin.maven</artifactId>
</plugin>
<!-- Uncomment below if you'd like to publish an archetype based on your plugin -->
<!--plugin>
<artifactId>maven-archetype-plugin</artifactId>
</plugin-->
<plugin>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>commons.loader</artifactId>
<version>1.0.29</version>
</dependency>
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-validation</artifactId>
<version>${dropwizardVersion}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>pmeaseRepo</id>
<name>PMEase Repository</name>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
<url>http://artifact.pmease.com/</url>
</repository>
<repository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<properties>
<moduleClass>com.pmease.commons.validation.ValidationModule</moduleClass>
</properties>
</project>

View File

@ -5,7 +5,7 @@
*
* Revision: $Id: PathElement.java 1209 2008-07-28 00:16:18Z robin $
*/
package com.pmease.commons.editable.annotation;
package com.pmease.commons.validation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@ -17,8 +17,6 @@ import javax.validation.Payload;
import org.hibernate.validator.constraints.NotEmpty;
import com.pmease.commons.editable.NameValidator;
/**
* @author robin
*/

View File

@ -1,9 +1,8 @@
package com.pmease.commons.editable;
package com.pmease.commons.validation;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import com.pmease.commons.editable.annotation.Name;
import com.pmease.commons.util.StringUtils;
public class NameValidator implements ConstraintValidator<Name, String> {

View File

@ -0,0 +1,21 @@
package com.pmease.commons.validation;
import javax.validation.Validation;
import javax.validation.Validator;
import com.pmease.commons.loader.AbstractPluginModule;
/**
* NOTE: Do not forget to rename moduleClass property defined in the pom if you've renamed this class.
*
*/
public class ValidationModule extends AbstractPluginModule {
@Override
protected void configure() {
super.configure();
bind(Validator.class).toInstance(Validation.buildDefaultValidatorFactory().getValidator());
}
}

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<archetype-descriptor name="archetype.plugin">
<fileSets>
<fileSet filtered="true" packaged="true">
<directory>src/main/java</directory>
</fileSet>
<fileSet filtered="false" packaged="false">
<directory>src/main/resources</directory>
</fileSet>
<fileSet filtered="false" packaged="false">
<directory>src/test/java</directory>
</fileSet>
<fileSet filtered="false" packaged="false">
<directory>src/test/resources</directory>
</fileSet>
</fileSets>
</archetype-descriptor>

View File

@ -0,0 +1,60 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
#if (\${groupId} != "com.pmease")
<groupId>\${groupId}</groupId>
#end
<artifactId>\${artifactId}</artifactId>
<version>\${version}</version>
<parent>
<groupId>com.pmease</groupId>
<artifactId>parent.general</artifactId>
<version>1.0.28</version>
</parent>
<build>
<plugins>
<plugin>
<groupId>com.pmease</groupId>
<artifactId>plugin.maven</artifactId>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>pmeaseRepo</id>
<name>PMEase Repository</name>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
<url>http://artifact.pmease.com/</url>
</repository>
</repositories>
<properties>
<moduleClass>\${package}.PluginModule</moduleClass>
</properties>
</project>

View File

@ -0,0 +1,13 @@
package ${package};
import java.util.Collection;
import com.pmease.commons.loader.AbstractPlugin;
public class Plugin extends AbstractPlugin {
@Override
public Collection<?> getExtensions() {
return null;
}
}

View File

@ -0,0 +1,24 @@
package ${package};
import com.pmease.commons.loader.AbstractPlugin;
import com.pmease.commons.loader.AbstractPluginModule;
/**
* NOTE: Do not forget to rename moduleClass property defined in the pom if you've renamed this class.
*
*/
public class PluginModule extends AbstractPluginModule {
@Override
protected void configure() {
super.configure();
// put your guice bindings here
}
@Override
protected Class<? extends AbstractPlugin> getPluginClass() {
return Plugin.class;
}
}

View File

@ -62,7 +62,7 @@ public class User extends AbstractUser implements ProtectedObject {
private Collection<Vote> votes = new ArrayList<Vote>();
@OneToMany(mappedBy="voter")
private Collection<VoteInvitation> voteVitations = new ArrayList<VoteInvitation>();
private Collection<VoteInvitation> voteInvitations = new ArrayList<VoteInvitation>();
@Editable(order=100)
@UserName
@ -156,19 +156,11 @@ public class User extends AbstractUser implements ProtectedObject {
}
public Collection<VoteInvitation> getVoteInvitations() {
return voteVitations;
return voteInvitations;
}
public void setVoteInvitations(Collection<VoteInvitation> voteInvitations) {
this.voteVitations = voteInvitations;
}
public Collection<VoteInvitation> getVoteVitations() {
return voteVitations;
}
public void setVoteVitations(Collection<VoteInvitation> voteVitations) {
this.voteVitations = voteVitations;
this.voteInvitations = voteInvitations;
}
@Override

View File

@ -8,7 +8,7 @@ import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import com.pmease.commons.editable.annotation.Name;
import com.pmease.commons.validation.Name;
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)

View File

@ -8,7 +8,7 @@ import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import com.pmease.commons.editable.annotation.Name;
import com.pmease.commons.validation.Name;
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)

View File

@ -108,11 +108,6 @@
<artifactId>gitop.web</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>commons.jersey</artifactId>
<version>1.0.30</version>
</dependency>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>gitop.rest</artifactId>

View File

@ -30,6 +30,11 @@
<artifactId>gitop.core</artifactId>
<version>1.0.30</version>
</dependency>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>commons.jersey</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<repositories>
@ -52,6 +57,7 @@
<properties>
<moduleClass>com.pmease.gitop.rest.RestModule</moduleClass>
<jerseyVersion>1.17</jerseyVersion>
</properties>
</project>

View File

@ -2,8 +2,12 @@ package com.pmease.gitop.rest;
import org.apache.shiro.web.filter.mgt.FilterChainManager;
import com.pmease.commons.jersey.JerseyConfigurator;
import com.pmease.commons.jersey.JerseyEnvironment;
import com.pmease.commons.jetty.ServletConfigurator;
import com.pmease.commons.loader.AbstractPluginModule;
import com.pmease.commons.shiro.FilterChainConfigurator;
import com.pmease.gitop.rest.resource.UserResource;
/**
* NOTE: Do not forget to rename moduleClass property defined in the pom if you've renamed this class.
@ -11,19 +15,31 @@ import com.pmease.commons.shiro.FilterChainConfigurator;
*/
public class RestModule extends AbstractPluginModule {
public static final String SERVLET_PATH = "/rest";
@Override
protected void configure() {
super.configure();
// put your guice bindings here
contribute(ServletConfigurator.class, RestServletConfigurator.class);
contribute(JerseyConfigurator.class, new JerseyConfigurator() {
@Override
public void configure(JerseyEnvironment environment) {
environment.addComponentFromPackage(UserResource.class);
}
});
contribute(FilterChainConfigurator.class, new FilterChainConfigurator() {
@Override
public void configure(FilterChainManager filterChainManager) {
filterChainManager.createChain("/rest/**", "noSessionCreation, authcBasic");
filterChainManager.createChain(SERVLET_PATH + "/**", "noSessionCreation, authcBasic");
}
});
}
}

View File

@ -0,0 +1,28 @@
package com.pmease.gitop.rest;
import javax.inject.Inject;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import com.pmease.commons.jetty.ServletConfigurator;
import com.sun.jersey.api.core.ResourceConfig;
import com.sun.jersey.spi.container.servlet.ServletContainer;
public class RestServletConfigurator implements ServletConfigurator {
private final ResourceConfig resourceConfig;
@Inject
public RestServletConfigurator(ResourceConfig resourceConfig) {
this.resourceConfig = resourceConfig;
}
@Override
public void configure(ServletContextHandler context) {
ServletHolder servletHolder = new ServletHolder(new ServletContainer(resourceConfig));
context.addServlet(servletHolder, RestModule.SERVLET_PATH + "/*");
}
}

View File

@ -0,0 +1,44 @@
package com.pmease.gitop.rest.resource;
import io.dropwizard.jersey.params.LongParam;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.codahale.metrics.annotation.Timed;
import com.pmease.gitop.core.manager.ProjectManager;
import com.pmease.gitop.core.model.Project;
@Path("/projects")
@Produces(MediaType.APPLICATION_JSON)
public class ProjectResource {
private final ProjectManager projectManager;
@Inject
public ProjectResource(ProjectManager projectManager) {
this.projectManager = projectManager;
}
@Path("/{projectId}")
@GET
@Timed
public Project get(@PathParam("projectId") LongParam projectId) {
Project project = projectManager.load(projectId.get());
project.getName();
project.getOwner().getRepositories().size();
return project;
}
@POST
public Long save(Project project) {
projectManager.save(project);
return project.getId();
}
}

View File

@ -0,0 +1,43 @@
package com.pmease.gitop.rest.resource;
import io.dropwizard.jersey.params.LongParam;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import com.codahale.metrics.annotation.Timed;
import com.pmease.gitop.core.manager.UserManager;
import com.pmease.gitop.core.model.User;
@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
public class UserResource {
private final UserManager userManager;
@Inject
public UserResource(UserManager userManager) {
this.userManager = userManager;
}
@GET
@Path("/{userId}")
@Timed
public User get(@PathParam("userId") LongParam userId) {
User user = userManager.load(userId.get());
user.getName();
return user;
}
@POST
public Long save(User user) {
userManager.save(user);
return user.getId();
}
}

View File

@ -55,12 +55,6 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.17</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
@ -73,16 +67,16 @@
<version>4.2</version>
</dependency>
<dependency>
<groupId>com.codahale.dropwizard</groupId>
<artifactId>dropwizard-jackson</artifactId>
<version>0.7.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>commons.jetty</artifactId>
<version>1.0.29</version>
</dependency>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>gitop.rest</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<repositories>
@ -101,19 +95,6 @@
</snapshots>
<url>http://artifact.pmease.com/</url>
</repository>
<repository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
<url>http://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<properties>

View File

@ -2,14 +2,10 @@ package com.pmease.gitop.web;
import javax.inject.Singleton;
import com.codahale.dropwizard.jackson.Jackson;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.inject.Provides;
import com.pmease.commons.jetty.ServletConfigurator;
import com.pmease.commons.loader.AbstractPluginModule;
import com.pmease.commons.wicket.AbstractWicketConfig;
import com.pmease.gitop.core.validation.UserNameReservation;
import com.pmease.gitop.web.resource.RestResourceModule;
/**
* NOTE: Do not forget to rename moduleClass property defined in the pom if you've renamed this class.
@ -27,14 +23,6 @@ public class WebModule extends AbstractPluginModule {
contribute(ServletConfigurator.class, WebServletConfigurator.class);
contribute(UserNameReservation.class, WebUserNameReservation.class);
install(new RestResourceModule());
}
@Provides
@Singleton
public ObjectMapper objectMapper() {
return Jackson.newObjectMapper();
}
}

View File

@ -42,7 +42,6 @@ public class WebUserNameReservation implements UserNameReservation {
}
reserved.add("wicket");
reserved.add("rest");
for (IRequestMapper mapper: webApp.getRequestMappers()) {
if (mapper instanceof MountedMapper || mapper instanceof ResourceMapper) {

View File

@ -1,10 +1,10 @@
package com.pmease.gitop.web.common.util;
import com.codahale.dropwizard.jackson.AnnotationSensitivePropertyNamingStrategy;
import com.codahale.dropwizard.jackson.DiscoverableSubtypeResolver;
import com.codahale.dropwizard.jackson.FuzzyEnumModule;
import com.codahale.dropwizard.jackson.GuavaExtrasModule;
import com.codahale.dropwizard.jackson.LogbackModule;
import io.dropwizard.jackson.AnnotationSensitivePropertyNamingStrategy;
import io.dropwizard.jackson.DiscoverableSubtypeResolver;
import io.dropwizard.jackson.FuzzyEnumModule;
import io.dropwizard.jackson.GuavaExtrasModule;
import io.dropwizard.jackson.LogbackModule;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;

View File

@ -20,7 +20,7 @@ import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import com.codahale.dropwizard.jackson.Jackson;
import io.dropwizard.jackson.Jackson;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

View File

@ -383,5 +383,8 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<slf4jVersion>1.7.5</slf4jVersion>
<logbackVersion>1.0.11</logbackVersion>
<dropwizardVersion>0.7.0-SNAPSHOT</dropwizardVersion>
<jerseyVersion>1.17</jerseyVersion>
<jacksonVersion>2.2.3</jacksonVersion>
</properties>
</project>