Skip to content

Commit 1bf4adc

Browse files
authored
Merge pull request #9 from joutvhu/development
0.0.10-SNAPSHOT
2 parents dd32167 + 6b94199 commit 1bf4adc

File tree

14 files changed

+252
-181
lines changed

14 files changed

+252
-181
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ plugins {
77
}
88

99
group = 'com.github.joutvhu'
10-
version '0.0.8-SNAPSHOT'
10+
version '0.0.10-SNAPSHOT'
1111
sourceCompatibility = 1.8
1212
targetCompatibility = 1.8
1313

src/main/java/com/joutvhu/fixedwidth/parser/FixedParser.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
import com.joutvhu.fixedwidth.parser.module.DefaultModule;
44
import com.joutvhu.fixedwidth.parser.module.FixedModule;
55
import com.joutvhu.fixedwidth.parser.support.FixedParseStrategy;
6-
import com.joutvhu.fixedwidth.parser.support.FixedTypeInfo;
76
import com.joutvhu.fixedwidth.parser.support.FixedStringAssembler;
7+
import com.joutvhu.fixedwidth.parser.support.FixedTypeInfo;
88
import com.joutvhu.fixedwidth.parser.support.StringAssembler;
99

1010
/**
@@ -50,7 +50,7 @@ public FixedParser with(FixedModule module) {
5050
*
5151
* @param line fixed-width string
5252
* @param type class type of result
53-
* @param <T> type of result
53+
* @param <T> type of result
5454
* @return object
5555
*/
5656
public <T> T parse(String line, Class<T> type) {
@@ -63,7 +63,7 @@ public <T> T parse(String line, Class<T> type) {
6363
* Export object to fixed-width string
6464
*
6565
* @param object value
66-
* @param <T> object type
66+
* @param <T> object type
6767
* @return fixed-width string
6868
*/
6969
public <T> String export(T object) {

src/main/java/com/joutvhu/fixedwidth/parser/convert/reader/CollectionReader.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import com.joutvhu.fixedwidth.parser.support.FixedParseStrategy;
66
import com.joutvhu.fixedwidth.parser.support.FixedTypeInfo;
77
import com.joutvhu.fixedwidth.parser.support.StringAssembler;
8-
import com.joutvhu.fixedwidth.parser.util.ClassUtil;
98
import com.joutvhu.fixedwidth.parser.util.FixedHelper;
109

1110
import java.util.Collection;
@@ -30,7 +29,7 @@ public CollectionReader(FixedTypeInfo info, FixedParseStrategy strategy) {
3029
@Override
3130
public Collection<?> read(StringAssembler assembler) {
3231
Class<?> type = info.getType();
33-
Class<? extends Collection> selectedType = (Class<? extends Collection>) ClassUtil.selectSubTypeOf(type);
32+
Class<? extends Collection> selectedType = (Class<? extends Collection>) FixedHelper.selectSubTypeOf(type);
3433
if (selectedType == null)
3534
throw new FixedException(String.format("Not found subclass for %s", info.getLabel()));
3635

src/main/java/com/joutvhu/fixedwidth/parser/convert/reader/MapReader.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import com.joutvhu.fixedwidth.parser.support.FixedParseStrategy;
66
import com.joutvhu.fixedwidth.parser.support.FixedTypeInfo;
77
import com.joutvhu.fixedwidth.parser.support.StringAssembler;
8-
import com.joutvhu.fixedwidth.parser.util.ClassUtil;
98
import com.joutvhu.fixedwidth.parser.util.FixedHelper;
109

1110
import java.util.Map;
@@ -35,7 +34,7 @@ public MapReader(FixedTypeInfo info, FixedParseStrategy strategy) {
3534
@Override
3635
public Map<?, ?> read(StringAssembler assembler) {
3736
Class<?> type = info.getType();
38-
Class<? extends Map> selectedType = (Class<? extends Map>) ClassUtil.selectSubTypeOf(type);
37+
Class<? extends Map> selectedType = (Class<? extends Map>) FixedHelper.selectSubTypeOf(type);
3938
if (selectedType == null)
4039
throw new FixedException(String.format("Not found subclass for %s", info.getLabel()));
4140

src/main/java/com/joutvhu/fixedwidth/parser/convert/validator/BooleanValidator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public boolean validate(String value, ValidationType type) {
3636
String message = getMessage(fixedFormat.message(),
3737
fixedFormat.nativeMessage(),
3838
"{title} should be equal to one of the following value(s): {0}.",
39-
StringUtils.join(options, ", "));
39+
"\"" + StringUtils.join(options, "\", \"") + "\"");
4040
throw new InvalidException(message);
4141
}
4242
return true;

src/main/java/com/joutvhu/fixedwidth/parser/convert/validator/OptionValidator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public boolean validate(String value, ValidationType type) {
3232
String message = getMessage(fixedOption.message(),
3333
fixedOption.nativeMessage(),
3434
"{label} at position {position} should be equal to one of the following value(s): {0}.",
35-
StringUtils.join(", ", options));
35+
"\"" + StringUtils.join(options, "\", \"") + "\"");
3636
throw new InvalidException(message);
3737
}
3838
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.joutvhu.fixedwidth.parser.exception;
2+
3+
public class FindTypeException extends FixedException {
4+
private Class<?> classType;
5+
6+
public FindTypeException(String message, Class<?> classType) {
7+
super(message);
8+
this.classType = classType;
9+
}
10+
11+
public FindTypeException(String message, Throwable cause, Class<?> classType) {
12+
super(message, cause);
13+
this.classType = classType;
14+
}
15+
16+
public FindTypeException(Throwable cause, Class<?> classType) {
17+
super(cause);
18+
this.classType = classType;
19+
}
20+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package com.joutvhu.fixedwidth.parser.support;
2+
3+
import com.google.re2j.Pattern;
4+
import com.joutvhu.fixedwidth.parser.annotation.FixedField;
5+
import com.joutvhu.fixedwidth.parser.annotation.FixedObject;
6+
import com.joutvhu.fixedwidth.parser.exception.FindTypeException;
7+
import com.joutvhu.fixedwidth.parser.util.CommonUtil;
8+
9+
import java.lang.reflect.Field;
10+
import java.lang.reflect.Modifier;
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
14+
/**
15+
* Find final type
16+
*
17+
* @author Giao Ho
18+
* @since 1.0.0
19+
*/
20+
public interface FinalTypeFinder {
21+
/**
22+
* Get all fixed fields of a object type
23+
*
24+
* @param type class
25+
* @return all fixed width fields
26+
*/
27+
default List<Field> getFixedFields(Class<?> type) {
28+
List<Field> fields = new ArrayList<>();
29+
Class<?> superType = type.getSuperclass();
30+
if (superType != null) fields.addAll(getFixedFields(superType));
31+
for (Field field : type.getDeclaredFields()) {
32+
FixedField fixedField = field.getAnnotation(FixedField.class);
33+
if (fixedField != null) fields.add(field);
34+
}
35+
return fields;
36+
}
37+
38+
/**
39+
* Get final type of a string by supper FixedObject
40+
*
41+
* @param assembler is {@link StringAssembler}
42+
* @param type of supper {@link FixedObject}
43+
* @return final class
44+
*/
45+
default Class<?> detectFinalType(StringAssembler assembler, Class<?> type) {
46+
FixedObject fixedObject = type.getAnnotation(FixedObject.class);
47+
if (fixedObject != null && CommonUtil.isNotBlank(fixedObject.subTypes())) {
48+
for (FixedObject.Type subType : fixedObject.subTypes()) {
49+
checkAssignableFrom(type, subType.value());
50+
if (checkSelectionCondition(subType, valueOf(assembler, type, subType)))
51+
return detectFinalType(assembler, subType.value());
52+
}
53+
if (!void.class.equals(fixedObject.defaultSubType())) {
54+
checkAssignableFrom(type, fixedObject.defaultSubType());
55+
return detectFinalType(assembler, fixedObject.defaultSubType());
56+
}
57+
}
58+
return type;
59+
}
60+
61+
/**
62+
* Check the subClass is extends from superClass
63+
*
64+
* @param superClass is super-class
65+
* @param subClass is sub-class
66+
*/
67+
default void checkAssignableFrom(Class<?> superClass, Class<?> subClass) {
68+
if (!superClass.isAssignableFrom(subClass)) {
69+
String message = String.format("%s class is not a subclass of %s class.",
70+
subClass.getName(), superClass.getName());
71+
throw new FindTypeException(message, superClass);
72+
}
73+
}
74+
75+
/**
76+
* Check that the final class is neither the interface nor the abstract class
77+
*
78+
* @param type is final class
79+
* @return final class
80+
*/
81+
default Class<?> checkFinalClass(Class<?> type) {
82+
int modifiers = type.getModifiers();
83+
if (!Modifier.isInterface(modifiers) && !Modifier.isAbstract(modifiers))
84+
return type;
85+
else {
86+
String message = String.format("Can't find the final class of %s.", type.getName());
87+
if (Modifier.isInterface(modifiers))
88+
message += String.format(" The %s is a interface.", type.getName());
89+
if (Modifier.isAbstract(modifiers))
90+
message += String.format(" The %s is a abstract class.", type.getName());
91+
throw new FindTypeException(message, type);
92+
}
93+
}
94+
95+
/**
96+
* Check selection condition of class
97+
*
98+
* @param subType {@link FixedObject.Type}
99+
* @param value for checking
100+
* @return can use this class?
101+
*/
102+
default boolean checkSelectionCondition(FixedObject.Type subType, String value) {
103+
if (CommonUtil.isNotBlank(subType.oneOf()) && CommonUtil.listOf(subType.oneOf()).contains(value))
104+
return true;
105+
if (CommonUtil.isNotBlank(subType.matchWith()) && Pattern.matches(subType.matchWith(), value))
106+
return true;
107+
return false;
108+
}
109+
110+
/**
111+
* Get value of field by {@link FixedObject.Type} annotation
112+
*
113+
* @param assembler {@link StringAssembler}
114+
* @param type is class type
115+
* @param subType {@link FixedObject.Type}
116+
* @return string value
117+
*/
118+
default String valueOf(StringAssembler assembler, Class<?> type, FixedObject.Type subType) {
119+
if (subType.length() > 0)
120+
return assembler.get(subType.start(), subType.length());
121+
else if (CommonUtil.isNotBlank(subType.prop()))
122+
return valueOf(assembler, type, subType.prop());
123+
else return null;
124+
}
125+
126+
/**
127+
* Get value of field by field name
128+
*
129+
* @param assembler {@link StringAssembler}
130+
* @param type is class type
131+
* @param prop is field name
132+
* @return string value
133+
*/
134+
default String valueOf(StringAssembler assembler, Class<?> type, String prop) {
135+
for (Field field : getFixedFields(type)) {
136+
if (field.getName().equals(prop)) {
137+
FixedField fixedField = field.getAnnotation(FixedField.class);
138+
if (fixedField != null)
139+
return assembler.get(fixedField.start(), fixedField.length());
140+
else throw new UnsupportedOperationException(String.format("%s field is not a fixed field.", prop));
141+
}
142+
}
143+
throw new NullPointerException(String.format("Can't found %s field.", prop));
144+
}
145+
}

src/main/java/com/joutvhu/fixedwidth/parser/support/FixedParseStrategy.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public Object read(FixedTypeInfo info, StringAssembler assembler) {
3434
assembler.trim(info);
3535
if (assembler.isBlank(info)) {
3636
if (info.require)
37-
throw new NullPointerException(info.buildMessage("{label} can\'t be blank."));
37+
throw new NullPointerException(info.buildMessage("{title} can\'t be blank."));
3838
return null;
3939
}
4040
validate(info, assembler.getValue(), ValidationType.BEFORE_READ);
@@ -43,7 +43,7 @@ public Object read(FixedTypeInfo info, StringAssembler assembler) {
4343
if (reader != null) {
4444
Object result = reader.read(assembler);
4545
if (result == null && info.require)
46-
throw new NullPointerException(info.buildMessage("{title} can\'t be null."));
46+
throw new NullPointerException(info.buildMessage("{label} can\'t be null."));
4747
return result;
4848
}
4949
throw new FixedException("Reader not found.");
@@ -66,7 +66,7 @@ public String write(FixedTypeInfo info, Object value) {
6666

6767
if (assembler.isBlank(info)) {
6868
if (info.require)
69-
throw new NullPointerException(info.buildMessage("{label} can\'t be blank."));
69+
throw new NullPointerException(info.buildMessage("{title} can\'t be blank."));
7070
} else validate(info, assembler.getValue(), ValidationType.AFTER_WRITE);
7171
return assembler.getValue();
7272
}

src/main/java/com/joutvhu/fixedwidth/parser/support/FixedStringAssembler.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.joutvhu.fixedwidth.parser.support;
22

33
import com.joutvhu.fixedwidth.parser.domain.Alignment;
4-
import com.joutvhu.fixedwidth.parser.domain.Padding;
54
import com.joutvhu.fixedwidth.parser.util.Assert;
65
import com.joutvhu.fixedwidth.parser.util.CommonUtil;
76
import org.apache.commons.lang3.StringUtils;

0 commit comments

Comments
 (0)