163 changed files with 3650 additions and 299 deletions
@ -1,23 +1,195 @@ |
|||||
package io.sc.engine.rule.core.code.impl.support.processor; |
package io.sc.engine.rule.core.code.impl.support.processor; |
||||
|
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; |
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.Parameter; |
||||
import io.sc.engine.rule.core.po.model.processor.MathFormulaParameterProcessor; |
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) |
@JsonIgnoreProperties(ignoreUnknown=true) |
||||
public class MathFormula { |
public class MathFormula { |
||||
public static List<ConditionRange> parse(String json) throws Exception { |
public static MathType parse(String xml) throws Exception { |
||||
return JacksonObjectMapper.getDefaultObjectMapper().readValue(json, new TypeReference<List<ConditionRange>>(){}); |
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{ |
public static String generateGroovyCode(Parameter parameter, MathFormulaParameterProcessor processor) throws Exception{ |
||||
if(parameter==null || processor==null){ |
if (parameter == null || processor == null) { |
||||
|
return null; |
||||
|
} |
||||
|
MathType math =parse(processor.getMathFormula()); |
||||
|
if(math==null){ |
||||
return null; |
return 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.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.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.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