163 changed files with 3650 additions and 299 deletions
@ -1,23 +1,195 @@ |
|||
package io.sc.engine.rule.core.code.impl.support.processor; |
|||
|
|||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
|||
import com.fasterxml.jackson.core.type.TypeReference; |
|||
import io.sc.engine.rule.core.math.MathType; |
|||
import io.sc.engine.rule.core.po.lib.Indicator; |
|||
import io.sc.engine.rule.core.po.lib.processor.MathFormulaIndicatorProcessor; |
|||
import io.sc.engine.rule.core.po.model.Parameter; |
|||
import io.sc.engine.rule.core.po.model.processor.MathFormulaParameterProcessor; |
|||
import io.sc.engine.rule.core.util.JacksonObjectMapper; |
|||
import org.springframework.util.StringUtils; |
|||
|
|||
import java.util.List; |
|||
import javax.xml.bind.JAXBContext; |
|||
import javax.xml.bind.JAXBElement; |
|||
import javax.xml.bind.Unmarshaller; |
|||
import javax.xml.stream.XMLEventReader; |
|||
import javax.xml.stream.XMLInputFactory; |
|||
import javax.xml.stream.XMLStreamReader; |
|||
import javax.xml.stream.events.Characters; |
|||
import javax.xml.stream.events.EndElement; |
|||
import javax.xml.stream.events.StartElement; |
|||
import javax.xml.stream.events.XMLEvent; |
|||
import java.io.Reader; |
|||
import java.io.StringReader; |
|||
import java.util.ArrayDeque; |
|||
|
|||
@JsonIgnoreProperties(ignoreUnknown=true) |
|||
public class MathFormula { |
|||
public static List<ConditionRange> parse(String json) throws Exception { |
|||
return JacksonObjectMapper.getDefaultObjectMapper().readValue(json, new TypeReference<List<ConditionRange>>(){}); |
|||
public static MathType parse(String xml) throws Exception { |
|||
if(!StringUtils.hasText(xml)){ |
|||
return null; |
|||
} |
|||
Reader reader = new StringReader(xml); |
|||
XMLInputFactory factory = XMLInputFactory.newInstance(); // Or newFactory()
|
|||
XMLStreamReader xmlReader = factory.createXMLStreamReader(reader); |
|||
|
|||
JAXBContext decodeJAXBContext =JAXBContext.newInstance(MathType.class); |
|||
Unmarshaller unmarshaller =decodeJAXBContext.createUnmarshaller(); |
|||
JAXBElement<MathType> obj =unmarshaller.unmarshal(xmlReader,MathType.class); |
|||
return obj.getValue(); |
|||
} |
|||
|
|||
public static String generateGroovyCode(Indicator indicator, MathFormulaIndicatorProcessor processor) throws Exception { |
|||
if (indicator == null || processor == null) { |
|||
return null; |
|||
} |
|||
String xml =processor.getMathFormula(); |
|||
if(!StringUtils.hasText(xml)){ |
|||
return null; |
|||
} |
|||
Reader reader = new StringReader(xml); |
|||
XMLInputFactory xmlInputFactory =XMLInputFactory.newFactory(); |
|||
XMLEventReader xmlEventReader =xmlInputFactory.createXMLEventReader(reader); |
|||
StringBuilder sb =new StringBuilder(); |
|||
while(xmlEventReader.hasNext()){ |
|||
XMLEvent xmlEvent = xmlEventReader.nextEvent(); |
|||
if (xmlEvent.isStartElement()){ |
|||
StartElement startElement = xmlEvent.asStartElement(); |
|||
if("mi".equalsIgnoreCase(startElement.getName().getLocalPart())){ |
|||
|
|||
} |
|||
} else if(xmlEvent.isCharacters()){ |
|||
Characters characters = xmlEvent.asCharacters(); |
|||
sb.append(characters.getData()); |
|||
} else if(xmlEvent.isEndElement()){ |
|||
EndElement endElement =xmlEvent.asEndElement(); |
|||
if("mi".equalsIgnoreCase(endElement.getName().getLocalPart())) { |
|||
|
|||
} |
|||
} |
|||
} |
|||
return sb.toString(); |
|||
} |
|||
|
|||
public static String generateGroovyCode(Parameter parameter, MathFormulaParameterProcessor processor) throws Exception{ |
|||
if (parameter == null || processor == null) { |
|||
return null; |
|||
} |
|||
MathType math =parse(processor.getMathFormula()); |
|||
if(math==null){ |
|||
return null; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public static void main(String[] args)throws Exception { |
|||
String xml ="<math>\n" + |
|||
" <mspace/>\n" + |
|||
" <mi>x</mi>\n" + |
|||
" <mspace/>\n" + |
|||
" <mo>+</mo>\n" + |
|||
" <mspace/>\n" + |
|||
" <mn>c</mn>\n" + |
|||
" <mspace/>\n" + |
|||
"</math>"; |
|||
Reader reader = new StringReader(xml); |
|||
XMLInputFactory xmlInputFactory =XMLInputFactory.newFactory(); |
|||
XMLEventReader xmlEventReader =xmlInputFactory.createXMLEventReader(reader); |
|||
StringBuilder sb =new StringBuilder(); |
|||
ArrayDeque<String> deque =new ArrayDeque<>(); |
|||
ArrayDeque<Boolean> twoPartDeque =new ArrayDeque<>(); |
|||
while(xmlEventReader.hasNext()){ |
|||
XMLEvent xmlEvent = xmlEventReader.nextEvent(); |
|||
if (xmlEvent.isStartElement()){ |
|||
StartElement startElement = xmlEvent.asStartElement(); |
|||
deque.push(startElement.getName().getLocalPart()); |
|||
String tagName =deque.peek(); |
|||
switch (tagName){ |
|||
case "mspace": |
|||
break; |
|||
case "mrow": |
|||
sb.append("("); |
|||
break; |
|||
case "mfrac": |
|||
twoPartDeque.push(true); |
|||
break; |
|||
case "msqrt": |
|||
sb.append("sqrt("); |
|||
break; |
|||
case "mroot": |
|||
twoPartDeque.push(true); |
|||
sb.append("root("); |
|||
break; |
|||
case "msup": |
|||
twoPartDeque.push(true); |
|||
sb.append("pow("); |
|||
break; |
|||
} |
|||
} else if(xmlEvent.isCharacters()){ |
|||
String tagName =deque.peek(); |
|||
Characters characters = xmlEvent.asCharacters(); |
|||
String text =characters.getData().trim(); |
|||
switch (tagName){ |
|||
case "mi": |
|||
sb.append("${").append(text); |
|||
break; |
|||
case "mo": |
|||
switch (text){ |
|||
case "×": |
|||
sb.append("*"); |
|||
break; |
|||
case "≥": |
|||
sb.append(">="); |
|||
break; |
|||
case "≤": |
|||
sb.append("<="); |
|||
break; |
|||
case "=": |
|||
sb.append("=="); |
|||
break; |
|||
default: |
|||
sb.append(text); |
|||
} |
|||
break; |
|||
case "mn": |
|||
sb.append(text); |
|||
break; |
|||
} |
|||
} else if(xmlEvent.isEndElement()) { |
|||
EndElement endElement = xmlEvent.asEndElement(); |
|||
String tagName = deque.peek(); |
|||
deque.pop(); |
|||
switch (tagName) { |
|||
case "mi": |
|||
sb.append("}"); |
|||
break; |
|||
case "mspace": |
|||
break; |
|||
case "mrow": |
|||
sb.append(")"); |
|||
if (twoPartDeque.peek()!=null && twoPartDeque.peek() && deque.peek()!=null) { |
|||
switch (deque.peek()){ |
|||
case "mfrac": |
|||
sb.append("/"); |
|||
break; |
|||
case "mroot": |
|||
case "msup": |
|||
sb.append(","); |
|||
break; |
|||
} |
|||
twoPartDeque.pop(); |
|||
} |
|||
break; |
|||
case "mfrac": |
|||
break; |
|||
case "msqrt": |
|||
case "mroot": |
|||
case "msup": |
|||
sb.append(")"); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
System.out.println(sb.toString()); |
|||
} |
|||
} |
|||
|
@ -0,0 +1,330 @@ |
|||
//
|
|||
// 此文件是由 JavaTM Architecture for XML Binding (JAXB) 引用实现 v2.2.8-b130911.1802 生成的
|
|||
// 请访问 <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
|
|||
// 在重新编译源模式时, 对此文件的所有修改都将丢失。
|
|||
// 生成时间: 2024.07.16 时间 03:39:28 PM CST
|
|||
//
|
|||
|
|||
|
|||
package io.sc.engine.rule.core.math; |
|||
|
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
import javax.xml.bind.annotation.XmlAccessType; |
|||
import javax.xml.bind.annotation.XmlAccessorType; |
|||
import javax.xml.bind.annotation.XmlType; |
|||
|
|||
|
|||
/** |
|||
* <p>mathType complex type的 Java 类。 |
|||
* |
|||
* <p>以下模式片段指定包含在此类中的预期内容。 |
|||
* |
|||
* <pre> |
|||
* <complexType name="mathType"> |
|||
* <complexContent> |
|||
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> |
|||
* <sequence> |
|||
* <element name="mi" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/> |
|||
* <element name="mn" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/> |
|||
* <element name="mo" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/> |
|||
* <element name="mspace" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/> |
|||
* <element name="msqrt" type="{http://www.w3.org/2001/XMLSchema}string" maxOccurs="unbounded" minOccurs="0"/> |
|||
* <element name="mroot" type="{http://www.sc.io/engine/rule/core/math}mathType" maxOccurs="unbounded" minOccurs="0"/> |
|||
* <element name="mrow" type="{http://www.sc.io/engine/rule/core/math}mathType" maxOccurs="unbounded" minOccurs="0"/> |
|||
* <element name="msup" type="{http://www.sc.io/engine/rule/core/math}mathType" maxOccurs="unbounded" minOccurs="0"/> |
|||
* <element name="mfrac" type="{http://www.sc.io/engine/rule/core/math}mathType" maxOccurs="unbounded" minOccurs="0"/> |
|||
* </sequence> |
|||
* </restriction> |
|||
* </complexContent> |
|||
* </complexType> |
|||
* </pre> |
|||
* |
|||
* |
|||
*/ |
|||
@XmlAccessorType(XmlAccessType.FIELD) |
|||
@XmlType(name = "mathType", propOrder = { |
|||
"mi", |
|||
"mn", |
|||
"mo", |
|||
"mspace", |
|||
"msqrt", |
|||
"mroot", |
|||
"mrow", |
|||
"msup", |
|||
"mfrac" |
|||
}) |
|||
public class MathType { |
|||
|
|||
protected List<String> mi; |
|||
protected List<String> mn; |
|||
protected List<String> mo; |
|||
protected List<String> mspace; |
|||
protected List<String> msqrt; |
|||
protected List<MathType> mroot; |
|||
protected List<MathType> mrow; |
|||
protected List<MathType> msup; |
|||
protected List<MathType> mfrac; |
|||
|
|||
/** |
|||
* Gets the value of the mi property. |
|||
* |
|||
* <p> |
|||
* This accessor method returns a reference to the live list, |
|||
* not a snapshot. Therefore any modification you make to the |
|||
* returned list will be present inside the JAXB object. |
|||
* This is why there is not a <CODE>set</CODE> method for the mi property. |
|||
* |
|||
* <p> |
|||
* For example, to add a new item, do as follows: |
|||
* <pre> |
|||
* getMi().add(newItem); |
|||
* </pre> |
|||
* |
|||
* |
|||
* <p> |
|||
* Objects of the following type(s) are allowed in the list |
|||
* {@link String } |
|||
* |
|||
* |
|||
*/ |
|||
public List<String> getMi() { |
|||
if (mi == null) { |
|||
mi = new ArrayList<String>(); |
|||
} |
|||
return this.mi; |
|||
} |
|||
|
|||
/** |
|||
* Gets the value of the mn property. |
|||
* |
|||
* <p> |
|||
* This accessor method returns a reference to the live list, |
|||
* not a snapshot. Therefore any modification you make to the |
|||
* returned list will be present inside the JAXB object. |
|||
* This is why there is not a <CODE>set</CODE> method for the mn property. |
|||
* |
|||
* <p> |
|||
* For example, to add a new item, do as follows: |
|||
* <pre> |
|||
* getMn().add(newItem); |
|||
* </pre> |
|||
* |
|||
* |
|||
* <p> |
|||
* Objects of the following type(s) are allowed in the list |
|||
* {@link String } |
|||
* |
|||
* |
|||
*/ |
|||
public List<String> getMn() { |
|||
if (mn == null) { |
|||
mn = new ArrayList<String>(); |
|||
} |
|||
return this.mn; |
|||
} |
|||
|
|||
/** |
|||
* Gets the value of the mo property. |
|||
* |
|||
* <p> |
|||
* This accessor method returns a reference to the live list, |
|||
* not a snapshot. Therefore any modification you make to the |
|||
* returned list will be present inside the JAXB object. |
|||
* This is why there is not a <CODE>set</CODE> method for the mo property. |
|||
* |
|||
* <p> |
|||
* For example, to add a new item, do as follows: |
|||
* <pre> |
|||
* getMo().add(newItem); |
|||
* </pre> |
|||
* |
|||
* |
|||
* <p> |
|||
* Objects of the following type(s) are allowed in the list |
|||
* {@link String } |
|||
* |
|||
* |
|||
*/ |
|||
public List<String> getMo() { |
|||
if (mo == null) { |
|||
mo = new ArrayList<String>(); |
|||
} |
|||
return this.mo; |
|||
} |
|||
|
|||
/** |
|||
* Gets the value of the mspace property. |
|||
* |
|||
* <p> |
|||
* This accessor method returns a reference to the live list, |
|||
* not a snapshot. Therefore any modification you make to the |
|||
* returned list will be present inside the JAXB object. |
|||
* This is why there is not a <CODE>set</CODE> method for the mspace property. |
|||
* |
|||
* <p> |
|||
* For example, to add a new item, do as follows: |
|||
* <pre> |
|||
* getMspace().add(newItem); |
|||
* </pre> |
|||
* |
|||
* |
|||
* <p> |
|||
* Objects of the following type(s) are allowed in the list |
|||
* {@link String } |
|||
* |
|||
* |
|||
*/ |
|||
public List<String> getMspace() { |
|||
if (mspace == null) { |
|||
mspace = new ArrayList<String>(); |
|||
} |
|||
return this.mspace; |
|||
} |
|||
|
|||
/** |
|||
* Gets the value of the msqrt property. |
|||
* |
|||
* <p> |
|||
* This accessor method returns a reference to the live list, |
|||
* not a snapshot. Therefore any modification you make to the |
|||
* returned list will be present inside the JAXB object. |
|||
* This is why there is not a <CODE>set</CODE> method for the msqrt property. |
|||
* |
|||
* <p> |
|||
* For example, to add a new item, do as follows: |
|||
* <pre> |
|||
* getMsqrt().add(newItem); |
|||
* </pre> |
|||
* |
|||
* |
|||
* <p> |
|||
* Objects of the following type(s) are allowed in the list |
|||
* {@link String } |
|||
* |
|||
* |
|||
*/ |
|||
public List<String> getMsqrt() { |
|||
if (msqrt == null) { |
|||
msqrt = new ArrayList<String>(); |
|||
} |
|||
return this.msqrt; |
|||
} |
|||
|
|||
/** |
|||
* Gets the value of the mroot property. |
|||
* |
|||
* <p> |
|||
* This accessor method returns a reference to the live list, |
|||
* not a snapshot. Therefore any modification you make to the |
|||
* returned list will be present inside the JAXB object. |
|||
* This is why there is not a <CODE>set</CODE> method for the mroot property. |
|||
* |
|||
* <p> |
|||
* For example, to add a new item, do as follows: |
|||
* <pre> |
|||
* getMroot().add(newItem); |
|||
* </pre> |
|||
* |
|||
* |
|||
* <p> |
|||
* Objects of the following type(s) are allowed in the list |
|||
* {@link MathType } |
|||
* |
|||
* |
|||
*/ |
|||
public List<MathType> getMroot() { |
|||
if (mroot == null) { |
|||
mroot = new ArrayList<MathType>(); |
|||
} |
|||
return this.mroot; |
|||
} |
|||
|
|||
/** |
|||
* Gets the value of the mrow property. |
|||
* |
|||
* <p> |
|||
* This accessor method returns a reference to the live list, |
|||
* not a snapshot. Therefore any modification you make to the |
|||
* returned list will be present inside the JAXB object. |
|||
* This is why there is not a <CODE>set</CODE> method for the mrow property. |
|||
* |
|||
* <p> |
|||
* For example, to add a new item, do as follows: |
|||
* <pre> |
|||
* getMrow().add(newItem); |
|||
* </pre> |
|||
* |
|||
* |
|||
* <p> |
|||
* Objects of the following type(s) are allowed in the list |
|||
* {@link MathType } |
|||
* |
|||
* |
|||
*/ |
|||
public List<MathType> getMrow() { |
|||
if (mrow == null) { |
|||
mrow = new ArrayList<MathType>(); |
|||
} |
|||
return this.mrow; |
|||
} |
|||
|
|||
/** |
|||
* Gets the value of the msup property. |
|||
* |
|||
* <p> |
|||
* This accessor method returns a reference to the live list, |
|||
* not a snapshot. Therefore any modification you make to the |
|||
* returned list will be present inside the JAXB object. |
|||
* This is why there is not a <CODE>set</CODE> method for the msup property. |
|||
* |
|||
* <p> |
|||
* For example, to add a new item, do as follows: |
|||
* <pre> |
|||
* getMsup().add(newItem); |
|||
* </pre> |
|||
* |
|||
* |
|||
* <p> |
|||
* Objects of the following type(s) are allowed in the list |
|||
* {@link MathType } |
|||
* |
|||
* |
|||
*/ |
|||
public List<MathType> getMsup() { |
|||
if (msup == null) { |
|||
msup = new ArrayList<MathType>(); |
|||
} |
|||
return this.msup; |
|||
} |
|||
|
|||
/** |
|||
* Gets the value of the mfrac property. |
|||
* |
|||
* <p> |
|||
* This accessor method returns a reference to the live list, |
|||
* not a snapshot. Therefore any modification you make to the |
|||
* returned list will be present inside the JAXB object. |
|||
* This is why there is not a <CODE>set</CODE> method for the mfrac property. |
|||
* |
|||
* <p> |
|||
* For example, to add a new item, do as follows: |
|||
* <pre> |
|||
* getMfrac().add(newItem); |
|||
* </pre> |
|||
* |
|||
* |
|||
* <p> |
|||
* Objects of the following type(s) are allowed in the list |
|||
* {@link MathType } |
|||
* |
|||
* |
|||
*/ |
|||
public List<MathType> getMfrac() { |
|||
if (mfrac == null) { |
|||
mfrac = new ArrayList<MathType>(); |
|||
} |
|||
return this.mfrac; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,60 @@ |
|||
//
|
|||
// 此文件是由 JavaTM Architecture for XML Binding (JAXB) 引用实现 v2.2.8-b130911.1802 生成的
|
|||
// 请访问 <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
|
|||
// 在重新编译源模式时, 对此文件的所有修改都将丢失。
|
|||
// 生成时间: 2024.07.16 时间 03:39:28 PM CST
|
|||
//
|
|||
|
|||
|
|||
package io.sc.engine.rule.core.math; |
|||
|
|||
import javax.xml.bind.JAXBElement; |
|||
import javax.xml.bind.annotation.XmlElementDecl; |
|||
import javax.xml.bind.annotation.XmlRegistry; |
|||
import javax.xml.namespace.QName; |
|||
|
|||
|
|||
/** |
|||
* This object contains factory methods for each |
|||
* Java content interface and Java element interface |
|||
* generated in the io.sc.engine.rule.core.math package. |
|||
* <p>An ObjectFactory allows you to programatically |
|||
* construct new instances of the Java representation |
|||
* for XML content. The Java representation of XML |
|||
* content can consist of schema derived interfaces |
|||
* and classes representing the binding of schema |
|||
* type definitions, element declarations and model |
|||
* groups. Factory methods for each of these are |
|||
* provided in this class. |
|||
* |
|||
*/ |
|||
@XmlRegistry |
|||
public class ObjectFactory { |
|||
|
|||
private final static QName _Math_QNAME = new QName("http://www.sc.io/engine/rule/core/math", "math"); |
|||
|
|||
/** |
|||
* Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: io.sc.engine.rule.core.math |
|||
* |
|||
*/ |
|||
public ObjectFactory() { |
|||
} |
|||
|
|||
/** |
|||
* Create an instance of {@link MathType } |
|||
* |
|||
*/ |
|||
public MathType createMathType() { |
|||
return new MathType(); |
|||
} |
|||
|
|||
/** |
|||
* Create an instance of {@link JAXBElement }{@code <}{@link MathType }{@code >}} |
|||
* |
|||
*/ |
|||
@XmlElementDecl(namespace = "http://www.sc.io/engine/rule/core/math", name = "math") |
|||
public JAXBElement<MathType> createMath(MathType value) { |
|||
return new JAXBElement<MathType>(_Math_QNAME, MathType.class, null, value); |
|||
} |
|||
|
|||
} |
@ -0,0 +1,9 @@ |
|||
//
|
|||
// 此文件是由 JavaTM Architecture for XML Binding (JAXB) 引用实现 v2.2.8-b130911.1802 生成的
|
|||
// 请访问 <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
|
|||
// 在重新编译源模式时, 对此文件的所有修改都将丢失。
|
|||
// 生成时间: 2024.07.16 时间 03:39:28 PM CST
|
|||
//
|
|||
|
|||
@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.sc.io/engine/rule/core/math") |
|||
package io.sc.engine.rule.core.math; |
@ -0,0 +1,58 @@ |
|||
<template> |
|||
<w-dialog |
|||
ref="dialogRef" |
|||
width="900px" |
|||
:can-maximize="false" |
|||
:buttons="[ |
|||
{ |
|||
label: $t('confirm'), |
|||
noCaps: true, |
|||
click: () => { |
|||
targetElementRef.innerHTML = modelValueRef; |
|||
close(); |
|||
}, |
|||
}, |
|||
]" |
|||
> |
|||
<w-code-mirror |
|||
v-model="modelValueRef" |
|||
lang="java" |
|||
:rows="2" |
|||
:placeholder="true" |
|||
:line-wrap="true" |
|||
:line-break="false" |
|||
:auto-completion="autoCompletion" |
|||
@confirm="blur" |
|||
@cancel="cancel" |
|||
></w-code-mirror> |
|||
</w-dialog> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
import { ref } from 'vue'; |
|||
|
|||
const props = defineProps({ |
|||
autoCompletion: { |
|||
type: Function, |
|||
default: undefined, |
|||
}, |
|||
}); |
|||
|
|||
const dialogRef = ref(); |
|||
const targetElementRef = ref(); |
|||
const modelValueRef = ref(); |
|||
|
|||
const open = (element) => { |
|||
targetElementRef.value = element; |
|||
modelValueRef.value = element.innerHTML; |
|||
dialogRef.value.show(); |
|||
}; |
|||
|
|||
const close = () => { |
|||
dialogRef.value.hide(); |
|||
}; |
|||
|
|||
defineExpose({ |
|||
open, |
|||
close, |
|||
}); |
|||
</script> |
@ -0,0 +1,46 @@ |
|||
<template> |
|||
<span> |
|||
<math display="inline"> |
|||
<mrow> |
|||
<mo>isInfinite</mo> |
|||
<mi>(</mi> |
|||
<mi>x</mi> |
|||
<mi>)</mi> |
|||
</mrow> |
|||
</math> |
|||
</span> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
const xmlData = ` |
|||
<mspace></mspace> |
|||
<mrow> |
|||
<mo>isInfinite</mo> |
|||
<mi>(</mi> |
|||
<mspace></mspace> |
|||
<mi>x</mi> |
|||
<mspace></mspace> |
|||
<mi>)</mi> |
|||
</mrow> |
|||
<mspace></mspace> |
|||
`; |
|||
|
|||
const modelValueRef = defineModel({ type: String, default: '' }); |
|||
const props = defineProps({ |
|||
sourceCodeEditor: { type: Object, default: undefined }, |
|||
}); |
|||
|
|||
const dragstart = (event) => { |
|||
event.dataTransfer.setData('math', xmlData); |
|||
event.dataTransfer.setDragImage(event.srcElement, 0, 0); |
|||
}; |
|||
|
|||
const append = () => { |
|||
props.sourceCodeEditor?.dispatch(props.sourceCodeEditor?.state?.replaceSelection('isInfinite(x)')); |
|||
modelValueRef.value = modelValueRef.value + xmlData.replace('<mspace></mspace>', ''); |
|||
}; |
|||
|
|||
defineExpose({ |
|||
dragstart, |
|||
append, |
|||
}); |
|||
</script> |
@ -0,0 +1,46 @@ |
|||
<template> |
|||
<span> |
|||
<math display="isNan"> |
|||
<mrow> |
|||
<mo>isNan</mo> |
|||
<mi>(</mi> |
|||
<mi>x</mi> |
|||
<mi>)</mi> |
|||
</mrow> |
|||
</math> |
|||
</span> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
const xmlData = ` |
|||
<mspace></mspace> |
|||
<mrow> |
|||
<mo>isNan</mo> |
|||
<mi>(</mi> |
|||
<mspace></mspace> |
|||
<mi>x</mi> |
|||
<mspace></mspace> |
|||
<mi>)</mi> |
|||
</mrow> |
|||
<mspace></mspace> |
|||
`; |
|||
|
|||
const modelValueRef = defineModel({ type: String, default: '' }); |
|||
const props = defineProps({ |
|||
sourceCodeEditor: { type: Object, default: undefined }, |
|||
}); |
|||
|
|||
const dragstart = (event) => { |
|||
event.dataTransfer.setData('math', xmlData); |
|||
event.dataTransfer.setDragImage(event.srcElement, 0, 0); |
|||
}; |
|||
|
|||
const append = () => { |
|||
props.sourceCodeEditor?.dispatch(props.sourceCodeEditor?.state?.replaceSelection('isNan(x)')); |
|||
modelValueRef.value = modelValueRef.value + xmlData.replace('<mspace></mspace>', ''); |
|||
}; |
|||
|
|||
defineExpose({ |
|||
dragstart, |
|||
append, |
|||
}); |
|||
</script> |
@ -0,0 +1,46 @@ |
|||
<template> |
|||
<span> |
|||
<math display="inline"> |
|||
<mrow> |
|||
<mo>isNil</mo> |
|||
<mi>(</mi> |
|||
<mi>x</mi> |
|||
<mi>)</mi> |
|||
</mrow> |
|||
</math> |
|||
</span> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
const xmlData = ` |
|||
<mspace></mspace> |
|||
<mrow> |
|||
<mo>isNil</mo> |
|||
<mi>(</mi> |
|||
<mspace></mspace> |
|||
<mi>x</mi> |
|||
<mspace></mspace> |
|||
<mi>)</mi> |
|||
</mrow> |
|||
<mspace></mspace> |
|||
`; |
|||
|
|||
const modelValueRef = defineModel({ type: String, default: '' }); |
|||
const props = defineProps({ |
|||
sourceCodeEditor: { type: Object, default: undefined }, |
|||
}); |
|||
|
|||
const dragstart = (event) => { |
|||
event.dataTransfer.setData('math', xmlData); |
|||
event.dataTransfer.setDragImage(event.srcElement, 0, 0); |
|||
}; |
|||
|
|||
const append = () => { |
|||
props.sourceCodeEditor?.dispatch(props.sourceCodeEditor?.state?.replaceSelection('isNil(x)')); |
|||
modelValueRef.value = modelValueRef.value + xmlData.replace('<mspace></mspace>', ''); |
|||
}; |
|||
|
|||
defineExpose({ |
|||
dragstart, |
|||
append, |
|||
}); |
|||
</script> |
@ -0,0 +1,46 @@ |
|||
<template> |
|||
<span> |
|||
<math display="inline"> |
|||
<mrow> |
|||
<mo>isZero</mo> |
|||
<mi>(</mi> |
|||
<mi>x</mi> |
|||
<mi>)</mi> |
|||
</mrow> |
|||
</math> |
|||
</span> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
const xmlData = ` |
|||
<mspace></mspace> |
|||
<mrow> |
|||
<mo>isZero</mo> |
|||
<mi>(</mi> |
|||
<mspace></mspace> |
|||
<mi>x</mi> |
|||
<mspace></mspace> |
|||
<mi>)</mi> |
|||
</mrow> |
|||
<mspace></mspace> |
|||
`; |
|||
|
|||
const modelValueRef = defineModel({ type: String, default: '' }); |
|||
const props = defineProps({ |
|||
sourceCodeEditor: { type: Object, default: undefined }, |
|||
}); |
|||
|
|||
const dragstart = (event) => { |
|||
event.dataTransfer.setData('math', xmlData); |
|||
event.dataTransfer.setDragImage(event.srcElement, 0, 0); |
|||
}; |
|||
|
|||
const append = () => { |
|||
props.sourceCodeEditor?.dispatch(props.sourceCodeEditor?.state?.replaceSelection('isZero(x)')); |
|||
modelValueRef.value = modelValueRef.value + xmlData.replace('<mspace></mspace>', ''); |
|||
}; |
|||
|
|||
defineExpose({ |
|||
dragstart, |
|||
append, |
|||
}); |
|||
</script> |
@ -0,0 +1,35 @@ |
|||
<template> |
|||
<div v-close-popup :title="$t('math.toolbar.math.root')" class="text-xl" draggable="true" @dragstart="dragstart" @click="append"> |
|||
<math display="inline"> |
|||
<mroot> |
|||
<mrow><mspace></mspace><mi>x</mi><mspace></mspace></mrow> |
|||
<mrow><mspace></mspace><mi>y</mi><mspace></mspace></mrow> |
|||
</mroot> |
|||
</math> |
|||
</div> |
|||
</template> |
|||
<script setup lang="ts"> |
|||
const xmlData = ` |
|||
<mspace></mspace> |
|||
<mroot> |
|||
<mrow><mspace></mspace><mi>x</mi><mspace></mspace></mrow> |
|||
<mrow><mspace></mspace><mi>y</mi><mspace></mspace></mrow> |
|||
</mroot> |
|||
<mspace></mspace> |
|||
`; |
|||
|
|||
const modelValueRef = defineModel({ type: String, default: '' }); |
|||
const props = defineProps({ |
|||
sourceCodeEditor: { type: Object, default: undefined }, |
|||
}); |
|||
|
|||
const dragstart = (event) => { |
|||
event.dataTransfer.setData('math', xmlData); |
|||
event.dataTransfer.setDragImage(event.srcElement, 0, 0); |
|||
}; |
|||
|
|||
const append = () => { |
|||
props.sourceCodeEditor?.dispatch(props.sourceCodeEditor?.state?.replaceSelection('root(x,y)')); |
|||
modelValueRef.value = modelValueRef.value + xmlData.replace('<mspace></mspace>', ''); |
|||
}; |
|||
</script> |
@ -0,0 +1,190 @@ |
|||
import { Tools } from '@/platform'; |
|||
|
|||
class AutoCompletionManager2 { |
|||
parameters: object[]; |
|||
valueTypes: object[]; |
|||
|
|||
public setParameters(parameters) { |
|||
this.parameters = parameters; |
|||
} |
|||
public setValueTypes(valueTypes) { |
|||
this.valueTypes = valueTypes; |
|||
} |
|||
|
|||
public getOptions(path: string): any { |
|||
if (!path) { |
|||
return this.getParameterOptions(); |
|||
} |
|||
if (path.endsWith('.')) { |
|||
path = path.substring(0, path.length - 1); |
|||
} |
|||
const names = path.split('.'); |
|||
if (!names) { |
|||
return this.getParameterOptions(); |
|||
} |
|||
//参数
|
|||
const parameter = this.findParmeter(names[0]); |
|||
if (!parameter) { |
|||
return null; |
|||
} |
|||
const valueTypeString = parameter.valueType; |
|||
const valueTypeVersion = parameter.valueTypeVersion; |
|||
let valueType = this.findValueType(valueTypeString, valueTypeVersion); |
|||
if (!valueType || !valueType.properties || valueType.properties.length <= 0) { |
|||
return null; |
|||
} |
|||
let index = 1; |
|||
let lastNameIsNotCompleted = false; |
|||
while (index < names.length) { |
|||
const _valueType = this.findValueTypeByProperty(valueType.code, valueType.version, names[index]); |
|||
if (_valueType) { |
|||
valueType = _valueType; |
|||
} else { |
|||
lastNameIsNotCompleted = true; |
|||
} |
|||
index++; |
|||
} |
|||
|
|||
const options = []; |
|||
if (lastNameIsNotCompleted) { |
|||
for (const property of valueType.properties) { |
|||
if (property.name.indexOf(names[names.length - 1]) != -1) { |
|||
const propertyValueType = this.findValueType(property.valueType, property.valueTypeVersion); |
|||
if (!propertyValueType) { |
|||
continue; |
|||
} |
|||
const info = propertyValueType.version ? propertyValueType.name + '(V' + propertyValueType.version + ')' : propertyValueType.name; |
|||
options.push({ label: property.name, type: 'property', apply: '${' + property.name + '}', info: info }); |
|||
} |
|||
} |
|||
return options; |
|||
} else { |
|||
for (const property of valueType.properties) { |
|||
const propertyValueType = this.findValueType(property.valueType, property.valueTypeVersion); |
|||
if (!propertyValueType) { |
|||
continue; |
|||
} |
|||
const info = propertyValueType.version ? propertyValueType.name + '(V' + propertyValueType.version + ')' : propertyValueType.name; |
|||
options.push({ label: property.name, type: 'property', apply: '${' + property.name + '}', info: info }); |
|||
} |
|||
return options; |
|||
} |
|||
} |
|||
|
|||
public findParmeter(parameterName) { |
|||
for (const parameter of this.parameters) { |
|||
if (parameter.name === parameterName) { |
|||
return parameter; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public findValueType(valueTypeString, valueTypeVersion) { |
|||
for (const valueType of this.valueTypes) { |
|||
if (valueType.code === valueTypeString && valueType.version === valueTypeVersion) { |
|||
return valueType; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public findValueTypeByProperty(valueTypeString, valueTypeVersion, propertyName) { |
|||
const valueType = this.findValueType(valueTypeString, valueTypeVersion); |
|||
if (!valueType) { |
|||
return null; |
|||
} |
|||
for (const property of valueType.properties) { |
|||
if (property.name === propertyName) { |
|||
return this.findValueType(property.valueType, property.valueTypeVersion); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public getParameterOptions(): any { |
|||
const options = []; |
|||
for (const parameter of this.parameters) { |
|||
const valueType = this.findValueType(parameter.valueType, parameter.valueTypeVersion); |
|||
const info = valueType.version ? valueType.name + '(V' + valueType.version + ')' : valueType.name; |
|||
options.push({ label: parameter.name, type: 'variable', apply: '${' + parameter.name + '}', info: info }); |
|||
} |
|||
return options; |
|||
} |
|||
|
|||
public getPropertyOptions(parameterName: string): any { |
|||
let parameterType = undefined; |
|||
for (const parameter of this.parameters) { |
|||
if (parameter.name === parameterName) { |
|||
parameterType = parameter.valueType; |
|||
} |
|||
} |
|||
if (!parameterType) { |
|||
return null; |
|||
} |
|||
for (const type of this.valueTypes) { |
|||
if (type.code === parameterType) { |
|||
parameterType = type; |
|||
} |
|||
} |
|||
if (!parameterType) { |
|||
return null; |
|||
} |
|||
|
|||
if (parameterType.properties && parameterType.properties.length > 0) { |
|||
const options = []; |
|||
for (const property of parameterType.properties) { |
|||
options.push({ label: property.name, type: 'property', apply: '${' + property.name + '}', detail: this.findValueTypeInfo(property.valueType) }); |
|||
} |
|||
return options; |
|||
} |
|||
} |
|||
|
|||
public autoCompletionParameters(to, matchedText): any { |
|||
return { |
|||
from: to, |
|||
options: this.getParameterOptions(), |
|||
validFor: /(.*)?/, |
|||
}; |
|||
} |
|||
|
|||
public autoCompletionProperties(to, matchedText): any { |
|||
const matchedTextReverse = Tools.reverseString(matchedText); |
|||
const regReverse = /((.*)?\}(.+?)\{\$)+/g; //匹配 'xxx.}xxx{$' 模式
|
|||
const matcheds = matchedTextReverse.match(regReverse); |
|||
if (Tools.isUndefinedOrNull(matcheds) || matcheds.length <= 0) { |
|||
return null; |
|||
} |
|||
const matched = Tools.reverseString(matcheds[0]); |
|||
const parameterName = matched.replace(/\$\{(.+?)\}/g, '$1'); |
|||
console.log(parameterName); |
|||
if (Tools.isUndefinedOrNull(parameterName)) { |
|||
return null; |
|||
} |
|||
const options = this.getOptions(parameterName); |
|||
if (Tools.isUndefinedOrNull(options)) { |
|||
return null; |
|||
} |
|||
return { |
|||
from: to, |
|||
options: options, |
|||
//validFor: /^(.*)?$/,
|
|||
}; |
|||
} |
|||
|
|||
public autoCompletion(context): any { |
|||
const beforeMatched = context.matchBefore(/(.+?)/g); |
|||
if (Tools.isUndefinedOrNull(beforeMatched)) { |
|||
return null; |
|||
} |
|||
const beforeText = beforeMatched.text || ''; |
|||
if (beforeText.endsWith(' ')) { |
|||
//匹配参数
|
|||
return this.autoCompletionParameters(beforeMatched.to); |
|||
} else { |
|||
//匹配属性
|
|||
return this.autoCompletionProperties(beforeMatched.to, beforeText); |
|||
} |
|||
} |
|||
} |
|||
|
|||
export { AutoCompletionManager2 }; |
@ -0,0 +1,190 @@ |
|||
import { Tools } from '@/platform'; |
|||
|
|||
class AutoCompletionManager2 { |
|||
parameters: object[]; |
|||
valueTypes: object[]; |
|||
|
|||
public setParameters(parameters) { |
|||
this.parameters = parameters; |
|||
} |
|||
public setValueTypes(valueTypes) { |
|||
this.valueTypes = valueTypes; |
|||
} |
|||
|
|||
public getOptions(path: string): any { |
|||
if (!path) { |
|||
return this.getParameterOptions(); |
|||
} |
|||
if (path.endsWith('.')) { |
|||
path = path.substring(0, path.length - 1); |
|||
} |
|||
const names = path.split('.'); |
|||
if (!names) { |
|||
return this.getParameterOptions(); |
|||
} |
|||
//参数
|
|||
const parameter = this.findParmeter(names[0]); |
|||
if (!parameter) { |
|||
return null; |
|||
} |
|||
const valueTypeString = parameter.valueType; |
|||
const valueTypeVersion = parameter.valueTypeVersion; |
|||
let valueType = this.findValueType(valueTypeString, valueTypeVersion); |
|||
if (!valueType || !valueType.properties || valueType.properties.length <= 0) { |
|||
return null; |
|||
} |
|||
let index = 1; |
|||
let lastNameIsNotCompleted = false; |
|||
while (index < names.length) { |
|||
const _valueType = this.findValueTypeByProperty(valueType.code, valueType.version, names[index]); |
|||
if (_valueType) { |
|||
valueType = _valueType; |
|||
} else { |
|||
lastNameIsNotCompleted = true; |
|||
} |
|||
index++; |
|||
} |
|||
|
|||
const options = []; |
|||
if (lastNameIsNotCompleted) { |
|||
for (const property of valueType.properties) { |
|||
if (property.name.indexOf(names[names.length - 1]) != -1) { |
|||
const propertyValueType = this.findValueType(property.valueType, property.valueTypeVersion); |
|||
if (!propertyValueType) { |
|||
continue; |
|||
} |
|||
const info = propertyValueType.version ? propertyValueType.name + '(V' + propertyValueType.version + ')' : propertyValueType.name; |
|||
options.push({ label: property.name, type: 'property', apply: '${' + property.name + '}', info: info }); |
|||
} |
|||
} |
|||
return options; |
|||
} else { |
|||
for (const property of valueType.properties) { |
|||
const propertyValueType = this.findValueType(property.valueType, property.valueTypeVersion); |
|||
if (!propertyValueType) { |
|||
continue; |
|||
} |
|||
const info = propertyValueType.version ? propertyValueType.name + '(V' + propertyValueType.version + ')' : propertyValueType.name; |
|||
options.push({ label: property.name, type: 'property', apply: '${' + property.name + '}', info: info }); |
|||
} |
|||
return options; |
|||
} |
|||
} |
|||
|
|||
public findParmeter(parameterName) { |
|||
for (const parameter of this.parameters) { |
|||
if (parameter.name === parameterName) { |
|||
return parameter; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public findValueType(valueTypeString, valueTypeVersion) { |
|||
for (const valueType of this.valueTypes) { |
|||
if (valueType.code === valueTypeString && valueType.version === valueTypeVersion) { |
|||
return valueType; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public findValueTypeByProperty(valueTypeString, valueTypeVersion, propertyName) { |
|||
const valueType = this.findValueType(valueTypeString, valueTypeVersion); |
|||
if (!valueType) { |
|||
return null; |
|||
} |
|||
for (const property of valueType.properties) { |
|||
if (property.name === propertyName) { |
|||
return this.findValueType(property.valueType, property.valueTypeVersion); |
|||
} |
|||
} |
|||
} |
|||
|
|||
public getParameterOptions(): any { |
|||
const options = []; |
|||
for (const parameter of this.parameters) { |
|||
const valueType = this.findValueType(parameter.valueType, parameter.valueTypeVersion); |
|||
const info = valueType.version ? valueType.name + '(V' + valueType.version + ')' : valueType.name; |
|||
options.push({ label: parameter.name, type: 'variable', apply: '${' + parameter.name + '}', info: info }); |
|||
} |
|||
return options; |
|||
} |
|||
|
|||
public getPropertyOptions(parameterName: string): any { |
|||
let parameterType = undefined; |
|||
for (const parameter of this.parameters) { |
|||
if (parameter.name === parameterName) { |
|||
parameterType = parameter.valueType; |
|||
} |
|||
} |
|||
if (!parameterType) { |
|||
return null; |
|||
} |
|||
for (const type of this.valueTypes) { |
|||
if (type.code === parameterType) { |
|||
parameterType = type; |
|||
} |
|||
} |
|||
if (!parameterType) { |
|||
return null; |
|||
} |
|||
|
|||
if (parameterType.properties && parameterType.properties.length > 0) { |
|||
const options = []; |
|||
for (const property of parameterType.properties) { |
|||
options.push({ label: property.name, type: 'property', apply: '${' + property.name + '}', detail: this.findValueTypeInfo(property.valueType) }); |
|||
} |
|||
return options; |
|||
} |
|||
} |
|||
|
|||
public autoCompletionParameters(to, matchedText): any { |
|||
return { |
|||
from: to, |
|||
options: this.getParameterOptions(), |
|||
validFor: /(.*)?/, |
|||
}; |
|||
} |
|||
|
|||
public autoCompletionProperties(to, matchedText): any { |
|||
const matchedTextReverse = Tools.reverseString(matchedText); |
|||
const regReverse = /((.*)?\}(.+?)\{\$)+/g; //匹配 'xxx.}xxx{$' 模式
|
|||
const matcheds = matchedTextReverse.match(regReverse); |
|||
if (Tools.isUndefinedOrNull(matcheds) || matcheds.length <= 0) { |
|||
return null; |
|||
} |
|||
const matched = Tools.reverseString(matcheds[0]); |
|||
const parameterName = matched.replace(/\$\{(.+?)\}/g, '$1'); |
|||
console.log(parameterName); |
|||
if (Tools.isUndefinedOrNull(parameterName)) { |
|||
return null; |
|||
} |
|||
const options = this.getOptions(parameterName); |
|||
if (Tools.isUndefinedOrNull(options)) { |
|||
return null; |
|||
} |
|||
return { |
|||
from: to, |
|||
options: options, |
|||
//validFor: /^(.*)?$/,
|
|||
}; |
|||
} |
|||
|
|||
public autoCompletion(context): any { |
|||
const beforeMatched = context.matchBefore(/(.+?)/g); |
|||
if (Tools.isUndefinedOrNull(beforeMatched)) { |
|||
return null; |
|||
} |
|||
const beforeText = beforeMatched.text || ''; |
|||
if (beforeText.endsWith(' ')) { |
|||
//匹配参数
|
|||
return this.autoCompletionParameters(beforeMatched.to); |
|||
} else { |
|||
//匹配属性
|
|||
return this.autoCompletionProperties(beforeMatched.to, beforeText); |
|||
} |
|||
} |
|||
} |
|||
|
|||
export { AutoCompletionManager2 }; |
@ -0,0 +1,10 @@ |
|||
package io.sc.platform.core.exception; |
|||
|
|||
public class PasswordStrengthException extends RuntimeException { |
|||
public PasswordStrengthException() { |
|||
} |
|||
|
|||
public PasswordStrengthException(String message) { |
|||
super(message); |
|||
} |
|||
} |
@ -0,0 +1,8 @@ |
|||
package io.sc.platform.core.service; |
|||
|
|||
public interface Desensitizer { |
|||
public String desensitizer(String string); |
|||
|
|||
public boolean isEnable(); |
|||
public void setEnable(boolean enable); |
|||
} |
@ -0,0 +1,30 @@ |
|||
package io.sc.platform.core.service.support; |
|||
|
|||
import org.springframework.boot.context.properties.ConfigurationProperties; |
|||
|
|||
/** |
|||
* 脱敏配置属性类 |
|||
* application.desensitizer.enable = true |
|||
* application.desensitizer.implementClassName = io.sc.platform.orm.desensitizer.DefaultDesensitizer |
|||
*/ |
|||
@ConfigurationProperties("application.desensitizer") |
|||
public class DesensitizerProperties { |
|||
private boolean enable; |
|||
private String implementClassName; |
|||
|
|||
public boolean isEnable() { |
|||
return enable; |
|||
} |
|||
|
|||
public void setEnable(boolean enable) { |
|||
this.enable = enable; |
|||
} |
|||
|
|||
public String getImplementClassName() { |
|||
return implementClassName; |
|||
} |
|||
|
|||
public void setImplementClassName(String implementClassName) { |
|||
this.implementClassName = implementClassName; |
|||
} |
|||
} |
@ -0,0 +1,122 @@ |
|||
package io.sc.platform.core.util; |
|||
|
|||
import io.sc.platform.core.Environment; |
|||
|
|||
import java.io.*; |
|||
|
|||
import javax.xml.bind.JAXBContext; |
|||
import javax.xml.bind.JAXBElement; |
|||
import javax.xml.bind.JAXBException; |
|||
import javax.xml.bind.Marshaller; |
|||
import javax.xml.bind.Unmarshaller; |
|||
import javax.xml.transform.stream.StreamSource; |
|||
|
|||
/** |
|||
* jaxb 辅助类 |
|||
* 主要用于序列化和反序列化 xml |
|||
* |
|||
*/ |
|||
public class JaxbUtil { |
|||
/** |
|||
* 解析 xml |
|||
* @param xml xml 内容 |
|||
* @param type 对象类型 |
|||
* @return 解析后的对象 |
|||
* @throws JAXBException 违例 |
|||
* |
|||
* @param <T> 数据类型 |
|||
*/ |
|||
public static <T> T unmarshal(String xml,Class<T> type) throws JAXBException{ |
|||
try { |
|||
InputStream in = new ByteArrayInputStream(xml.getBytes(Environment.DEFAULT_CHARSET_NAME)); |
|||
return unmarshal(in, type); |
|||
}catch (Exception e){ |
|||
throw new JAXBException(e); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 解析 xml (文件) |
|||
* @param file 文件路径 |
|||
* @param type 对象类型 |
|||
* @return 解析后的对象 |
|||
* @throws JAXBException 违例 |
|||
* |
|||
* @param <T> 数据类型 |
|||
*/ |
|||
public static <T> T unmarshal(File file,Class<T> type) throws JAXBException{ |
|||
return unmarshal(new StreamSource(file),type); |
|||
} |
|||
|
|||
/** |
|||
* 解析 xml (输入流) |
|||
* @param inputStream 输入流 |
|||
* @param type 对象类型 |
|||
* @return 解析后的对象 |
|||
* @throws JAXBException 违例 |
|||
* |
|||
* @param <T> 数据类型 |
|||
*/ |
|||
public static <T> T unmarshal(InputStream inputStream,Class<T> type) throws JAXBException{ |
|||
return unmarshal(new StreamSource(inputStream),type); |
|||
} |
|||
|
|||
/** |
|||
* 解析 xml (StreamSource) |
|||
* @param streamSource StreamSource |
|||
* @param type 对象类型 |
|||
* @return 解析后的对象 |
|||
* @throws JAXBException 违例 |
|||
* |
|||
* @param <T> 数据类型 |
|||
*/ |
|||
public static <T> T unmarshal(StreamSource streamSource,Class<T> type) throws JAXBException{ |
|||
JAXBContext decodeJAXBContext =JAXBContext.newInstance(type); |
|||
Unmarshaller unmarshaller =decodeJAXBContext.createUnmarshaller(); |
|||
JAXBElement<T> obj =unmarshaller.unmarshal(streamSource,type); |
|||
return obj.getValue(); |
|||
} |
|||
|
|||
/** |
|||
* 将对象序列化成 xml |
|||
* @param object 对象 |
|||
* @param type 对象类型 |
|||
* @return xml |
|||
* @throws JAXBException 违例 |
|||
* |
|||
* @param <T> 数据类型 |
|||
*/ |
|||
public static <T> String marshal(Object object,Class<T> type) throws JAXBException{ |
|||
StringWriter writer =new StringWriter(); |
|||
marshal(object,type,writer); |
|||
return writer.toString(); |
|||
} |
|||
|
|||
/** |
|||
* 将对象序列化成 xml,并写入 OutputStream |
|||
* @param object 对象 |
|||
* @param type 对象类型 |
|||
* @param outputStream 输出流 |
|||
* @throws JAXBException 违例 |
|||
* |
|||
* @param <T> 数据类型 |
|||
*/ |
|||
public static <T> void marshal(Object object,Class<T> type,OutputStream outputStream) throws JAXBException{ |
|||
marshal(object,type,new OutputStreamWriter(outputStream)); |
|||
} |
|||
|
|||
/** |
|||
* 将对象序列化成 xml,并写入 Writer |
|||
* @param object 对象 |
|||
* @param type 对象类型 |
|||
* @param writer 输出流 |
|||
* @throws JAXBException 违例 |
|||
* |
|||
* @param <T> 数据类型 |
|||
*/ |
|||
public static <T> void marshal(Object object,Class<T> type,Writer writer) throws JAXBException{ |
|||
JAXBContext decodeJAXBContext =JAXBContext.newInstance(type); |
|||
Marshaller marshaller =decodeJAXBContext.createMarshaller(); |
|||
marshaller.marshal(object, writer); |
|||
} |
|||
} |
@ -1,2 +1,2 @@ |
|||
io.sc.platform.core.response.ValidateException=Request Parameter Validate Error |
|||
io.sc.platform.orm.api.exception.UserRawPasswordNotMatchException=Raw Password Error |
|||
io.sc.platform.core.exception.PasswordStrengthException=Password must contain uppercase, lowercase, numbers, special characters, and must be greater than or equal to {0} in length. |
@ -1,2 +1,2 @@ |
|||
io.sc.platform.core.response.ValidateException=\u8ACB\u6C42\u53C3\u6578\u9A57\u8B49\u932F\u8AA4 |
|||
io.sc.platform.orm.api.exception.UserRawPasswordNotMatchException=\u539F\u5BC6\u78BC\u932F\u8AA4 |
|||
io.sc.platform.core.exception.PasswordStrengthException=\u5BC6\u78BC\u5FC5\u9808\u5305\u542B:\u5927\u5BEB\u5B57\u6BCD\u3001\u5C0F\u5BEB\u5B57\u6BCD\u3001\u6578\u5B57\u3001\u7279\u6B8A\u5B57\u7B26, \u4E14\u9577\u5EA6\u5FC5\u9808\u5927\u65BC\u7B49\u65BC {0} \u4E2A\u3002 |
@ -1,2 +1,2 @@ |
|||
io.sc.platform.core.response.ValidateException=\u8BF7\u6C42\u53C2\u6570\u9A8C\u8BC1\u9519\u8BEF |
|||
io.sc.platform.orm.api.exception.UserRawPasswordNotMatchException=\u539F\u5BC6\u7801\u9519\u8BEF |
|||
io.sc.platform.core.exception.PasswordStrengthException=\u5BC6\u7801\u5FC5\u987B\u5305\u542B:\u5927\u5199\u5B57\u6BCD\u3001\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u7279\u6B8A\u5B57\u7B26, \u4E14\u957F\u5EA6\u5FC5\u987B\u5927\u4E8E\u7B49\u4E8E {0} \u4E2A\u3002 |
@ -0,0 +1,4 @@ |
|||
package io.sc.platform.orm.annotation; |
|||
|
|||
public @interface Desensitizeable { |
|||
} |
@ -0,0 +1,33 @@ |
|||
package io.sc.platform.orm.converter; |
|||
|
|||
import io.sc.platform.core.Environment; |
|||
import io.sc.platform.core.util.StringEncryptorUtil; |
|||
import io.sc.platform.orm.service.DesensitizerAuthorizerService; |
|||
import io.sc.platform.orm.service.DesensitizerManagerService; |
|||
import io.sc.platform.orm.service.support.Desensitizer; |
|||
|
|||
import javax.persistence.AttributeConverter; |
|||
|
|||
public interface DesensitizeAndEncodeStringCoverter extends AttributeConverter<String, String> { |
|||
public String getEntityClassName(); |
|||
public String getEntityFieldName(); |
|||
public String getDesensitizerName(); |
|||
|
|||
@Override |
|||
default public String convertToDatabaseColumn(String attribute) { |
|||
return StringEncryptorUtil.encrypt(attribute); |
|||
} |
|||
|
|||
@Override |
|||
default public String convertToEntityAttribute(String dbData) { |
|||
String decryptData =StringEncryptorUtil.decrypt(dbData); |
|||
DesensitizerAuthorizerService authorizer =Environment.getInstance().getApplicationContext().getBean(DesensitizerAuthorizerService.class); |
|||
if(authorizer.authorize(getEntityClassName(),getEntityFieldName())){ |
|||
// 通过脱敏管理器获取脱敏器
|
|||
DesensitizerManagerService manager =Environment.getInstance().getApplicationContext().getBean(DesensitizerManagerService.class); |
|||
Desensitizer desensitizer =manager.getDesensitizer(getDesensitizerName()); |
|||
return desensitizer.desensitize(decryptData); |
|||
} |
|||
return decryptData; |
|||
} |
|||
} |
@ -0,0 +1,31 @@ |
|||
package io.sc.platform.orm.converter; |
|||
|
|||
import io.sc.platform.core.Environment; |
|||
import io.sc.platform.core.util.StringEncryptorUtil; |
|||
import io.sc.platform.orm.service.DesensitizerAuthorizerService; |
|||
import io.sc.platform.orm.service.DesensitizerManagerService; |
|||
|
|||
import javax.persistence.AttributeConverter; |
|||
|
|||
public interface DesensitizeStringCoverter extends AttributeConverter<String, String> { |
|||
public String getEntityClassName(); |
|||
public String getEntityFieldName(); |
|||
public String getDesensitizerName(); |
|||
|
|||
@Override |
|||
default public String convertToDatabaseColumn(String attribute) { |
|||
return StringEncryptorUtil.encrypt(attribute); |
|||
} |
|||
|
|||
@Override |
|||
default public String convertToEntityAttribute(String dbData) { |
|||
DesensitizerAuthorizerService authorizer =Environment.getInstance().getApplicationContext().getBean(DesensitizerAuthorizerService.class); |
|||
if(authorizer.authorize(getEntityClassName(),getEntityFieldName())){ |
|||
// 通过脱敏管理器获取脱敏器
|
|||
DesensitizerManagerService manager =Environment.getInstance().getApplicationContext().getBean(DesensitizerManagerService.class); |
|||
io.sc.platform.orm.service.support.Desensitizer desensitizer =manager.getDesensitizer(getDesensitizerName()); |
|||
return desensitizer.desensitize(dbData); |
|||
} |
|||
return dbData; |
|||
} |
|||
} |
@ -0,0 +1,39 @@ |
|||
package io.sc.platform.orm.converter.support; |
|||
|
|||
public class DesensitizeConvertWrapper<T> { |
|||
private T value; |
|||
private String className; |
|||
private String fieldName; |
|||
|
|||
public DesensitizeConvertWrapper(){} |
|||
public DesensitizeConvertWrapper(String className, String fieldName, T value){ |
|||
this.className =className; |
|||
this.fieldName =fieldName; |
|||
this.value =value; |
|||
} |
|||
|
|||
|
|||
public T getValue() { |
|||
return value; |
|||
} |
|||
|
|||
public void setValue(T value) { |
|||
this.value = value; |
|||
} |
|||
|
|||
public String getClassName() { |
|||
return className; |
|||
} |
|||
|
|||
public void setClassName(String className) { |
|||
this.className = className; |
|||
} |
|||
|
|||
public String getFieldName() { |
|||
return fieldName; |
|||
} |
|||
|
|||
public void setFieldName(String fieldName) { |
|||
this.fieldName = fieldName; |
|||
} |
|||
} |
@ -0,0 +1,36 @@ |
|||
package io.sc.platform.orm.desensitizer; |
|||
|
|||
import io.sc.platform.core.service.Desensitizer; |
|||
import org.springframework.util.StringUtils; |
|||
|
|||
import java.util.Random; |
|||
|
|||
public class DefaultDesensitizer implements Desensitizer { |
|||
private Random random =new Random(); |
|||
private boolean enable = true; |
|||
|
|||
public boolean isEnable() { |
|||
return enable; |
|||
} |
|||
|
|||
public void setEnable(boolean enable) { |
|||
this.enable = enable; |
|||
} |
|||
|
|||
@Override |
|||
public String desensitizer(String string) { |
|||
if(this.enable && StringUtils.hasText(string)) { |
|||
int length =string.length(); |
|||
int cout =0; |
|||
if(length<=3){ |
|||
return "***" + string + "***"; |
|||
}else { |
|||
cout =(int)length/2; //需要脱敏的字符数
|
|||
cout =Math.max(cout,3); |
|||
int index =random.nextInt(length-cout); |
|||
return "***" + string.substring(index,index+cout) + "***"; |
|||
} |
|||
} |
|||
return string; |
|||
} |
|||
} |
@ -0,0 +1,5 @@ |
|||
package io.sc.platform.orm.service; |
|||
|
|||
public interface DesensitizerAuthorizerService { |
|||
public boolean authorize(String className,String fieldName); |
|||
} |
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue