meta parsing

This commit is contained in:
ialbert 2022-11-01 18:24:36 +03:00
parent 15f42c96b8
commit 47b0e6d6c4
16 changed files with 937 additions and 0 deletions

View file

@ -82,6 +82,11 @@
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.11</version>
</dependency>
</dependencies>
<dependencyManagement>

View file

@ -0,0 +1,49 @@
package ru.spcex.clearing.backendapi.meta;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.LinkedList;
import java.util.List;
@SuppressWarnings({"DefaultAnnotationParam", "unused"})
public class ActionElement {
@JsonProperty(value = "class")
private String clazz = null;
@JsonProperty(value = "name", required = true)
private String name = null;
@JsonProperty(value = "destination", required = false)
private String destination = null;
@JsonProperty(value = "array", required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Boolean isArray = null;
// @JsonProperty(value = "fields", required = true)
// private List<Map<String, ActionField>> fields = new LinkedList<>();
@JsonProperty(value = "fields", required = true)
private List<ActionField> fields = new LinkedList<>();
public String getName() {
return name;
}
public List<ActionField> getFields() {
return fields;
}
public String getDestination() {
return destination;
}
public String getClazz() {
return clazz;
}
public Boolean getArray() {
return isArray;
}
}

View file

@ -0,0 +1,118 @@
package ru.spcex.clearing.backendapi.meta;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.util.HashMap;
import java.util.Map;
public class ActionField {
@JsonProperty(value = "code")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
private String code;
@JsonProperty(value = "name")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
private String name;
@JsonProperty(value = "shortname")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
private String shortname;
@JsonProperty(value = "linkCode")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
private String linkcode;
@JsonProperty(value = "link")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
private String link;
@JsonProperty(value = "field")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
private String field;
@JsonProperty(value = "length")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
private Integer length;
@JsonProperty(value = "required")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
private Boolean required;
@JsonProperty(value = "table")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
private String table;
@JsonProperty(value = "type")
@JsonDeserialize(using = MetaDataTypeDeserializer.class)
@JsonSerialize(using = MetaDataTypeSerializer.class, include = JsonSerialize.Inclusion.NON_EMPTY)
private MetaDataTypes type;
@JsonProperty(value = "virtual")
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
private Boolean virtual;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<>();
public String getCode() {
return code;
}
public String getField() {
return field;
}
public Integer getLength() {
return length;
}
public Boolean isRequired() {
return required;
}
public MetaDataTypes getType() {
return type;
}
public String getName() {
return name;
}
public String getLink() {
return link;
}
public String getShortname() {
return shortname;
}
public String getLinkcode() {
return linkcode;
}
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
public Boolean isVirtual(){
return virtual;
}
public Boolean getVirtual() {
return virtual;
}
public void setVirtual(Boolean virtual) {
this.virtual = virtual;
}
}

View file

@ -0,0 +1,21 @@
package ru.spcex.clearing.backendapi.meta;
import ru.clearing.classes.ConstSerializable;
public class ClearingMetaServerValidationException extends RuntimeException {
private static final long serialVersionUID = ConstSerializable.serialVersionUID;
public ClearingMetaServerValidationException(String s) {
super(s);
}
public ClearingMetaServerValidationException(String s, Throwable throwable) {
super(s, throwable);
}
public ClearingMetaServerValidationException(Throwable throwable) {
super(throwable);
}
}

View file

@ -0,0 +1,100 @@
package ru.spcex.clearing.backendapi.meta;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
public abstract class FieldExtracted {
private final Logger log = LoggerFactory.getLogger(this.getClass());
private ActionField field;
private String memberName;
private Collection<String> getterNames;
public FieldExtracted(ActionField field) {
this.field = field;
this.memberName = field.getField() != null ? field.getField() : field.getCode();
this.getterNames = gettersForField(this.memberName);
}
public static Collection<String> gettersForField(String fieldName) {
String[] fieldParts = fieldName.split("\\.");
List<String> getters = new LinkedList<>();
for (String partName : fieldParts) {
getters.add(String.format("%s%s%s",
RfHelper.GETTER_NAME_PREFIX,
partName.substring(0, 1).toUpperCase(),
partName.substring(1, partName.length())
));
}
return getters;
}
@Override
public String toString() {
return String.format("%s (%s) (getters=%d)", field.getCode(), memberName, getterNames.size());
}
public abstract Object getObjectRef(Object o);
public Object extractValue(Object from)
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Object result = from;
for (String getterName : getGetterNames()) {
if (RfHelper.BUSINESS_OBJECT_REF.equals(result.getClass().getSimpleName()) && !RfHelper.GETTER_NAME_ID.equals(getterName)) {
Object resultNew = getObjectRef(result);
if (resultNew == null) {
log.warn("BusinessObject by referenceId does not exists!");
break;
}
result = resultNew;
}
Method m = result.getClass().getMethod(getterName);
result = m.invoke(result);
if (result == null)
break;
}
// тут нужно вернуть список id объектов а не список самих объектов для случая
// - add(r, "addresseeId", o.getAddressee() == null ? null : o.getAddressee().stream().map(OtcObjectBase::getId).collect(Collectors.toSet()), fieldFilter);
if (result instanceof Set && ((Set) result).size() > 0) {
try {
Set t = new HashSet();
Class citem = (((Set) result).iterator().next()).getClass();
for (Object item : (Set) result) {
t.add(citem.getMethod(RfHelper.GETTER_NAME_ID).invoke(item));
}
result = t;
} catch (Throwable ignored) {// вернем сами объекты
}
}
return result;
}
public ActionField getField() {
return field;
}
public void setField(ActionField field) {
this.field = field;
}
public void setMemberName(String memberName) {
this.memberName = memberName;
}
public void setGetterNames(Collection<String> getterNames) {
this.getterNames = getterNames;
}
public String getMemberName() {
return memberName;
}
public Collection<String> getGetterNames() {
return getterNames;
}
}

View file

@ -0,0 +1,49 @@
package ru.spcex.clearing.backendapi.meta;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.*;
public class MetaBase {
@JsonProperty(required = true, defaultValue = "unknown")
private String version = null;
public String getVersion() {
return version;
}
@JsonProperty(required = true)
private Map<String, ObjectEnumElement> enums = new LinkedHashMap<>();
@JsonProperty(required = true)
private Map<String, ObjectElement> objects = new LinkedHashMap<>();
@JsonProperty(required = true)
private List<Map<String, String>> types = new LinkedList<>();
@JsonProperty
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> views = new HashMap<>();
public Map<String, ObjectEnumElement> getEnums() {
return enums;
}
public Map<String, ObjectElement> getObjects() {
return objects;
}
public List<Map<String, String>> getTypes() {
return types;
}
public Map<String, Object> getViews() {
return views;
}
public void setViews(Map<String, Object> views) {
this.views = views;
}
}

View file

@ -0,0 +1,20 @@
package ru.spcex.clearing.backendapi.meta;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import ru.spcex.platform.utils.enumeration.IEnumId;
import java.io.IOException;
public class MetaDataTypeDeserializer extends JsonDeserializer<MetaDataTypes> {
@Override
public MetaDataTypes deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
if (p.getText() != null && p.getText().length() > 0) {
if (!"0".equals(p.getText()) && !p.getText().matches("[1-9]+[0-9]*")) return null;
Long metaDataType = new Long(p.getText());
return IEnumId.getEnumById(MetaDataTypes.class, metaDataType);
} else return null;
}
}

View file

@ -0,0 +1,15 @@
package ru.spcex.clearing.backendapi.meta;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
public class MetaDataTypeSerializer extends JsonSerializer<MetaDataTypes> {
@Override
public void serialize(MetaDataTypes metaDataTypes, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeNumber(metaDataTypes.getId());
}
}

View file

@ -0,0 +1,52 @@
package ru.spcex.clearing.backendapi.meta;
import ru.spcex.platform.utils.enumeration.IEnumId;
public enum MetaDataTypes implements IEnumId {
Identity(1L),
String(2L),
Long(3L),
DateTime(4L),
Time(5L),
Date(6L),
Array(7L),
Object(8L),
Boolean(9L),
Double(10L),
UID(11L);
private final Long id;
MetaDataTypes(Long id) {
this.id = id;
}
@Override
public java.lang.Long getId() {
return this.id;
}
public int getTypeSize() {
switch (this) {
case Long:
return java.lang.String.valueOf(java.lang.Long.MAX_VALUE).length();
case Identity:
return java.lang.String.valueOf(java.lang.Long.MAX_VALUE).length();
case DateTime:
return 25;
case Time:
return 25;
case Date:
return 25;
case Array:
return java.lang.String.valueOf(java.lang.Long.MAX_VALUE).length() * 400;
case Boolean:
return java.lang.Boolean.TRUE.toString().length();
case Double:
return 18;
case UID:
return 36;
}
return 0;
}
}

View file

@ -0,0 +1,191 @@
package ru.spcex.clearing.backendapi.meta;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
public abstract class MetaServer extends MetaBase {
private final Logger log = LoggerFactory.getLogger(this.getClass());
private Collection<ObjectExtracted> objectsExtracted;
private Map<String, ObjectExtracted> objectsExtractedByClazz;
private Map<String, ObjectExtracted> objectsExtractedByDestination;
private Map<String, ObjectExtracted> actionObjectsExtracted;
private Map<String, ObjectElement> objectElementByDestination;
protected abstract ObjectExtracted getImplInstanceObjectExtracted(String clazz, List<ActionField> actionFields);
@SuppressWarnings("Duplicates")
public void initAndValidate() throws ClearingMetaServerValidationException, OtcMetaServerGetterNotFoundException {
if (objectsExtracted == null) {
objectsExtracted = new LinkedList<>();
actionObjectsExtracted = new ConcurrentHashMap<>();
objectsExtractedByClazz = new ConcurrentHashMap<>();
objectsExtractedByDestination = new ConcurrentHashMap<>();
objectElementByDestination = new ConcurrentHashMap<>();
try {
Map<String, ObjectElement> objects = getObjects();
log.info("Meta objects:\n{}",
objects.values()
.stream()
.map(ObjectElement::getName)
.collect(Collectors.joining(";", "[", "]")));
for (String key : objects.keySet()) {
ObjectExtracted oe;
ObjectElement objectElement = objects.get(key);
if (objectElement.getSubscription() != null) {
objectElementByDestination.put(objectElement.getSubscription().destination, objectElement);
if (objectElement.getSubscriptionHistory() != null) {
objectElementByDestination.put(objectElement.getSubscriptionHistory().destination, objectElement);
}
}
try {
oe = getImplInstanceObjectExtracted(objectElement.getClazz(), objectElement.getFields());
} catch (Throwable e) {
log.warn("META SERVER >>> Класс {} не найден!", objects.get(key).getClazz());
continue;
}
objectsExtracted.add(oe);
objectsExtractedByClazz.put(oe.getClassName(), oe);
if (objectElement.getSubscription() != null && objectElement.getSubscription().destination != null) {
objectsExtractedByDestination.put(objectElement.getSubscription().destination, oe);
}
for (ActionElement actionElement : objectElement.getActions()) {
if (actionElement.getClazz() == null) {
continue;
}
try {
oe = getImplInstanceObjectExtracted(actionElement.getClazz(), actionElement.getFields());
if (actionElement.getArray() != null) {
oe.setArray(actionElement.getArray());
}
} catch (Throwable e) {
log.warn("META SERVER >>> {}", e.getLocalizedMessage());
continue;
}
actionObjectsExtracted.put(actionElement.getDestination(), oe);
}
}
} catch (Throwable e) {
throw new ClearingMetaServerValidationException(e.getLocalizedMessage());
}
}
for (ObjectExtracted o : this.objectsExtracted) {
try {
if (!RfHelper.isAbstract(o.getClazz())) {
try {
Object instance = newInstance(o.getClassName());
// создается успешно.
} catch (Throwable e) {
log.warn("META SERVER >>> Не удается создать класс {} !", o.getClassName());
}
}
validateGetterForObject(o);
} catch (OtcMetaServerGetterNotFoundException e) {
throw e;
} catch (Throwable e) {
throw new ClearingMetaServerValidationException(e.getLocalizedMessage());
}
}
for (ObjectExtracted o : this.actionObjectsExtracted.values()) {
try {
if (!RfHelper.isAbstract(o.getClazz())) {
try {
Object instance = newInstance(o.getClassName());
// создается успешно.
} catch (Throwable e) {
log.warn("META SERVER ACTION >>> Не удается создать класс {} !", o.getClassName());
}
}
validateGetterForObject(o);
} catch (OtcMetaServerGetterNotFoundException e) {
throw e;
} catch (Throwable e) {
throw new ClearingMetaServerValidationException(e.getLocalizedMessage());
}
}
}
/**
* проверим наличие геттеров к полям
*
* @param o
* @throws ClassNotFoundException
*/
private void validateGetterForObject(ObjectExtracted o) throws ClassNotFoundException {
for (FieldExtracted field : o.getFields()) {
Class<?> c = o.getClazz();
for (String getterName : field.getGetterNames()) {
try {
Method m = RfHelper.searchGetter(c, getterName);
if (m == null) {
for (Class<?> sub : RfHelper.getSubclasses(c)) {
m = RfHelper.searchGetter(sub, getterName);
if (m != null)
break;
}
if (m == null) {
throw new OtcMetaServerGetterNotFoundException(c, getterName);
}
}
c = RfHelper.getMetodReturnClazz(m);
} catch (OtcMetaServerGetterNotFoundException e) {
log.warn("META SERVER >>> Геттер {}.{} не найден!", o.getClassName(), getterName);
}
}
}
}
public Object newInstance(String className, Object... args) throws Exception {
Class<?> clazz = Class.forName(className);
if (args == null || args.length == 0) {
return clazz.newInstance();
}
List<Class<?>> argTypes = new ArrayList<Class<?>>();
for (Object object : args) {
argTypes.add(object.getClass());
}
Constructor<?> explicitConstructor = clazz.getConstructor(argTypes.toArray(new Class[argTypes.size()]));
return explicitConstructor.newInstance(args);
}
public Collection<ObjectExtracted> getObjectsExtracted() {
return objectsExtracted;
}
public Map<String, ObjectExtracted> getActionObjectsExtracted() {
return actionObjectsExtracted;
}
public Map<String, ObjectExtracted> getObjectsExtractedByClazz() {
return objectsExtractedByClazz;
}
public Map<String, ObjectElement> getObjectElementByDestination() {
return objectElementByDestination;
}
public Map<String, ObjectExtracted> getObjectsExtractedByDestination() {
return objectsExtractedByDestination;
}
public Integer getPartSizeValueByDestination(String destination) {
ObjectElement objectElementByDestination = getObjectElementByDestination().get(destination);
Integer partSize = null;
if (objectElementByDestination == null) {
log.warn("Null objectElement for destination: {}", destination);
} else {
partSize = objectElementByDestination.getSubscription().getPartSize();
}
return partSize;
}
}

View file

@ -0,0 +1,79 @@
package ru.spcex.clearing.backendapi.meta;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.*;
@SuppressWarnings({"DefaultAnnotationParam", "unused"})
public class ObjectElement {
@JsonProperty(required = true)
private String name = null;
@JsonProperty(value = "class", required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String clazz = null;
@JsonProperty(required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String table = null;
@JsonProperty(value = "fields", required = true)
private List<ActionField> fields = new LinkedList<>();
@JsonProperty(required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> query = new LinkedHashMap<>();
@JsonProperty(required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Subscription subscription;
@JsonProperty(required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Subscription subscriptionHistory;
@JsonProperty(required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<ActionElement> actions = new LinkedList<>();
@JsonProperty(required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<Map<String, String>> values = new LinkedList<>();
@JsonProperty(required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> views = new HashMap<>();
public String getName() {
return name;
}
public String getClazz() {
return clazz;
}
public Map<String, Object> getQuery() {
return query;
}
public Subscription getSubscription() {
return subscription;
}
public List<ActionElement> getActions() {
return actions;
}
public List<Map<String, String>> getValues() {
return values;
}
public List<ActionField> getFields() {
return fields;
}
public Subscription getSubscriptionHistory() {
return subscriptionHistory;
}
}

View file

@ -0,0 +1,63 @@
package ru.spcex.clearing.backendapi.meta;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.*;
@SuppressWarnings({"DefaultAnnotationParam", "unused"})
public class ObjectEnumElement {
@JsonProperty(required = true)
private String name = null;
@JsonProperty(value = "class", required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String clazz = null;
@JsonProperty(required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private String table = null;
@JsonProperty(value = "fields", required = true)
private List<ActionField> fields = new LinkedList<>();
@JsonProperty(required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> query = new LinkedHashMap<>();
@JsonProperty(required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<ActionElement> actions = new LinkedList<>();
@JsonProperty(required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<Map<String, Object>> values = new LinkedList<>();
@JsonProperty(required = false)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> views = new HashMap<>();
public String getName() {
return name;
}
public String getClazz() {
return clazz;
}
public Map<String, Object> getQuery() {
return query;
}
public List<ActionElement> getActions() {
return actions;
}
public List<Map<String, Object>> getValues() {
return values;
}
public List<ActionField> getFields() {
return fields;
}
}

View file

@ -0,0 +1,61 @@
package ru.spcex.clearing.backendapi.meta;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
public abstract class ObjectExtracted {
private String className;
private Class<?> clazz;
private List<FieldExtracted> fields = new LinkedList<>();
private Map<String, FieldExtracted> fieldByCode = new ConcurrentHashMap<>();
private boolean isArray = false;
public ObjectExtracted(String clazz, List<ActionField> actionFields) {
this.className = clazz;
try {
this.clazz = Class.forName(this.className);
} catch (ClassNotFoundException e) {
throw new ClearingMetaServerValidationException(String.format("Class not found [%s]", this.className));
}
for (ActionField field : actionFields) {
if (field.getVirtual() != null && field.isVirtual()){
continue;
}
FieldExtracted fe = getImplFieldExtracted(field);
fields.add(fe);
fieldByCode.put(field.getCode(), fe);
}
}
public abstract FieldExtracted getImplFieldExtracted(ActionField field);
@Override
public String toString() {
return String.format("%s (fields=%d)", className, fields.size());
}
public String getClassName() {
return className;
}
public Class<?> getClazz() {
return clazz;
}
public List<FieldExtracted> getFields() {
return new ArrayList<>(fields);
}
public Map<String, FieldExtracted> getFieldByCode() {
return new HashMap<>(fieldByCode);
}
public boolean isArray() {
return isArray;
}
public void setArray(boolean array) {
isArray = array;
}
}

View file

@ -0,0 +1,18 @@
package ru.spcex.clearing.backendapi.meta;
import ru.clearing.classes.ConstSerializable;
public class OtcMetaServerGetterNotFoundException extends RuntimeException {
private static final long serialVersionUID = ConstSerializable.serialVersionUID;
public OtcMetaServerGetterNotFoundException(Class clazz, String getterName) {
super(
String.format(
"Method %s() not found for class %s and subclasses!",
getterName, clazz
)
);
}
}

View file

@ -0,0 +1,58 @@
package ru.spcex.clearing.backendapi.meta;
import org.reflections.Reflections;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class RfHelper {
private static Map<String, Reflections> REFLECTION_CACHE = new HashMap<>();
public static final String BUSINESS_OBJECT_REF = "BusinessObjectRef";
public static final String OTC_CLASSES_PACKAGE = "com.moex.otc.classes";
public static final String GETTER_NAME_PREFIX = "get";
public static final String GETTER_NAME_ID = GETTER_NAME_PREFIX + "Id";
public static Method searchGetter(Class<?> methodOwner, String name) {
for (Method m : methodOwner.getMethods()) {
if (m.getName().equals(name)) {
return m;
}
}
return null;
}
public static <T> Class<?>[] getSubclasses(Class<T> clazz) {
return getSubclasses(clazz, OTC_CLASSES_PACKAGE);
}
public static <T> Class<?>[] getSubclasses(Class<T> clazz, String packageName) {
Reflections reflections = REFLECTION_CACHE.computeIfAbsent(packageName, k -> new Reflections(packageName));
Set<Class<? extends T>> classes = reflections.getSubTypesOf(clazz);
return classes.toArray(new Class<?>[]{});
}
public static boolean isAbstract(Class<?> clazz) {
return Modifier.isAbstract(clazz.getModifiers());
}
public static Class getMetodReturnClazz(Method m) throws ClassNotFoundException {
Type t = m.getAnnotatedReturnType().getType();
if (t instanceof ParameterizedType) {
Class<?> raw = Class.forName(((ParameterizedType) t).getRawType().getTypeName());
if (BUSINESS_OBJECT_REF.equals(raw.getSimpleName())) {
return Class.forName(((ParameterizedType) t).getActualTypeArguments()[0].getTypeName());
} else if ("Set".equals(raw.getSimpleName())) { // множества пока не распаковываем
return Class.forName(raw.getName());
}
}
return Class.forName(t.getTypeName());
}
}

View file

@ -0,0 +1,38 @@
package ru.spcex.clearing.backendapi.meta;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Subscription {
@JsonProperty
public String destination;
@JsonProperty
public boolean enabled;
@JsonProperty(value = "partSize")
private Integer partSize;
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Integer getPartSize() {
return partSize;
}
public void setPartSize(Integer partSize) {
this.partSize = partSize;
}
}