Commit 42e5e623 authored by yihua.huang's avatar yihua.huang

remove project avalon

parent 00dfebbc
......@@ -54,7 +54,6 @@
<module>webmagic-selenium</module>
<module>webmagic-saxon</module>
<module>webmagic-samples</module>
<module>webmagic-avalon</module>
</modules>
<dependencyManagement>
......
WebMagic-Avalon
========
> Spiders Manage Web
see [#issue43](https://github.com/code4craft/webmagic/issues/43)
\ No newline at end of file
This diff is collapsed.
forger
======
Dynamic Java object generator with template class and configuration.
## Compiler
Use groovy compiler. Compile source code to Java class.
## PropertyLoader
Load properties of object from user input.
## API
```java
@Test
public void testForgerCreateByClassAnnotationCompile() throws Exception {
ForgerFactory forgerFactory = new ForgerFactory(new AnnotationPropertyLoader(), new GroovyForgerCompiler());
Forger<Fooable> forger = forgerFactory.<Fooable>compile(Foo.SOURCE_CODE);
Fooable foo = forger.forge(ImmutableMap.<String, Object>of("fooa", "test"));
Field field = forger.getClazz().getDeclaredField("foo");
field.setAccessible(true);
assertThat(field.get(foo)).isEqualTo("test");
assertThat(foo.foo()).isEqualTo("test");
}
```
\ No newline at end of file
<?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/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>7</version>
</parent>
<groupId>us.codecraft</groupId>
<artifactId>forger</artifactId>
<version>0.1.1-SNAPSHOT</version>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<name>forger</name>
<description>
Dynamic Java object generator with template class and configuration.
</description>
<url>https://github.com/code4craft/forger/</url>
<developers>
<developer>
<id>code4craft</id>
<name>Yihua huang</name>
<email>code4crafer@gmail.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:git@github.com:code4craft/forger.git</connection>
<developerConnection>scm:git:git@github.com:code4craft/forger.git</developerConnection>
<url>git@github.com:code4craft/forger.git</url>
<tag>HEAD</tag>
</scm>
<licenses>
<license>
<name>Apache License,Version 2</name>
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
<distribution>repo</distribution>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>1.5.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.6</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>15.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.4.1</version>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release-sign-artifacts</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
package us.codecraft.forger;
import us.codecraft.forger.property.Property;
import us.codecraft.forger.property.PropertyLoader;
import java.util.List;
import java.util.Map;
/**
* @author code4crafter@gmail.com
*/
public class Forger<T> {
private final Class<T> clazz;
private final PropertyLoader propertyLoader;
public Forger(Class<T> clazz,PropertyLoader propertyLoader) {
this.clazz = clazz;
this.propertyLoader = propertyLoader;
}
public T forge(Map<String, Object> properties) throws IllegalAccessException, InstantiationException {
T t = clazz.newInstance();
propertyLoader.load(t, properties);
return t;
}
public List<Property> getPropertyNames() {
return propertyLoader.getProperties(clazz);
}
public Class<T> getClazz() {
return clazz;
}
}
package us.codecraft.forger;
import us.codecraft.forger.compiler.ForgerCompiler;
import us.codecraft.forger.property.PropertyLoader;
/**
* @author code4crafter@gmail.com
*/
public class ForgerFactory {
private final PropertyLoader propertyLoader;
private final ForgerCompiler forgerCompiler;
public ForgerFactory(PropertyLoader propertyLoader, ForgerCompiler forgerCompiler) {
this.propertyLoader = propertyLoader;
this.forgerCompiler = forgerCompiler;
}
public <T> Forger<T> compile(String sourceCode) {
Class clazz = forgerCompiler.compile(sourceCode);
return new Forger(clazz, propertyLoader);
}
public <T> Forger<T> create(Class clazz) {
return new Forger(clazz, propertyLoader);
}
}
package us.codecraft.forger.compiler;
/**
* @author code4crafter@gmail.com
*/
public interface ForgerCompiler {
public Class compile(String sourceCode);
}
package us.codecraft.forger.compiler;
import groovy.lang.GroovyClassLoader;
/**
* @author code4crafter@gmail.com
*/
public class GroovyForgerCompiler implements ForgerCompiler{
private GroovyClassLoader groovyClassLoader = new GroovyClassLoader();
@Override
public Class compile(String sourceCode) {
return groovyClassLoader.parseClass(sourceCode);
}
}
package us.codecraft.forger.property;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import us.codecraft.forger.property.format.*;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author code4crafter@gmail.com
*/
public abstract class AbstractPropertyLoader implements PropertyLoader {
private TypeFormatterFactory typeFormatterFactory = new TypeFormatterFactory();
protected Logger logger = LoggerFactory.getLogger(getClass());
protected TypeFormatterFactory getTypeFormatterFactory() {
return typeFormatterFactory;
}
@Override
public <T> T load(T object, Map<String, Object> propertyConfigs) {
List<Property> properties = getProperties(object.getClass());
for (Property property : properties) {
Object value = propertyConfigs.get(property.getName());
if (value == null) {
throw new IllegalArgumentException("Config for property " + property.getName() + " is missing!");
}
ObjectFormatter objectFormatter = property.getObjectFormatter();
switch (property.getType()) {
case PropertyString:
Object fieldValue = objectFormatter.format(String.valueOf(value));
try {
property.getField().set(object, fieldValue);
} catch (IllegalAccessException e) {
logger.warn("Set field " + property.getField() + " error!", e);
}
break;
case PropertyList:
if (!List.class.isAssignableFrom(value.getClass())) {
throw new IllegalArgumentException("Config for property " + property.getName() + " should be subclass of List!");
}
List listField = new ArrayList();
List<String> listConfigs = (List) value;
for (String listConfig : listConfigs) {
listField.add(objectFormatter.format(listConfig));
}
try {
property.getField().set(object, listField);
} catch (IllegalAccessException e) {
logger.warn("Set field " + property.getField() + " error!", e);
}
break;
case PropertyMap:
if (!Map.class.isAssignableFrom(value.getClass())) {
throw new IllegalArgumentException("Config for property " + property.getName() + " should be subclass of List!");
}
Map mapField = new HashMap();
Map<String, String> mapConfigs = (Map<String, String>) value;
for (Map.Entry<String, String> entry : mapConfigs.entrySet()) {
mapField.put(entry.getKey(), objectFormatter.format(entry.getValue()));
}
try {
property.getField().set(object, mapField);
} catch (IllegalAccessException e) {
logger.warn("Set field " + property.getField() + " error!", e);
}
break;
}
}
return object;
}
protected ObjectFormatter prepareTypeFormatterParam(TypeFormatter objectFormatter, String[] params) {
if (params == null) {
return objectFormatter;
}
return new ObjectFormatterWithParams().setTypeFormatter(objectFormatter).setParams(params);
}
protected ObjectFormatter getObjectFormatter(Field field) {
Class type = field.getType();
if (List.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type)) {
type = String.class;
}
if (field.isAnnotationPresent(Formatter.class)) {
Formatter formatter = field.getAnnotation(Formatter.class);
if (!formatter.formatter().equals(TypeFormatter.class)) {
TypeFormatter typeFormatter = typeFormatterFactory.getByFormatterClass(formatter.formatter());
if (typeFormatter != null) {
return prepareTypeFormatterParam(typeFormatter,formatter.value());
}
typeFormatterFactory.put(formatter.formatter());
return prepareTypeFormatterParam(typeFormatterFactory.getByFormatterClass(formatter.formatter()), formatter.value());
} else if (!formatter.subClazz().equals(String.class)) {
type = formatter.subClazz();
TypeFormatter typeFormatter = typeFormatterFactory.get(type);
if (typeFormatter == null) {
throw new IllegalArgumentException("No typeFormatter for class " + type);
}
return prepareTypeFormatterParam(typeFormatter, formatter.value());
}
}
return getTypeFormatterFactory().get(BasicTypeFormatter.detectBasicClass(type));
}
}
package us.codecraft.forger.property;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* @author code4crafter@gmail.com
*/
public class AnnotationPropertyLoader extends AbstractPropertyLoader {
@Override
public List<Property> getProperties(Class clazz) {
Field[] fields = clazz.getDeclaredFields();
List<Property> properties = new ArrayList<Property>(fields.length);
for (Field field : fields) {
Inject inject = field.getAnnotation(Inject.class);
if (inject != null) {
if (!field.isAccessible()) {
field.setAccessible(true);
}
Property property = Property.fromField(field);
if (inject.value().length() > 0) {
property.setName(inject.value());
}
property.setObjectFormatter(getObjectFormatter(field));
properties.add(property);
}
}
return properties;
}
}
package us.codecraft.forger.property;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* @author code4crafter@gmail.com
*/
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Inject {
String value() default "";
}
package us.codecraft.forger.property;
import us.codecraft.forger.property.format.ObjectFormatter;
import java.lang.reflect.Field;
/**
* @author code4crafter@gmail.com
*/
public class Property {
private String name;
private PropertyType type;
private Field field;
private ObjectFormatter objectFormatter;
public ObjectFormatter getObjectFormatter() {
return objectFormatter;
}
public Property setObjectFormatter(ObjectFormatter objectFormatter) {
this.objectFormatter = objectFormatter;
return this;
}
public String getName() {
return name;
}
public Property setName(String name) {
this.name = name;
return this;
}
public PropertyType getType() {
return type;
}
public Property setType(PropertyType type) {
this.type = type;
return this;
}
public Field getField() {
return field;
}
public Property setField(Field field) {
this.field = field;
return this;
}
public static Property fromField(Field field) {
return new Property().setName(field.getName()).setType(PropertyType.from(field.getType())).setField(field);
}
}
package us.codecraft.forger.property;
import java.util.List;
import java.util.Map;
/**
* @author code4crafter@gmail.com
*/
public interface PropertyLoader {
public <T> T load(T object, Map<String, Object> propertyConfigs);
public List<Property> getProperties(Class clazz);
}
package us.codecraft.forger.property;
import java.util.List;
import java.util.Map;
/**
* @author code4crafter@gmail.com
*/
public enum PropertyType {
PropertyString,PropertyMap,PropertyList;
public static PropertyType from(Class clazz){
if (Map.class.isAssignableFrom(clazz)){
return PropertyMap;
}
if (List.class.isAssignableFrom(clazz)){
return PropertyList;
}
return PropertyString;
}
}
package us.codecraft.forger.property;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
/**
* @author code4crafter@gmail.com
*/
public class SimpleFieldPropertyLoader extends AbstractPropertyLoader {
@Override
public List<Property> getProperties(Class clazz) {
Field[] fields = clazz.getDeclaredFields();
List<Property> properties = new ArrayList<Property>(fields.length);
for (Field field : fields) {
if (Modifier.isStatic(field.getModifiers())){
continue;
}
if (!field.isAccessible()){
field.setAccessible(true);
}
properties.add(Property.fromField(field).setObjectFormatter(getObjectFormatter(field)));
}
return properties;
}
}
package us.codecraft.forger.property.format;
import java.util.Arrays;
import java.util.List;
/**
* @author code4crafter@gmail.com
* @since 0.3.2
*/
public abstract class BasicTypeFormatter<T> implements TypeFormatter<T> {
@Override
public T format(String text) {
if (text == null) {
return null;
}
text = text.trim();
return formatTrimmed(text);
}
@Override
public T format(String text, String[] params) {
return format(text);
}
protected abstract T formatTrimmed(String raw);
public static final List<Class<? extends TypeFormatter>> basicTypeFormatters = Arrays.<Class<? extends TypeFormatter>>asList(IntegerFormatter.class,
LongFormatter.class, DoubleFormatter.class, FloatFormatter.class, ShortFormatter.class,
CharactorFormatter.class, ByteFormatter.class, BooleanFormatter.class, DateFormatter.class, StringFormatter.class);
public static Class<?> detectBasicClass(Class<?> type) {
if (type.equals(Integer.TYPE) || type.equals(Integer.class)) {
return Integer.class;
} else if (type.equals(Long.TYPE) || type.equals(Long.class)) {
return Long.class;
} else if (type.equals(Double.TYPE) || type.equals(Double.class)) {
return Double.class;
} else if (type.equals(Float.TYPE) || type.equals(Float.class)) {
return Float.class;
} else if (type.equals(Short.TYPE) || type.equals(Short.class)) {
return Short.class;
} else if (type.equals(Character.TYPE) || type.equals(Character.class)) {
return Character.class;
} else if (type.equals(Byte.TYPE) || type.equals(Byte.class)) {
return Byte.class;
} else if (type.equals(Boolean.TYPE) || type.equals(Boolean.class)) {
return Boolean.class;
}
return type;
}
public static class IntegerFormatter extends BasicTypeFormatter<Integer> {
@Override
public Integer formatTrimmed(String raw) {
return Integer.parseInt(raw);
}
@Override
public Class<Integer> clazz() {
return Integer.class;
}
}
public static class LongFormatter extends BasicTypeFormatter<Long> {
@Override
public Long formatTrimmed(String raw) {
return Long.parseLong(raw);
}
@Override
public Class<Long> clazz() {
return Long.class;
}
}
public static class DoubleFormatter extends BasicTypeFormatter<Double> {
@Override
public Double formatTrimmed(String raw) {
return Double.parseDouble(raw);
}
@Override
public Class<Double> clazz() {
return Double.class;
}
}
public static class FloatFormatter extends BasicTypeFormatter<Float> {
@Override
public Float formatTrimmed(String raw) {
return Float.parseFloat(raw);
}
@Override
public Class<Float> clazz() {
return Float.class;
}
}
public static class ShortFormatter extends BasicTypeFormatter<Short> {
@Override
public Short formatTrimmed(String raw) {
return Short.parseShort(raw);
}
@Override
public Class<Short> clazz() {
return Short.class;
}
}
public static class CharactorFormatter extends BasicTypeFormatter<Character> {
@Override
public Character formatTrimmed(String raw) {
return raw.charAt(0);
}
@Override
public Class<Character> clazz() {
return Character.class;
}
}
public static class ByteFormatter extends BasicTypeFormatter<Byte> {
@Override
public Byte formatTrimmed(String raw) {
return Byte.parseByte(raw, 10);
}
@Override
public Class<Byte> clazz() {
return Byte.class;
}
}
public static class BooleanFormatter extends BasicTypeFormatter<Boolean> {
@Override
public Boolean formatTrimmed(String raw) {
return Boolean.parseBoolean(raw);
}
@Override
public Class<Boolean> clazz() {
return Boolean.class;
}
}
public static class StringFormatter implements TypeFormatter<String> {
@Override
public String format(String text) {
return text;
}
@Override
public String format(String text, String[] params) {
return format(text);
}
@Override
public Class<String> clazz() {
return String.class;
}
}
}
package us.codecraft.forger.property.format;
import org.apache.commons.lang3.time.DateUtils;
import java.text.ParseException;
import java.util.Date;
/**
* @author code4crafter@gmail.com
* @since 0.3.2
*/
public class DateFormatter implements TypeFormatter<Date> {
public static final String[] DEFAULT_PATTERN = new String[]{"yyyy-MM-dd HH:mm"};
@Override
public Date format(String text) {
return format(text,DEFAULT_PATTERN);
}
@Override
public Date format(String text, String[] params) {
try {
return DateUtils.parseDate(text, params);
} catch (ParseException e) {
throw new IllegalArgumentException(e);
}
}
@Override
public Class<Date> clazz() {
return Date.class;
}
}
package us.codecraft.forger.property.format;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* Define how the result string is convert to an object for field.
*
* @author code4crafter@gmail.com <br>
* @since 0.3.2
*/
@Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Formatter {
/**
* Set formatter params.
*
* @return formatter params
*/
String[] value();
/**
* Specific the class of field of class of elements in collection for field. <br>
* It is not necessary to be set because we can detect the class by class of field,
* unless you use a collection as a field. <br>
*
* @return the class of field
*/
Class subClazz() default String.class;
/**
* If there are more than one formatter for a class, just specify the implement.
* @return implement
*/
Class<? extends TypeFormatter> formatter() default TypeFormatter.class;
}
package us.codecraft.forger.property.format;
/**
* @author code4crafter@gmail.com
*/
public interface ObjectFormatter<T> {
T format(String text);
}
package us.codecraft.forger.property.format;
/**
* @author code4crafter@gmail.com
*/
public class ObjectFormatterWithParams<T> implements ObjectFormatter<T> {
private TypeFormatter<T> typeFormatter;
private String[] params;
public TypeFormatter getTypeFormatter() {
return typeFormatter;
}
public ObjectFormatterWithParams<T> setTypeFormatter(TypeFormatter typeFormatter) {
this.typeFormatter = typeFormatter;
return this;
}
public String[] getParams() {
return params;
}
public ObjectFormatterWithParams setParams(String[] params) {
this.params = params;
return this;
}
@Override
public T format(String text) {
return typeFormatter.format(text, params);
}
}
package us.codecraft.forger.property.format;
/**
* @author code4crafter@gmail.com
*/
public interface TypeFormatter<T> extends ObjectFormatter<T> {
T format(String text, String[] params);
Class<T> clazz();
}
package us.codecraft.forger.property.format;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author code4crafter@gmail.com
* @since 0.3.2
*/
public class TypeFormatterFactory {
private Logger logger = LoggerFactory.getLogger(getClass());
private Map<Class, TypeFormatter> objectFormatterMapWithPropertyAsKey = new ConcurrentHashMap<Class, TypeFormatter>();
private Map<Class, TypeFormatter> objectFormatterMapWithClassAsKey = new ConcurrentHashMap<Class, TypeFormatter>();
public TypeFormatterFactory() {
initFormatterMap();
}
private void initFormatterMap() {
for (Class<? extends TypeFormatter> basicTypeFormatter : BasicTypeFormatter.basicTypeFormatters) {
put(basicTypeFormatter);
}
put(DateFormatter.class);
}
public synchronized void put(Class<? extends TypeFormatter> objectFormatterClazz) {
try {
TypeFormatter typeFormatter = objectFormatterClazz.newInstance();
if (typeFormatter.clazz() != null) {
objectFormatterMapWithPropertyAsKey.put(typeFormatter.clazz(), typeFormatter);
}
objectFormatterMapWithClassAsKey.put(objectFormatterClazz, typeFormatter);
} catch (InstantiationException e) {
logger.error("Init objectFormatter error", e);
} catch (IllegalAccessException e) {
logger.error("Init objectFormatter error", e);
}
}
public TypeFormatter get(Class<?> clazz) {
return objectFormatterMapWithPropertyAsKey.get(clazz);
}
public TypeFormatter getByFormatterClass(Class<?> clazz) {
return objectFormatterMapWithClassAsKey.get(clazz);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yy-MM-dd HH:mm:ss,SSS} %-5p %c(%F:%L) ## %m%n" />
</layout>
</appender>
<logger name="org.apache" additivity="false">
<level value="warn" />
<appender-ref ref="stdout" />
</logger>
<root>
<level value="info" />
<appender-ref ref="stdout" />
</root>
</log4j:configuration>
package us.codecraft.forger;
import us.codecraft.forger.property.Inject;
import us.codecraft.forger.property.format.Formatter;
import java.util.List;
import java.util.Map;
/**
* @author code4crafter@gmail.com
*/
public class Bar {
@Inject("bar")
private String bar;
@Inject
private List<String> values;
@Formatter(value = "", subClazz = Integer.class)
@Inject
private Map<String, Integer> idMap;
public String getBar() {
return bar;
}
public void setBar(String bar) {
this.bar = bar;
}
public List<String> getValues() {
return values;
}
public void setValues(List<String> values) {
this.values = values;
}
public Map<String, Integer> getIdMap() {
return idMap;
}
public void setIdMap(Map<String, Integer> idMap) {
this.idMap = idMap;
}
}
package us.codecraft.forger;
import us.codecraft.forger.property.Inject;
import us.codecraft.forger.property.format.Formatter;
/**
* @author code4crafter@gmail.com
*/
public class Foo implements Fooable{
@Formatter("")
@Inject("fooa")
private String foo;
public static final String SOURCE_CODE="import us.codecraft.forger.*;\n" +
"import us.codecraft.forger.property.Inject;\n" +
"import us.codecraft.forger.property.Inject;\n" +
"import us.codecraft.forger.property.format.Formatter;\n" +
"\n" +
"/**\n" +
" * @author code4crafter@gmail.com\n" +
" */\n" +
"public class Foo implements Fooable{\n" +
"\n" +
" @Formatter(\"\")\n" +
" @Inject(\"fooa\")\n" +
" private String foo;\n" +
"\n" +
" public String getFoo() {\n" +
" return foo;\n" +
" }\n" +
"\n" +
" @Override\n" +
" public String foo() {\n" +
" return foo;\n" +
" }\n" +
"}";
public String getFoo() {
return foo;
}
@Override
public String foo() {
return foo;
}
}
package us.codecraft.forger;
/**
* @author code4crafter@gmail.com
*/
public interface Fooable {
public String foo();
}
package us.codecraft.forger;
import com.google.common.collect.ImmutableMap;
import org.junit.Test;
import us.codecraft.forger.compiler.GroovyForgerCompiler;
import us.codecraft.forger.property.AnnotationPropertyLoader;
import us.codecraft.forger.property.SimpleFieldPropertyLoader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.assertj.core.api.Assertions.*;
/**
* @author code4crafter@gmail.com
*/
public class ForgerFactoryTest {
@Test
public void testForgerCreateByClassProperty() throws Exception {
ForgerFactory forgerFactory = new ForgerFactory(new SimpleFieldPropertyLoader(), null);
Forger<Foo> forger = forgerFactory.<Foo>create(Foo.class);
Foo foo = forger.forge(ImmutableMap.<String, Object>of("foo", "test"));
assertThat(foo.getFoo()).isEqualTo("test");
}
@Test
public void testForgerCreateByClassAnnotation() throws Exception {
ForgerFactory forgerFactory = new ForgerFactory(new AnnotationPropertyLoader(), null);
Forger<Foo> forger = forgerFactory.<Foo>create(Foo.class);
Foo foo = forger.forge(ImmutableMap.<String, Object>of("fooa", "test"));
assertThat(foo.getFoo()).isEqualTo("test");
}
@Test
public void testForgerCreateByClassAnnotationCompile() throws Exception {
ForgerFactory forgerFactory = new ForgerFactory(new AnnotationPropertyLoader(), new GroovyForgerCompiler());
Forger<Fooable> forger = forgerFactory.<Fooable>compile(Foo.SOURCE_CODE);
Fooable foo = forger.forge(ImmutableMap.<String, Object>of("fooa", "test"));
Field field = forger.getClazz().getDeclaredField("foo");
field.setAccessible(true);
assertThat(field.get(foo)).isEqualTo("test");
assertThat(foo.foo()).isEqualTo("test");
}
@Test
public void testForgerCreateByClassAnnotationWithCollections() throws Exception {
ForgerFactory forgerFactory = new ForgerFactory(new AnnotationPropertyLoader(), null);
Forger<Bar> forger = forgerFactory.<Bar>create(Bar.class);
Map<String, Object> map = new HashMap<String, Object>();
map.put("bar", "bar");
Map<String, String> submap = new HashMap<String, String>();
submap.put("1", "1");
submap.put("2", "2");
map.put("idMap", submap);
List<String> sublist = new ArrayList<String>();
sublist.add("test");
map.put("values", sublist);
Bar forge = forger.forge(map);
assertThat(forge.getValues().size() > 0);
assertThat(forge.getIdMap().get("1")).isEqualTo(1);
}
}
package us.codecraft.forger.compiler;
import org.junit.Test;
import us.codecraft.forger.Foo;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author code4crafter@gmail.com
*/
public class GroovyForgerCompilerTest {
@Test
public void testGroovyClassLoader() throws Exception {
GroovyForgerCompiler groovyForgerCompiler = new GroovyForgerCompiler();
Class compiledClass = groovyForgerCompiler.compile(Foo.SOURCE_CODE);
assertThat(compiledClass.getName()).isEqualTo("Foo");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yy-MM-dd HH:mm:ss,SSS} %-5p %c(%F:%L) ## %m%n" />
</layout>
</appender>
<logger name="org.springframework" additivity="false">
<level value="warn" />
<appender-ref ref="stdout" />
</logger>
<logger name="org.apache" additivity="false">
<level value="warn" />
<appender-ref ref="stdout" />
</logger>
<logger name="net.sf.ehcache" additivity="false">
<level value="warn" />
<appender-ref ref="stdout" />
</logger>
<root>
<level value="info" />
<appender-ref ref="stdout" />
</root>
</log4j:configuration>
<?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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>webmagic-parent</artifactId>
<groupId>us.codecraft</groupId>
<version>0.5.4-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-avalon</artifactId>
<packaging>pom</packaging>
<modules>
<module>forger</module>
<module>webmagic-admin</module>
<module>webmagic-worker</module>
<module>webmagic-avalon-common</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-scripts</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.19</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring-version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>1.5.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring-version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.37</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
WebMagic-Admin
=====
Admin is the control web of workers.
\ No newline at end of file
<?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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>webmagic-avalon</artifactId>
<groupId>us.codecraft</groupId>
<version>0.5.4-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-admin</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>us.codecraft</groupId>
<artifactId>webmagic-avalon-common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package us.codecraft.webmagic.avalon.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
* @author code4crafter@gmail.com
*/
@Controller("dashboard")
@RequestMapping("/")
public class DashBoardController {
@RequestMapping
public ModelAndView index() {
ModelAndView map = new ModelAndView("dashboard");
return map;
}
}
package us.codecraft.webmagic.avalon.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
import java.util.Map;
/**
* @author code4crafter@gmail.com
*/
@Controller("spider")
@RequestMapping("spider")
public class SpiderController {
@RequestMapping("create")
@ResponseBody
public Map<String, Object> create() {
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("code", 200);
return map;
}
}
number_format=#
classic_compatible=true
default_encoding=UTF-8
template_update_delay=0
#########################
template_exception_handler=rethrow
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yy-MM-dd HH:mm:ss,SSS} %-5p %c(%F:%L) ## %m%n" />
</layout>
</appender>
<logger name="org.apache" additivity="false">
<level value="warn" />
<appender-ref ref="stdout" />
</logger>
<root>
<level value="info" />
<appender-ref ref="stdout" />
</root>
</log4j:configuration>
<%@ page language="java" contentType="text/html; charset=utf8"
pageEncoding="utf8" isErrorPage="true" import="java.io.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8">
<title>500</title>
</head>
<body>
页面出错啦!
<%
StringWriter stringWriter = new StringWriter();
exception.printStackTrace(new PrintWriter(stringWriter));
out.println(stringWriter.toString());
%>
</body>
</html>
\ No newline at end of file
<html>
<head>
<script src=""></script>
</head>
<div class="url-box">
<input type="text" id="url-input">
</div>
<div class="content-show">
</div>
</html>
\ No newline at end of file
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:/config/spring/applicationContext*.xml,
</param-value>
</context-param>
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.XmlWebApplicationContext</param-value>
</context-param>
<!--由Sprng载入的Log4j配置文件位置 -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log/log4j.xml</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value>
</context-param>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:config/spring/applicationContext*.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/jsp/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/WEB-INF/jsp/500.jsp</location>
</error-page>
</web-app>
/*
ColorBox Core Style:
The following CSS is consistent between example themes and should not be altered.
*/
#colorbox, #cboxOverlay, #cboxWrapper{position:absolute; top:0; left:0; z-index:9999; overflow:hidden;}
#cboxOverlay{position:fixed; width:100%; height:100%;}
#cboxMiddleLeft, #cboxBottomLeft{clear:left;}
#cboxContent{position:relative;}
#cboxLoadedContent{overflow:auto;}
#cboxTitle{margin:0;}
#cboxLoadingOverlay, #cboxLoadingGraphic{position:absolute; top:0; left:0; width:100%; height:100%;}
#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{cursor:pointer;}
.cboxPhoto{float:left; margin:auto; border:0; display:block; max-width:none;}
.cboxIframe{width:100%; height:100%; display:block; border:0;}
#colorbox, #cboxContent, #cboxLoadedContent{box-sizing:content-box;}
/*
User Style:
Change the following styles to modify the appearance of ColorBox. They are
ordered & tabbed in a way that represents the nesting of the generated HTML.
*/
#cboxOverlay{background:#000;}
#colorbox{}
#cboxTopLeft{width:14px; height:14px; background:url(../img/controls.png) no-repeat 0 0;}
#cboxTopCenter{height:14px; background:url(../img/border.png) repeat-x top left;}
#cboxTopRight{width:14px; height:14px; background:url(../img/controls.png) no-repeat -36px 0;}
#cboxBottomLeft{width:14px; height:43px; background:url(../img/controls.png) no-repeat 0 -32px;}
#cboxBottomCenter{height:43px; background:url(../img/border.png) repeat-x bottom left;}
#cboxBottomRight{width:14px; height:43px; background:url(../img/controls.png) no-repeat -36px -32px;}
#cboxMiddleLeft{width:14px; background:url(../img/controls.png) repeat-y -175px 0;}
#cboxMiddleRight{width:14px; background:url(../img/controls.png) repeat-y -211px 0;}
#cboxContent{background:#fff; overflow:visible;}
.cboxIframe{background:#fff;}
#cboxError{padding:50px; border:1px solid #ccc;}
#cboxLoadedContent{margin-bottom:5px;}
#cboxLoadingOverlay{background:url(../img/loading_background.png) no-repeat center center;}
#cboxLoadingGraphic{background:url(../img/loading.gif) no-repeat center center;}
#cboxTitle{position:absolute; bottom:-25px; left:0; text-align:center; width:100%; font-weight:bold; color:#7C7C7C;}
#cboxCurrent{position:absolute; bottom:-25px; left:58px; font-weight:bold; color:#7C7C7C;}
#cboxPrevious, #cboxNext, #cboxClose, #cboxSlideshow{position:absolute; bottom:-29px; background:url(../img/controls.png) no-repeat 0px 0px; width:23px; height:23px; text-indent:-9999px;}
#cboxPrevious{left:0px; background-position: -51px -25px;}
#cboxPrevious:hover{background-position:-51px 0px;}
#cboxNext{left:27px; background-position:-75px -25px;}
#cboxNext:hover{background-position:-75px 0px;}
#cboxClose{right:0; background-position:-100px -25px;}
#cboxClose:hover{background-position:-100px 0px;}
.cboxSlideshow_on #cboxSlideshow{background-position:-125px 0px; right:27px;}
.cboxSlideshow_on #cboxSlideshow:hover{background-position:-150px 0px;}
.cboxSlideshow_off #cboxSlideshow{background-position:-150px -25px; right:27px;}
.cboxSlideshow_off #cboxSlideshow:hover{background-position:-125px 0px;}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment