diff --git a/language/properties/extractor/README.md b/language/properties/extractor/README.md
new file mode 100644
index 00000000..c263a521
--- /dev/null
+++ b/language/properties/extractor/README.md
@@ -0,0 +1,9 @@
+# Introduction
+The codefuse-query properties extractor transforms the source code of xml file into standardized coref-properties data, which is utilized for further analysis by codefuse-query.
+
+# Quick Start
+1. Set `JAVA_HOME`. Execute `echo $JAVA_HOME` to display its current setting. If it displays as empty, then it has not been configured yet.
+2. Build. Execute `mvn clean install`.
+3. Run. Execute `java -jar target/properties-extractor-1.0-SNAPSHOT-jar-with-dependencies.jar ${YOUR_REPO} ./db`.
+
+After execution, a file named coref_properties_src.db will be generated in the ./db directory.
diff --git a/language/properties/extractor/README_cn.md b/language/properties/extractor/README_cn.md
new file mode 100644
index 00000000..a64a7f77
--- /dev/null
+++ b/language/properties/extractor/README_cn.md
@@ -0,0 +1,9 @@
+# 简介
+Codefuse-query Properties 提取器将 Properties 文件的源代码转换为标准化的 coref-properties 数据,这些数据用于 codefuse-query 进行进一步分析。
+
+# 快速开始
+1. 设置 JAVA_HOME。执行 echo $JAVA_HOME 来显示当前的设置。如果显示为空,则表示尚未配置。
+2. 构建。执行 mvn clean install。
+3. 运行。执行 java -jar target/properties-extractor-1.0-SNAPSHOT-jar-with-dependencies.jar ${YOUR_REPO} ./db。
+
+执行后,一个名为 coref_properties_src.db 的文件将生成在 ./db 目录下。
\ No newline at end of file
diff --git a/language/properties/extractor/pom.xml b/language/properties/extractor/pom.xml
new file mode 100644
index 00000000..d60dae4d
--- /dev/null
+++ b/language/properties/extractor/pom.xml
@@ -0,0 +1,159 @@
+
+ 4.0.0
+
+ com.alipay.codequery.properties
+ properties-extractor
+ 1.0-SNAPSHOT
+
+ jar
+
+ properties-extractor
+ http://maven.apache.org
+
+
+ UTF-8
+
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.12.0
+
+
+
+ commons-codec
+ commons-codec
+ 1.15
+
+
+ org.projectlombok
+ lombok
+ 1.18.16
+ provided
+
+
+
+ org.xerial
+ sqlite-jdbc
+ 3.36.0.2
+
+
+
+ org.mybatis
+ mybatis
+ 3.5.7
+
+
+
+ tk.mybatis
+ mapper
+
+ 4.1.5
+
+
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.14.1
+
+
+ org.apache.logging.log4j
+ log4j-api
+ 2.14.1
+
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+ 2.14.1
+
+
+ info.picocli
+ picocli
+ 4.6.1
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 8
+ 8
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.4.2
+
+ true
+
+
+
+ org.mybatis.generator
+ mybatis-generator-maven-plugin
+ 1.3.7
+
+ true
+ true
+
+
+
+ org.xerial
+ sqlite-jdbc
+ 3.36.0.2
+
+
+ tk.mybatis
+ mapper
+ 4.1.5
+
+
+
+
+ Generate MyBatis Artifacts
+
+ generate
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.5.5
+
+
+
+ com.alipay.codequery.properties.Extractor
+
+
+
+ jar-with-dependencies
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
+
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/Extractor.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/Extractor.java
new file mode 100644
index 00000000..2283f6c6
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/Extractor.java
@@ -0,0 +1,141 @@
+
+package com.alipay.codequery.properties;
+
+import com.alipay.codequery.properties.core.CorefExtractor;
+import com.alipay.codequery.properties.model.Folder;
+import com.alipay.codequery.properties.model.Node;
+import com.alipay.codequery.properties.model.Program;
+import com.alipay.codequery.properties.storage.CorefStorage;
+import com.alipay.codequery.properties.core.CorefURI;
+import com.alipay.codequery.properties.util.LoggerUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Parameters;
+
+import java.io.*;
+import java.util.concurrent.Callable;
+
+
+@Command(name = "extract", mixinStandardHelpOptions = true, version = "extract 1.0",
+ description = "extract COREF-Properties db from a src directory.")
+@Slf4j
+public class Extractor implements Callable {
+
+ private static final Logger logger = LogManager.getLogger(Extractor.class);
+ @Parameters(index = "0", description = "The source directory to extract.")
+ private File srcRootDir;
+
+ @Parameters(index = "1", description = "The output directory for the DB file.")
+ private File dbDir;
+
+ @CommandLine.Option(names = {"--corpus"}, description = "Specify the corpus of the codebase.")
+ private String corpus = "";
+
+ /**
+ *
+ * main method.
+ */
+ public static void main(String[] args) {
+ int exitCode = new CommandLine(new Extractor()).execute(args);
+ System.exit(exitCode);
+ }
+
+ private void parse(File rootDir, CorefStorage corefStorage, CorefURI corefURI) throws IOException{
+ File[] files = rootDir.listFiles();
+ for (File file : files) {
+ if (file.isDirectory()) {
+ parse(file, corefStorage, corefURI);
+ } else {
+
+ // Support extracting file's extension is 'properties' or 'properties.vm'.
+ if (file.getName().endsWith(".properties") || file.getName().endsWith(".properties.vm")) {
+ logger.info("Start Extracting properties file: {}", file.getAbsolutePath());
+ try {
+ CorefExtractor extractor = new CorefExtractor(file, corefStorage, srcRootDir.getAbsolutePath(), corefURI);
+ extractor.parse();
+ } catch (Exception e) {
+ logger.error("Extraction failed, error message:{} on file {}", e.getMessage(), file.getAbsolutePath());
+ }
+ }
+ }
+ }
+ }
+
+ private Program createProgramNode(String repoDir, CorefStorage corefStorage, CorefURI corefURI) {
+ Program program = new Program();
+ program.oid = corefURI.generateCorpusOid();
+ program.prefix = repoDir;
+ corefStorage.storeProgram(program.extractProgram());
+ return program;
+ }
+
+ private void visitDirectory(String repoDir, Node parent, CorefStorage corefStorage, CorefURI corefURI) {
+ File file = new File(repoDir);
+
+ // Ignore the folder starts with "."
+ if (file.isDirectory() && !(file.getName().startsWith("."))) {
+ String absolutePath = file.getAbsolutePath();
+
+ Folder parentFolder = new Folder();
+ parentFolder.name = file.getName();
+ parentFolder.parent = parent;
+
+ // Calculate the relative path of the folder.
+ if (absolutePath.endsWith(srcRootDir.getAbsolutePath())) {
+ parentFolder.relativePath = "ROOT";
+ } else {
+ char head = repoDir.charAt(0);
+ switch (head) {
+ case '/':
+ parentFolder.relativePath = absolutePath.substring(srcRootDir.getAbsolutePath().length() + 1);
+ break;
+ case '.':
+ parentFolder.relativePath = absolutePath.substring(absolutePath.indexOf(repoDir) + 2);
+ break;
+ default:
+ parentFolder.relativePath = absolutePath.substring(absolutePath.indexOf(repoDir));
+ }
+ }
+ corefURI.setPath(parentFolder.relativePath);
+ parentFolder.oid = corefURI.generateFileOid();
+ corefStorage.storeFolder(parentFolder.extractFolder());
+
+ // Recursively visit the sub folders.
+ for (File f : file.listFiles()) {
+ if (f.isDirectory()) {
+ visitDirectory(f.getAbsolutePath(), parentFolder, corefStorage, corefURI);
+ } else if (f.getName().endsWith(".properties")) {
+ CorefURI.fileMap.put(f.getAbsolutePath(), parentFolder.oid);
+ }
+ }
+ }
+ }
+
+ /**
+ * Override the call method.
+ * @return
+ * @throws Exception
+ */
+ @Override
+ public Integer call() throws Exception {
+ LoggerUtil.initLogger(Level.INFO);
+
+ long start = System.currentTimeMillis();
+ CorefStorage corefStorage = new CorefStorage(dbDir.getAbsolutePath());
+ CorefURI corefURI = StringUtils.isBlank(corpus) ? new CorefURI(srcRootDir.getAbsolutePath()) : new CorefURI(corpus);
+ Program program = createProgramNode(srcRootDir.getAbsolutePath(), corefStorage, corefURI);
+ visitDirectory(srcRootDir.getAbsolutePath(), program, corefStorage, corefURI);
+
+ parse(srcRootDir, corefStorage, corefURI);
+ corefStorage.store();
+
+ logger.info("Time to completion (TTC): " + (System.currentTimeMillis() - start));
+
+ return 0;
+ }
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/core/CorefExtractor.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/core/CorefExtractor.java
new file mode 100644
index 00000000..e63993e4
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/core/CorefExtractor.java
@@ -0,0 +1,164 @@
+
+package com.alipay.codequery.properties.core;
+
+import com.alipay.codequery.properties.model.*;
+import com.alipay.codequery.properties.util.SafeProperties;
+import lombok.SneakyThrows;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import com.alipay.codequery.properties.storage.CorefStorage;
+
+import java.io.*;
+import java.io.File;
+import java.util.List;
+
+
+public class CorefExtractor{
+ private static final Logger logger = LogManager.getLogger(CorefExtractor.class);
+
+ private CorefStorage corefStorage;
+ private File file;
+
+ private com.alipay.codequery.properties.model.File propertiesFile;
+
+ private final CorefURI corefURI;
+ private String root;
+
+ private SafeProperties safeProperties = new SafeProperties();
+
+ /**
+ * The constructor.
+ * @param file
+ * @param corefStorage
+ * @param rootPath
+ * @param corefURI
+ */
+ @SneakyThrows
+ public CorefExtractor(File file, CorefStorage corefStorage, String rootPath, CorefURI corefURI) {
+ this.corefStorage = corefStorage;
+ this.file = file;
+ this.root = rootPath;
+ this.corefURI = corefURI;
+ this.corefURI.setPath(file.getAbsolutePath().substring(root.length() + 1));
+ this.propertiesFile = visitPropertiesFile(file);
+ }
+
+ /**
+ * Get element oid except file or folder or program.
+ * @param node
+ * @return
+ */
+ public Long getOid(Node node) {
+ if (node == null) {
+ return -1L;
+ }
+
+ String signature = SignatureGenerator.generate(node);
+ Long oid = corefURI.generateOid(signature);
+ return oid;
+ }
+
+ /**
+ * Parse the properties file.
+ */
+ public void parse() {
+ try{
+ InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
+ safeProperties.load(inputStream);
+ PropertiesContext propertiesContext = safeProperties.getContext();
+
+ List commentOrEntrys = propertiesContext.getCommentOrEntrys();
+ for (int index = 0; index < commentOrEntrys.size(); index++) {
+ Node obj = commentOrEntrys.get(index);
+ obj.oid = getOid(obj);
+ obj.file = propertiesFile;
+
+ if (obj instanceof PropertyEntry) {
+ if (obj != null) {
+
+ visitPropertyEntry((PropertyEntry) obj);
+
+ }
+ } else if (obj instanceof PropertyComment) {
+
+ visitComment((PropertyComment) obj);
+
+ } else {
+ visitEmptyLine((EmptyLine) obj);
+ }
+
+ }
+ }catch (IOException e){
+ logger.error("Extraction failed, error message:{} on file {}", e.getMessage(), file.getAbsolutePath());
+ }
+
+ }
+
+ private void visitPropertyEntry(PropertyEntry propertyEntry) {
+ propertyEntry.location = calculateLocation(propertyEntry);
+ String value = propertyEntry.getValue();
+ if(value.contains("${") && (!value.contains("\'{")) && (!value.contains("\"{"))) {
+ visitPropertyEntryVarialbe(propertyEntry);
+ }
+ corefStorage.storeEntry(propertyEntry.extractEntry());
+ }
+
+ private void visitPropertyEntryVarialbe(PropertyEntry propertyEntry) {
+ String value = propertyEntry.getValue();
+ int startIndex = value.indexOf("${");
+ int endIndex = value.indexOf("}");
+ String originalText = value.substring(startIndex, endIndex + 1);
+ Variable variable = new Variable(originalText, startIndex);
+ variable.parent = propertyEntry;
+ variable.oid = getOid(variable);
+ variable.name = value.substring(startIndex + 2, endIndex);
+ corefStorage.storeEntryVariable(variable.extractVariable());
+ }
+
+ private com.alipay.codequery.properties.model.File visitPropertiesFile(File file) {
+ propertiesFile = new com.alipay.codequery.properties.model.File(corefURI.generateFileOid());
+ propertiesFile.name = file.getName();
+ propertiesFile.relativePath = this.corefURI.getPath();
+
+ // Save file's extension is 'properties' or 'properties.vm'
+ if(file.getName().endsWith("properties")) {
+ propertiesFile.extension = "properties";
+ } else if(file.getName().endsWith("properties.vm")) {
+ propertiesFile.extension = "properties.vm";
+ }
+
+ corefStorage.storeFile(propertiesFile.extractFile());
+ if (CorefURI.fileMap.containsKey(file.getAbsolutePath())) {
+ ContainerParent containerParent = new ContainerParent(propertiesFile.oid, CorefURI.fileMap.get(file.getAbsolutePath()));
+ corefStorage.storeContainerParent(containerParent.extractContainerParent());
+ }
+ visitNumberOfLines();
+ return propertiesFile;
+ }
+
+ private void visitComment(PropertyComment propertyComment) {
+ propertyComment.location = calculateLocation(propertyComment);
+ corefStorage.storeComment(propertyComment.extractComment());
+ }
+
+ private void visitEmptyLine(EmptyLine emptyLine) {
+ emptyLine.location = calculateLocation(emptyLine);
+ corefStorage.storeEmptyLine(emptyLine.extractEmptyLine());
+ }
+
+ private Location calculateLocation(Node node) {
+ Location location = new Location(node.oid, node.file, node.localLocation);
+ corefStorage.storeLocation(location.extractLocation());
+ return location;
+ }
+
+ private void visitNumberOfLines() {
+ PropertiesContext propertiesContext = safeProperties.getContext();
+ Location.NumberOfLines numberOfLines = new Location.NumberOfLines(this.propertiesFile.oid);
+ numberOfLines.numberOfLines = safeProperties.getSize();
+ numberOfLines.numberOfCommentLines = propertiesContext.getComments().size();
+ numberOfLines.numberOfCodeLines = safeProperties.getSize() - propertiesContext.getEmptyLines().size() - numberOfLines.numberOfCommentLines;
+ corefStorage.storeNumberOfLines(numberOfLines.extractNumberOfLines());
+ }
+
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/core/CorefURI.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/core/CorefURI.java
new file mode 100644
index 00000000..338b542c
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/core/CorefURI.java
@@ -0,0 +1,92 @@
+
+package com.alipay.codequery.properties.core;
+
+import com.alipay.codequery.properties.util.HashUtil;
+import lombok.Data;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+@Data
+public class CorefURI {
+
+ private static String URI_TEMPLATE = "coref://%s?path=%s#%s";
+
+ private String signature;
+ private String corpus;
+ private String path;
+
+ /**
+ * Store all the containing info between file and folder.
+ */
+ public static final Map fileMap = new ConcurrentHashMap<>();
+
+ /**
+ * Constructor.
+ * @param corpus
+ */
+ public CorefURI(String corpus) {
+ this.corpus = corpus;
+ }
+
+ /**
+ * Get the string format.
+ * @return
+ */
+ public String toString() {
+ return generate(corpus, path, signature);
+ }
+
+ /**
+ * Generate URI for coref element.
+ * @param corpus
+ * @param path
+ * @param signature
+ * @return
+ */
+ public static String generate(String corpus, String path, String signature) {
+ if(StringUtils.isBlank(corpus)
+ || StringUtils.isBlank(path)
+ || StringUtils.isBlank(signature)) {
+ throw new RuntimeException("blank corpus or path or signature");
+ }
+
+ return String.format(URI_TEMPLATE, corpus, path, signature);
+ }
+
+ /**
+ * Generate corpus oid.
+ * @return
+ */
+ public Long generateCorpusOid() {
+ return CorefURI.generateCorpusOid(corpus);
+ }
+
+ /**
+ * Generate corpus oid by given corpus.
+ * @param corpus
+ * @return
+ */
+ public static Long generateCorpusOid(String corpus) {
+ return HashUtil.hashString(String.format("coref://%s", corpus));
+ }
+
+ /**
+ * Generate oid by given signature.
+ * @param signature
+ * @return
+ */
+ public Long generateOid(String signature) {
+ return HashUtil.hashString(generate(corpus, path, signature));
+ }
+
+ /**
+ * Generate file oid.
+ * @return
+ */
+ public Long generateFileOid() {
+ return HashUtil.hashString(String.format("coref://%s?path=%s", corpus, path));
+ }
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/core/SignatureGenerator.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/core/SignatureGenerator.java
new file mode 100644
index 00000000..181acf31
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/core/SignatureGenerator.java
@@ -0,0 +1,36 @@
+
+package com.alipay.codequery.properties.core;
+
+import com.alipay.codequery.properties.model.Node;
+import com.alipay.codequery.properties.model.Variable;
+
+
+public class SignatureGenerator {
+
+ /**
+ * Generate signature for element except file, folder or program.
+ * @param node
+ * @return
+ */
+ public static String generate(Node node) {
+ if (node == null) {
+ return "null";
+ }
+
+ if (node instanceof Variable) {
+ return String.format("%s:%s:(%d,%d)",
+ node.getClass().getSimpleName(),
+ node.printableText != null ? node.printableText : "NULL",
+ ((Variable) node).beginIndex,
+ node.parent.localLocation.endLineNumber
+ );
+ } else {
+ return String.format("%s:%s:(%d,%d)",
+ node.getClass().getSimpleName(),
+ node.printableText != null ? node.printableText : "NULL",
+ node.localLocation.startColumnNumber,
+ node.localLocation.startLineNumber
+ );
+ }
+ }
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Comment.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Comment.java
new file mode 100644
index 00000000..8916fdbb
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Comment.java
@@ -0,0 +1,84 @@
+package com.alipay.codequery.properties.dal.mybatis.domain;
+
+import javax.persistence.*;
+
+@Table(name = "comment")
+public class Comment {
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ private String text;
+
+ @Column(name = "parent_oid")
+ private Long parentOid;
+
+ @Column(name = "location_oid")
+ private Long locationOid;
+
+ public Comment(Long elementOid, String text, Long parentOid, Long locationOid) {
+ this.elementOid = elementOid;
+ this.text = text;
+ this.parentOid = parentOid;
+ this.locationOid = locationOid;
+ }
+
+ public Comment() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return text
+ */
+ public String getText() {
+ return text;
+ }
+
+ /**
+ * @param text
+ */
+ public void setText(String text) {
+ this.text = text == null ? null : text.trim();
+ }
+
+ /**
+ * @return parent_oid
+ */
+ public Long getParentOid() {
+ return parentOid;
+ }
+
+ /**
+ * @param parentOid
+ */
+ public void setParentOid(Long parentOid) {
+ this.parentOid = parentOid;
+ }
+
+ /**
+ * @return location_oid
+ */
+ public Long getLocationOid() {
+ return locationOid;
+ }
+
+ /**
+ * @param locationOid
+ */
+ public void setLocationOid(Long locationOid) {
+ this.locationOid = locationOid;
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/ContainerParent.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/ContainerParent.java
new file mode 100644
index 00000000..f0ab50d7
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/ContainerParent.java
@@ -0,0 +1,49 @@
+package com.alipay.codequery.properties.dal.mybatis.domain;
+
+import javax.persistence.*;
+
+@Table(name = "container_parent")
+public class ContainerParent {
+ @Column(name = "child_oid")
+ private Long childOid;
+
+ @Column(name = "parent_oid")
+ private Long parentOid;
+
+ public ContainerParent(Long childOid, Long parentOid) {
+ this.childOid = childOid;
+ this.parentOid = parentOid;
+ }
+
+ public ContainerParent() {
+ super();
+ }
+
+ /**
+ * @return child_oid
+ */
+ public Long getChildOid() {
+ return childOid;
+ }
+
+ /**
+ * @param childOid
+ */
+ public void setChildOid(Long childOid) {
+ this.childOid = childOid;
+ }
+
+ /**
+ * @return parent_oid
+ */
+ public Long getParentOid() {
+ return parentOid;
+ }
+
+ /**
+ * @param parentOid
+ */
+ public void setParentOid(Long parentOid) {
+ this.parentOid = parentOid;
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/EmptyLine.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/EmptyLine.java
new file mode 100644
index 00000000..58e9de15
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/EmptyLine.java
@@ -0,0 +1,68 @@
+package com.alipay.codequery.properties.dal.mybatis.domain;
+
+import javax.persistence.*;
+
+@Table(name = "empty_line")
+public class EmptyLine {
+ @Id
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ @Column(name = "location_oid")
+ private Long locationOid;
+
+ @Column(name = "file_oid")
+ private Long fileOid;
+
+ public EmptyLine(Long elementOid, Long locationOid, Long fileOid) {
+ this.elementOid = elementOid;
+ this.locationOid = locationOid;
+ this.fileOid = fileOid;
+ }
+
+ public EmptyLine() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return location_oid
+ */
+ public Long getLocationOid() {
+ return locationOid;
+ }
+
+ /**
+ * @param locationOid
+ */
+ public void setLocationOid(Long locationOid) {
+ this.locationOid = locationOid;
+ }
+
+ /**
+ * @return file_oid
+ */
+ public Long getFileOid() {
+ return fileOid;
+ }
+
+ /**
+ * @param fileOid
+ */
+ public void setFileOid(Long fileOid) {
+ this.fileOid = fileOid;
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Entry.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Entry.java
new file mode 100644
index 00000000..885f2bd4
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Entry.java
@@ -0,0 +1,101 @@
+package com.alipay.codequery.properties.dal.mybatis.domain;
+
+import javax.persistence.*;
+
+@Table(name = "entry")
+public class Entry {
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ private String key;
+
+ private String value;
+
+ @Column(name = "printable_text")
+ private String printableText;
+
+ @Column(name = "location_oid")
+ private Long locationOid;
+
+ public Entry(Long elementOid, String key, String value, String printableText, Long locationOid) {
+ this.elementOid = elementOid;
+ this.key = key;
+ this.value = value;
+ this.printableText = printableText;
+ this.locationOid = locationOid;
+ }
+
+ public Entry() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return key
+ */
+ public String getKey() {
+ return key;
+ }
+
+ /**
+ * @param key
+ */
+ public void setKey(String key) {
+ this.key = key == null ? null : key.trim();
+ }
+
+ /**
+ * @return value
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * @param value
+ */
+ public void setValue(String value) {
+ this.value = value == null ? null : value.trim();
+ }
+
+ /**
+ * @return printable_text
+ */
+ public String getPrintableText() {
+ return printableText;
+ }
+
+ /**
+ * @param printableText
+ */
+ public void setPrintableText(String printableText) {
+ this.printableText = printableText == null ? null : printableText.trim();
+ }
+
+ /**
+ * @return location_oid
+ */
+ public Long getLocationOid() {
+ return locationOid;
+ }
+
+ /**
+ * @param locationOid
+ */
+ public void setLocationOid(Long locationOid) {
+ this.locationOid = locationOid;
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/File.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/File.java
new file mode 100644
index 00000000..6de11830
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/File.java
@@ -0,0 +1,83 @@
+package com.alipay.codequery.properties.dal.mybatis.domain;
+
+import javax.persistence.*;
+
+@Table(name = "file")
+public class File {
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ @Column(name = "relative_path")
+ private String relativePath;
+
+ private String extension;
+
+ private String name;
+
+ public File(Long elementOid, String relativePath, String extension, String name) {
+ this.elementOid = elementOid;
+ this.relativePath = relativePath;
+ this.extension = extension;
+ this.name = name;
+ }
+
+ public File() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return relative_path
+ */
+ public String getRelativePath() {
+ return relativePath;
+ }
+
+ /**
+ * @param relativePath
+ */
+ public void setRelativePath(String relativePath) {
+ this.relativePath = relativePath == null ? null : relativePath.trim();
+ }
+
+ /**
+ * @return extension
+ */
+ public String getExtension() {
+ return extension;
+ }
+
+ /**
+ * @param extension
+ */
+ public void setExtension(String extension) {
+ this.extension = extension == null ? null : extension.trim();
+ }
+
+ /**
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name
+ */
+ public void setName(String name) {
+ this.name = name == null ? null : name.trim();
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Folder.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Folder.java
new file mode 100644
index 00000000..0210c51d
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Folder.java
@@ -0,0 +1,84 @@
+package com.alipay.codequery.properties.dal.mybatis.domain;
+
+import javax.persistence.*;
+
+@Table(name = "folder")
+public class Folder {
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ @Column(name = "relative_path")
+ private String relativePath;
+
+ private String name;
+
+ @Column(name = "parent_oid")
+ private Long parentOid;
+
+ public Folder(Long elementOid, String relativePath, String name, Long parentOid) {
+ this.elementOid = elementOid;
+ this.relativePath = relativePath;
+ this.name = name;
+ this.parentOid = parentOid;
+ }
+
+ public Folder() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return relative_path
+ */
+ public String getRelativePath() {
+ return relativePath;
+ }
+
+ /**
+ * @param relativePath
+ */
+ public void setRelativePath(String relativePath) {
+ this.relativePath = relativePath == null ? null : relativePath.trim();
+ }
+
+ /**
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name
+ */
+ public void setName(String name) {
+ this.name = name == null ? null : name.trim();
+ }
+
+ /**
+ * @return parent_oid
+ */
+ public Long getParentOid() {
+ return parentOid;
+ }
+
+ /**
+ * @param parentOid
+ */
+ public void setParentOid(Long parentOid) {
+ this.parentOid = parentOid;
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Location.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Location.java
new file mode 100644
index 00000000..f13bce43
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Location.java
@@ -0,0 +1,121 @@
+package com.alipay.codequery.properties.dal.mybatis.domain;
+
+import javax.persistence.*;
+
+@Table(name = "location")
+public class Location {
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ @Column(name = "file_oid")
+ private Long fileOid;
+
+ @Column(name = "start_line_number")
+ private Integer startLineNumber;
+
+ @Column(name = "start_column_number")
+ private Integer startColumnNumber;
+
+ @Column(name = "end_line_number")
+ private Integer endLineNumber;
+
+ @Column(name = "end_column_number")
+ private Integer endColumnNumber;
+
+ public Location(Long elementOid, Long fileOid, Integer startLineNumber, Integer startColumnNumber, Integer endLineNumber, Integer endColumnNumber) {
+ this.elementOid = elementOid;
+ this.fileOid = fileOid;
+ this.startLineNumber = startLineNumber;
+ this.startColumnNumber = startColumnNumber;
+ this.endLineNumber = endLineNumber;
+ this.endColumnNumber = endColumnNumber;
+ }
+
+ public Location() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return file_oid
+ */
+ public Long getFileOid() {
+ return fileOid;
+ }
+
+ /**
+ * @param fileOid
+ */
+ public void setFileOid(Long fileOid) {
+ this.fileOid = fileOid;
+ }
+
+ /**
+ * @return start_line_number
+ */
+ public Integer getStartLineNumber() {
+ return startLineNumber;
+ }
+
+ /**
+ * @param startLineNumber
+ */
+ public void setStartLineNumber(Integer startLineNumber) {
+ this.startLineNumber = startLineNumber;
+ }
+
+ /**
+ * @return start_column_number
+ */
+ public Integer getStartColumnNumber() {
+ return startColumnNumber;
+ }
+
+ /**
+ * @param startColumnNumber
+ */
+ public void setStartColumnNumber(Integer startColumnNumber) {
+ this.startColumnNumber = startColumnNumber;
+ }
+
+ /**
+ * @return end_line_number
+ */
+ public Integer getEndLineNumber() {
+ return endLineNumber;
+ }
+
+ /**
+ * @param endLineNumber
+ */
+ public void setEndLineNumber(Integer endLineNumber) {
+ this.endLineNumber = endLineNumber;
+ }
+
+ /**
+ * @return end_column_number
+ */
+ public Integer getEndColumnNumber() {
+ return endColumnNumber;
+ }
+
+ /**
+ * @param endColumnNumber
+ */
+ public void setEndColumnNumber(Integer endColumnNumber) {
+ this.endColumnNumber = endColumnNumber;
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/NumberOfLines.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/NumberOfLines.java
new file mode 100644
index 00000000..0495f403
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/NumberOfLines.java
@@ -0,0 +1,85 @@
+package com.alipay.codequery.properties.dal.mybatis.domain;
+
+import javax.persistence.*;
+
+@Table(name = "number_of_lines")
+public class NumberOfLines {
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ @Column(name = "number_of_lines")
+ private Integer numberOfLines;
+
+ @Column(name = "number_of_valid_lines")
+ private Integer numberOfValidLines;
+
+ @Column(name = "number_of_comment_lines")
+ private Integer numberOfCommentLines;
+
+ public NumberOfLines(Long elementOid, Integer numberOfLines, Integer numberOfValidLines, Integer numberOfCommentLines) {
+ this.elementOid = elementOid;
+ this.numberOfLines = numberOfLines;
+ this.numberOfValidLines = numberOfValidLines;
+ this.numberOfCommentLines = numberOfCommentLines;
+ }
+
+ public NumberOfLines() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return number_of_lines
+ */
+ public Integer getNumberOfLines() {
+ return numberOfLines;
+ }
+
+ /**
+ * @param numberOfLines
+ */
+ public void setNumberOfLines(Integer numberOfLines) {
+ this.numberOfLines = numberOfLines;
+ }
+
+ /**
+ * @return number_of_valid_lines
+ */
+ public Integer getNumberOfValidLines() {
+ return numberOfValidLines;
+ }
+
+ /**
+ * @param numberOfValidLines
+ */
+ public void setNumberOfValidLines(Integer numberOfValidLines) {
+ this.numberOfValidLines = numberOfValidLines;
+ }
+
+ /**
+ * @return number_of_comment_lines
+ */
+ public Integer getNumberOfCommentLines() {
+ return numberOfCommentLines;
+ }
+
+ /**
+ * @param numberOfCommentLines
+ */
+ public void setNumberOfCommentLines(Integer numberOfCommentLines) {
+ this.numberOfCommentLines = numberOfCommentLines;
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Program.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Program.java
new file mode 100644
index 00000000..e639e39d
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Program.java
@@ -0,0 +1,49 @@
+package com.alipay.codequery.properties.dal.mybatis.domain;
+
+import javax.persistence.*;
+
+@Table(name = "program")
+public class Program {
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ @Column(name = "absolute_path_prefix")
+ private String absolutePathPrefix;
+
+ public Program(Long elementOid, String absolutePathPrefix) {
+ this.elementOid = elementOid;
+ this.absolutePathPrefix = absolutePathPrefix;
+ }
+
+ public Program() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return absolute_path_prefix
+ */
+ public String getAbsolutePathPrefix() {
+ return absolutePathPrefix;
+ }
+
+ /**
+ * @param absolutePathPrefix
+ */
+ public void setAbsolutePathPrefix(String absolutePathPrefix) {
+ this.absolutePathPrefix = absolutePathPrefix == null ? null : absolutePathPrefix.trim();
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Variable.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Variable.java
new file mode 100644
index 00000000..d2643942
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/domain/Variable.java
@@ -0,0 +1,102 @@
+package com.alipay.codequery.properties.dal.mybatis.domain;
+
+import javax.persistence.*;
+
+@Table(name = "variable")
+public class Variable {
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ @Column(name = "parent_oid")
+ private Long parentOid;
+
+ @Column(name = "start_index")
+ private Integer startIndex;
+
+ private String name;
+
+ @Column(name = "printable_text")
+ private String printableText;
+
+ public Variable(Long elementOid, Long parentOid, Integer startIndex, String name, String printableText) {
+ this.elementOid = elementOid;
+ this.parentOid = parentOid;
+ this.startIndex = startIndex;
+ this.name = name;
+ this.printableText = printableText;
+ }
+
+ public Variable() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return parent_oid
+ */
+ public Long getParentOid() {
+ return parentOid;
+ }
+
+ /**
+ * @param parentOid
+ */
+ public void setParentOid(Long parentOid) {
+ this.parentOid = parentOid;
+ }
+
+ /**
+ * @return start_index
+ */
+ public Integer getStartIndex() {
+ return startIndex;
+ }
+
+ /**
+ * @param startIndex
+ */
+ public void setStartIndex(Integer startIndex) {
+ this.startIndex = startIndex;
+ }
+
+ /**
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name
+ */
+ public void setName(String name) {
+ this.name = name == null ? null : name.trim();
+ }
+
+ /**
+ * @return printable_text
+ */
+ public String getPrintableText() {
+ return printableText;
+ }
+
+ /**
+ * @param printableText
+ */
+ public void setPrintableText(String printableText) {
+ this.printableText = printableText == null ? null : printableText.trim();
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/CommentMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/CommentMapper.java
new file mode 100644
index 00000000..3e4c03b4
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/CommentMapper.java
@@ -0,0 +1,8 @@
+package com.alipay.codequery.properties.dal.mybatis.mapper;
+
+import com.alipay.codequery.properties.dal.mybatis.domain.Comment;
+import org.apache.ibatis.annotations.Select;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface CommentMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/ContainerParentMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/ContainerParentMapper.java
new file mode 100644
index 00000000..06747287
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/ContainerParentMapper.java
@@ -0,0 +1,8 @@
+package com.alipay.codequery.properties.dal.mybatis.mapper;
+
+import com.alipay.codequery.properties.dal.mybatis.domain.ContainerParent;
+import org.apache.ibatis.annotations.Select;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface ContainerParentMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/EmptyLineMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/EmptyLineMapper.java
new file mode 100644
index 00000000..1e686d79
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/EmptyLineMapper.java
@@ -0,0 +1,8 @@
+package com.alipay.codequery.properties.dal.mybatis.mapper;
+
+import com.alipay.codequery.properties.dal.mybatis.domain.EmptyLine;
+import org.apache.ibatis.annotations.Select;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface EmptyLineMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/EntryMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/EntryMapper.java
new file mode 100644
index 00000000..b02e7894
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/EntryMapper.java
@@ -0,0 +1,8 @@
+package com.alipay.codequery.properties.dal.mybatis.mapper;
+
+import com.alipay.codequery.properties.dal.mybatis.domain.Entry;
+import org.apache.ibatis.annotations.Select;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface EntryMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/FileMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/FileMapper.java
new file mode 100644
index 00000000..30e8c6d2
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/FileMapper.java
@@ -0,0 +1,8 @@
+package com.alipay.codequery.properties.dal.mybatis.mapper;
+
+import com.alipay.codequery.properties.dal.mybatis.domain.File;
+import org.apache.ibatis.annotations.Select;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface FileMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/FolderMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/FolderMapper.java
new file mode 100644
index 00000000..b0a03363
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/FolderMapper.java
@@ -0,0 +1,8 @@
+package com.alipay.codequery.properties.dal.mybatis.mapper;
+
+import com.alipay.codequery.properties.dal.mybatis.domain.Folder;
+import org.apache.ibatis.annotations.Select;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface FolderMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/LocationMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/LocationMapper.java
new file mode 100644
index 00000000..b87fad4e
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/LocationMapper.java
@@ -0,0 +1,8 @@
+package com.alipay.codequery.properties.dal.mybatis.mapper;
+
+import com.alipay.codequery.properties.dal.mybatis.domain.Location;
+import org.apache.ibatis.annotations.Select;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface LocationMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/NumberOfLinesMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/NumberOfLinesMapper.java
new file mode 100644
index 00000000..928f7652
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/NumberOfLinesMapper.java
@@ -0,0 +1,8 @@
+package com.alipay.codequery.properties.dal.mybatis.mapper;
+
+import com.alipay.codequery.properties.dal.mybatis.domain.NumberOfLines;
+import org.apache.ibatis.annotations.Select;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface NumberOfLinesMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/ProgramMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/ProgramMapper.java
new file mode 100644
index 00000000..847c9721
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/ProgramMapper.java
@@ -0,0 +1,8 @@
+package com.alipay.codequery.properties.dal.mybatis.mapper;
+
+import com.alipay.codequery.properties.dal.mybatis.domain.Program;
+import org.apache.ibatis.annotations.Select;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface ProgramMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/VariableMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/VariableMapper.java
new file mode 100644
index 00000000..5490cb8e
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/dal/mybatis/mapper/VariableMapper.java
@@ -0,0 +1,8 @@
+package com.alipay.codequery.properties.dal.mybatis.mapper;
+
+import com.alipay.codequery.properties.dal.mybatis.domain.Variable;
+import org.apache.ibatis.annotations.Select;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface VariableMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Comment.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Comment.java
new file mode 100644
index 00000000..624b8200
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Comment.java
@@ -0,0 +1,84 @@
+package com.alipay.codequery.properties.domain;
+
+import javax.persistence.*;
+
+@Table(name = "comment")
+public class Comment {
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ private String text;
+
+ @Column(name = "parent_oid")
+ private Long parentOid;
+
+ @Column(name = "location_oid")
+ private Long locationOid;
+
+ public Comment(Long elementOid, String text, Long parentOid, Long locationOid) {
+ this.elementOid = elementOid;
+ this.text = text;
+ this.parentOid = parentOid;
+ this.locationOid = locationOid;
+ }
+
+ public Comment() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return text
+ */
+ public String getText() {
+ return text;
+ }
+
+ /**
+ * @param text
+ */
+ public void setText(String text) {
+ this.text = text == null ? null : text.trim();
+ }
+
+ /**
+ * @return parent_oid
+ */
+ public Long getParentOid() {
+ return parentOid;
+ }
+
+ /**
+ * @param parentOid
+ */
+ public void setParentOid(Long parentOid) {
+ this.parentOid = parentOid;
+ }
+
+ /**
+ * @return location_oid
+ */
+ public Long getLocationOid() {
+ return locationOid;
+ }
+
+ /**
+ * @param locationOid
+ */
+ public void setLocationOid(Long locationOid) {
+ this.locationOid = locationOid;
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/ContainerParent.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/ContainerParent.java
new file mode 100644
index 00000000..fcaf08fd
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/ContainerParent.java
@@ -0,0 +1,49 @@
+package com.alipay.codequery.properties.domain;
+
+import javax.persistence.*;
+
+@Table(name = "container_parent")
+public class ContainerParent {
+ @Column(name = "child_oid")
+ private Long childOid;
+
+ @Column(name = "parent_oid")
+ private Long parentOid;
+
+ public ContainerParent(Long childOid, Long parentOid) {
+ this.childOid = childOid;
+ this.parentOid = parentOid;
+ }
+
+ public ContainerParent() {
+ super();
+ }
+
+ /**
+ * @return child_oid
+ */
+ public Long getChildOid() {
+ return childOid;
+ }
+
+ /**
+ * @param childOid
+ */
+ public void setChildOid(Long childOid) {
+ this.childOid = childOid;
+ }
+
+ /**
+ * @return parent_oid
+ */
+ public Long getParentOid() {
+ return parentOid;
+ }
+
+ /**
+ * @param parentOid
+ */
+ public void setParentOid(Long parentOid) {
+ this.parentOid = parentOid;
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/EmptyLine.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/EmptyLine.java
new file mode 100644
index 00000000..7077a1e6
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/EmptyLine.java
@@ -0,0 +1,68 @@
+package com.alipay.codequery.properties.domain;
+
+import javax.persistence.*;
+
+@Table(name = "empty_line")
+public class EmptyLine {
+ @Id
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ @Column(name = "location_oid")
+ private Long locationOid;
+
+ @Column(name = "file_oid")
+ private Long fileOid;
+
+ public EmptyLine(Long elementOid, Long locationOid, Long fileOid) {
+ this.elementOid = elementOid;
+ this.locationOid = locationOid;
+ this.fileOid = fileOid;
+ }
+
+ public EmptyLine() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return location_oid
+ */
+ public Long getLocationOid() {
+ return locationOid;
+ }
+
+ /**
+ * @param locationOid
+ */
+ public void setLocationOid(Long locationOid) {
+ this.locationOid = locationOid;
+ }
+
+ /**
+ * @return file_oid
+ */
+ public Long getFileOid() {
+ return fileOid;
+ }
+
+ /**
+ * @param fileOid
+ */
+ public void setFileOid(Long fileOid) {
+ this.fileOid = fileOid;
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Entry.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Entry.java
new file mode 100644
index 00000000..6b97c11a
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Entry.java
@@ -0,0 +1,101 @@
+package com.alipay.codequery.properties.domain;
+
+import javax.persistence.*;
+
+@Table(name = "entry")
+public class Entry {
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ private String key;
+
+ private String value;
+
+ @Column(name = "printable_text")
+ private String printableText;
+
+ @Column(name = "location_oid")
+ private Long locationOid;
+
+ public Entry(Long elementOid, String key, String value, String printableText, Long locationOid) {
+ this.elementOid = elementOid;
+ this.key = key;
+ this.value = value;
+ this.printableText = printableText;
+ this.locationOid = locationOid;
+ }
+
+ public Entry() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return key
+ */
+ public String getKey() {
+ return key;
+ }
+
+ /**
+ * @param key
+ */
+ public void setKey(String key) {
+ this.key = key == null ? null : key.trim();
+ }
+
+ /**
+ * @return value
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * @param value
+ */
+ public void setValue(String value) {
+ this.value = value == null ? null : value.trim();
+ }
+
+ /**
+ * @return printable_text
+ */
+ public String getPrintableText() {
+ return printableText;
+ }
+
+ /**
+ * @param printableText
+ */
+ public void setPrintableText(String printableText) {
+ this.printableText = printableText == null ? null : printableText.trim();
+ }
+
+ /**
+ * @return location_oid
+ */
+ public Long getLocationOid() {
+ return locationOid;
+ }
+
+ /**
+ * @param locationOid
+ */
+ public void setLocationOid(Long locationOid) {
+ this.locationOid = locationOid;
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/File.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/File.java
new file mode 100644
index 00000000..daecee37
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/File.java
@@ -0,0 +1,83 @@
+package com.alipay.codequery.properties.domain;
+
+import javax.persistence.*;
+
+@Table(name = "file")
+public class File {
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ @Column(name = "relative_path")
+ private String relativePath;
+
+ private String extension;
+
+ private String name;
+
+ public File(Long elementOid, String relativePath, String extension, String name) {
+ this.elementOid = elementOid;
+ this.relativePath = relativePath;
+ this.extension = extension;
+ this.name = name;
+ }
+
+ public File() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return relative_path
+ */
+ public String getRelativePath() {
+ return relativePath;
+ }
+
+ /**
+ * @param relativePath
+ */
+ public void setRelativePath(String relativePath) {
+ this.relativePath = relativePath == null ? null : relativePath.trim();
+ }
+
+ /**
+ * @return extension
+ */
+ public String getExtension() {
+ return extension;
+ }
+
+ /**
+ * @param extension
+ */
+ public void setExtension(String extension) {
+ this.extension = extension == null ? null : extension.trim();
+ }
+
+ /**
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name
+ */
+ public void setName(String name) {
+ this.name = name == null ? null : name.trim();
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Folder.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Folder.java
new file mode 100644
index 00000000..7fd5a51b
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Folder.java
@@ -0,0 +1,84 @@
+package com.alipay.codequery.properties.domain;
+
+import javax.persistence.*;
+
+@Table(name = "folder")
+public class Folder {
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ @Column(name = "relative_path")
+ private String relativePath;
+
+ private String name;
+
+ @Column(name = "parent_oid")
+ private Long parentOid;
+
+ public Folder(Long elementOid, String relativePath, String name, Long parentOid) {
+ this.elementOid = elementOid;
+ this.relativePath = relativePath;
+ this.name = name;
+ this.parentOid = parentOid;
+ }
+
+ public Folder() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return relative_path
+ */
+ public String getRelativePath() {
+ return relativePath;
+ }
+
+ /**
+ * @param relativePath
+ */
+ public void setRelativePath(String relativePath) {
+ this.relativePath = relativePath == null ? null : relativePath.trim();
+ }
+
+ /**
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name
+ */
+ public void setName(String name) {
+ this.name = name == null ? null : name.trim();
+ }
+
+ /**
+ * @return parent_oid
+ */
+ public Long getParentOid() {
+ return parentOid;
+ }
+
+ /**
+ * @param parentOid
+ */
+ public void setParentOid(Long parentOid) {
+ this.parentOid = parentOid;
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Location.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Location.java
new file mode 100644
index 00000000..54fb4694
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Location.java
@@ -0,0 +1,121 @@
+package com.alipay.codequery.properties.domain;
+
+import javax.persistence.*;
+
+@Table(name = "location")
+public class Location {
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ @Column(name = "file_oid")
+ private Long fileOid;
+
+ @Column(name = "start_line_number")
+ private Integer startLineNumber;
+
+ @Column(name = "start_column_number")
+ private Integer startColumnNumber;
+
+ @Column(name = "end_line_number")
+ private Integer endLineNumber;
+
+ @Column(name = "end_column_number")
+ private Integer endColumnNumber;
+
+ public Location(Long elementOid, Long fileOid, Integer startLineNumber, Integer startColumnNumber, Integer endLineNumber, Integer endColumnNumber) {
+ this.elementOid = elementOid;
+ this.fileOid = fileOid;
+ this.startLineNumber = startLineNumber;
+ this.startColumnNumber = startColumnNumber;
+ this.endLineNumber = endLineNumber;
+ this.endColumnNumber = endColumnNumber;
+ }
+
+ public Location() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return file_oid
+ */
+ public Long getFileOid() {
+ return fileOid;
+ }
+
+ /**
+ * @param fileOid
+ */
+ public void setFileOid(Long fileOid) {
+ this.fileOid = fileOid;
+ }
+
+ /**
+ * @return start_line_number
+ */
+ public Integer getStartLineNumber() {
+ return startLineNumber;
+ }
+
+ /**
+ * @param startLineNumber
+ */
+ public void setStartLineNumber(Integer startLineNumber) {
+ this.startLineNumber = startLineNumber;
+ }
+
+ /**
+ * @return start_column_number
+ */
+ public Integer getStartColumnNumber() {
+ return startColumnNumber;
+ }
+
+ /**
+ * @param startColumnNumber
+ */
+ public void setStartColumnNumber(Integer startColumnNumber) {
+ this.startColumnNumber = startColumnNumber;
+ }
+
+ /**
+ * @return end_line_number
+ */
+ public Integer getEndLineNumber() {
+ return endLineNumber;
+ }
+
+ /**
+ * @param endLineNumber
+ */
+ public void setEndLineNumber(Integer endLineNumber) {
+ this.endLineNumber = endLineNumber;
+ }
+
+ /**
+ * @return end_column_number
+ */
+ public Integer getEndColumnNumber() {
+ return endColumnNumber;
+ }
+
+ /**
+ * @param endColumnNumber
+ */
+ public void setEndColumnNumber(Integer endColumnNumber) {
+ this.endColumnNumber = endColumnNumber;
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/NumberOfLines.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/NumberOfLines.java
new file mode 100644
index 00000000..833cc3de
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/NumberOfLines.java
@@ -0,0 +1,85 @@
+package com.alipay.codequery.properties.domain;
+
+import javax.persistence.*;
+
+@Table(name = "number_of_lines")
+public class NumberOfLines {
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ @Column(name = "number_of_lines")
+ private Integer numberOfLines;
+
+ @Column(name = "number_of_valid_lines")
+ private Integer numberOfValidLines;
+
+ @Column(name = "number_of_comment_lines")
+ private Integer numberOfCommentLines;
+
+ public NumberOfLines(Long elementOid, Integer numberOfLines, Integer numberOfValidLines, Integer numberOfCommentLines) {
+ this.elementOid = elementOid;
+ this.numberOfLines = numberOfLines;
+ this.numberOfValidLines = numberOfValidLines;
+ this.numberOfCommentLines = numberOfCommentLines;
+ }
+
+ public NumberOfLines() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return number_of_lines
+ */
+ public Integer getNumberOfLines() {
+ return numberOfLines;
+ }
+
+ /**
+ * @param numberOfLines
+ */
+ public void setNumberOfLines(Integer numberOfLines) {
+ this.numberOfLines = numberOfLines;
+ }
+
+ /**
+ * @return number_of_valid_lines
+ */
+ public Integer getNumberOfValidLines() {
+ return numberOfValidLines;
+ }
+
+ /**
+ * @param numberOfValidLines
+ */
+ public void setNumberOfValidLines(Integer numberOfValidLines) {
+ this.numberOfValidLines = numberOfValidLines;
+ }
+
+ /**
+ * @return number_of_comment_lines
+ */
+ public Integer getNumberOfCommentLines() {
+ return numberOfCommentLines;
+ }
+
+ /**
+ * @param numberOfCommentLines
+ */
+ public void setNumberOfCommentLines(Integer numberOfCommentLines) {
+ this.numberOfCommentLines = numberOfCommentLines;
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Program.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Program.java
new file mode 100644
index 00000000..701f4bf6
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Program.java
@@ -0,0 +1,49 @@
+package com.alipay.codequery.properties.domain;
+
+import javax.persistence.*;
+
+@Table(name = "program")
+public class Program {
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ @Column(name = "absolute_path_prefix")
+ private String absolutePathPrefix;
+
+ public Program(Long elementOid, String absolutePathPrefix) {
+ this.elementOid = elementOid;
+ this.absolutePathPrefix = absolutePathPrefix;
+ }
+
+ public Program() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return absolute_path_prefix
+ */
+ public String getAbsolutePathPrefix() {
+ return absolutePathPrefix;
+ }
+
+ /**
+ * @param absolutePathPrefix
+ */
+ public void setAbsolutePathPrefix(String absolutePathPrefix) {
+ this.absolutePathPrefix = absolutePathPrefix == null ? null : absolutePathPrefix.trim();
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Variable.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Variable.java
new file mode 100644
index 00000000..57e2a5eb
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/domain/Variable.java
@@ -0,0 +1,102 @@
+package com.alipay.codequery.properties.domain;
+
+import javax.persistence.*;
+
+@Table(name = "variable")
+public class Variable {
+ @Column(name = "element_oid")
+ private Long elementOid;
+
+ @Column(name = "parent_oid")
+ private Long parentOid;
+
+ @Column(name = "start_index")
+ private Integer startIndex;
+
+ private String name;
+
+ @Column(name = "printable_text")
+ private String printableText;
+
+ public Variable(Long elementOid, Long parentOid, Integer startIndex, String name, String printableText) {
+ this.elementOid = elementOid;
+ this.parentOid = parentOid;
+ this.startIndex = startIndex;
+ this.name = name;
+ this.printableText = printableText;
+ }
+
+ public Variable() {
+ super();
+ }
+
+ /**
+ * @return element_oid
+ */
+ public Long getElementOid() {
+ return elementOid;
+ }
+
+ /**
+ * @param elementOid
+ */
+ public void setElementOid(Long elementOid) {
+ this.elementOid = elementOid;
+ }
+
+ /**
+ * @return parent_oid
+ */
+ public Long getParentOid() {
+ return parentOid;
+ }
+
+ /**
+ * @param parentOid
+ */
+ public void setParentOid(Long parentOid) {
+ this.parentOid = parentOid;
+ }
+
+ /**
+ * @return start_index
+ */
+ public Integer getStartIndex() {
+ return startIndex;
+ }
+
+ /**
+ * @param startIndex
+ */
+ public void setStartIndex(Integer startIndex) {
+ this.startIndex = startIndex;
+ }
+
+ /**
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param name
+ */
+ public void setName(String name) {
+ this.name = name == null ? null : name.trim();
+ }
+
+ /**
+ * @return printable_text
+ */
+ public String getPrintableText() {
+ return printableText;
+ }
+
+ /**
+ * @param printableText
+ */
+ public void setPrintableText(String printableText) {
+ this.printableText = printableText == null ? null : printableText.trim();
+ }
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/CommentMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/CommentMapper.java
new file mode 100644
index 00000000..7d0d8ded
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/CommentMapper.java
@@ -0,0 +1,7 @@
+package com.alipay.codequery.properties.mapper;
+
+import com.alipay.codequery.properties.domain.Comment;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface CommentMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/ContainerParentMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/ContainerParentMapper.java
new file mode 100644
index 00000000..fc3dd584
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/ContainerParentMapper.java
@@ -0,0 +1,7 @@
+package com.alipay.codequery.properties.mapper;
+
+import com.alipay.codequery.properties.domain.ContainerParent;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface ContainerParentMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/EmptyLineMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/EmptyLineMapper.java
new file mode 100644
index 00000000..a293fe1f
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/EmptyLineMapper.java
@@ -0,0 +1,7 @@
+package com.alipay.codequery.properties.mapper;
+
+import com.alipay.codequery.properties.domain.EmptyLine;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface EmptyLineMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/EntryMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/EntryMapper.java
new file mode 100644
index 00000000..0e67bb55
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/EntryMapper.java
@@ -0,0 +1,7 @@
+package com.alipay.codequery.properties.mapper;
+
+import com.alipay.codequery.properties.domain.Entry;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface EntryMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/FileMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/FileMapper.java
new file mode 100644
index 00000000..8d025112
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/FileMapper.java
@@ -0,0 +1,7 @@
+package com.alipay.codequery.properties.mapper;
+
+import com.alipay.codequery.properties.domain.File;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface FileMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/FolderMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/FolderMapper.java
new file mode 100644
index 00000000..50f865e7
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/FolderMapper.java
@@ -0,0 +1,7 @@
+package com.alipay.codequery.properties.mapper;
+
+import com.alipay.codequery.properties.domain.Folder;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface FolderMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/LocationMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/LocationMapper.java
new file mode 100644
index 00000000..dea3b9bf
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/LocationMapper.java
@@ -0,0 +1,7 @@
+package com.alipay.codequery.properties.mapper;
+
+import com.alipay.codequery.properties.domain.Location;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface LocationMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/NumberOfLinesMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/NumberOfLinesMapper.java
new file mode 100644
index 00000000..da39bf7c
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/NumberOfLinesMapper.java
@@ -0,0 +1,7 @@
+package com.alipay.codequery.properties.mapper;
+
+import com.alipay.codequery.properties.domain.NumberOfLines;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface NumberOfLinesMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/ProgramMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/ProgramMapper.java
new file mode 100644
index 00000000..2325b0f1
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/ProgramMapper.java
@@ -0,0 +1,7 @@
+package com.alipay.codequery.properties.mapper;
+
+import com.alipay.codequery.properties.domain.Program;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface ProgramMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/VariableMapper.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/VariableMapper.java
new file mode 100644
index 00000000..b1f3e1ae
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/mapper/VariableMapper.java
@@ -0,0 +1,7 @@
+package com.alipay.codequery.properties.mapper;
+
+import com.alipay.codequery.properties.domain.Variable;
+import tk.mybatis.mapper.common.Mapper;
+
+public interface VariableMapper extends Mapper {
+}
\ No newline at end of file
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/ContainerParent.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/ContainerParent.java
new file mode 100644
index 00000000..93af80c5
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/ContainerParent.java
@@ -0,0 +1,24 @@
+
+package com.alipay.codequery.properties.model;
+
+
+public class ContainerParent extends Node {
+ /**
+ * Constructor.
+ * @param oid
+ * @param parentOid
+ */
+ public ContainerParent(Long oid, Long parentOid) {
+ this.oid = oid;
+ this.parent = new Node(parentOid);
+ }
+
+ /**
+ * Extract corresponding mybatis object.
+ * @return
+ */
+ public com.alipay.codequery.properties.dal.mybatis.domain.ContainerParent extractContainerParent() {
+ return new com.alipay.codequery.properties.dal.mybatis.domain.ContainerParent(this.oid, this.parent.oid);
+ }
+
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/EmptyLine.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/EmptyLine.java
new file mode 100644
index 00000000..c33252bf
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/EmptyLine.java
@@ -0,0 +1,33 @@
+
+package com.alipay.codequery.properties.model;
+
+
+public class EmptyLine extends Node {
+
+ /**
+ * @param line
+ */
+ public EmptyLine(String line, Location.LocalLocation localLocation) {
+ this.printableText = line;
+ this.localLocation = localLocation;
+ }
+
+ /**
+ * Get printable text.
+ * @return
+ */
+ public String toString() {
+ if (printableText != null) {
+ return printableText;
+ }
+ return null;
+ }
+
+ /**
+ * Extract corresponding mybatis object.
+ * @return
+ */
+ public com.alipay.codequery.properties.dal.mybatis.domain.EmptyLine extractEmptyLine() {
+ return new com.alipay.codequery.properties.dal.mybatis.domain.EmptyLine(this.oid, this.location.oid, this.file.oid);
+ }
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/File.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/File.java
new file mode 100644
index 00000000..e1d30e0a
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/File.java
@@ -0,0 +1,40 @@
+
+package com.alipay.codequery.properties.model;
+
+
+public class File extends Node{
+ /**
+ * File's relative path.
+ */
+ public String relativePath;
+ /**
+ * File's extention.
+ */
+ public String extension;
+ /**
+ * File's name.
+ */
+ public String name;
+
+ /**
+ * Extract corresponding mybatis object.
+ * @return
+ */
+ public com.alipay.codequery.properties.dal.mybatis.domain.File extractFile(){
+ return new com.alipay.codequery.properties.dal.mybatis.domain.File(this.oid, this.relativePath, this.extension, this.name);
+ }
+
+ /**
+ * Constructor.
+ * @param oid
+ */
+ public File(Long oid) {
+ super(oid);
+ }
+
+ /**
+ * Default constructor.
+ */
+ public File() {
+ }
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/Folder.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/Folder.java
new file mode 100644
index 00000000..fa874129
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/Folder.java
@@ -0,0 +1,37 @@
+
+package com.alipay.codequery.properties.model;
+
+public class Folder extends Node{
+
+ /**
+ * Folder's relative path.
+ */
+ public String relativePath;
+
+ /**
+ * Folder's name.
+ */
+ public String name;
+
+ /**
+ * Default constructor.
+ */
+ public Folder() {
+ }
+
+ /**
+ * Constructor.
+ * @param oid
+ */
+ public Folder(Long oid) {
+ super(oid);
+ }
+
+ /**
+ * Extract corresponding mybatis object.
+ * @return
+ */
+ public com.alipay.codequery.properties.dal.mybatis.domain.Folder extractFolder(){
+ return new com.alipay.codequery.properties.dal.mybatis.domain.Folder(this.oid,this.relativePath,this.name, this.parent.oid);
+ }
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/Location.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/Location.java
new file mode 100644
index 00000000..a0dfe1f8
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/Location.java
@@ -0,0 +1,139 @@
+
+package com.alipay.codequery.properties.model;
+
+
+public class Location extends Node{
+
+ /**
+ * The file info of the location.
+ */
+ public File file;
+
+ /**
+ * The start line number of the location.
+ */
+ public int startLineNumber;
+
+ /**
+ * The start column number of the location.
+ */
+ public int startColumnNumber;
+
+ /**
+ * The end line number of the location.
+ */
+ public int endLineNumber;
+
+ /**
+ * The end column number of the location.
+ */
+ public int endColumnNumber;
+
+ /**
+ * Constructor.
+ * @param oid
+ */
+ public Location(Long oid) {
+ super(oid);
+ }
+
+ /**
+ * Default constructor.
+ */
+ public Location() {
+ }
+
+ /**
+ * Constructor.
+ * @param oid
+ * @param file
+ * @param localLocation
+ */
+ public Location(Long oid, File file, LocalLocation localLocation) {
+ this.oid = oid;
+ this.file = file;
+ this.startLineNumber = localLocation.startLineNumber;
+ this.startColumnNumber = localLocation.startColumnNumber;
+ this.endLineNumber = localLocation.endLineNumber;
+ this.endColumnNumber = localLocation.endColumnNumber;
+ }
+
+ /**
+ * Extract corresponding mybatis object.
+ * @return
+ */
+ public com.alipay.codequery.properties.dal.mybatis.domain.Location extractLocation(){
+ return new com.alipay.codequery.properties.dal.mybatis.domain.Location(
+ this.oid,
+ this.file.oid,
+ this.startLineNumber,
+ this.startColumnNumber,
+ this.endLineNumber,
+ this.endColumnNumber);
+ }
+
+ /**
+ * The local location element.
+ */
+ public static class LocalLocation extends Location {
+
+ /**
+ * Default constructor.
+ */
+ public LocalLocation() {
+
+ }
+
+ /**
+ * Constructor.
+ * @param startLineNumber
+ * @param startColumnNumber
+ * @param endLineNumber
+ * @param endColumnNumber
+ */
+ public LocalLocation(int startLineNumber,int startColumnNumber, int endLineNumber, int endColumnNumber ){
+ this.startLineNumber = startLineNumber;
+ this.startColumnNumber = startColumnNumber;
+ this.endLineNumber = endLineNumber;
+ this.endColumnNumber = endColumnNumber;
+ }
+ }
+
+ /**
+ * NumberOfLines element.
+ */
+ public static class NumberOfLines extends Location {
+
+ /**
+ * The total number of lines of the element.
+ */
+ public int numberOfLines;
+
+ /**
+ * The total number of comment lines of the element.
+ */
+ public int numberOfCommentLines;
+
+ /**
+ * The total number of code lines of the element.
+ */
+ public int numberOfCodeLines;
+
+ /**
+ * Constructor.
+ * @param oid
+ */
+ public NumberOfLines(Long oid) {
+ this.oid = oid;
+ }
+
+ /**
+ * Extract corresponding mybatis object.
+ * @return
+ */
+ public com.alipay.codequery.properties.dal.mybatis.domain.NumberOfLines extractNumberOfLines(){
+ return new com.alipay.codequery.properties.dal.mybatis.domain.NumberOfLines(this.oid, this.numberOfLines,this.numberOfCodeLines,this.numberOfCommentLines);
+ }
+ }
+
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/Node.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/Node.java
new file mode 100644
index 00000000..3e5d97d0
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/Node.java
@@ -0,0 +1,78 @@
+
+package com.alipay.codequery.properties.model;
+
+
+public class Node {
+
+ /**
+ * The location info of the element.
+ */
+ public Location location;
+
+ /**
+ * The parent node.
+ */
+ public Node parent;
+
+ /**
+ * The local location info of the element.
+ */
+ public Location.LocalLocation localLocation;
+
+ /**
+ * The printable text of the element, aka the corresponding src code.
+ */
+ public String printableText;
+
+ /**
+ * The oid of the element, which can be uniquely identified the element.
+ */
+ public Long oid;
+
+ /**
+ * The file info the element.
+ */
+ public File file;
+
+ /**
+ * Get the printable text of the element.
+ * @return
+ */
+ public String getPrintableText() {
+ return printableText;
+ }
+
+ /**
+ * Set printable text of the element.
+ * @param line
+ */
+ public void setPrintableText(String line) {
+ this.printableText = line;
+ }
+
+ /**
+ * Constructor.
+ * @param oid
+ */
+ public Node(Long oid) {
+ this.oid = oid;
+ }
+
+ /**
+ * Constructor.
+ * @param oid
+ * @param printableText
+ * @param file
+ */
+ public Node(Long oid, String printableText, File file) {
+ this.oid = oid;
+ this.printableText = printableText;
+ this.file = file;
+ }
+
+ /**
+ * Default constructor.
+ */
+ public Node() {
+ }
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/Program.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/Program.java
new file mode 100644
index 00000000..be07299a
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/Program.java
@@ -0,0 +1,31 @@
+
+package com.alipay.codequery.properties.model;
+
+public class Program extends Node{
+ /**
+ * The prefix of the root node(Corpus).
+ */
+ public String prefix = "";
+
+ /**
+ * Default constructor.
+ */
+ public Program() {
+ }
+
+ /**
+ * Constructor by set oid.
+ * @param oid
+ */
+ public Program(Long oid) {
+ super(oid);
+ }
+
+ /**
+ * Extract corresponding mybatis object.
+ * @return
+ */
+ public com.alipay.codequery.properties.dal.mybatis.domain.Program extractProgram(){
+ return new com.alipay.codequery.properties.dal.mybatis.domain.Program(this.oid, this.prefix);
+ }
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/PropertiesContext.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/PropertiesContext.java
new file mode 100644
index 00000000..748368a1
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/PropertiesContext.java
@@ -0,0 +1,115 @@
+
+package com.alipay.codequery.properties.model;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class PropertiesContext {
+
+ private List commentOrEntrys = new ArrayList();
+
+ private List comments = new ArrayList();
+
+ private List emptyLines = new ArrayList();
+
+ /**
+ * Get all elements.
+ * @return
+ */
+ public List getCommentOrEntrys() {
+ return commentOrEntrys;
+ }
+
+ /**
+ * Get the list of comment elements.
+ * @return
+ */
+ public List getComments() {
+ return comments;
+ }
+
+ /**
+ * Get the list of empty line elements.
+ * @return
+ */
+ public List getEmptyLines() {
+ return emptyLines;
+ }
+
+ /**
+ * Add comment element to commentOrEntrys list.
+ * @param line
+ * @param localLocation
+ */
+ public void addCommentLine(String line, Location.LocalLocation localLocation) {
+ PropertyComment propertyComment = new PropertyComment(line, localLocation);
+ comments.add(propertyComment);
+ commentOrEntrys.add(propertyComment);
+ }
+
+ /**
+ * Add empty line element to commentOrEntrys list.
+ * @param line
+ * @param localLocation
+ */
+ public void addEmptyLine(String line, Location.LocalLocation localLocation) {
+ EmptyLine emptyLine = new EmptyLine(line, localLocation);
+ emptyLines.add(emptyLine);
+ commentOrEntrys.add(emptyLine);
+ }
+
+ /**
+ * Add entry element to commentOrEntrys list.
+ * @param pe
+ */
+ public void putOrUpdate(PropertyEntry pe) {
+ remove(pe.getKey());
+ commentOrEntrys.add(pe);
+ }
+
+ /**
+ *
+ * @param key
+ * @param value
+ * @param line
+ * @param localLocation
+ */
+ public void putOrUpdate(String key, String value, String line, Location.LocalLocation localLocation) {
+ PropertyEntry pe = new PropertyEntry(key, value, line, localLocation);
+ remove(key);
+ commentOrEntrys.add(pe);
+ }
+
+ /**
+ *
+ * @param key
+ * @param value
+ */
+ public void putOrUpdate(String key, String value) {
+ PropertyEntry pe = new PropertyEntry(key, value);
+ int index = remove(key);
+ commentOrEntrys.add(index,pe);
+ }
+
+ /**
+ * Remove entry by key value.
+ * @param key
+ * @return
+ */
+ public int remove(String key) {
+ for (int index = 0; index < commentOrEntrys.size(); index++) {
+ Object obj = commentOrEntrys.get(index);
+ if (obj instanceof PropertyEntry) {
+ if (obj != null) {
+ if (key.equals(((PropertyEntry) obj).getKey())) {
+ commentOrEntrys.remove(obj);
+ return index;
+ }
+ }
+ }
+ }
+ return commentOrEntrys.size();
+ }
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/PropertyComment.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/PropertyComment.java
new file mode 100644
index 00000000..383b8587
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/PropertyComment.java
@@ -0,0 +1,44 @@
+
+package com.alipay.codequery.properties.model;
+
+import com.alipay.codequery.properties.dal.mybatis.domain.Comment;
+
+
+public class PropertyComment extends Node{
+
+ /**
+ * @param printableText
+ */
+ public PropertyComment(String printableText) {
+ this.printableText = printableText;
+ }
+
+ /**
+ * Constructor.
+ * @param printableText
+ * @param localLocation
+ */
+ public PropertyComment(String printableText, Location.LocalLocation localLocation) {
+ this.printableText = printableText;
+ this.localLocation = localLocation;
+ }
+
+ /**
+ * Get the string presentation of the lement.
+ * @return
+ */
+ public String toString() {
+ if (printableText != null) {
+ return printableText;
+ }
+ return null;
+ }
+
+ /**
+ * Extract corresponding mybatis object.
+ * @return
+ */
+ public Comment extractComment() {
+ return new Comment(this.oid, this.printableText, this.file.oid, this.location.oid);
+ }
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/PropertyEntry.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/PropertyEntry.java
new file mode 100644
index 00000000..32096d55
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/PropertyEntry.java
@@ -0,0 +1,90 @@
+
+package com.alipay.codequery.properties.model;
+
+import com.alipay.codequery.properties.util.SafeProperties;
+import com.alipay.codequery.properties.dal.mybatis.domain.Entry;
+
+
+public class PropertyEntry extends Node {
+ private String key;
+
+ private String value;
+
+ /**
+ * Constructor.
+ * @param key
+ * @param value
+ */
+ public PropertyEntry(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ /**
+ * @param key
+ * @param value
+ * @param printableText
+ */
+ public PropertyEntry(String key, String value, String printableText, Location.LocalLocation localLocation) {
+ this(key, value);
+ this.printableText = printableText;
+ this.localLocation = localLocation;
+ }
+
+ /**
+ * Get the key value of the entry.
+ * @return
+ */
+ public String getKey() {
+ return key;
+ }
+
+ /**
+ * Set the key value of the entry.
+ * @param key
+ */
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ /**
+ * Get the value of the entry.
+ * @return
+ */
+ public String getValue() {
+ return value;
+ }
+
+ /**
+ * Set the value of the entry.
+ * @param value
+ */
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ /**
+ * The printable text of the entry element.
+ * @return
+ */
+ public String toString() {
+ if (this.printableText != null) {
+ return this.printableText;
+ }
+ if (key != null && value != null) {
+ String k = SafeProperties.saveConvert(key, true);
+ String v = SafeProperties.saveConvert(value, false);
+ return k + "=" + v;
+ }
+ return null;
+ }
+
+ /**
+ * Extract corresponding mybatis object.
+ * @return
+ */
+ public Entry extractEntry() {
+ return new Entry(this.oid, this.key, this.value, this.printableText, this.location.oid);
+ }
+
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/Variable.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/Variable.java
new file mode 100644
index 00000000..73ca1986
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/model/Variable.java
@@ -0,0 +1,52 @@
+
+package com.alipay.codequery.properties.model;
+
+
+public class Variable extends Node {
+
+ /**
+ * The begin index of the variable in its parent.
+ */
+ public int beginIndex;
+
+ /**
+ * The name of the variable.
+ */
+ public String name;
+
+ /**
+ * @param printableText
+ */
+ public Variable(String printableText) {
+ this.printableText = printableText;
+ }
+
+ /**
+ * Constructor.
+ * @param printableText
+ * @param beginIndex
+ */
+ public Variable(String printableText, int beginIndex) {
+ this.printableText = printableText;
+ this.beginIndex = beginIndex;
+ }
+
+ /**
+ * The printable text of the element.
+ * @return
+ */
+ public String toString() {
+ if (printableText != null) {
+ return printableText;
+ }
+ return null;
+ }
+
+ /**
+ * Extract corresponding mybatis object.
+ * @return
+ */
+ public com.alipay.codequery.properties.dal.mybatis.domain.Variable extractVariable() {
+ return new com.alipay.codequery.properties.dal.mybatis.domain.Variable(this.oid, this.parent.oid, this.beginIndex, this.name, this.printableText);
+ }
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/storage/CorefStorage.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/storage/CorefStorage.java
new file mode 100644
index 00000000..d5f61585
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/storage/CorefStorage.java
@@ -0,0 +1,185 @@
+
+package com.alipay.codequery.properties.storage;
+
+import com.alipay.codequery.properties.dal.mybatis.domain.*;
+import com.alipay.codequery.properties.dal.mybatis.mapper.*;
+import org.apache.ibatis.datasource.DataSourceFactory;
+import org.apache.ibatis.datasource.pooled.PooledDataSourceFactory;
+import org.apache.ibatis.mapping.Environment;
+import org.apache.ibatis.session.Configuration;
+import org.apache.ibatis.session.SqlSession;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.session.SqlSessionFactoryBuilder;
+import org.apache.ibatis.transaction.TransactionFactory;
+import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
+import tk.mybatis.mapper.common.BaseMapper;
+import tk.mybatis.mapper.entity.Config;
+import tk.mybatis.mapper.mapperhelper.MapperHelper;
+
+import javax.sql.DataSource;
+import java.io.*;
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Properties;
+
+
+public class CorefStorage {
+
+ private final SqlSession session;
+
+ /**
+ * The path of the folder which contains the db file.
+ */
+ public String dbDir;
+
+ /**
+ * Db connection method.
+ * @param dbDir
+ * @throws IOException
+ */
+ public CorefStorage(String dbDir) throws IOException {
+ this.dbDir = dbDir.endsWith(File.separator) ? dbDir : dbDir + File.separator;
+ Properties properties = new Properties();
+ properties.setProperty("driver", "org.sqlite.JDBC");
+ copyDBFiles(dbDir);
+
+ properties.setProperty("url", "jdbc:sqlite:" + this.dbDir + "coref_properties_src.db");
+ properties.setProperty("username", "");
+ properties.setProperty("password", "");
+ DataSourceFactory factory = new PooledDataSourceFactory();
+ DataSource dataSource = factory.getDataSource();
+ factory.setProperties(properties);
+ TransactionFactory transactionFactory = new JdbcTransactionFactory();
+ Environment environment = new Environment("development", transactionFactory, dataSource);
+ Configuration configuration = new Configuration(environment);
+ configuration.addMappers("com.alipay.codequery.properties.dal.mybatis.mapper");
+ MapperHelper mapperHelper = new MapperHelper();
+ Config config = new Config();
+ config.setIDENTITY("MYSQL");
+ config.setEnableMethodAnnotation(true);
+ config.setNotEmpty(true);
+ config.setCheckExampleEntityClass(true);
+ config.setUseSimpleType(true);
+ config.setEnumAsSimpleType(true);
+ config.setWrapKeyword("`{0}`");
+ mapperHelper.setConfig(config);
+
+ SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
+ session = sqlSessionFactory.openSession();
+ mapperHelper.processConfiguration(session.getConfiguration());
+
+ }
+
+ private void copyDBFiles(String dbDir) throws IOException {
+ Path dir = Files.createDirectories(Paths.get(dbDir));
+ Path destPath = Paths.get(dir.toFile() + File.separator + "coref_properties_src.db");
+ if (destPath.toFile().exists()) {
+ Files.delete(destPath);
+ }
+ File destFile = Files.createFile(destPath).toFile();
+ InputStream in = this.getClass().getClassLoader().getResourceAsStream("coref_properties_src.db");
+
+ OutputStream os = new FileOutputStream(destFile);
+ int bytesRead = 0;
+ byte[] buffer = new byte[8192];
+ while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {
+ os.write(buffer, 0, bytesRead);
+ }
+ os.close();
+ in.close();
+ }
+
+ private void insert(Class mapperClass, Object object) {
+ BaseMapper mapper = (BaseMapper) session.getMapper(mapperClass);
+ mapper.insert(object);
+ }
+
+ /**
+ * Save coref file records.
+ * @param file
+ */
+ public void storeFile(com.alipay.codequery.properties.dal.mybatis.domain.File file) {
+ insert(FileMapper.class, file);
+ }
+
+ /**
+ * Save folder records.
+ * @param folder
+ */
+ public void storeFolder(Folder folder) {
+ insert(FolderMapper.class, folder);
+ }
+
+ /**
+ * Save container parent records.
+ * @param containerParent
+ */
+ public void storeContainerParent(ContainerParent containerParent) {
+ insert(ContainerParentMapper.class, containerParent);
+ }
+
+ /**
+ * Save entry records.
+ * @param entry
+ */
+ public void storeEntry(Entry entry) {
+ insert(EntryMapper.class, entry);
+ }
+
+ /**
+ * Save entry variable records
+ * @param variable
+ */
+ public void storeEntryVariable(Variable variable) {
+ insert(VariableMapper.class, variable);
+ }
+
+ /**
+ * Save comment records.
+ * @param comment
+ */
+ public void storeComment(Comment comment) {
+ insert(CommentMapper.class, comment);
+ }
+
+ /**
+ * Save empty line records.
+ * @param emptyLine
+ */
+ public void storeEmptyLine(EmptyLine emptyLine) {
+ insert(EmptyLineMapper.class, emptyLine);
+ }
+
+ /**
+ * Save location records.
+ * @param location
+ */
+ public void storeLocation(Location location) {
+ insert(LocationMapper.class, location);
+ }
+
+ /**
+ * Save program records.
+ * @param program
+ */
+ public void storeProgram(Program program) {
+ insert(ProgramMapper.class, program);
+ }
+
+ /**
+ * Save numberofline records.
+ * @param numberOfLines
+ */
+ public void storeNumberOfLines(NumberOfLines numberOfLines) {
+ insert(NumberOfLinesMapper.class, numberOfLines);
+ }
+
+ /**
+ * Commit db session.
+ */
+ public void store() {
+ session.commit();
+ }
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/util/HashUtil.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/util/HashUtil.java
new file mode 100644
index 00000000..15685d94
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/util/HashUtil.java
@@ -0,0 +1,180 @@
+
+package com.alipay.codequery.properties.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.MessageDigest;
+
+import com.alipay.codequery.properties.Extractor;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+
+public class HashUtil {
+ private static final Logger logger = LogManager.getLogger(Extractor.class);
+
+ /**
+ * Get the md5 value of the file.
+ * @param filename
+ * @return
+ */
+ public static String getFileMD5(String filename) {
+ File cachedfile = new File(filename);
+ FileInputStream fileInputStream = null;
+ try {
+ MessageDigest MD5 = MessageDigest.getInstance("MD5");
+ fileInputStream = new FileInputStream(cachedfile);
+ byte[] buffer = new byte[8192];
+ int length;
+ while ((length = fileInputStream.read(buffer)) != -1) {
+ MD5.update(buffer, 0, length);
+ }
+ return new String(Hex.encodeHex(MD5.digest()));
+ } catch (Exception e) {
+ logger.error("Extraction failed, error message:{}", e.getMessage());
+ return null;
+ } finally {
+ try {
+ if (fileInputStream != null) {
+ fileInputStream.close();
+ }
+ } catch (IOException e) {
+ logger.error("Extraction failed, error message:{}", e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * Get the md5 value of a given string.
+ * @param target
+ * @return
+ */
+ public static String getStringMD5(String target) {
+ return DigestUtils.md5Hex(target);
+ }
+
+ /**
+ * Get the sha1 value of the file.
+ * @param filename
+ * @return
+ */
+ public static String getFileSHA1(String filename) {
+ File cachedfile = new File(filename);
+ String str = "";
+ try {
+ str = getHashCode(cachedfile, "SHA-256");
+ } catch (Exception e) {
+ logger.error("Extraction failed, error message:{}", e.getMessage());
+ }
+ return str;
+ }
+
+ /**
+ * Calculate the hash value of a given string.
+ * @param value
+ * @return
+ */
+ public static Long hashString(String value) {
+ Long hash = 0L;
+ if (value.length() > 0) {
+ for (int i = 0; i < value.length(); i++) {
+ hash = 63 * hash + value.charAt(i);
+ }
+ }
+ return hash;
+ }
+
+ /**
+ * Calculate the hash value of a given string.
+ * @param value
+ * @return
+ */
+ public static Long getStringHash(String value) {
+ return HashUtil.hashString(value);
+ }
+
+ /**
+ * Calculate the sha256 value of a given string.
+ * @param base
+ * @return
+ */
+ public static Long getStringSHA256(String base) {
+ try {
+ MessageDigest digest = MessageDigest.getInstance("SHA-256");
+ byte[] hash = digest.digest(base.getBytes("UTF-8"));
+ StringBuffer hexString = new StringBuffer();
+ for (int i = 0; i < hash.length; i++) {
+ String hex = Integer.toHexString(0xff & hash[i]);
+ if (hex.length() == 1) {
+ hexString.append('0');
+ }
+ hexString.append(hex);
+ }
+ String temp = hexString.toString();
+ Long hashId = Long.parseLong(temp.substring(49, 64), 16);
+ return hashId;
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ /**
+ * Calculate the short sha256 value of a given string.
+ * @param base
+ * @return
+ */
+ public static int getShortStringSHA256(String base) {
+ try {
+ MessageDigest digest = MessageDigest.getInstance("SHA-256");
+ byte[] hash = digest.digest(base.getBytes("UTF-8"));
+ StringBuffer hexString = new StringBuffer();
+ for (int i = 0; i < hash.length; i++) {
+ String hex = Integer.toHexString(0xff & hash[i]);
+ if (hex.length() == 1) {
+ hexString.append('0');
+ }
+ hexString.append(hex);
+ }
+ String temp = hexString.toString();
+ int hashId = Integer.parseInt(temp.substring(57, 64), 16);
+ return hashId;
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ /**
+ * Calculate the hash value of a given file and given hash type.
+ * @param file
+ * @param hashType
+ * @return
+ * @throws Exception
+ */
+ public static String getHashCode(File file, String hashType) throws Exception {
+ InputStream fis = new FileInputStream(file);
+ byte buffer[] = new byte[1024];
+ MessageDigest sha256 = MessageDigest.getInstance(hashType);
+ for (int numRead = 0; (numRead = fis.read(buffer)) > 0; ) {
+ sha256.update(buffer, 0, numRead);
+ }
+ fis.close();
+ return toHexString(sha256.digest());
+ }
+
+ /**
+ * Transfer the byte array value to hex.
+ * @param b
+ * @return
+ */
+ public static String toHexString(byte b[]) {
+ StringBuilder sb = new StringBuilder();
+ for (byte aB : b) {
+ sb.append(Integer.toHexString(aB & 0xFF));
+ }
+ return sb.toString();
+ }
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/util/LoggerUtil.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/util/LoggerUtil.java
new file mode 100644
index 00000000..c211a0c2
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/util/LoggerUtil.java
@@ -0,0 +1,50 @@
+
+
+package com.alipay.codequery.properties.util;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.appender.ConsoleAppender;
+import org.apache.logging.log4j.core.config.Configurator;
+import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder;
+import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
+import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
+import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder;
+import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
+
+
+public class LoggerUtil {
+
+ /**
+ * Init logger by given level and pattern.
+ * @param level
+ * @param pattern
+ */
+ public static void initLogger(Level level, String pattern) {
+ ConfigurationBuilder builder = ConfigurationBuilderFactory.newConfigurationBuilder();
+
+ builder.setStatusLevel(level);
+ // naming the logger configuration
+ builder.setConfigurationName("DefaultLogger");
+
+ // create a console appender
+ AppenderComponentBuilder appenderBuilder = builder.newAppender("Console", "CONSOLE")
+ .addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
+ // add a layout like pattern, json etc
+ appenderBuilder.add(builder.newLayout("PatternLayout")
+ .addAttribute("pattern", pattern));
+ RootLoggerComponentBuilder rootLogger = builder.newRootLogger(level);
+ rootLogger.add(builder.newAppenderRef("Console"));
+
+ builder.add(appenderBuilder);
+ builder.add(rootLogger);
+ Configurator.reconfigure(builder.build());
+ }
+
+ /**
+ * Init logger by given level.
+ * @param logLevel
+ */
+ public static void initLogger(Level logLevel) {
+ initLogger(logLevel, "%d %p %c [%t] (%F:%L) %m%n");
+ }
+}
diff --git a/language/properties/extractor/src/main/java/com/alipay/codequery/properties/util/SafeProperties.java b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/util/SafeProperties.java
new file mode 100644
index 00000000..4e7cc1c4
--- /dev/null
+++ b/language/properties/extractor/src/main/java/com/alipay/codequery/properties/util/SafeProperties.java
@@ -0,0 +1,398 @@
+
+package com.alipay.codequery.properties.util;
+
+import com.alipay.codequery.properties.model.Location;
+import com.alipay.codequery.properties.model.PropertiesContext;
+
+import java.io.*;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+
+public class SafeProperties extends Properties {
+ private static final long serialVersionUID = 5011694856722313621L;
+
+ private static final String keyValueSeparators = "=: \t\r\n\f";
+
+ private static final String strictKeyValueSeparators = "=:";
+
+ private static final String specialSaveChars = "=: \t\r\n\f#!";
+
+ private static final String whiteSpaceChars = " \t\r\n\f";
+
+ private PropertiesContext context = new PropertiesContext();
+
+ /**
+ * Get the PropertiesContext value.
+ * @return
+ */
+ public PropertiesContext getContext() {
+ return context;
+ }
+
+ private int size = 0;
+
+ /**
+ * Get size value.
+ */
+ public int getSize() {
+ return size;
+ }
+
+ /**
+ * Override the load method.
+ * @param inStream the input stream.
+ * @throws IOException
+ */
+ public synchronized void load(InputStream inStream) throws IOException {
+
+ BufferedReader in;
+
+ in = new BufferedReader(new InputStreamReader(inStream, "UTF-8"));
+
+ int count = 0;
+ while (true) {
+ Location.LocalLocation localLocation = new Location.LocalLocation();
+ count++;
+ // Get next line
+ String line = in.readLine();
+ // intract property/comment string
+ String intactLine = line;
+ if (line == null) {
+ return;
+ }
+
+ if (line.length() > 0) {
+ // Find start of key
+ int len = line.length();
+ int keyStart;
+ for (keyStart = 0; keyStart < len; keyStart++) {
+ if (whiteSpaceChars.indexOf(line.charAt(keyStart)) == -1) {
+ break;
+ }
+ }
+
+ // Blank lines are ignored
+ if (keyStart == len) {
+ continue;
+ }
+
+ // Continue lines that end in slashes if they are not comments
+ char firstChar = line.charAt(keyStart);
+
+ localLocation.startLineNumber = count;
+ localLocation.startColumnNumber = keyStart + 1;
+ localLocation.endLineNumber = count;
+ localLocation.endColumnNumber = line.length();
+
+ if ((firstChar != '#') && (firstChar != '!')) {
+ while (continueLine(line)) {
+ count ++;
+ String nextLine = in.readLine();
+ localLocation.endLineNumber = count;
+ localLocation.endColumnNumber = nextLine.length();
+ intactLine = intactLine + "\n" + nextLine;
+ if (nextLine == null) {
+ nextLine = "";
+ }
+
+ String loppedLine = line.substring(0, len - 1);
+ // Advance beyond whitespace on new line
+ int startIndex;
+ for (startIndex = 0; startIndex < nextLine.length(); startIndex++) {
+ if (whiteSpaceChars.indexOf(nextLine.charAt(startIndex)) == -1) {
+ break;
+ }
+ }
+
+ nextLine = nextLine.substring(startIndex, nextLine.length());
+ line = new String(loppedLine + nextLine);
+ len = line.length();
+ }
+
+ // Find separation between key and value
+ int separatorIndex;
+ for (separatorIndex = keyStart; separatorIndex < len; separatorIndex++) {
+ char currentChar = line.charAt(separatorIndex);
+ if (currentChar == '\\') {
+ separatorIndex++;
+ }
+ else if (keyValueSeparators.indexOf(currentChar) != -1) {
+ break;
+ }
+
+ }
+
+ // Skip over whitespace after key if any
+ int valueIndex;
+ for (valueIndex = separatorIndex; valueIndex < len; valueIndex++) {
+ if (whiteSpaceChars.indexOf(line.charAt(valueIndex)) == -1) {
+ break;
+ }
+
+ }
+
+
+ // Skip over one non whitespace key value separators if any
+ if (valueIndex < len) {
+ if (strictKeyValueSeparators.indexOf(line.charAt(valueIndex)) != -1) {
+ valueIndex++;
+ }
+ }
+
+
+ // Skip over white space after other separators if any
+ while (valueIndex < len) {
+ if (whiteSpaceChars.indexOf(line.charAt(valueIndex)) == -1) {
+ break;
+ }
+
+ valueIndex++;
+ }
+ String key = line.substring(keyStart, separatorIndex);
+ String value = (separatorIndex < len) ? line.substring(valueIndex, len) : "";
+
+ // Convert then store key and value
+ key = loadConvert(key);
+ value = loadConvert(value);
+ //memorize the property also with the whole string
+ put(key, value, line, localLocation);
+ } else {
+ //memorize the comment string
+ context.addCommentLine(intactLine, localLocation);
+ }
+ } else {
+ //memorize the string even the string is empty
+ localLocation.startLineNumber = localLocation.endLineNumber = count;
+ localLocation.startColumnNumber = localLocation.endColumnNumber = 0;
+ context.addEmptyLine(intactLine, localLocation);
+ }
+ size = count;
+ }
+ }
+
+ /*
+ * Converts encoded \uxxxx to unicode chars and changes special saved
+ * chars to their original forms
+ */
+ private String loadConvert(String theString) {
+ char aChar;
+ int len = theString.length();
+ StringBuffer outBuffer = new StringBuffer(len);
+
+ for (int x = 0; x < len;) {
+ aChar = theString.charAt(x++);
+ if (aChar == '\\') {
+ aChar = theString.charAt(x++);
+ if (aChar == 'u') {
+ // Read the xxxx
+ int value = 0;
+ for (int i = 0; i < 4; i++) {
+ aChar = theString.charAt(x++);
+ switch (aChar) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ value = (value << 4) + aChar - '0';
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ value = (value << 4) + 10 + aChar - 'a';
+ break;
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ value = (value << 4) + 10 + aChar - 'A';
+ break;
+ default:
+ throw new IllegalArgumentException("Malformed \\uxxxx encoding.");
+ }
+ }
+ outBuffer.append((char) value);
+ } else {
+ if (aChar == 't') {
+ outBuffer.append('\t'); /* ibm@7211 */
+ } else if (aChar == 'r') {
+ outBuffer.append('\r'); /* ibm@7211 */
+ } else if (aChar == 'n') {
+ /*
+ * ibm@8897 do not convert a \n to a line.separator
+ * because on some platforms line.separator is a String
+ * of "\r\n". When a Properties class is saved as a file
+ * (store()) and then restored (load()) the restored
+ * input MUST be the same as the output (so that
+ * Properties.equals() works).
+ *
+ */
+ outBuffer.append('\n'); /* ibm@8897 ibm@7211 */
+ } else if (aChar == 'f') {
+ outBuffer.append('\f'); /* ibm@7211 */
+ } else {
+ /* ibm@7211 */
+ outBuffer.append(aChar); /* ibm@7211 */
+ }
+
+ }
+ } else {
+ outBuffer.append(aChar);
+ }
+ }
+ return outBuffer.toString();
+ }
+
+ /**
+ * Override the store method.
+ * @param out an output stream.
+ * @param header a description of the property list.
+ * @throws IOException
+ */
+ public synchronized void store(OutputStream out, String header) throws IOException {
+ BufferedWriter awriter;
+ awriter = new BufferedWriter(new OutputStreamWriter(out, "8859_1"));
+ if (header != null) {
+ writeln(awriter, "#" + header);
+ }
+ List entrys = context.getCommentOrEntrys();
+ for (Iterator iter = entrys.iterator(); iter.hasNext();) {
+ Object obj = iter.next();
+ if (obj.toString() != null) {
+ writeln(awriter, obj.toString());
+ }
+ }
+ awriter.flush();
+ }
+
+ private static void writeln(BufferedWriter bw, String s) throws IOException {
+ bw.write(s);
+ bw.newLine();
+ }
+
+ private boolean continueLine(String line) {
+ int slashCount = 0;
+ int index = line.length() - 1;
+ while ((index >= 0) && (line.charAt(index--) == '\\')) {
+ slashCount++;
+ }
+ return (slashCount % 2 == 1);
+ }
+
+ /*
+ * Converts unicodes to encoded \uxxxx and writes out any of the
+ * characters in specialSaveChars with a preceding slash
+ */
+ public static String saveConvert(String theString, boolean escapeSpace) {
+ int len = theString.length();
+ StringBuffer outBuffer = new StringBuffer(len * 2);
+
+ for (int x = 0; x < len; x++) {
+ char aChar = theString.charAt(x);
+ switch (aChar) {
+ case ' ':
+ if (x == 0 || escapeSpace) {
+ outBuffer.append('\\');
+ }
+ outBuffer.append(' ');
+ break;
+ case '\\':
+ outBuffer.append('\\');
+ outBuffer.append('\\');
+ break;
+ case '\t':
+ outBuffer.append('\\');
+ outBuffer.append('t');
+ break;
+ case '\n':
+ outBuffer.append('\\');
+ outBuffer.append('n');
+ break;
+ case '\r':
+ outBuffer.append('\\');
+ outBuffer.append('r');
+ break;
+ case '\f':
+ outBuffer.append('\\');
+ outBuffer.append('f');
+ break;
+ default:
+ if ((aChar < 0x0020) || (aChar > 0x007e)) {
+ outBuffer.append('\\');
+ outBuffer.append('u');
+ outBuffer.append(toHex((aChar >> 12) & 0xF));
+ outBuffer.append(toHex((aChar >> 8) & 0xF));
+ outBuffer.append(toHex((aChar >> 4) & 0xF));
+ outBuffer.append(toHex(aChar & 0xF));
+ } else {
+ if (specialSaveChars.indexOf(aChar) != -1) {
+ outBuffer.append('\\');
+ }
+ outBuffer.append(aChar);
+ }
+ }
+ }
+ return outBuffer.toString();
+ }
+
+ /**
+ * Convert a nibble to a hex character
+ *
+ * @param nibble
+ * the nibble to convert.
+ */
+ private static char toHex(int nibble) {
+ return hexDigit[(nibble & 0xF)];
+ }
+
+ /** A table of hex digits */
+ private static final char[] hexDigit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
+ 'F' };
+
+ /**
+ * Override the put method.
+ * @param key key with which the specified value is to be associated
+ * @param value value to be associated with the specified key
+ * @return
+ */
+ public synchronized Object put(Object key, Object value) {
+ context.putOrUpdate(key.toString(), value.toString());
+ return super.put(key, value);
+ }
+
+ /**
+ * Override the put method.
+ * @param key
+ * @param value
+ * @param line
+ * @param localLocation
+ * @return
+ */
+ public synchronized Object put(Object key, Object value, String line, Location.LocalLocation localLocation) {
+ context.putOrUpdate(key.toString(), value.toString(), line, localLocation);
+ return super.put(key, value);
+ }
+
+ /**
+ * Override the remove method.
+ * @param key the key that needs to be removed
+ * @return
+ */
+ public synchronized Object remove(Object key) {
+ context.remove(key.toString());
+ return super.remove(key);
+ }
+
+}
diff --git a/language/properties/extractor/src/main/resources/coref_properties_src.db b/language/properties/extractor/src/main/resources/coref_properties_src.db
new file mode 100644
index 00000000..4db2cc9c
Binary files /dev/null and b/language/properties/extractor/src/main/resources/coref_properties_src.db differ
diff --git a/language/properties/extractor/src/main/resources/coref_properties_src.sql b/language/properties/extractor/src/main/resources/coref_properties_src.sql
new file mode 100644
index 00000000..7c5e3a6d
--- /dev/null
+++ b/language/properties/extractor/src/main/resources/coref_properties_src.sql
@@ -0,0 +1,62 @@
+BEGIN TRANSACTION;
+CREATE TABLE IF NOT EXISTS "folder" (
+ "element_oid" INTEGER,
+ "relative_path" TEXT NOT NULL,
+ "name" TEXT NOT NULL,
+ "parent_oid" INTEGER
+);
+CREATE TABLE IF NOT EXISTS "location" (
+ "element_oid" INTEGER,
+ "file_oid" INTEGER,
+ "start_line_number" INTEGER,
+ "start_column_number" INTEGER,
+ "end_line_number" INTEGER,
+ "end_column_number" INTEGER
+);
+CREATE TABLE IF NOT EXISTS "comment" (
+ "element_oid" INTEGER,
+ "text" text NOT NULL,
+ "parent_oid" INTEGER NOT NULL,
+ "location_oid" INTEGER NOT NULL
+);
+CREATE TABLE IF NOT EXISTS "entry" (
+ "element_oid" INTEGER NOT NULL,
+ "key" TEXT NOT NULL,
+ "value" TEXT NOT NULL,
+ "printable_text" TEXT NOT NULL,
+ "location_oid" INTEGER NOT NULL
+);
+CREATE TABLE IF NOT EXISTS "number_of_lines" (
+ "element_oid" INTEGER NOT NULL,
+ "number_of_lines" INTEGER NOT NULL,
+ "number_of_valid_lines" INTEGER NOT NULL,
+ "number_of_comment_lines" INTEGER NOT NULL
+);
+CREATE TABLE IF NOT EXISTS "program" (
+ "element_oid" INTEGER NOT NULL,
+ "absolute_path_prefix" TEXT NOT NULL
+);
+CREATE TABLE IF NOT EXISTS "variable" (
+ "element_oid" INTEGER NOT NULL,
+ "parent_oid" INTEGER NOT NULL,
+ "start_index" INTEGER NOT NULL,
+ "name" TEXT NOT NULL,
+ "printable_text" TEXT NOT NULL
+);
+CREATE TABLE IF NOT EXISTS "container_parent" (
+ "child_oid" INTEGER NOT NULL,
+ "parent_oid" INTEGER NOT NULL
+);
+CREATE TABLE IF NOT EXISTS "file" (
+ "element_oid" INTEGER NOT NULL,
+ "relative_path" TEXT NOT NULL,
+ "extension" TEXT NOT NULL,
+ "name" TEXT NOT NULL
+);
+CREATE TABLE IF NOT EXISTS "empty_line" (
+ "element_oid" INTEGER NOT NULL,
+ "location_oid" INTEGER NOT NULL,
+ "file_oid" INTEGER NOT NULL,
+ PRIMARY KEY("element_oid")
+);
+COMMIT;
diff --git a/language/properties/extractor/src/main/resources/generatorConfig.xml b/language/properties/extractor/src/main/resources/generatorConfig.xml
new file mode 100644
index 00000000..fc0d2ef2
--- /dev/null
+++ b/language/properties/extractor/src/main/resources/generatorConfig.xml
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/language/properties/extractor/src/main/resources/mybatis-config.xml b/language/properties/extractor/src/main/resources/mybatis-config.xml
new file mode 100644
index 00000000..ef47a929
--- /dev/null
+++ b/language/properties/extractor/src/main/resources/mybatis-config.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/language/properties/lib/DOClass.gdl b/language/properties/lib/DOClass.gdl
new file mode 100644
index 00000000..6ee4c5c1
--- /dev/null
+++ b/language/properties/lib/DOClass.gdl
@@ -0,0 +1,458 @@
+/**
+ * @brief DO class: A comment.
+ */
+schema PropertiesCommentDO {
+ @primary element_oid: int,
+ text: string,
+ parent_oid: int,
+ location_oid: int
+}
+
+impl PropertiesCommentDO {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *PropertiesCommentDO {
+ for (tmp in db.comment) {
+ yield PropertiesCommentDO {
+ element_oid : tmp.element_oid,
+ text : tmp.text,
+ parent_oid : tmp.parent_oid,
+ location_oid : tmp.location_oid
+ }
+ }
+ }
+ /**
+ * @brief gets the text of this element.
+ * @return string
+ */
+ pub fn getText(self) -> string {
+ return self.text
+ }
+ /**
+ * @brief gets the parent oid of this element.
+ * @return int
+ */
+ pub fn getParentOid(self) -> int {
+ return self.parent_oid
+ }
+ /**
+ * @brief gets the location oid of this element.
+ * @return int
+ */
+ pub fn getLocationOid(self) -> int {
+ return self.location_oid
+ }
+}
+/**
+ * @brief DO class: A container parent.
+ */
+schema ContainerParentDO {
+ @primary child_oid: int,
+ parent_oid: int
+}
+impl ContainerParentDO {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *ContainerParentDO {
+ for (tmp in db.container_parent) {
+ yield ContainerParentDO {
+ child_oid : tmp.child_oid,
+ parent_oid : tmp.parent_oid
+ }
+ }
+ }
+ /**
+ * @brief gets the parent oid of this element.
+ * @return int
+ */
+ pub fn getParentOid(self) -> int {
+ return self.parent_oid
+ }
+}
+/**
+ *
+ * @brief DO class: An empty line.
+ */
+schema EmptyLineDO {
+ @primary oid: int,
+ location_oid: int,
+ file_oid: int
+}
+impl EmptyLineDO {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *EmptyLineDO {
+ for (tmp in db.empty_line) {
+ yield EmptyLineDO {
+ oid : tmp.oid,
+ location_oid : tmp.location_oid,
+ file_oid : tmp.file_oid
+ }
+ }
+ }
+ /**
+ * @brief gets the location oid of this element.
+ * @return int
+ */
+ pub fn getLocationOid(self) -> int {
+ return self.location_oid
+ }
+ /**
+ * @brief gets the file oid of this element.
+ * @return int
+ */
+ pub fn getFileOid(self) -> int {
+ return self.file_oid
+ }
+}
+/**
+ * @brief DO class: An entry.
+ */
+schema EntryDO {
+ @primary element_oid: int,
+ key: string,
+ value: string,
+ printable_text: string,
+ location_oid: int
+}
+impl EntryDO {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *EntryDO {
+ for (tmp in db.entry) {
+ yield EntryDO {
+ element_oid : tmp.element_oid,
+ key : tmp.key,
+ value : tmp.value,
+ printable_text : tmp.printable_text,
+ location_oid : tmp.location_oid
+ }
+ }
+ }
+ /**
+ * @brief gets the key of this element.
+ * @return string
+ */
+ pub fn getKey(self) -> string {
+ return self.key
+ }
+ /**
+ * @brief gets the value of this element.
+ * @return string
+ */
+ pub fn getValue(self) -> string {
+ return self.value
+ }
+ /**
+ * @brief gets the printable text of this element.
+ * @return string
+ */
+ pub fn getPrintableText(self) -> string {
+ return self.printable_text
+ }
+ /**
+ * @brief gets the location oid of this element.
+ * @return int
+ */
+ pub fn getLocationOid(self) -> int {
+ return self.location_oid
+ }
+}
+/**
+ * @brief DO class: A file.
+ */
+schema FileDO {
+ @primary element_oid: int,
+ relative_path: string,
+ extension: string,
+ name: string
+}
+impl FileDO {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *FileDO {
+ for (tmp in db.file) {
+ yield FileDO {
+ element_oid : tmp.element_oid,
+ relative_path : tmp.relative_path,
+ extension : tmp.extension,
+ name : tmp.name
+ }
+ }
+ }
+ /**
+ * @brief gets the relative path of this element.
+ * @return string
+ */
+ pub fn getRelativePath(self) -> string {
+ return self.relative_path
+ }
+ /**
+ * @brief gets the extension of this element.
+ * @return string
+ */
+ pub fn getExtension(self) -> string {
+ return self.extension
+ }
+ /**
+ * @brief gets the name of this element.
+ * @return string
+ */
+ pub fn getName(self) -> string {
+ return self.name
+ }
+ /**
+ * @brief gets the number of lines oid of this element.
+ * @return int
+ */
+ pub fn getNumberOfLinesOid(self) -> int {
+ return self.element_oid
+ }
+}
+/**
+ *
+ * @brief DO class: A folder.
+ */
+schema FolderDO {
+ @primary element_oid: int,
+ relative_path: string,
+ name: string,
+ parent_oid: int
+}
+impl FolderDO {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *FolderDO {
+ for (tmp in db.folder) {
+ yield FolderDO {
+ element_oid : tmp.element_oid,
+ relative_path : tmp.relative_path,
+ name : tmp.name,
+ parent_oid : tmp.parent_oid
+ }
+ }
+ }
+ /**
+ * @brief gets the relative path of this element.
+ * @return string
+ */
+ pub fn getRelativePath(self) -> string {
+ return self.relative_path
+ }
+ /**
+ * @brief gets the name of this element.
+ * @return string
+ */
+ pub fn getName(self) -> string {
+ return self.name
+ }
+ /**
+ * @brief gets the parent oid of this element.
+ * @return int
+ */
+ pub fn getParentOid(self) -> int {
+ return self.parent_oid
+ }
+}
+/**
+ *
+ * @brief DO class: A location.
+ */
+schema LocationDO {
+ @primary element_oid: int,
+ file_oid: int,
+ start_line_number: int,
+ start_column_number: int,
+ end_line_number: int,
+ end_column_number: int
+}
+impl LocationDO {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *LocationDO {
+ for (tmp in db.location) {
+ yield LocationDO {
+ element_oid : tmp.element_oid,
+ file_oid : tmp.file_oid,
+ start_line_number : tmp.start_line_number,
+ start_column_number : tmp.start_column_number,
+ end_line_number : tmp.end_line_number,
+ end_column_number : tmp.end_column_number
+ }
+ }
+ }
+ /**
+ * @brief gets the file oid of this element.
+ * @return int
+ */
+ pub fn getFileOid(self) -> int {
+ return self.file_oid
+ }
+ /**
+ * @brief gets the start line number of this element.
+ * @return int
+ */
+ pub fn getStartLineNumber(self) -> int {
+ return self.start_line_number
+ }
+ /**
+ * @brief gets the start column number of this element.
+ * @return int
+ */
+ pub fn getStartColumnNumber(self) -> int {
+ return self.start_column_number
+ }
+ /**
+ * @brief gets the end line number of this element.
+ * @return int
+ */
+ pub fn getEndLineNumber(self) -> int {
+ return self.end_line_number
+ }
+ /**
+ * @brief gets the end column number of this element.
+ * @return int
+ */
+ pub fn getEndColumnNumber(self) -> int {
+ return self.end_column_number
+ }
+}
+/**
+ *
+ * @brief DO class: A number of lines.
+ */
+schema NumberOfLinesDO {
+ @primary oid: int,
+ number_of_lines_edb: int,
+ number_of_valid_lines: int,
+ number_of_comment_lines: int
+}
+impl NumberOfLinesDO {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *NumberOfLinesDO {
+ for (tmp in db.number_of_lines) {
+ yield NumberOfLinesDO {
+ oid : tmp.oid,
+ number_of_lines_edb : tmp.number_of_lines_edb,
+ number_of_valid_lines : tmp.number_of_valid_lines,
+ number_of_comment_lines : tmp.number_of_comment_lines
+ }
+ }
+ }
+ /**
+ * @brief gets the number of lines of this element.
+ * @return int
+ */
+ pub fn getNumberOfLines(self) -> int {
+ return self.number_of_lines_edb
+ }
+ /**
+ * @brief gets the number of valid lines of this element.
+ * @return int
+ */
+ pub fn getNumberOfValidLines(self) -> int {
+ return self.number_of_valid_lines
+ }
+ /**
+ * @brief gets the number of comment lines of this element.
+ * @return int
+ */
+ pub fn getNumberOfCommentLines(self) -> int {
+ return self.number_of_comment_lines
+ }
+}
+/**
+ *
+ * @brief DO class: A program.
+ */
+schema ProgramDO {
+ @primary oid: int,
+ absolute_path_prefix: string
+}
+impl ProgramDO {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *ProgramDO {
+ for (tmp in db.program) {
+ yield ProgramDO {
+ oid : tmp.oid,
+ absolute_path_prefix : tmp.absolute_path_prefix
+ }
+ }
+ }
+ /**
+ * @brief gets the absolute path prefix of this element.
+ * @return string
+ */
+ pub fn getAbsolutePathPrefix(self) -> string {
+ return self.absolute_path_prefix
+ }
+}
+/**
+ *
+ * @brief DO class: A variable.
+ */
+schema VariableDO {
+ @primary element_oid: int,
+ parent_oid: int,
+ start_index: int,
+ name: string,
+ printable_text: string
+}
+impl VariableDO {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *VariableDO {
+ for (tmp in db.variable) {
+ yield VariableDO {
+ element_oid : tmp.element_oid,
+ parent_oid : tmp.parent_oid,
+ start_index : tmp.start_index,
+ name : tmp.name,
+ printable_text : tmp.printable_text
+ }
+ }
+ }
+ /**
+ * @brief gets the parent oid of this element.
+ * @return int
+ */
+ pub fn getParentOid(self) -> int {
+ return self.parent_oid
+ }
+ /**
+ * @brief gets the start index of this element.
+ * @return int
+ */
+ pub fn getStartIndex(self) -> int {
+ return self.start_index
+ }
+ /**
+ * @brief gets the name of this element.
+ * @return string
+ */
+ pub fn getName(self) -> string {
+ return self.name
+ }
+ /**
+ * @brief gets the printable text of this element.
+ * @return string
+ */
+ pub fn getPrintableText(self) -> string {
+ return self.printable_text
+ }
+}
+
+database PropertiesDB {
+ comment: *PropertiesCommentDO,
+ container_parent: *ContainerParentDO,
+ empty_line: *EmptyLineDO,
+ entry: *EntryDO,
+ file: *FileDO,
+ folder: *FolderDO,
+ location: *LocationDO,
+ number_of_lines: *NumberOfLinesDO,
+ program: *ProgramDO,
+ variable: *VariableDO,
+}
\ No newline at end of file
diff --git a/language/properties/lib/Entry.gdl b/language/properties/lib/Entry.gdl
new file mode 100644
index 00000000..5dc5c2ae
--- /dev/null
+++ b/language/properties/lib/Entry.gdl
@@ -0,0 +1,118 @@
+/**
+ * @date: 2022/11/11
+ * @brief: LOCATION provides classes and predicates for working with property files entry elements.
+ */
+
+/**
+ * @brief A properties comment.
+ */
+schema PropertiesComment extends PropertiesCommentDO {
+
+}
+impl PropertiesComment {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *PropertiesComment {
+ for (tmp in PropertiesCommentDO(db)) {
+ yield PropertiesComment {
+ element_oid : tmp.element_oid,
+ text : tmp.text,
+ parent_oid : tmp.parent_oid,
+ location_oid : tmp.location_oid
+ }
+ }
+ }
+ /**
+ * @brief gets the location for the element.
+ * @return Location
+ */
+ pub fn getLocation(self) -> Location {
+ for (loc in Location(__all_data__)) {
+ if (loc.element_oid = self.getLocationOid()) {
+ return loc
+ }
+ }
+ }
+}
+/**
+ * @brief A properties entry.
+ */
+schema Entry extends EntryDO {
+
+}
+impl Entry {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *Entry {
+ for (tmp in EntryDO(db)) {
+ yield Entry {
+ element_oid : tmp.element_oid,
+ key : tmp.key,
+ value : tmp.value,
+ printable_text : tmp.printable_text,
+ location_oid : tmp.location_oid
+ }
+ }
+ }
+ /**
+ * @brief gets the location for the element.
+ * @return Location
+ */
+ pub fn getLocation(self) -> Location {
+ for (loc in Location(__all_data__)) {
+ if (loc.element_oid = self.getLocationOid()) {
+ return loc
+ }
+ }
+ }
+}
+/**
+ * @brief A properties entry variable.
+ */
+schema Variable extends VariableDO {
+
+}
+impl Variable {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *Variable {
+ for (tmp in VariableDO(db)) {
+ yield Variable {
+ element_oid : tmp.element_oid,
+ parent_oid : tmp.parent_oid,
+ start_index : tmp.start_index,
+ name : tmp.name,
+ printable_text : tmp.printable_text
+ }
+ }
+ }
+ /**
+ * @brief gets the belonged entry element of the element
+ * @return Entry
+ */
+ pub fn getBelongedEntry(self) -> Entry {
+ for (entry in Entry(__all_data__)) {
+ if (entry.element_oid = self.getParentOid()) {
+ return entry
+ }
+ }
+ }
+ /**
+ * @brief gets the length of the variable's original text
+ * @return Entry
+ */
+ pub fn getLengthOfPrintableText(self) -> int {
+ return self.getPrintableText().len()
+ }
+ /**
+ * @brief gets the location for the element.
+ * @return Location
+ */
+ pub fn getLocation(self) -> Location {
+ for (loc in Location(__all_data__)) {
+ if (loc.element_oid = self.getParentOid()) {
+ return loc
+ }
+ }
+ }
+}
diff --git a/language/properties/lib/Location.gdl b/language/properties/lib/Location.gdl
new file mode 100644
index 00000000..41e89b56
--- /dev/null
+++ b/language/properties/lib/Location.gdl
@@ -0,0 +1,205 @@
+ /**
+ * @date: 2022/11/11
+ * @brief: LOCATION provides classes and predicates for working with property files location and container elements.
+ */
+/**
+ * @brief The location information of a locatable elements.
+ */
+schema Location extends LocationDO {
+
+}
+impl Location {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *Location {
+ for (tmp in LocationDO(db)) {
+ yield Location {
+ element_oid : tmp.element_oid,
+ file_oid : tmp.file_oid,
+ start_line_number : tmp.start_line_number,
+ start_column_number : tmp.start_column_number,
+ end_line_number : tmp.end_line_number,
+ end_column_number : tmp.end_column_number
+ }
+ }
+ }
+ /**
+ * @brief gets the file information for the location
+ * @return File
+ */
+ pub fn getFile(self) -> File {
+ for (f in File(__all_data__)) {
+ if (f.element_oid = self.getFileOid()) {
+ return f
+ }
+ }
+ }
+}
+/**
+ * @brief The number of lines for a java file.
+ */
+schema NumberOfLines extends NumberOfLinesDO {
+
+}
+impl NumberOfLines {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *NumberOfLines {
+ for (tmp in NumberOfLinesDO(db)) {
+ yield NumberOfLines {
+ oid : tmp.oid,
+ number_of_lines_edb : tmp.number_of_lines_edb,
+ number_of_valid_lines : tmp.number_of_valid_lines,
+ number_of_comment_lines : tmp.number_of_comment_lines
+ }
+ }
+ }
+}
+/**
+ * @brief The root of the extracted project.
+ */
+schema Program extends ProgramDO {
+
+}
+impl Program {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *Program {
+ for (tmp in ProgramDO(db)) {
+ yield Program {
+ oid : tmp.oid,
+ absolute_path_prefix : tmp.absolute_path_prefix
+ }
+ }
+ }
+}
+/**
+ * @brief A java file.
+ */
+schema File extends FileDO {
+
+}
+impl File {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *File {
+ for (tmp in FileDO(db)) {
+ yield File {
+ element_oid : tmp.element_oid,
+ relative_path : tmp.relative_path,
+ extension : tmp.extension,
+ name : tmp.name
+ }
+ }
+ }
+ /**
+ * @brief gets the folder which contains the file, if any.
+ * @return Folder
+ */
+ pub fn getBelongedFolder(self) -> Folder {
+ for (f in Folder(__all_data__),
+ container in ContainerParent(__all_data__)) {
+ if (self.key_eq(container)) {
+ if (f.element_oid = container.getParentOid()) {
+ return f
+ }
+ }
+ }
+ }
+ /**
+ * @brief gets the size information for the element.
+ * @return NumberOfLines
+ */
+ pub fn getSize(self) -> NumberOfLines {
+ for (n in NumberOfLines(__all_data__)) {
+ if (n.oid = self.getNumberOfLinesOid()) {
+ return n
+ }
+ }
+ }
+}
+/**
+ * @brief A folder.
+ */
+schema Folder extends FolderDO {
+
+}
+impl Folder {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *Folder {
+ for (tmp in FolderDO(db)) {
+ yield Folder {
+ element_oid : tmp.element_oid,
+ relative_path : tmp.relative_path,
+ name : tmp.name,
+ parent_oid : tmp.parent_oid
+ }
+ }
+ }
+ /**
+ * @brief gets all files in the folder.
+ * @return File
+ */
+ pub fn getAllContainingFiles(self) -> *File {
+ for (f in File(__all_data__),
+ container in ContainerParent(__all_data__)) {
+ if (f.key_eq(container)) {
+ if (self.element_oid = container.getParentOid()) {
+ yield f
+ }
+ }
+ }
+ }
+ /**
+ * @brief gets the folder which contains the element.
+ * @return Folder
+ */
+ pub fn getParent(self) -> Folder {
+ for (f in Folder(__all_data__)) {
+ if (f.element_oid = self.getParentOid()) {
+ return f
+ }
+ }
+ }
+}
+ // /**
+ // * @brief gets an ancestor of the element.
+ // * @return ElementParent
+ // */
+ // ElementParent getAnAncestor(){
+ // return ancestor : exists(ElementParent ancestor, ElementParent temp) { this = temp and ancestor = temp.getAnAncestor() }
+ // }
+ /**
+ // * @brief gets an ancestor of the element.
+ // * @return ElementParent
+ // */
+ /**
+ * @brief Describe a file belonged to a certain folder.
+ */
+schema ContainerParent extends ContainerParentDO {
+
+}
+impl ContainerParent {
+ @data_constraint
+ @inline
+ pub fn __all__(db: PropertiesDB) -> *ContainerParent {
+ for (tmp in ContainerParentDO(db)) {
+ yield ContainerParent {
+ child_oid : tmp.child_oid,
+ parent_oid : tmp.parent_oid
+ }
+ }
+ }
+ /**
+ * @brief gets the folder which contains the file, if any.
+ * @return Folder
+ */
+ pub fn getBelongedFolder(self) -> Folder {
+ for (f in Folder(__all_data__)) {
+ if (f.element_oid = self.getParentOid()) {
+ return f
+ }
+ }
+ }
+}