meta parsing
This commit is contained in:
parent
15f42c96b8
commit
47b0e6d6c4
16 changed files with 937 additions and 0 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue