mirror of
https://github.com/theonedev/onedev.git
synced 2025-12-08 18:26:30 +00:00
Add basic editable. Refactor plugin extension point mechanism.
This commit is contained in:
parent
5920de5c9d
commit
f1e37112c5
@ -16,12 +16,20 @@
|
||||
<module>../commons.util</module>
|
||||
<module>../commons.bootstrap</module>
|
||||
<module>../commons.jetty</module>
|
||||
<module>../commons.persistence</module>
|
||||
<module>../commons.web</module>
|
||||
<module>../commons.security</module>
|
||||
<module>../commons.rest</module>
|
||||
<module>../gitop</module>
|
||||
<module>../gitop.core</module>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<module>../gitop.core</module>
|
||||
<module>../commons.editable</module>
|
||||
<module>../commons.git</module>
|
||||
<module>../commons.hibernate</module>
|
||||
<module>../commons.jersey</module>
|
||||
<module>../commons.shiro</module>
|
||||
<module>../commons.wicket</module>
|
||||
<module>../gitop.product</module>
|
||||
<module>../gitop.web</module>
|
||||
</modules>
|
||||
<repositories>
|
||||
<repository>
|
||||
|
||||
61
commons.editable/pom.xml
Normal file
61
commons.editable/pom.xml
Normal file
@ -0,0 +1,61 @@
|
||||
<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.editable</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>
|
||||
</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.editable.EditableModule</moduleClass>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,30 @@
|
||||
package com.pmease.commons.editable;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import com.pmease.commons.editable.typeconverter.TypeConverter;
|
||||
|
||||
@Singleton
|
||||
public class DefaultTypeConverterRegistry implements TypeConverterRegistry {
|
||||
|
||||
private Set<TypeConverter> typeConverters;
|
||||
|
||||
@Inject
|
||||
public DefaultTypeConverterRegistry(Set<TypeConverter> typeConverters) {
|
||||
this.typeConverters = typeConverters;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeConverter getTypeConverter(Method getter) {
|
||||
for (TypeConverter each: typeConverters) {
|
||||
if (each.accept(getter))
|
||||
return each;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.pmease.commons.editable;
|
||||
|
||||
import com.pmease.commons.editable.typeconverter.TypeConverter;
|
||||
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 EditableModule extends AbstractPluginModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
|
||||
// put your guice bindings here
|
||||
addExtensionsFromPackage(TypeConverter.class, TypeConverter.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<? extends AbstractPlugin> getPluginClass() {
|
||||
return EditablePlugin.class;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.pmease.commons.editable;
|
||||
|
||||
import java.util.Collection;
|
||||
import com.pmease.commons.loader.AbstractPlugin;
|
||||
|
||||
public class EditablePlugin extends AbstractPlugin {
|
||||
|
||||
@Override
|
||||
public Collection<?> getExtensions() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.pmease.commons.editable;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.google.inject.ImplementedBy;
|
||||
import com.pmease.commons.editable.typeconverter.TypeConverter;
|
||||
|
||||
@ImplementedBy(DefaultTypeConverterRegistry.class)
|
||||
public interface TypeConverterRegistry {
|
||||
|
||||
/**
|
||||
* Get type converter of the property given the property getter.
|
||||
* <p>
|
||||
* @param getter
|
||||
* getter of the property
|
||||
* @return
|
||||
* type converter instance for the property, or <i>null</i> if no
|
||||
* type converter matches the property getter
|
||||
*/
|
||||
TypeConverter getTypeConverter(Method getter);
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.pmease.commons.editable.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.METHOD, ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ChoiceProvider {
|
||||
String value();
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.pmease.commons.editable.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.METHOD, ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Choices {
|
||||
String[] value();
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.pmease.commons.editable.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
public @interface Editable {
|
||||
String name() default "";
|
||||
|
||||
int order() default 0;
|
||||
|
||||
String description() default "";
|
||||
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.pmease.commons.editable.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ImplementationProvider {
|
||||
Class<?> clazz() default Void.class;
|
||||
|
||||
String method();
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright PMEase (c) 2005-2008,
|
||||
* Date: Feb 24, 2008
|
||||
* Time: 4:29:05 PM
|
||||
* All rights reserved.
|
||||
*
|
||||
* Revision: $Id: Multiline.java 1209 2008-07-28 00:16:18Z robin $
|
||||
*/
|
||||
package com.pmease.commons.editable.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.METHOD, ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Multiline {
|
||||
int value() default 4;
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.pmease.commons.editable.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.METHOD, ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Numeric {
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.pmease.commons.editable.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Password {
|
||||
boolean confirmative() default false;
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package com.pmease.commons.editable.typeconverter;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class BooleanConverter implements TypeConverter {
|
||||
|
||||
public boolean accept(Method getter) {
|
||||
return getter.getReturnType() == boolean.class ||
|
||||
getter.getReturnType() == Boolean.class;
|
||||
}
|
||||
|
||||
public Object toObject(Class<?> type, String string) {
|
||||
if (string == null)
|
||||
return null;
|
||||
|
||||
if ("yes".equalsIgnoreCase(string) || "y".equalsIgnoreCase(string)
|
||||
|| "true".equalsIgnoreCase(string) || "t".equalsIgnoreCase(string))
|
||||
return Boolean.TRUE;
|
||||
|
||||
if ("no".equalsIgnoreCase(string) || "n".equalsIgnoreCase(string)
|
||||
|| "false".equalsIgnoreCase(string) || "f".equalsIgnoreCase(string))
|
||||
return Boolean.FALSE;
|
||||
|
||||
throw new ConversionException("Invalid boolean value: " + string);
|
||||
}
|
||||
|
||||
public String toString(Object obj) {
|
||||
if (obj == null)
|
||||
return null;
|
||||
|
||||
if ((Boolean)obj)
|
||||
return "yes";
|
||||
else
|
||||
return "no";
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package com.pmease.commons.editable.typeconverter;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.pmease.commons.editable.annotation.Password;
|
||||
import com.pmease.commons.util.StringUtils;
|
||||
|
||||
public class ConfirmativePasswordConverter implements TypeConverter {
|
||||
|
||||
public boolean accept(Method getter) {
|
||||
return getter.getAnnotation(Password.class) != null
|
||||
&& getter.getAnnotation(Password.class).confirmative();
|
||||
}
|
||||
|
||||
public Object toObject(Class<?> type, String string) {
|
||||
if (string != null) {
|
||||
if (string.indexOf('\n') != -1) {
|
||||
String[] parts = StringUtils.split(string, "\n");
|
||||
if (parts.length == 0) {
|
||||
return null;
|
||||
} else if (parts.length != 2 || !parts[0].equals(parts[1])) {
|
||||
throw new ConversionException("Password and it's " +
|
||||
"confirmation should be identical.");
|
||||
} else {
|
||||
if (parts[0].length() == 0)
|
||||
return null;
|
||||
else
|
||||
return parts[0];
|
||||
}
|
||||
} else {
|
||||
return string;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString(Object obj) {
|
||||
return (String) obj;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.pmease.commons.editable.typeconverter;
|
||||
|
||||
import com.pmease.commons.util.ExceptionUtils;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class ConversionException extends RuntimeException {
|
||||
public ConversionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ConversionException(String message, Object...factors) {
|
||||
super(ExceptionUtils.buildMessage(message, factors));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package com.pmease.commons.editable.typeconverter;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public class EnumConverter implements TypeConverter {
|
||||
|
||||
public boolean accept(Method getter) {
|
||||
return Enum.class.isAssignableFrom(getter.getReturnType());
|
||||
}
|
||||
|
||||
public Object toObject(Class type, String string) {
|
||||
if (string == null)
|
||||
return null;
|
||||
|
||||
try {
|
||||
return Enum.valueOf(type, string);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new ConversionException("Invalid value of enum '" +
|
||||
type.getName() + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
public String toString(Object obj) {
|
||||
if (obj == null)
|
||||
return null;
|
||||
else
|
||||
return obj.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package com.pmease.commons.editable.typeconverter;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.pmease.commons.editable.annotation.Numeric;
|
||||
|
||||
public class NumericConverter implements TypeConverter {
|
||||
|
||||
public boolean accept(Method getter) {
|
||||
Class<?> type = getter.getReturnType();
|
||||
return type == int.class || type == long.class || type == Integer.class ||
|
||||
type == Long.class || type == float.class || type == Float.class ||
|
||||
type == double.class || type == Double.class || getter.getAnnotation(Numeric.class) != null;
|
||||
}
|
||||
|
||||
public Object toObject(Class<?> type, String string) {
|
||||
if (string == null) {
|
||||
if (type == int.class || type == long.class
|
||||
|| type == float.class || type == double.class) {
|
||||
throw new ConversionException("Should not be empty.");
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (type == int.class || type == Integer.class) {
|
||||
return Integer.parseInt(string);
|
||||
} else if (type == long.class || type == Long.class) {
|
||||
return Long.parseLong(string);
|
||||
} else if (type == float.class || type == Float.class) {
|
||||
return Float.parseFloat(string);
|
||||
} else if (type == double.class || type == Double.class) {
|
||||
return Double.parseDouble(string);
|
||||
} else {
|
||||
Long.parseLong(string);
|
||||
return string;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ConversionException("Invalid numeric value.");
|
||||
}
|
||||
}
|
||||
|
||||
public String toString(Object obj) {
|
||||
if (obj == null)
|
||||
return null;
|
||||
else
|
||||
return obj.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.pmease.commons.editable.typeconverter;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.pmease.commons.editable.annotation.Password;
|
||||
|
||||
public class PasswordConverter implements TypeConverter {
|
||||
|
||||
public boolean accept(Method getter) {
|
||||
return getter.getReturnType() == String.class &&
|
||||
getter.getAnnotation(Password.class) != null &&
|
||||
!getter.getAnnotation(Password.class).confirmative();
|
||||
}
|
||||
|
||||
public Object toObject(Class<?> type, String string) {
|
||||
return string;
|
||||
}
|
||||
|
||||
public String toString(Object obj) {
|
||||
return (String) obj;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package com.pmease.commons.editable.typeconverter;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.pmease.commons.editable.annotation.Password;
|
||||
|
||||
public class StringConverter implements TypeConverter {
|
||||
|
||||
public boolean accept(Method getter) {
|
||||
if (getter.getAnnotation(Password.class) != null)
|
||||
return false;
|
||||
else
|
||||
return getter.getReturnType() == String.class;
|
||||
}
|
||||
|
||||
public Object toObject(Class<?> type, String string) {
|
||||
return string;
|
||||
}
|
||||
|
||||
public String toString(Object obj) {
|
||||
if (obj == null)
|
||||
return null;
|
||||
else
|
||||
return obj.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.pmease.commons.editable.typeconverter;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public interface TypeConverter {
|
||||
|
||||
boolean accept(Method getter);
|
||||
|
||||
String toString(Object obj);
|
||||
|
||||
Object toObject(Class<?> type, String string);
|
||||
}
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -73,11 +73,6 @@
|
||||
<artifactId>jtds</artifactId>
|
||||
<version>1.3.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.17.1-GA</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.pmease</groupId>
|
||||
<artifactId>commons.jetty</artifactId>
|
||||
|
||||
@ -3,6 +3,7 @@ package com.pmease.commons.hibernate;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
@ -15,8 +16,6 @@ import org.hibernate.cfg.NamingStrategy;
|
||||
|
||||
import com.google.inject.Provider;
|
||||
import com.pmease.commons.bootstrap.Bootstrap;
|
||||
import com.pmease.commons.hibernate.extensionpoints.ModelContribution;
|
||||
import com.pmease.commons.loader.PluginManager;
|
||||
import com.pmease.commons.util.ClassUtils;
|
||||
import com.pmease.commons.util.StringUtils;
|
||||
|
||||
@ -25,16 +24,16 @@ public class ConfigurationProvider implements Provider<Configuration> {
|
||||
|
||||
private Configuration configuration;
|
||||
|
||||
private final PluginManager pluginManager;
|
||||
private final Set<ModelProvider> modelProviders;
|
||||
|
||||
private final NamingStrategy namingStrategy;
|
||||
|
||||
private final Properties hibernateProperties;
|
||||
|
||||
@Inject
|
||||
public ConfigurationProvider(PluginManager pluginManager, NamingStrategy namingStrategy,
|
||||
public ConfigurationProvider(Set<ModelProvider> modelProviders, NamingStrategy namingStrategy,
|
||||
@Nullable @Named("hibernate") Properties hibernateProperties) {
|
||||
this.pluginManager = pluginManager;
|
||||
this.modelProviders = modelProviders;
|
||||
this.namingStrategy = namingStrategy;
|
||||
this.hibernateProperties = hibernateProperties;
|
||||
}
|
||||
@ -51,17 +50,15 @@ public class ConfigurationProvider implements Provider<Configuration> {
|
||||
|
||||
configuration = new Configuration();
|
||||
configuration.setNamingStrategy(namingStrategy);
|
||||
Collection<Class<AbstractEntity>> modelClasses =
|
||||
Collection<Class<? extends AbstractEntity>> modelClasses =
|
||||
ClassUtils.findSubClasses(AbstractEntity.class, AbstractEntity.class);
|
||||
for (Class<AbstractEntity> model: modelClasses) {
|
||||
for (Class<? extends AbstractEntity> model: modelClasses) {
|
||||
if (!Modifier.isAbstract(model.getModifiers()))
|
||||
configuration.addAnnotatedClass(model);
|
||||
}
|
||||
|
||||
Collection<ModelContribution> contributions =
|
||||
pluginManager.getExtensions(ModelContribution.class);
|
||||
for (ModelContribution contribution: contributions) {
|
||||
for (Class<? extends AbstractEntity> modelClass: contribution.getModelClasses())
|
||||
for (ModelProvider provider: modelProviders) {
|
||||
for (Class<? extends AbstractEntity> modelClass: provider.getModelClasses())
|
||||
configuration.addAnnotatedClass(modelClass);
|
||||
}
|
||||
|
||||
|
||||
@ -32,7 +32,6 @@ public class HibernateModule extends AbstractPluginModule {
|
||||
bind(Configuration.class).toProvider(ConfigurationProvider.class);
|
||||
bind(UnitOfWork.class).to(UnitOfWorkImpl.class);
|
||||
bind(Session.class).toProvider(UnitOfWorkImpl.class);
|
||||
bind(SessionProvider.class).to(UnitOfWorkImpl.class);
|
||||
|
||||
bind(GeneralDao.class).to(DefaultGeneralDao.class);
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package com.pmease.commons.hibernate;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
|
||||
@ -10,8 +12,10 @@ import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.pmease.commons.jetty.extensionpoints.ServletContextConfigurator;
|
||||
import com.pmease.commons.loader.AbstractPlugin;
|
||||
import com.pmease.commons.util.ExceptionUtils;
|
||||
|
||||
public class HibernatePlugin extends AbstractPlugin {
|
||||
|
||||
@ -19,6 +23,21 @@ public class HibernatePlugin extends AbstractPlugin {
|
||||
|
||||
private final HibernateFilter hibernateFilter;
|
||||
|
||||
private static Field typeLiteralTypeField;
|
||||
|
||||
static {
|
||||
try {
|
||||
typeLiteralTypeField = TypeLiteral.class.getDeclaredField("type");
|
||||
typeLiteralTypeField.setAccessible(true);
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(typeLiteralTypeField, Modifier.PROTECTED);
|
||||
} catch (Exception e) {
|
||||
throw ExceptionUtils.unchecked(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Inject
|
||||
public HibernatePlugin(PersistService persistService, HibernateFilter hibernateFilter) {
|
||||
this.persistService = persistService;
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
package com.pmease.commons.hibernate;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface ModelProvider {
|
||||
Collection<Class<? extends AbstractEntity>> getModelClasses();
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
package com.pmease.commons.hibernate;
|
||||
|
||||
import javax.inject.Provider;
|
||||
|
||||
import org.hibernate.Session;
|
||||
|
||||
public interface SessionProvider extends Provider<Session> {
|
||||
|
||||
}
|
||||
@ -11,7 +11,7 @@ import com.google.inject.Provider;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
@Singleton
|
||||
public class UnitOfWorkImpl implements UnitOfWork, Provider<Session>, SessionProvider {
|
||||
public class UnitOfWorkImpl implements UnitOfWork, Provider<Session> {
|
||||
|
||||
private final Provider<SessionFactory> sessionFactoryProvider;
|
||||
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
package com.pmease.commons.hibernate.extensionpoints;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.pmease.commons.hibernate.AbstractEntity;
|
||||
|
||||
public interface ModelContribution {
|
||||
Collection<Class<? extends AbstractEntity>> getModelClasses();
|
||||
}
|
||||
@ -3,6 +3,7 @@ package com.pmease.commons.jetty;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.Filter;
|
||||
@ -24,7 +25,6 @@ import com.pmease.commons.bootstrap.BootstrapUtils;
|
||||
import com.pmease.commons.jetty.extensionpoints.ServerConfigurator;
|
||||
import com.pmease.commons.jetty.extensionpoints.ServletContextConfigurator;
|
||||
import com.pmease.commons.loader.AbstractPlugin;
|
||||
import com.pmease.commons.loader.PluginManager;
|
||||
|
||||
public class JettyPlugin extends AbstractPlugin {
|
||||
|
||||
@ -32,11 +32,16 @@ public class JettyPlugin extends AbstractPlugin {
|
||||
|
||||
private ServletContextHandler context;
|
||||
|
||||
private final PluginManager pluginManager;
|
||||
private final Set<ServerConfigurator> serverConfigurators;
|
||||
|
||||
private final Set<ServletContextConfigurator> servletContextConfigurators;
|
||||
|
||||
@Inject
|
||||
public JettyPlugin(PluginManager pluginManager) {
|
||||
this.pluginManager = pluginManager;
|
||||
public JettyPlugin(
|
||||
Set<ServerConfigurator> serverConfigurators,
|
||||
Set<ServletContextConfigurator> servletContextConfigurators) {
|
||||
this.serverConfigurators = serverConfigurators;
|
||||
this.servletContextConfigurators = servletContextConfigurators;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -75,8 +80,6 @@ public class JettyPlugin extends AbstractPlugin {
|
||||
|
||||
context.addFilter(DisableTraceFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
|
||||
|
||||
Collection<ServletContextConfigurator> servletContextConfigurators =
|
||||
pluginManager.getExtensions(ServletContextConfigurator.class);
|
||||
for (ServletContextConfigurator configurator: servletContextConfigurators)
|
||||
configurator.configure(context);
|
||||
|
||||
@ -89,9 +92,7 @@ public class JettyPlugin extends AbstractPlugin {
|
||||
|
||||
server.setHandler(context);
|
||||
|
||||
Collection<ServerConfigurator> servletContainerConfigurators =
|
||||
pluginManager.getExtensions(ServerConfigurator.class);
|
||||
for (ServerConfigurator configurator: servletContainerConfigurators)
|
||||
for (ServerConfigurator configurator: serverConfigurators)
|
||||
configurator.configure(server);
|
||||
|
||||
return server;
|
||||
|
||||
@ -52,7 +52,11 @@
|
||||
<groupId>com.google.inject.extensions</groupId>
|
||||
<artifactId>guice-multibindings</artifactId>
|
||||
<version>${guiceVersion}</version>
|
||||
</dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
@ -72,7 +76,7 @@
|
||||
</repository>
|
||||
</repositories>
|
||||
<properties>
|
||||
<guiceVersion>3.0</guiceVersion>
|
||||
<guiceVersion>4.0-beta</guiceVersion>
|
||||
</properties>
|
||||
<version>1.0.29</version>
|
||||
</project>
|
||||
|
||||
@ -11,6 +11,7 @@ import com.google.inject.multibindings.Multibinder;
|
||||
import com.google.inject.spi.InjectionListener;
|
||||
import com.google.inject.spi.TypeEncounter;
|
||||
import com.google.inject.spi.TypeListener;
|
||||
import com.pmease.commons.util.ClassUtils;
|
||||
import com.pmease.commons.util.dependency.Dependency;
|
||||
|
||||
public abstract class AbstractPluginModule extends AbstractModule implements Dependency {
|
||||
@ -31,8 +32,7 @@ public abstract class AbstractPluginModule extends AbstractModule implements Dep
|
||||
protected void configure() {
|
||||
final Class<? extends AbstractPlugin> pluginClass = getPluginClass();
|
||||
if (pluginClass != null) {
|
||||
Multibinder<AbstractPlugin> pluginBinder = Multibinder.newSetBinder(binder(), AbstractPlugin.class);
|
||||
pluginBinder.addBinding().to(pluginClass).in(Singleton.class);
|
||||
addExtension(AbstractPlugin.class, pluginClass);
|
||||
|
||||
bindListener(new AbstractMatcher<TypeLiteral<?>>() {
|
||||
|
||||
@ -101,4 +101,16 @@ public abstract class AbstractPluginModule extends AbstractModule implements Dep
|
||||
return pluginDependencies;
|
||||
}
|
||||
|
||||
protected <T> void addExtension(Class<T> extensionPoint, Class<? extends T> extensionClass) {
|
||||
Multibinder<T> pluginBinder = Multibinder.newSetBinder(binder(), extensionPoint);
|
||||
pluginBinder.addBinding().to(extensionClass).in(Singleton.class);
|
||||
}
|
||||
|
||||
protected <T> void addExtensionsFromPackage(Class<T> extensionPoint, Class<?> packageLocator) {
|
||||
for (Class<? extends T> subClass: ClassUtils.findSubClasses(extensionPoint, packageLocator)) {
|
||||
if (ClassUtils.isConcrete(subClass))
|
||||
addExtension(extensionPoint, subClass);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -8,6 +8,16 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import javassist.ClassClassPath;
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.CtConstructor;
|
||||
import javassist.bytecode.SignatureAttribute.ClassSignature;
|
||||
import javassist.bytecode.SignatureAttribute.ClassType;
|
||||
import javassist.bytecode.SignatureAttribute.TypeArgument;
|
||||
import javassist.bytecode.SignatureAttribute.TypeParameter;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -15,11 +25,14 @@ import org.slf4j.LoggerFactory;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.util.Modules;
|
||||
import com.google.inject.util.Modules.OverriddenModuleBuilder;
|
||||
import com.pmease.commons.bootstrap.Bootstrap;
|
||||
import com.pmease.commons.bootstrap.Lifecycle;
|
||||
import com.pmease.commons.util.ExceptionUtils;
|
||||
import com.pmease.commons.util.FileUtils;
|
||||
import com.pmease.commons.util.StringUtils;
|
||||
import com.pmease.commons.util.dependency.DependencyHelper;
|
||||
@ -30,6 +43,9 @@ public class AppLoader implements Lifecycle {
|
||||
|
||||
public static Injector injector;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private static Map<String, TypeLiteral> typeLiterals = new HashMap<String, TypeLiteral>();
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
File tempDir = Bootstrap.getTempDir();
|
||||
@ -117,4 +133,46 @@ public class AppLoader implements Lifecycle {
|
||||
return injector.getInstance(type);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked"})
|
||||
public static <T> Set<T> getExtensions(Class<T> extensionPoint) {
|
||||
synchronized (typeLiterals) {
|
||||
TypeLiteral<Set<T>> typeLiteral = typeLiterals.get(extensionPoint.getName());
|
||||
if (typeLiteral == null) {
|
||||
try {
|
||||
String packageName = extensionPoint.getPackage().getName();
|
||||
String generatedTypeLiteralClassName =
|
||||
"generated." + packageName + "." + extensionPoint.getSimpleName() + "TypeLiteral";
|
||||
ClassPool classPool = ClassPool.getDefault();
|
||||
classPool.insertClassPath(new ClassClassPath(TypeLiteral.class));
|
||||
CtClass ctGeneratedTypeLiteral = classPool.makeClass(generatedTypeLiteralClassName);
|
||||
CtClass ctTypeLiteral = classPool.get(TypeLiteral.class.getName());
|
||||
ctGeneratedTypeLiteral.setSuperclass(ctTypeLiteral);
|
||||
CtConstructor constructor = new CtConstructor(new CtClass[0], ctGeneratedTypeLiteral);
|
||||
constructor.setBody(null);
|
||||
ctGeneratedTypeLiteral.addConstructor(constructor);
|
||||
|
||||
TypeArgument setTypeArgument = new TypeArgument(new ClassType(extensionPoint.getName()));
|
||||
TypeArgument superClassTypeArgument = new TypeArgument(
|
||||
new ClassType(Set.class.getName(), new TypeArgument[]{setTypeArgument}));
|
||||
|
||||
ClassType superClass = new ClassType(
|
||||
TypeLiteral.class.getName(),
|
||||
new TypeArgument[]{superClassTypeArgument});
|
||||
|
||||
ClassSignature signature = new ClassSignature(new TypeParameter[0], superClass, new ClassType[0]);
|
||||
ctGeneratedTypeLiteral.setGenericSignature(signature.encode());
|
||||
|
||||
Class<?> typeLiteralClassOfExtensionPoint = ctGeneratedTypeLiteral.toClass();
|
||||
typeLiteral = (TypeLiteral<Set<T>>) typeLiteralClassOfExtensionPoint.newInstance();
|
||||
|
||||
typeLiterals.put(extensionPoint.getName(), typeLiteral);
|
||||
} catch (Exception e) {
|
||||
throw ExceptionUtils.unchecked(e);
|
||||
}
|
||||
}
|
||||
|
||||
return injector.getInstance(Key.get(typeLiteral));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -54,24 +54,6 @@ public class DefaultPluginManager implements PluginManager {
|
||||
plugin.stop();
|
||||
}
|
||||
|
||||
public <T> Collection<T> getExtensions(Class<T> extensionPoint) {
|
||||
List<T> extensions = new ArrayList<T>();
|
||||
for (AbstractPlugin plugin: pluginMap.values()) {
|
||||
if (plugin.isEnabled()) {
|
||||
Collection<?> pluginExtensions = plugin.getExtensions();
|
||||
if (pluginExtensions != null) {
|
||||
for (Object extension: pluginExtensions) {
|
||||
if (extension != null && extensionPoint.isAssignableFrom(
|
||||
extension.getClass())) {
|
||||
extensions.add(extensionPoint.cast(extension));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return extensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<AbstractPlugin> getPlugins() {
|
||||
return Collections.unmodifiableCollection(pluginMap.values());
|
||||
|
||||
@ -6,8 +6,6 @@ import com.pmease.commons.bootstrap.Lifecycle;
|
||||
|
||||
public interface PluginManager extends Lifecycle {
|
||||
|
||||
<T> Collection<T> getExtensions(Class<T> extensionPoint);
|
||||
|
||||
Collection<AbstractPlugin> getPlugins();
|
||||
|
||||
<T extends AbstractPlugin> T getPlugin(Class<T> pluginClass);
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
package com.pmease.commons.shiro;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.apache.shiro.web.filter.mgt.FilterChainManager;
|
||||
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
|
||||
|
||||
import com.pmease.commons.loader.PluginManager;
|
||||
import com.pmease.commons.shiro.extensionpoint.FilterChainConfigurator;
|
||||
|
||||
@Singleton
|
||||
@ -14,7 +15,7 @@ public class DefaultFilterChainResolver extends PathMatchingFilterChainResolver
|
||||
|
||||
@Inject
|
||||
public DefaultFilterChainResolver(
|
||||
PluginManager pluginManager,
|
||||
Set<FilterChainConfigurator> filterChainConfigurators,
|
||||
BasicAuthenticationFilter basicAuthenticationFilter) {
|
||||
|
||||
super();
|
||||
@ -23,7 +24,7 @@ public class DefaultFilterChainResolver extends PathMatchingFilterChainResolver
|
||||
|
||||
filterChainManager.addFilter("authcBasic", basicAuthenticationFilter);
|
||||
|
||||
for (FilterChainConfigurator configurator: pluginManager.getExtensions(FilterChainConfigurator.class)) {
|
||||
for (FilterChainConfigurator configurator: filterChainConfigurators) {
|
||||
configurator.configure(filterChainManager);
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.GenericArrayType;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.lang.reflect.TypeVariable;
|
||||
@ -27,21 +28,21 @@ public class ClassUtils extends org.apache.commons.lang3.ClassUtils {
|
||||
*
|
||||
* @param superClass
|
||||
* super class (or interface) to match.
|
||||
* @param packageClass
|
||||
* @param packageLocatorClass
|
||||
* find sub classes in the same package as this class. Package will not be searched recursively.
|
||||
* @return collection of sub classes (not include the super class)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Collection<Class<T>> findSubClasses(Class<T> superClass, Class<?> packageClass) {
|
||||
public static <T> Collection<Class<? extends T>> findSubClasses(Class<T> superClass, Class<?> packageLocatorClass) {
|
||||
Preconditions.checkNotNull(superClass);
|
||||
Preconditions.checkNotNull(packageClass);
|
||||
Preconditions.checkNotNull(packageLocatorClass);
|
||||
|
||||
Collection<Class<T>> classes = new HashSet<Class<T>>();
|
||||
Collection<Class<? extends T>> classes = new HashSet<Class<? extends T>>();
|
||||
|
||||
File location = new File(packageClass.getProtectionDomain()
|
||||
File location = new File(packageLocatorClass.getProtectionDomain()
|
||||
.getCodeSource().getLocation().getFile());
|
||||
if (location.isFile()) {
|
||||
String packagePath = packageClass.getPackage().getName().replace('.', '/') + "/";
|
||||
String packagePath = packageLocatorClass.getPackage().getName().replace('.', '/') + "/";
|
||||
JarFile jarFile;
|
||||
try {
|
||||
jarFile = new JarFile(location);
|
||||
@ -68,14 +69,14 @@ public class ClassUtils extends org.apache.commons.lang3.ClassUtils {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String packagePath = packageClass.getPackage().getName().replace('.', File.separatorChar);
|
||||
String packagePath = packageLocatorClass.getPackage().getName().replace('.', File.separatorChar);
|
||||
File packageDir = new File(location, packagePath);
|
||||
if (packageDir.exists()) {
|
||||
for (File file: packageDir.listFiles()) {
|
||||
if (file.getName().endsWith(".class")) {
|
||||
Class<T> clazz;
|
||||
try {
|
||||
String className = packageClass.getPackage().getName() + "." +
|
||||
String className = packageLocatorClass.getPackage().getName() + "." +
|
||||
StringUtils.substringBeforeLast(file.getName(), ".");
|
||||
clazz = (Class<T>) superClass.getClassLoader().loadClass(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
@ -181,5 +182,9 @@ public class ClassUtils extends org.apache.commons.lang3.ClassUtils {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isConcrete(Class<?> clazz) {
|
||||
return !clazz.isInterface() && !Modifier.isAbstract(clazz.getModifiers());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.pmease.commons.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
@ -28,4 +29,16 @@ public class EasyMap {
|
||||
return map;
|
||||
}
|
||||
|
||||
public static Map<Object, Object> ofOrdered(Object...objects) {
|
||||
Map<Object, Object> map = new LinkedHashMap<Object, Object>();
|
||||
fill(map, objects);
|
||||
return map;
|
||||
}
|
||||
|
||||
public static Map<String, String> ofOrdered(String...strings) {
|
||||
Map<String, String> map = new LinkedHashMap<String, String>();
|
||||
fill(map, (Object[])strings);
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
package com.pmease.commons.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.pmease.commons.bootstrap.BootstrapUtils;
|
||||
@ -31,4 +36,24 @@ public class ExceptionUtils extends org.apache.commons.lang3.exception.Exception
|
||||
return BootstrapUtils.unchecked(e);
|
||||
}
|
||||
|
||||
public static String buildMessage(String cause, Object...factors) {
|
||||
return buildMessage(cause, EasyMap.ofOrdered(factors));
|
||||
}
|
||||
|
||||
public static String buildMessage(String cause, Map<String, String> factors) {
|
||||
String message = cause;
|
||||
message += " (";
|
||||
|
||||
List<String> factorMessages = new ArrayList<String>();
|
||||
for (Iterator<Map.Entry<String, String>> it = factors.entrySet().iterator(); it.hasNext();) {
|
||||
Map.Entry<String, String> entry = (Entry<String, String>) it.next();
|
||||
factorMessages.add(entry.getKey().toString() + ":" + entry.getValue().toString());
|
||||
}
|
||||
|
||||
message += StringUtils.join(factorMessages.iterator(), ", ");
|
||||
message += ")";
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -57,7 +57,12 @@
|
||||
<groupId>com.pmease</groupId>
|
||||
<artifactId>commons.jetty</artifactId>
|
||||
<version>1.0.29</version>
|
||||
</dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.pmease</groupId>
|
||||
<artifactId>commons.editable</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<moduleClass>com.pmease.commons.wicket.WicketModule</moduleClass>
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
package com.pmease.gitop.core;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
|
||||
import com.pmease.commons.hibernate.AbstractEntity;
|
||||
import com.pmease.commons.hibernate.ModelProvider;
|
||||
import com.pmease.commons.util.ClassUtils;
|
||||
import com.pmease.gitop.core.model.ModelLocator;
|
||||
|
||||
public class CoreModelProvider implements ModelProvider {
|
||||
|
||||
@Override
|
||||
public Collection<Class<? extends AbstractEntity>> getModelClasses() {
|
||||
Collection<Class<? extends AbstractEntity>> modelClasses =
|
||||
new HashSet<Class<? extends AbstractEntity>>();
|
||||
modelClasses.addAll(ClassUtils.findSubClasses(AbstractEntity.class, ModelLocator.class));
|
||||
return modelClasses;
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,9 +3,7 @@ package com.pmease.gitop.core;
|
||||
import java.io.Serializable;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@ -14,13 +12,9 @@ import org.apache.commons.lang3.SerializationUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.pmease.commons.hibernate.AbstractEntity;
|
||||
import com.pmease.commons.hibernate.extensionpoints.ModelContribution;
|
||||
import com.pmease.commons.loader.AbstractPlugin;
|
||||
import com.pmease.commons.loader.AppLoader;
|
||||
import com.pmease.commons.util.ClassUtils;
|
||||
import com.pmease.gitop.core.manager.InitManager;
|
||||
import com.pmease.gitop.core.model.ModelLocator;
|
||||
import com.pmease.gitop.core.setting.ServerConfig;
|
||||
|
||||
public class Gitop extends AbstractPlugin {
|
||||
@ -41,18 +35,7 @@ public class Gitop extends AbstractPlugin {
|
||||
|
||||
@Override
|
||||
public Collection<?> getExtensions() {
|
||||
return Arrays.asList(
|
||||
new ModelContribution() {
|
||||
|
||||
@Override
|
||||
public Collection<Class<? extends AbstractEntity>> getModelClasses() {
|
||||
Collection<Class<? extends AbstractEntity>> modelClasses =
|
||||
new HashSet<Class<? extends AbstractEntity>>();
|
||||
modelClasses.addAll(ClassUtils.findSubClasses(AbstractEntity.class, ModelLocator.class));
|
||||
return modelClasses;
|
||||
}
|
||||
}
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
|
||||
@ -2,6 +2,7 @@ package com.pmease.gitop.core;
|
||||
|
||||
import org.hibernate.cfg.NamingStrategy;
|
||||
|
||||
import com.pmease.commons.hibernate.ModelProvider;
|
||||
import com.pmease.commons.hibernate.PrefixedNamingStrategy;
|
||||
import com.pmease.commons.loader.AbstractPlugin;
|
||||
import com.pmease.commons.loader.AbstractPluginModule;
|
||||
@ -20,6 +21,7 @@ public class GitopModule extends AbstractPluginModule {
|
||||
|
||||
bind(AbstractRealm.class).to(UserRealm.class);
|
||||
|
||||
addExtension(ModelProvider.class, CoreModelProvider.class);
|
||||
bind(NamingStrategy.class).toInstance(new PrefixedNamingStrategy("G"));
|
||||
|
||||
bind(Gitop.class);
|
||||
|
||||
@ -56,7 +56,7 @@
|
||||
</repositories>
|
||||
|
||||
<properties>
|
||||
<moduleClass>com.pmease.gitop.web.PluginModule</moduleClass>
|
||||
<moduleClass>com.pmease.gitop.web.WebModule</moduleClass>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
||||
@ -312,6 +312,11 @@
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<version>3.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.18.0-GA</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.ant</groupId>
|
||||
<artifactId>ant</artifactId>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user