diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..7093a8492 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: + - package-ecosystem: "gradle" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 1 + target-branch: "develop" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 913ab4173..af849b80f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,7 @@ on: - "main" - "develop" - "feature/corese-next" + workflow_dispatch: permissions: contents: read @@ -24,11 +25,14 @@ jobs: env: PACKAGE_TOKEN: ${{ secrets.JLS_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} steps: - - name: Checkout of head + - name: Checkout sources id: ci-sources-checkout uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Set up JDK 21 id: ci-java-setup @@ -37,6 +41,16 @@ jobs: java-version: 21 distribution: 'temurin' + - name: Cache Gradle + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/gradle.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + - name: Gradle build id: ci-gradle-build run: ./gradlew clean assemble @@ -44,9 +58,15 @@ jobs: - name: Gradle tests run: ./gradlew test - - name: Run Coverage + - name: Generate JaCoCo Coverage Report run: ./gradlew jacocoTestReport + - name: SonarQube analysis + run: | + ./gradlew sonar -Dsonar.projectKey=crs-core-new \ + -Dsonar.host.url=https://sonarqube.inria.fr/sonarqube \ + -Dsonar.login=${{ secrets.SONAR_TOKEN }} + - name: Add coverage to PR id: jacoco uses: madrapps/jacoco-report@v1.7.0 @@ -58,7 +78,7 @@ jobs: min-coverage-changed-files: 60 update-comment: true - - name: Get the Coverage info + - name: Display Coverage info run: | echo "Total coverage ${{ steps.jacoco.outputs.coverage-overall }}" echo "Changed Files coverage ${{ steps.jacoco.outputs.coverage-changed-files }}" @@ -70,8 +90,8 @@ jobs: files: | build/test-results/**/*.xml - - name: Get test artifacts - if: ${{ failure() }} + - name: Archive test artifacts + if: failure() uses: actions/upload-artifact@v4 with: name: Package diff --git a/.github/workflows/publish-prerelease.yml b/.github/workflows/publish-prerelease.yml index b23520a34..16861ada5 100644 --- a/.github/workflows/publish-prerelease.yml +++ b/.github/workflows/publish-prerelease.yml @@ -22,11 +22,11 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Set up JDK 11 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '21' cache: 'gradle' - name: Cache Gradle diff --git a/.github/workflows/release-github.yml b/.github/workflows/release-github.yml index 65b807c81..d5d6a5b14 100644 --- a/.github/workflows/release-github.yml +++ b/.github/workflows/release-github.yml @@ -23,11 +23,11 @@ jobs: with: ref: ${{ github.event.inputs.ref || github.ref_name }} - - name: Set up JDK 11 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '21' cache: 'gradle' - name: Cache Gradle diff --git a/.github/workflows/release-maven-central.yml b/.github/workflows/release-maven-central.yml index 6ae32e4e1..849cc4f8a 100644 --- a/.github/workflows/release-maven-central.yml +++ b/.github/workflows/release-maven-central.yml @@ -21,11 +21,11 @@ jobs: with: ref: ${{ github.event.inputs.ref || github.ref }} - - name: Set up JDK 11 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '11' + java-version: '21' cache: 'gradle' - name: Cache Gradle diff --git a/.gitignore b/.gitignore index e1aae5568..c1877fba4 100644 --- a/.gitignore +++ b/.gitignore @@ -66,6 +66,7 @@ target/ /dist/ /nbdist/ /.nb-gradle/ +.continue/ # Logs and coverage reports *.log @@ -73,9 +74,18 @@ target/ *.coverage *.reports +# Generated files +gradle/gradle-daemon-jvm.properties + ## ################################################################# ## Miscellaneous ignores ## ################################################################# # Other build directories and generated files /bin/ +/out/ + +# Fichiers de logs +logs/ +*.log +.sonarlint/ diff --git a/build.gradle.kts b/build.gradle.kts index 7c6be41b5..93fdfb7c1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,6 @@ +import java.time.LocalDate +import java.time.format.DateTimeFormatter + plugins { // Core Gradle plugins `java-library` // For creating reusable Java libraries @@ -9,9 +12,59 @@ plugins { // Tooling plugins `jacoco` // For code coverage reports - id("com.gradleup.shadow") version "8.3.7" // Bundles dependencies into a single JAR + id("com.gradleup.shadow") version "8.3.7" + id("org.sonarqube") version "6.1.0.5360" // SonarQube integration + id("com.intershop.gradle.javacc") version "5.0.1" // JavaCC plugin for parsing JavaCC files + id("antlr") // Antlr plugin for generating parsers from grammar files +} + +// SonarQube configuration + +val currentDate: String = LocalDate.now().format(DateTimeFormatter.ISO_DATE) + +sonar { + properties { + property("sonar.projectKey", "crs-core-new") + property("sonar.host.url", "https://sonarqube.inria.fr/sonarqube") + property("sonar.login", System.getenv("SONAR_TOKEN")) + property("sonar.coverage.jacoco.xmlReportPaths", "build/reports/jacoco/test/jacocoTestReport.xml") + property("sonar.sourceEncoding", "UTF-8") + property("sonar.projectDate", currentDate) + } +} + +// === Generated sources directories === +val javaccGeneratedDir = layout.buildDirectory.dir("generated-src/javacc").get().asFile +val antlrGeneratedDir = layout.buildDirectory.dir("generated-src/antlr").get().asFile +val antlrPackageDir = layout.buildDirectory.dir("generated-src/antlr/fr/inria/corese/core/next/impl/parser/antlr").get().asFile + +// JavaCC configuration +javacc { + configs { + register("sparqlCorese") { + inputFile = file("src/main/java/fr/inria/corese/core/sparql/triple/javacc1/sparql_corese.jj") + packageName = "fr.inria.corese.core.sparql.triple.javacc1" + outputDir = javaccGeneratedDir + } + } } +// Configure source sets to include generated sources +sourceSets { + main { + java { + srcDir(javaccGeneratedDir) + srcDir(antlrGeneratedDir) + } + } +} + +// Ensure JavaCC generation happens before compilation +tasks.named("compileJava") { + dependsOn("javaccSparqlCorese") +} + + ///////////////////////// // Project metadata // ///////////////////////// @@ -25,7 +78,7 @@ object Meta { // Project description const val desc = "Corese is a Semantic Web Factory (triple store and SPARQL endpoint) implementing RDF, RDFS, SPARQL 1.1 Query and Update, Shacl. STTL. LDScript." const val githubRepo = "corese-stack/corese-core" - + // License information const val license = "CeCILL-C License" const val licenseUrl = "https://opensource.org/licenses/CeCILL-C" @@ -37,8 +90,11 @@ object Meta { // Java compilation settings java { - // Note: withJavadocJar() and withSourcesJar() are handled by com.vanniktech.maven.publish plugin - sourceCompatibility = JavaVersion.VERSION_11 // Configure minimum Java version + withJavadocJar() // Include Javadoc JAR in publications + withSourcesJar() // Include sources JAR in publications + toolchain { + languageVersion.set(JavaLanguageVersion.of(21)) + } } ///////////////////////// @@ -51,7 +107,6 @@ repositories { mavenCentral() // Then, check Maven Central } -// Define dependencies dependencies { // === Logging === // As a library, corese-core should only depend on the SLF4J API. @@ -60,23 +115,41 @@ dependencies { api("org.slf4j:slf4j-api:2.0.17") // Logging API only (SLF4J) // === Core dependencies === - api("fr.com.hp.hpl.jena.rdf.arp:arp:2.2.b") // RDF/XML parser (Jena ARP) + api("fr.com.hp.hpl.jena.rdf.arp:arp:2.2.b") // RDF/XML parser (Jena ARP) implementation("fr.inria.corese.org.semarglproject:semargl-rdfa:0.7.2") // RDFa parser (Semargl) implementation("com.github.jsonld-java:jsonld-java:0.13.4") // JSON-LD processing + // === Antlr dependencies === + antlr("org.antlr:antlr4:4.13.2") // Antlr for parsing (ANTLR 4) + implementation("org.antlr:antlr4-runtime:4.13.2") // Antlr runtime for parsing + // === HTTP and XML === implementation("org.glassfish.jersey.core:jersey-client:3.1.10") // HTTP client (Jersey) implementation("org.glassfish.jersey.inject:jersey-hk2:3.1.10") // Dependency injection for Jersey implementation("com.sun.activation:jakarta.activation:2.0.1") // MIME type handling (Jakarta Activation) + // === JSONLD Parsing === + implementation("com.apicatalog:titanium-json-ld:1.6.0") // JSON-LD processing library + implementation("com.apicatalog:titanium-rdf-api:1.0.0") // Titanium RDF API for JSON-LD processing + implementation("org.eclipse.parsson:parsson:1.1.7") // JSON parser for JSON-LD + implementation("jakarta.json:jakarta.json-api:2.1.3") // Jakarta JSON API for JSON processing + + + // === XML parsing === + implementation("com.typesafe.akka:akka-stream_2.13:2.6.20") // Akka Streams for reactive streams processing + implementation("com.lightbend.akka:akka-stream-alpakka-xml_2.13:3.0.4") // Alpakka XML for XML processing with Akka Streams + // === Utilities === implementation("org.apache.commons:commons-text:1.13.1") // Text manipulation utilities (Commons Text) implementation("org.json:json:20250517") // JSON processing implementation("com.typesafe:config:1.4.3") // Configuration library (Typesafe Config) // === Test dependencies === - testImplementation("junit:junit:4.13.2") // Unit testing framework - testRuntimeOnly("ch.qos.logback:logback-classic:1.5.20") // Logging implementation for tests and development + testImplementation(platform("org.junit:junit-bom:5.13.2")) // JUnit BOM for consistent test versions + testImplementation("org.junit.jupiter:junit-jupiter:5.13.2") // JUnit Jupiter API and engine + testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.13.2") // JUnit platform launcher (runtime) + testImplementation("org.mockito:mockito-core:5.18.0") // Mockito core for mocking in tests + testImplementation("org.mockito:mockito-junit-jupiter:5.18.0") // Mockito integration with JUnit Jupiter } ///////////////////////// @@ -146,7 +219,7 @@ mavenPublishing { ///////////////////////// // Set UTF-8 encoding for Java compilation tasks -tasks.withType() { +tasks.withType { options.encoding = "UTF-8" options.compilerArgs.add("-Xlint:none") } @@ -167,7 +240,7 @@ tasks.withType().configureEach { tasks { shadowJar { this.archiveClassifier = "jar-with-dependencies" - } + } } // Configure the build task to depend on the shadow JAR task. @@ -190,10 +263,11 @@ tasks.jacocoTestReport { // Set the test task to be followed by Jacoco report generation. // This ensures that test coverage reports are always generated after tests. tasks.test { + useJUnitPlatform() testLogging { - events("passed", "skipped", "failed") // Affiche les résultats des tests - showStandardStreams = true // Affiche les sorties console des tests (y compris les logs) + events("passed", "skipped", "failed") } + systemProperty("java.util.logging.config.file", "src/test/resources/logging.properties") finalizedBy(tasks.jacocoTestReport) } @@ -208,3 +282,53 @@ tasks.withType().configureEach { tasks.withType().configureEach { dependsOn(tasks.withType()) } + +// === Antlr generated sources configuration === + +// Configure the Antlr task to generate parser code with specific arguments +tasks.named("generateGrammarSource") { + arguments.addAll(listOf("-visitor", "-long-messages", "-package", "fr.inria.corese.core.next.impl.parser.antlr")) + outputDirectory = antlrPackageDir + inputs.files(fileTree("src/main/antlr")) + outputs.dir(antlrPackageDir) +} + +// Ensure Java compilation depends on both JavaCC and Antlr code generation +tasks.named("compileJava") { + dependsOn("generateGrammarSource", "javaccSparqlCorese") +} + +// Ensure sources JAR includes generated sources and depends on code generation +tasks.named("sourcesJar") { + dependsOn("generateGrammarSource", "javaccSparqlCorese") + from(javaccGeneratedDir) + from(antlrGeneratedDir) + includeEmptyDirs = false + duplicatesStrategy = DuplicatesStrategy.EXCLUDE +} + +// Clean up generated sources on clean +tasks.clean { + doLast { + delete(javaccGeneratedDir) + delete(antlrGeneratedDir) + } +} + +// Ensure generated directories exist before generation +tasks.register("createGeneratedDirs") { + doLast { + javaccGeneratedDir.mkdirs() + antlrGeneratedDir.mkdirs() + antlrPackageDir.mkdirs() + } +} + +// Make generation tasks depend on directory creation +tasks.named("generateGrammarSource") { + dependsOn("createGeneratedDirs") +} + +tasks.named("javaccSparqlCorese") { + dependsOn("createGeneratedDirs") +} \ No newline at end of file diff --git a/corese-core.graphml b/corese-core.graphml new file mode 100644 index 000000000..80c6906f2 --- /dev/null +++ b/corese-core.graphml @@ -0,0 +1,309 @@ + + + + + + + + + + + + + + + + + + + + + + + + approximate + + + + + + + + + + + + compiler + + + + + + + + + + + + edge + + + + + + + + + + + + elasticsearch + + + + + + + + + + + + extension + + + + + + + + + + + + index + + + + + + + + + + + + kgram + + + + + + + + + + + + load + + + + + + + + + + + + logic + + + + + + + + + + + + print + + + + + + + + + + + + api + + + + + + + + + + + + producer + + + + + + + + + + + + query + + + + + + + + + + + + rule + + + + + + + + + + + + shacl + + + + + + + + + + + + shex.shacl + + + + + + + + + + + + sparql + + + + + + + + + + + + stats + + + + + + + + + + + + storage + + + + + + + + + + + + transform + + + + + + + + + + + + util + + + + + + + + + + + + visitor + + + + + + + + + + + + workflow + + + + + + + + + + + + Graph + + + + + + + + + diff --git a/docs/source/user_guide.md b/docs/source/user_guide.md index 1785df6d5..a87f4ab9e 100644 --- a/docs/source/user_guide.md +++ b/docs/source/user_guide.md @@ -173,8 +173,14 @@ import fr.inria.corese.core.kgram.core.Mappings; import fr.inria.corese.core.print.ResultFormat; import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.exceptions.EngineException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class Example { + + private static final Logger logger = LoggerFactory.getLogger(Example.class); + public static void main(String[] args) throws EngineException { // Create a new empty Graph @@ -192,7 +198,7 @@ public class Example { Mappings map = exec.query("select * where { ?s ?p ?o }"); // Print results in Markdown format - System.out.println(ResultFormat.create(map, ResultFormat.format.CSV_FORMAT).toString()); + logger.info("Result : {}", ResultFormat.create(map, ResultFormat.format.CSV_FORMAT).toString()); } } ``` @@ -216,8 +222,13 @@ import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.core.Mappings; import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.exceptions.EngineException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class Example { + private static final Logger logger = LoggerFactory.getLogger(Example.class); + public static void main(String[] args) throws EngineException { // Create a new empty Graph @@ -236,7 +247,7 @@ public class Example { // Print boolean result // If the mapping is empty, the result is false; otherwise, it is true. - System.out.println(!map.isEmpty()); + logger.info("Result : {}", !map.isEmpty()); } } ``` @@ -252,8 +263,14 @@ import fr.inria.corese.core.load.Load; import fr.inria.corese.core.print.ResultFormat; import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.exceptions.EngineException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class Example { + + private static final Logger logger = LoggerFactory.getLogger(Example.class); + public static void main(String[] args) throws EngineException { // Create a new empty Graph @@ -281,7 +298,7 @@ public class Example { Graph resultGraph = (Graph) map.getGraph(); // Print results in TriG format - System.out.println(ResultFormat.create(resultGraph, ResultFormat.format.TRIG_FORMAT).toString()); + logger.info("Result : {}", ResultFormat.create(resultGraph, ResultFormat.format.TRIG_FORMAT).toString()); } } ``` @@ -310,8 +327,14 @@ import fr.inria.corese.core.load.Load; import fr.inria.corese.core.print.ResultFormat; import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.exceptions.EngineException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class Example { + + private static final Logger logger = LoggerFactory.getLogger(Example.class); + public static void main(String[] args) throws EngineException { // Create a new empty Graph @@ -336,7 +359,7 @@ public class Example { """); // Print updated graph in Turtle format - System.out.println(ResultFormat.create(graph, ResultFormat.format.TURTLE_FORMAT).toString()); + logger.info("Result : {}", ResultFormat.create(graph, ResultFormat.format.TURTLE_FORMAT).toString()); } } ``` @@ -365,8 +388,14 @@ import fr.inria.corese.core.print.ResultFormat; import fr.inria.corese.core.shacl.Shacl; import fr.inria.corese.core.sparql.api.ResultFormatDef; import fr.inria.corese.core.sparql.exceptions.EngineException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class Example { + + private static final Logger logger = LoggerFactory.getLogger(Example.class); + public static void main(String[] args) throws LoadException, EngineException { // Load data graph Graph dataGraph = Graph.create(); @@ -384,7 +413,7 @@ public class Example { // Print results ResultFormat exporter = ResultFormat.create(result, ResultFormatDef.format.TURTLE_FORMAT); - System.out.println(exporter.toString()); + logger.info("Result : {}", exporter.toString()); } } ``` @@ -708,8 +737,14 @@ import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.datatype.DatatypeMap; import fr.inria.corese.core.sparql.exceptions.EngineException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class Example { + + private static final Logger logger = LoggerFactory.getLogger(Example.class); + public static void main(String[] args) throws EngineException, IOException { // Open LDScript file Path path = Path.of("input LDScript file path.rq"); @@ -724,7 +759,7 @@ public class Example { IDatatype dt = exec.funcall(name, DatatypeMap.newInstance(12)); // Print result - System.out.println(dt); + logger.info("Result : {}", dt); } } ``` @@ -808,8 +843,14 @@ import java.nio.file.Path; import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.exceptions.EngineException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class Example { + + private static final Logger logger = LoggerFactory.getLogger(Example.class); + public static void main(String[] args) throws EngineException, IOException { // Open LDScript file Path path = Path.of("input LDScript file path.rq"); @@ -824,7 +865,7 @@ public class Example { IDatatype dt = exec.funcall(name); // Print result - System.out.println(dt); + logger.info("Result : {}", dt); } } ``` diff --git a/src/main/antlr/NQuads.g4 b/src/main/antlr/NQuads.g4 new file mode 100644 index 000000000..b49ab92b1 --- /dev/null +++ b/src/main/antlr/NQuads.g4 @@ -0,0 +1,114 @@ +grammar NQuads; + +nquadsDoc + : statement? (EOL* statement)* EOL* EOF + ; + +statement + : subject predicate object graphLabel? '.' + ; + +subject + : IRIREF + | BLANK_NODE_LABEL + ; + +predicate + : IRIREF + ; + +object + : IRIREF + | BLANK_NODE_LABEL + | literal + ; + +graphLabel + : IRIREF + | BLANK_NODE_LABEL + ; + +literal + : STRING_LITERAL_QUOTE ('^^' IRIREF | LANGTAG)? + ; + +LANGTAG + : '@' [a-zA-Z]+ ('-' [a-zA-Z0-9]+)* + ; + +EOL + : [\u000D\u000A]+ + ; + +IRIREF + : '<' ( IRI_CHAR | UCHAR )* '>' + ; + +fragment IRI_CHAR + : ~ ( '\u0000'..'\u0020' | '<' | '>' | '"' | '{' | '}' | '|' | '^' | '`' | '\\' ) + ; + +STRING_LITERAL_QUOTE + : '"' ( ~( [\u0022] | [\u005C] | [\u000A] | [\u000D] ) | ECHAR | UCHAR )* '"' + ; + +BLANK_NODE_LABEL +// '_:' (PN_CHARS_U | [0-9]) ((PN_CHARS | '.')* PN_CHARS)? + : '_:' (PN_CHARS_U | [0-9]) ((PN_CHARS | '.')* PN_CHARS)? + ; + +UCHAR + : '\\u' HEX HEX HEX HEX + | '\\U' HEX HEX HEX HEX HEX HEX HEX HEX + ; + +HEX + : [0-9] + | [A-F] + | [a-f] + ; + +ECHAR + : '\\' [tbnrf"'\\] + ; + +PN_CHARS_BASE + : 'A' .. 'Z' + | 'a' .. 'z' + | '\u00C0' .. '\u00D6' + | '\u00D8' .. '\u00F6' + | '\u00F8' .. '\u02FF' + | '\u0370' .. '\u037D' + | '\u037F' .. '\u1FFF' + | '\u200C' .. '\u200D' + | '\u2070' .. '\u218F' + | '\u2C00' .. '\u2FEF' + | '\u3001' .. '\uD7FF' + | '\uF900' .. '\uFDCF' + | '\uFDF0' .. '\uFFFD' +// | '\u10000' .. '\uEFFFF' + ; + +PN_CHARS_U +// PN_CHARS_BASE | '_' | ':' + : PN_CHARS_BASE + | '_' + | ':' + ; + +PN_CHARS + : PN_CHARS_U + | '-' + | [0-9] + | [\u00B7] + | [\u0300-\u036F] + | [\u203F-\u2040] + ; + +LC + : '#' ~[\r\n]* -> channel(HIDDEN) + ; + +WS + : ([\t\r\n\u000C] | ' ')+ -> skip + ; \ No newline at end of file diff --git a/src/main/antlr/NTriples.g4 b/src/main/antlr/NTriples.g4 new file mode 100644 index 000000000..db639ccb2 --- /dev/null +++ b/src/main/antlr/NTriples.g4 @@ -0,0 +1,118 @@ + +// $antlr-format alignTrailingComments true, columnLimit 150, minEmptyLines 1, maxEmptyLinesToKeep 1, reflowComments false, useTab false +// $antlr-format allowShortRulesOnASingleLine false, allowShortBlocksOnASingleLine true, alignSemicolons hanging, alignColons hanging + + +grammar NTriples; + + +ntriplesDoc +// triple? (EOL triple)* EOL? + : triple? (EOL* triple)* EOL* + ; + +directive + : {notifyErrorListeners("Directives are not allowed in N-Triples");} + ('@prefix' | '@base') + ; + +triple + : subject predicate object '.' + ; + +subject + : IRIREF + | BLANK_NODE_LABEL + ; + +predicate + : IRIREF + ; + +object + : IRIREF + | BLANK_NODE_LABEL + | literal + ; + +literal + : STRING_LITERAL_QUOTE ('^^' IRIREF | LANGTAG)? + ; + +LANGTAG + : '@' [a-zA-Z]+ ('-' [a-zA-Z0-9]+)* + ; + +EOL + : [\u000D\u000A]+ + ; + +IRIREF +// '<' ([^#x00-#x20<>"{}|^`\] | UCHAR)* '>' + : '<' [a-zA-Z0-9-]+':' ((~( [\u0000-\u0020] | '<' | '>' | '"' | '{'| '}' | '|'| '^'| '`' | '\\' )) | UCHAR)* '>' + ; + +STRING_LITERAL_QUOTE + : '"' ( ~( [\u0022] | [\u005C] | [\u000A] | [\u000D] ) | ECHAR | UCHAR )* '"' + ; + +BLANK_NODE_LABEL +// '_:' (PN_CHARS_U | [0-9]) ((PN_CHARS | '.')* PN_CHARS)? + : '_:' (PN_CHARS_U | [0-9]) ((PN_CHARS | '.')* PN_CHARS)? + ; + +UCHAR + : '\\u' HEX HEX HEX HEX + | '\\U' HEX HEX HEX HEX HEX HEX HEX HEX + ; + +HEX + : [0-9] + | [A-F] + | [a-f] + ; + +ECHAR + : '\\' [tbnrf"'\\] + ; + +PN_CHARS_BASE + : 'A' .. 'Z' + | 'a' .. 'z' + | '\u00C0' .. '\u00D6' + | '\u00D8' .. '\u00F6' + | '\u00F8' .. '\u02FF' + | '\u0370' .. '\u037D' + | '\u037F' .. '\u1FFF' + | '\u200C' .. '\u200D' + | '\u2070' .. '\u218F' + | '\u2C00' .. '\u2FEF' + | '\u3001' .. '\uD7FF' + | '\uF900' .. '\uFDCF' + | '\uFDF0' .. '\uFFFD' +// | '\u10000' .. '\uEFFFF' + ; + +PN_CHARS_U +// PN_CHARS_BASE | '_' | ':' + : PN_CHARS_BASE + | '_' + | ':' + ; + +PN_CHARS + : PN_CHARS_U + | '-' + | [0-9] + | [\u00B7] + | [\u0300-\u036F] + | [\u203F-\u2040] + ; + +LC + : '#' ~[\r\n]* -> channel(HIDDEN) + ; + +WS + : ([\t\r\n\u000C] | ' ')+ -> skip + ; \ No newline at end of file diff --git a/src/main/antlr/TriG.g4 b/src/main/antlr/TriG.g4 new file mode 100644 index 000000000..91c95b222 --- /dev/null +++ b/src/main/antlr/TriG.g4 @@ -0,0 +1,335 @@ +// $antlr-format alignTrailingComments true, columnLimit 150, minEmptyLines 1, maxEmptyLinesToKeep 1, reflowComments false, useTab false +// $antlr-format allowShortRulesOnASingleLine false, allowShortBlocksOnASingleLine true, alignSemicolons hanging, alignColons hanging + +grammar TriG; + +trigDoc + : ( directive | block )* EOF + ; + +block + : triplesOrGraph + | wrappedGraph + | triples2 + | Graph_w labelOrSubject wrappedGraph + ; + +triplesOrGraph + : labelOrSubject (wrappedGraph | predicateObjectList '.') + ; + +triples2 + : blankNodePropertyList predicateObjectList? '.' + | collection predicateObjectList? '.' + ; + +wrappedGraph + : '{' triplesBlock? '}' + ; + +triplesBlock + : triples ('.'? triplesBlock?)? + ; + +labelOrSubject + : iri + | blankNode + ; + +directive + : prefixID + | base + | sparqlPrefix + | sparqlBase + ; + +prefixID + : '@prefix' PNAME_NS IRIREF '.' + ; + +base + : '@base' IRIREF '.' + ; + +sparqlPrefix + : Prefix_w PNAME_NS IRIREF + ; + +sparqlBase + : Base_w IRIREF + ; + +triples + : subject predicateObjectList + | blankNodePropertyList predicateObjectList? + ; + +predicateObjectList + : verb objectList (';' (verb objectList)?)* + ; + +objectList + : object (',' object)* + ; + +verb + : predicate + | 'a' + ; + +subject + : iri + | blank + ; + +predicate + : iri + ; + +object + : iri + | blank + | blankNodePropertyList + | literal + ; + +literal + : rDFLiteral + | numericLiteral + | BooleanLiteral + ; + +blank + : blankNode + | collection + ; + +blankNodePropertyList + : '[' predicateObjectList ']' + ; + +collection + : '(' object* ')' + ; + +numericLiteral + : INTEGER + | DECIMAL + | DOUBLE + ; + +rDFLiteral + : string LANGTAG + | string ('^^' iri)? + ; + +string + : STRING_LITERAL_QUOTE + | STRING_LITERAL_SINGLE_QUOTE + | STRING_LITERAL_LONG_SINGLE_QUOTE + | STRING_LITERAL_LONG_QUOTE + ; + +iri + : prefixedName + | IRIREF + ; + +prefixedName + : PNAME_LN + | PNAME_NS + ; + +blankNode + : BLANK_NODE_LABEL + | ANON + ; + +WS + : (('\u0020' | '\u0009' | '\u000A' | '\u000D' ) )+ -> skip + ; + + +Graph_w options { caseInsensitive=true; } + : 'GRAPH' + ; + +Base_w options { caseInsensitive=true; } + : 'BASE' + ; + +Prefix_w options { caseInsensitive=true; } + : 'PREFIX' + ; + +BooleanLiteral + : 'true' + | 'false' + ; + +IRIREF + : '<' (PN_CHARS | '.' | ':' | '#' | '@' | '%' | '&' | '$' | '!' | '\'' | '*' | '+' | '/' | '(' | ')' | '-' | ',' | '?' | '~' | ';' | '=' | UCHAR)* '>' + ; + +BLANK_NODE_LABEL + : '_:' (PN_CHARS_U | [0-9] | PLX) ((PN_CHARS | '.' | PLX)* (PN_CHARS | PLX))? + ; + +PNAME_NS + : PN_PREFIX ':' + | ':' + ; + +PNAME_LN + : PNAME_NS PN_LOCAL + ; + +LANGTAG + : '@' ('a'.. 'z' | 'A' .. 'Z')+ ('-' ('a'.. 'z' | 'A' .. 'Z' | '0' .. '9')* )* + ; + +INTEGER + : ('+' | '-' )? ('0' .. '9')+ + ; + +DECIMAL + : ('+' | '-' )? ('0' .. '9')* '.' ('0' .. '9')+ + ; + +DOUBLE + : ('+' | '-')? ( + ( ('0'..'9')+ '.' ('0'..'9')* EXPONENT ) + | ( '.' ('0'..'9')+ EXPONENT ) + | ( ('0'..'9')+ EXPONENT ) + ) + ; + +EXPONENT + : ('e' | 'E') ('+' | '-' )? ('0' .. '9')+ + ; + +STRING_LITERAL_QUOTE + : '"' ((~[\u0022\u005C\u000A\u000D]) | ECHAR | UCHAR)* '"' + ; + +STRING_LITERAL_SINGLE_QUOTE + : '\'' ((~[\u0027\u005C\u000A\u000D]) | ECHAR | UCHAR)* '\'' + ; + +STRING_LITERAL_LONG_SINGLE_QUOTE + : '\'\'\'' (LONG_STRING_CHAR_SINGLE | ECHAR | UCHAR)* '\'\'\'' + ; + +STRING_LITERAL_LONG_QUOTE + : '"""' (LONG_STRING_CHAR_DOUBLE | ECHAR | UCHAR)* '"""' + ; + +fragment LONG_STRING_CHAR_DOUBLE + : ~[\\"] + | '"' ~["] + | '"' '"' ~["] + ; + +fragment LONG_STRING_CHAR_SINGLE + : ~[\\'] + | '\'' ~['] + | '\'' '\'' ~['] + ; + +UCHAR + : '\\u' HEX HEX HEX HEX + | '\\U' HEX HEX HEX HEX HEX HEX HEX HEX + ; + +ECHAR options { caseInsensitive=true; } + : '\\' [tbnrf"'\\] + ; + +WHITESPACE + : [\u0020\u0009\u000A\u000D] + ; + +ANON + : '[' [\u0009\u000A\u000D\u0020]* ']' + ; + +fragment PN_CHARS_BASE + : 'A' .. 'Z' + | 'a' .. 'z' + | '\u00C0' .. '\u00D6' + | '\u00D8' .. '\u00F6' + | '\u00F8' .. '\u02FF' + | '\u0370' .. '\u037D' + | '\u037F' .. '\u1FFF' + | '\u200C' .. '\u200D' + | '\u2070' .. '\u218F' + | '\u2C00' .. '\u2FEF' + | '\u3001' .. '\uD7FF' + | '\uF900' .. '\uFDCF' + | '\uFDF0' .. '\uFFFD' + | '\u{10000}'..'\u{EFFFF}' + ; + +fragment PN_CHARS_U + : PN_CHARS_BASE + | '_' + ; + +fragment PN_CHARS + : PN_CHARS_U + | '-' + | [0-9] + | [\u00B7] + | [\u0300-\u036F] + | [\u203F-\u2040] + ; + +fragment PN_PREFIX + : PN_CHARS_BASE ((PN_CHARS | '.')* PN_CHARS)? + ; + +fragment PN_LOCAL + : (PN_CHARS_U | [0-9] | PLX) ((PN_CHARS | '.' | ':' | PLX)* (PN_CHARS | ':' | PLX))? + ; + +fragment PLX + : PERCENT + | PN_LOCAL_ESC + ; + +fragment PERCENT + : '%' HEX HEX + ; + +fragment HEX + : [0-9a-fA-F] + ; + +fragment PN_LOCAL_ESC + : '\\' ( + '_' + | '~' + | '.' + | '-' + | '!' + | '$' + | '&' + | '\'' + | '(' + | ')' + | '*' + | '+' + | ',' + | ';' + | '=' + | '/' + | '?' + | '#' + | '@' + | '%' + ) + ; + +LC + : '#' ~[\r\n]+ -> channel(HIDDEN) + ; \ No newline at end of file diff --git a/src/main/antlr/Turtle.g4 b/src/main/antlr/Turtle.g4 new file mode 100644 index 000000000..100d602d6 --- /dev/null +++ b/src/main/antlr/Turtle.g4 @@ -0,0 +1,309 @@ +/* + [The "BSD licence"] + Copyright (c) 2014, Alejandro Medrano (@ Universidad Politecnica de Madrid, http://www.upm.es/) + All rights reserved. +*/ +/* Derived from http://www.w3.org/TR/turtle/#sec-grammar-grammar */ + +grammar Turtle; + +turtleDoc + : statement* EOF + ; + +statement + : directive + | triples '.' + ; + +directive + : prefixID + | base + | sparqlPrefix + | sparqlBase + ; + +triples + : subject predicateObjectList + | blankNodePropertyList predicateObjectList? + ; + +predicateObjectList + : verb objectList (';' (verb objectList)?)* + ; + +objectList + : object_ (',' object_)* + ; + +verb + : predicate + | 'a' + ; + +subject + : iri + | BlankNode + | collection + ; + +predicate + : iri + ; + + +object_ + : iri + | BlankNode + | collection + | blankNodePropertyList + | literal + ; + +literal + : rdfLiteral + | numericLiteral + | BooleanLiteral + ; + +blankNodePropertyList + : '[' predicateObjectList ']' + ; + +collection + : '(' object_* ')' + ; + +prefixID + : '@prefix' PNAME_NS IRIREF '.' + ; + +base + : '@base' IRIREF '.' + ; + +sparqlBase + : Base_w IRIREF + ; + +sparqlPrefix + : Prefix_w PNAME_NS IRIREF + ; + +numericLiteral + : INTEGER + | DECIMAL + | DOUBLE + ; + +rdfLiteral + : string (LANGTAG | '^^' iri)? + ; + +BooleanLiteral + : 'true' + | 'false' + ; + +string + : STRING_LITERAL_QUOTE + | STRING_LITERAL_SINGLE_QUOTE + | STRING_LITERAL_LONG_SINGLE_QUOTE + | STRING_LITERAL_LONG_QUOTE + ; + +iri + : IRIREF + | PNAME_LN + | PNAME_NS + ; + +BlankNode + : BLANK_NODE_LABEL + | ANON + ; + +WS + : ([\t\r\n\u000C] | ' ')+ -> skip + ; + +// LEXER + +Base_w options { caseInsensitive=true; } + : 'BASE' + ; + +Prefix_w options { caseInsensitive=true; } + : 'PREFIX' + ; + +PN_PREFIX + : PN_CHARS_BASE ((PN_CHARS | '.')* PN_CHARS)? + ; + +IRIREF + : '<' (~( '\u0000' | '\u0020' | '<' | '>' | '"' | '{' | '}' | '|' | '^' | '`' | '\\' ) | UCHAR)* '>' + ; + +// Prefix alone +PNAME_NS + : PN_PREFIX? ':' + ; + +PNAME_LN + : PNAME_NS PN_LOCAL + ; + +BLANK_NODE_LABEL + : '_:' (PN_CHARS_U | '0' .. '9') ((PN_CHARS | '.')* PN_CHARS)? + ; + +LANGTAG + : '@' ('a'.. 'z' | 'A' .. 'Z')+ ('-' ('a'.. 'z' | 'A' .. 'Z' | '0' .. '9')* )* + ; + +INTEGER + : ('+' | '-' )? ('0' .. '9')+ + ; + +DECIMAL + : ('+' | '-' )? ('0' .. '9')* '.' ('0' .. '9')+ + ; + +DOUBLE + : ('+' | '-' )? (('0' .. '9')+ '.' ('0' .. '9')* EXPONENT + | '.' ('0' .. '9')+ EXPONENT + | ('0' .. '9')+ EXPONENT) + ; + +EXPONENT + : ('e' | 'E') ('+' | '-' )? ('0' .. '9')+ + ; + +// "'''" (("'" | "''")? ([^'\] | ECHAR | UCHAR))* "'''" +STRING_LITERAL_LONG_SINGLE_QUOTE + : '\'\'\'' ( + ( ~['\\] | ECHAR | UCHAR ) + | '\'' ~['\\] + | '\'\'' ~['\\] + )* '\'\'\'' + ; + +// '"""' (('"' | '""')? ([^"\] | ECHAR | UCHAR))* '"""' +STRING_LITERAL_LONG_QUOTE + : '"""' ( + ( ~["\\] | ECHAR | UCHAR ) + | '"' ~["\\] + | '""' ~["\\] + )* '"""' + ; + +STRING_LITERAL_QUOTE + : '"' (~["\\\r\n] | ECHAR | UCHAR)* '"' + ; + +STRING_LITERAL_SINGLE_QUOTE + : '\'' (~['\\\r\n] | ECHAR | UCHAR)* '\'' + ; + +// Hexadecimal unicode character +UCHAR + : '\\u' HEX HEX HEX HEX + | '\\U' HEX HEX HEX HEX HEX HEX HEX HEX + ; + +// Escaped character +ECHAR + : '\\' [tbnrf"'\\] + ; + +ANON_WS + : ' ' + | '\t' + | '\r' + | '\n' + ; + +ANON + : '[' ANON_WS* ']' + ; + +PN_CHARS_BASE + : 'A' .. 'Z' + | 'a' .. 'z' + | '\u00C0' .. '\u00D6' + | '\u00D8' .. '\u00F6' + | '\u00F8' .. '\u02FF' + | '\u0370' .. '\u037D' + | '\u037F' .. '\u1FFF' + | '\u200C' .. '\u200D' + | '\u2070' .. '\u218F' + | '\u2C00' .. '\u2FEF' + | '\u3001' .. '\uD7FF' + | '\uF900' .. '\uFDCF' + | '\uFDF0' .. '\uFFFD' + | '\u{10000}'..'\u{EFFFF}' + ; + +PN_CHARS_U + : PN_CHARS_BASE + | '_' + ; + +PN_CHARS + : PN_CHARS_U + | '-' + | [0-9] + | [\u00B7] + | [\u0300-\u036F] + | [\u203F-\u2040] + ; + +PN_LOCAL + : (PN_CHARS_U | ':' | [0-9] | PLX) ((PN_CHARS | '.' | ':' | PLX)* (PN_CHARS | ':' | PLX))? + ; + +PLX + : PERCENT + | PN_LOCAL_ESC + ; + +PERCENT + : '%' HEX HEX + ; + +HEX + : [0-9] + | [A-F] + | [a-f] + ; + +PN_LOCAL_ESC + : '\\' ( + '_' + | '~' + | '.' + | '-' + | '!' + | '$' + | '&' + | '\'' + | '(' + | ')' + | '*' + | '+' + | ',' + | ';' + | '=' + | '/' + | '?' + | '#' + | '@' + | '%' + ) + ; + +LC + : '#' ~[\r\n]* -> channel(HIDDEN) + ; + diff --git a/src/main/java/fr/inria/corese/core/CompareWithoutDatatypeEntailment.java b/src/main/java/fr/inria/corese/core/CompareWithoutDatatypeEntailment.java index 4c22584a9..75b9df3e8 100644 --- a/src/main/java/fr/inria/corese/core/CompareWithoutDatatypeEntailment.java +++ b/src/main/java/fr/inria/corese/core/CompareWithoutDatatypeEntailment.java @@ -1,6 +1,7 @@ package fr.inria.corese.core; import fr.inria.corese.core.sparql.api.IDatatype; + import java.util.Comparator; @@ -8,12 +9,12 @@ * TreeMap Node index comparator without D-entailment * Assign Node index for: * 1) graph match node join without D-entailment - * 2) sorting graph Index edge list + * 2) sorting graph Index edge list * Assign same node index when same datatype and same value (and possibly - * different labels) + * different labels) * 1 and 01 have same index * integer|decimal and double|float have different index - *'1'^^xsd:boolean and true have same index + * '1'^^xsd:boolean and true have same index */ class CompareWithoutDatatypeEntailment implements Comparator { diff --git a/src/main/java/fr/inria/corese/core/Context.java b/src/main/java/fr/inria/corese/core/Context.java index ea55ecd27..93973ee41 100644 --- a/src/main/java/fr/inria/corese/core/Context.java +++ b/src/main/java/fr/inria/corese/core/Context.java @@ -1,32 +1,31 @@ package fr.inria.corese.core; -import fr.inria.corese.core.sparql.api.IDatatype; -import fr.inria.corese.core.sparql.datatype.DatatypeMap; import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.api.query.Graphable; import fr.inria.corese.core.kgram.core.Query; +import fr.inria.corese.core.load.QueryLoad; import fr.inria.corese.core.query.RDFizer; import fr.inria.corese.core.rule.RuleEngine; -import fr.inria.corese.core.load.QueryLoad; +import fr.inria.corese.core.sparql.api.IDatatype; +import fr.inria.corese.core.sparql.datatype.DatatypeMap; +import org.slf4j.LoggerFactory; + import java.io.IOException; import java.util.ArrayList; -import org.slf4j.LoggerFactory; /** * Graph Execution Context * Store History * * @author Olivier Corby, Wimmics INRIA I3S, 2014 - * */ public class Context implements Graphable { - private ArrayList queryNodes; - private Node ruleEngineNode; + private final ArrayList queryNodes; RuleEngine re; - private int max = 10; - Graph graph; + private Node ruleEngineNode; + private int max = 10; Context(Graph g) { this.graph = g; @@ -39,18 +38,17 @@ public class Context implements Graphable { public Node getQueryNode() { if (queryNodes.isEmpty()) { return null; - } + } return queryNodes.get(queryNodes.size() - 1); } - - Node getRE(){ + + Node getRE() { RuleEngine re = RuleEngine.create(Graph.create()); - for (Node n : queryNodes){ + for (Node n : queryNodes) { Query q = (Query) n.getNodeObject(); re.defRule(q); } - Node res = DatatypeMap.createObject("RuleEngine", re); - return res; + return DatatypeMap.createObject("RuleEngine", re); } /** @@ -58,18 +56,18 @@ Node getRE(){ * 0 is last, 1 is before last ... */ public Node getQueryNode(int n) { - if (n == -1){ + if (n == -1) { return getRE(); } - int i = queryNodes.size() - 1 - n ; - if (i >= 0 && i < queryNodes.size()){ + int i = queryNodes.size() - 1 - n; + if (i >= 0 && i < queryNodes.size()) { return queryNodes.get(i); } return null; } /** - * @param queryNode the queryNode to set + * @param q the queryNode to set */ public void setQuery(Query q) { while (queryNodes.size() >= max) { @@ -84,30 +82,30 @@ public void setQuery(Query q) { public Node getRuleEngineNode() { return ruleEngineNode; } - + public Node getRecordNode() { - if (re == null){ + if (re == null) { return null; } return create("Record", re.getRecord()); } /** - * @param ruleEngineNode the ruleEngineNode to set + * @param re the ruleEngineNode to set */ public void setRuleEngine(RuleEngine re) { this.re = re; this.ruleEngineNode = create("RuleEngine", re); } - - Node create(String name, Object obj){ + + Node create(String name, Object obj) { return DatatypeMap.createObject(name, obj); } - - Node create(String name, Object obj, String dt){ + + Node create(String name, Object obj, String dt) { return DatatypeMap.createObject(name, obj, dt); } - + /** * @return the max */ @@ -121,8 +119,8 @@ public int getMax() { public void setMax(int max) { this.max = max; } - - public void storeIndex(String name){ + + public void storeIndex(String name) { Graph g = new RDFizer().getGraph(graph.describe()); graph.setNamedGraph(name, g); } @@ -130,23 +128,22 @@ public void storeIndex(String name){ @Override public String toGraph() { StringBuilder sb = new StringBuilder(); - //sb.append(toRDF()); sb.append(graph.toRDF()); return sb.toString(); } @Override - public void setGraph(Object obj) { + public Object getGraph() { + return null; } @Override - public Object getGraph() { - return null; + public void setGraph(Object obj) { } - - String toRDF(){ + + String toRDF() { QueryLoad ql = QueryLoad.create(); - String str = ""; + String str = ""; try { str = ql.getResource("/data/kgram.ttl"); } catch (IOException ex) { diff --git a/src/main/java/fr/inria/corese/core/DataStore.java b/src/main/java/fr/inria/corese/core/DataStore.java index 49763e558..a0effce2e 100644 --- a/src/main/java/fr/inria/corese/core/DataStore.java +++ b/src/main/java/fr/inria/corese/core/DataStore.java @@ -1,7 +1,8 @@ package fr.inria.corese.core; -import fr.inria.corese.core.producer.DataProducer; import fr.inria.corese.core.kgram.api.core.Node; +import fr.inria.corese.core.producer.DataProducer; + import java.util.ArrayList; import java.util.List; @@ -12,14 +13,13 @@ * Producer uses getDefault() * getDefault().iterate() * getNamed().iterate() - * - * @author Olivier Corby, Wimmics INRIA I3S, 2016 * + * @author Olivier Corby, Wimmics INRIA I3S, 2016 */ public class DataStore { + private final ArrayList defaultGraphList; Graph graph; - private ArrayList defaultGraphList; DataStore(Graph g) { graph = g; @@ -40,11 +40,11 @@ public DataProducer getNamed(List list, Node source) { public DataProducer getDefaultBasic() { return new DataProducer(graph); } - + public DataProducer getDefaultUnion() { return new DataProducer(graph); } - + public DataProducer getDefaultGraph() { return getDefaultBasic().from(graph.getNodeDefault()); } @@ -69,7 +69,7 @@ public DataStore addDefaultGraph(Node node) { } return this; } - + public DataStore addDefaultGraph() { return addDefaultGraph(graph.getNodeDefault()); } diff --git a/src/main/java/fr/inria/corese/core/EdgeFactory.java b/src/main/java/fr/inria/corese/core/EdgeFactory.java index 16a60274d..5618f09b8 100644 --- a/src/main/java/fr/inria/corese/core/EdgeFactory.java +++ b/src/main/java/fr/inria/corese/core/EdgeFactory.java @@ -2,18 +2,25 @@ import fr.inria.corese.core.edge.*; import fr.inria.corese.core.edge.binary.*; -import fr.inria.corese.core.edge.internal.*; -import fr.inria.corese.core.edge.rule.*; -import fr.inria.corese.core.sparql.datatype.DatatypeMap; +import fr.inria.corese.core.edge.internal.EdgeInternal; +import fr.inria.corese.core.edge.internal.EdgeInternalDefault; +import fr.inria.corese.core.edge.internal.EdgeInternalEntail; +import fr.inria.corese.core.edge.internal.EdgeInternalRule; +import fr.inria.corese.core.edge.rule.EdgeRule; +import fr.inria.corese.core.edge.rule.EdgeRuleGraph; +import fr.inria.corese.core.edge.rule.EdgeRuleSubclass; +import fr.inria.corese.core.edge.rule.EdgeRuleType; +import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.logic.Entailment; import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.api.IDatatype; +import fr.inria.corese.core.sparql.datatype.DatatypeMap; import fr.inria.corese.core.sparql.exceptions.EngineException; import fr.inria.corese.core.sparql.triple.parser.NSManager; -import java.util.List; -import fr.inria.corese.core.kgram.api.core.Edge; + import java.util.ArrayList; +import java.util.List; /* * Factory creates Edges @@ -23,16 +30,21 @@ * */ public class EdgeFactory { - public static int std = 0, def = 0, rul = 0, ent = 0, typ = 0, sub = 0, fst = 0, rst = 0; static final String METADATA = NSManager.USER + "metadata"; + public static int std = 0; + public static int def = 0; + public static int rul = 0; + public static int ent = 0; + public static int typ = 0; + public static int sub = 0; + public static int fst = 0; + public static int rst = 0; public static boolean OPTIMIZE_EDGE = true; public static boolean EDGE_TRIPLE_NODE = false; - public static boolean trace = false; Graph graph; QueryProcess exec; - boolean - isTag = false, - isGraph = false; + boolean isTag = false; + boolean isGraph = false; int count = 0; String key; private boolean optimize = OPTIMIZE_EDGE; @@ -42,41 +54,25 @@ public EdgeFactory(Graph g) { key = hashCode() + "."; } - static public void trace(){ - System.out.println("Typ: " + typ); - System.out.println("Sub: " + sub); - System.out.println("Fst: " + fst); - System.out.println("Rst: " + rst); - System.out.println(); - System.out.println("Def: " + def); - System.out.println("Rul: " + rul); - System.out.println("Ent: " + ent); - System.out.println("Std: " + std); - System.out.println("Tot: " + (std+def+rul+ent)); - } - public Edge create(Node source, Node subject, Node predicate, Node object) { - if (graph.isTuple()){ - return EdgeImpl.create(source, subject, predicate, object); - } - else if (graph.isMetadata()) { - return EdgeImpl.createMetadata(source, subject, predicate, object, metadata()); - } - else if (isOptimize()) { + if (graph.isTuple()) { + return EdgeImpl.create(source, subject, predicate, object); + } else if (graph.isMetadata()) { + return EdgeImpl.createMetadata(source, subject, predicate, object, metadata()); + } else if (isOptimize()) { return genCreate(source, subject, predicate, object); - } - else { + } else { return createGeneric(source, subject, predicate, object); } - } - + } + Node metadata() { if (exec == null) { exec = QueryProcess.create(Graph.create()); } IDatatype dt = null; try { - dt = exec.funcall(METADATA, new IDatatype[0]); + dt = exec.funcall(METADATA); } catch (EngineException ex) { } if (dt == null) { @@ -84,36 +80,37 @@ Node metadata() { } return graph.getNode(dt, true, false); } - + IDatatype defaultMetadata() { return DatatypeMap.newInstance(count++); } - - public Edge internal(Edge ent){ - if (ent.nbNode() > 2 || ! isOptimize()) { + + public Edge internal(Edge ent) { + if (ent.nbNode() > 2 || !isOptimize()) { return ent; } Edge edge = ent; - switch (ent.getGraph().getIndex()){ + switch (ent.getGraph().getIndex()) { // rule edge must store an index - case Graph.RULE_INDEX: return ent; - + case Graph.RULE_INDEX: + return ent; + case Graph.ENTAIL_INDEX: edge = EdgeInternalEntail.create(ent); break; - + case Graph.DEFAULT_INDEX: edge = EdgeInternalDefault.create(ent); break; - default: - edge = EdgeInternal.create(ent); + default: + edge = EdgeInternal.create(ent); break; } edge.setLevel(ent.getLevel()); return edge; } - + /** * Use case: Index edge iterator, edge is internal (predicate==null) * create a buffer edge where to record index getPredicate() @@ -127,17 +124,18 @@ public EdgeTop createDuplicate(Edge ent) { return ee; } } - - public Edge compact(Edge ent){ - switch (ent.getGraph().getIndex()){ - case Graph.RULE_INDEX: + + public Edge compact(Edge ent) { + switch (ent.getGraph().getIndex()) { + case Graph.RULE_INDEX: Edge edge = EdgeInternalRule.create(ent.getNode(0), ent.getNode(1)); edge.setLevel(ent.getLevel()); return edge; - default: return ent; + default: + return ent; } } - + /** * Specific named graph and specific properties have specific Edge class */ @@ -146,9 +144,9 @@ public Edge genCreate(Node source, Node subject, Node predicate, Node value) { case Graph.RULE_INDEX: rul++; return ruleCreate(source, subject, predicate, value); - case Graph.ENTAIL_INDEX: + case Graph.ENTAIL_INDEX: ent++; - return entailCreate(source, subject, predicate, value); + return entailCreate(source, subject, predicate, value); case Graph.DEFAULT_INDEX: def++; return defaultCreate(source, subject, predicate, value); @@ -157,40 +155,40 @@ public Edge genCreate(Node source, Node subject, Node predicate, Node value) { // source = kg:rule but index = -1 (data manager node, not in corese graph) // Construct insert rule edge via storage data manager // edge require explicit graph and index - if (source.getIndex()==-1 && source.getLabel().startsWith(Entailment.RULE)){ - return new EdgeRuleGraph(source, predicate, subject, value); + if (source.getIndex() == -1 && source.getLabel().startsWith(Entailment.RULE)) { + return new EdgeRuleGraph(source, predicate, subject, value); } std++; return createQuad(source, subject, predicate, value); } } - + /** * Edge for default graph kg:default * Named Graph is not stored in Edge * Several properties have specific class: rdf:type, rdf:first, rdf:rest, rdfs:subClassOf */ public Edge defaultCreate(Node source, Node subject, Node predicate, Node value) { - switch (predicate.getIndex()){ - case Graph.TYPE_INDEX: + switch (predicate.getIndex()) { + case Graph.TYPE_INDEX: typ++; return EdgeBinaryType.create(source, subject, predicate, value); - case Graph.SUBCLASS_INDEX: + case Graph.SUBCLASS_INDEX: sub++; return EdgeBinarySubclass.create(source, subject, predicate, value); - case Graph.LABEL_INDEX: + case Graph.LABEL_INDEX: return EdgeBinaryLabel.create(source, subject, predicate, value); case Graph.FIRST_INDEX: fst++; - return EdgeBinaryFirst.create(source, subject, predicate, value); - case Graph.REST_INDEX: + return EdgeBinaryFirst.create(source, subject, predicate, value); + case Graph.REST_INDEX: rst++; - return EdgeBinaryRest.create(source, subject, predicate, value); - default: - return EdgeDefault.create(source, subject, predicate, value); - } + return EdgeBinaryRest.create(source, subject, predicate, value); + default: + return EdgeDefault.create(source, subject, predicate, value); + } } - + /** * Edge for RDFS entailment graph kg:entail */ @@ -203,18 +201,18 @@ public Edge entailCreate(Node source, Node subject, Node predicate, Node value) * Edge for rule graph kg:rule, store an index and a provenance * Named Graph is not stored in Edge * Several properties have specific class: rdf:type, rdfs:subClassOf - */ + */ public Edge ruleCreate(Node source, Node subject, Node predicate, Node value) { - switch (predicate.getIndex()){ - case Graph.TYPE_INDEX: + switch (predicate.getIndex()) { + case Graph.TYPE_INDEX: typ++; return EdgeRuleType.create(source, subject, predicate, value); - case Graph.SUBCLASS_INDEX: + case Graph.SUBCLASS_INDEX: sub++; - return EdgeRuleSubclass.create(source, subject, predicate, value); - default: - return EdgeRule.create(source, subject, predicate, value); - } + return EdgeRuleSubclass.create(source, subject, predicate, value); + default: + return EdgeRule.create(source, subject, predicate, value); + } } /** @@ -223,34 +221,33 @@ public Edge ruleCreate(Node source, Node subject, Node predicate, Node value) { public Edge createQuad(Node source, Node subject, Node predicate, Node value) { return EdgeQuad.create(source, subject, predicate, value); } - + // default when not optimize public Edge createGeneric(Node source, Node subject, Node predicate, Node value) { if (EDGE_TRIPLE_NODE) { return createTripleNode(source, subject, predicate, value); - } - else { + } else { return createBasicGeneric(source, subject, predicate, value); } } - + public Edge createTripleNode(Node source, Node subject, Node predicate, Node value) { return new EdgeTripleNode(source, subject, predicate, value); } - + public Edge createBasicGeneric(Node source, Node subject, Node predicate, Node value) { return EdgeGeneric.create(source, subject, predicate, value); } - + public Edge create(Node source, Node predicate, List list) { return create(source, predicate, list, false); } - + public Edge create(Node source, Node predicate, List list, boolean nested) { if (EDGE_TRIPLE_NODE && list.size() == 3 && list.get(2).isTripleNode()) { // use case: Construct created triple node reference as additional node TripleNode t = (TripleNode) list.get(2); - Edge edge = new EdgeTripleNode(source, t); + Edge edge = new EdgeTripleNode(source, t); edge.setNested(nested); return edge; } @@ -266,13 +263,15 @@ public Edge createEdgeList(Node source, Node predicate, List list, boolean } return ee; } - + public Edge create(Node source, Node subject, Node predicate, Node object, Node node, boolean nested) { ArrayList list = new ArrayList<>(); - list.add(subject);list.add(object); list.add(node); - return create(source, predicate, list, nested); + list.add(subject); + list.add(object); + list.add(node); + return create(source, predicate, list, nested); } - + // @todo: check this public Edge name(Edge edge, Node predicate, Node name) { if (edge.hasReferenceNode()) { @@ -281,36 +280,35 @@ public Edge name(Edge edge, Node predicate, Node name) { } return create(edge.getGraph(), edge.getNode(0), predicate, edge.getNode(1), name, edge.isNested()); } - + /** - * Return a copy of edge with new named graph + * Return a copy of edge with new named graph * to be inserted in same Graph * edge nodes are already inserted + * * @pragma: pred == edge.getPredicate() - * */ public Edge copy(Node graphNode, Node pred, Edge edge) { Edge copy; - if (edge.isTripleNode()) { - return ((EdgeTripleNode)edge).copy(graphNode); + if (edge.isTripleNode()) { + return ((EdgeTripleNode) edge).copy(graphNode); } if (edge instanceof EdgeImpl) { - copy = ((EdgeImpl)edge).copy(); + copy = ((EdgeImpl) edge).copy(); copy.setGraph(graphNode); - } - else { - copy = create(graphNode, edge.getNode(0), pred, edge.getNode(1)); + } else { + copy = create(graphNode, edge.getNode(0), pred, edge.getNode(1)); } copy.setLevel(edge.getLevel()); return copy; } - - public Edge copy(Edge ent){ + + public Edge copy(Edge ent) { return copy(ent.getGraph(), ent.getEdgeNode(), ent); } - - - public Edge queryEdge(Edge ent){ + + + public Edge queryEdge(Edge ent) { if (graph.isMetadata()) { return createGeneric(ent.getGraph(), ent.getNode(0), ent.getEdgeNode(), ent.getNode(1)); } @@ -326,9 +324,9 @@ public void setGraph(Edge ent, Node g) { // EdgeTop e = (EdgeTop) ent; // e.setGraph(g); // } - + } - + Edge tag(Edge ent) { if (ent instanceof EdgeImpl) { EdgeImpl ee = (EdgeImpl) ent; @@ -347,8 +345,8 @@ public Edge createDelete(Node source, Node subject, Node predicate, Node value) public Edge createDelete(Node source, Node predicate, List list) { return create(source, predicate, list); } - - + + boolean hasTag() { return graph.hasTag(); } diff --git a/src/main/java/fr/inria/corese/core/Event.java b/src/main/java/fr/inria/corese/core/Event.java index b937a4649..5c381bbe0 100644 --- a/src/main/java/fr/inria/corese/core/Event.java +++ b/src/main/java/fr/inria/corese/core/Event.java @@ -2,42 +2,41 @@ /** * Collection of events trapped by graph event manager - * in order to ensure consistency of graph index and entailments + * in order to ensure consistency of graph index and entailments * w.r.t graph modifications - * - * @author Olivier Corby, Wimmics INRIA I3S, 2017 * + * @author Olivier Corby, Wimmics INRIA I3S, 2017 */ -public enum Event { - Start, Finish, +public enum Event { + Start, Finish, Process, // alternative to start/finish and also general purpose graph access -> graph.index() - + InitGraph, IndexNodeManager, IndexNodeManagerReduce, ClearNodeManager, IndexGraph, IndexMetadata, - - Query, + + Query, // fake select where query for initialization purpose e.g. Visitor - InitQuery, InitUpdateQuery, - Construct, Rule, + InitQuery, InitUpdateQuery, + Construct, Rule, Service, LoadAPI, LoadStep, // load() Update, UpdateStep, BasicUpdate, LoadUpdate, // SPARQL Update load - DeleteInsert, DeleteData, InsertData, + DeleteInsert, DeleteData, InsertData, Delete, Insert, - - WorkflowParser, + + WorkflowParser, WorkflowQuery, WorkflowTransformation, - + Format, Transformation, RuleEngine, WorkflowEngine, // rule and entailment InferenceEngine, InferenceCycle, // rule and entailment CleanOntology, // OWL RL clean OWL ontology before processing // (des)activate existing processor for future process cycle, does not process yet - ActivateRDFSEntailment, ActivateRuleEngine, + ActivateRDFSEntailment, ActivateRuleEngine, // activate entailment processing for next cycle (e.g. next query) ActivateEntailment - + } diff --git a/src/main/java/fr/inria/corese/core/EventHandler.java b/src/main/java/fr/inria/corese/core/EventHandler.java index 08f8ae3f8..4130270e7 100644 --- a/src/main/java/fr/inria/corese/core/EventHandler.java +++ b/src/main/java/fr/inria/corese/core/EventHandler.java @@ -6,11 +6,11 @@ * */ public interface EventHandler { - + default void delete(Edge query, Edge target) { } - + default void insert(Edge edge) { } - + } diff --git a/src/main/java/fr/inria/corese/core/EventLogger.java b/src/main/java/fr/inria/corese/core/EventLogger.java index 56fc5f9ea..e660f16b7 100644 --- a/src/main/java/fr/inria/corese/core/EventLogger.java +++ b/src/main/java/fr/inria/corese/core/EventLogger.java @@ -1,50 +1,46 @@ package fr.inria.corese.core; import fr.inria.corese.core.compiler.eval.QuerySolverVisitor; -import fr.inria.corese.core.sparql.exceptions.EngineException; import fr.inria.corese.core.index.NodeManager; -import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.kgram.api.core.DatatypeValue; import fr.inria.corese.core.kgram.api.core.Edge; -import fr.inria.corese.core.sparql.api.IDatatype; +import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.datatype.DatatypeMap; +import fr.inria.corese.core.sparql.exceptions.EngineException; import fr.inria.corese.core.sparql.triple.parser.NSManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.Date; import java.util.HashMap; -import java.util.logging.Level; -import org.slf4j.LoggerFactory; -import org.slf4j.Logger; + /** - * * @author Olivier Corby, Wimmics INRIA I3S, 2017 - * */ public class EventLogger { - private static Logger logger = LoggerFactory.getLogger(EventLogger.class); - public static boolean DEFAULT_METHOD = false; static final String INSERT_FUN = NSManager.USER + "insert"; static final String DELETE_FUN = NSManager.USER + "delete"; - + private static final Logger logger = LoggerFactory.getLogger(EventLogger.class); + public static boolean DEFAULT_METHOD = false; EventManager mgr; QueryProcess exec; HashMap show, hide; private boolean method = DEFAULT_METHOD; EventLogger(EventManager ev) { - mgr = ev; + mgr = ev; } - + public void show(Event e, boolean b) { if (b) { show().put(e, e); - } - else { + } else { show().remove(e); } } - + public void hide(Event e, boolean b) { if (b) { hide().put(e, e); @@ -54,87 +50,93 @@ public void hide(Event e, boolean b) { } public void focus() { - show().clear(); - hide().clear(); + show().clear(); + hide().clear(); } - + HashMap show() { - if (show == null) {show = new HashMap<>();} + if (show == null) { + show = new HashMap<>(); + } return show; } - + HashMap hide() { - if (hide == null) {hide = new HashMap<>();} + if (hide == null) { + hide = new HashMap<>(); + } return hide; } - + boolean accept(Event e) { - return (show().isEmpty() || show().containsKey(e)) && - (hide().isEmpty() || ! hide().containsKey(e)) ; + return (show().isEmpty() || show().containsKey(e)) && + (hide().isEmpty() || !hide().containsKey(e)); } - + void trace(Event type, Event e, Object o, Object o2) { if (accept(e)) { - if (isMethod()){ + if (isMethod()) { method(type, e, o, o2); - } - else { + } else { message(type, e, o); } } } - + void message(Event type, Event e, Object o) { switch (type) { case Start: case Process: switch (e) { - case LoadStep: logLoadStep(); break; - - case Service: + case LoadStep: + logLoadStep(); + break; + + case Service: logger.info(type + " " + e + serviceSeparator(o) + o); break; - - default: logger.info(type + " " + e + pretty(o)); + + default: + logger.info(type + " " + e + pretty(o)); } break; - + case Finish: switch (e) { case IndexNodeManager: logger.info(type + " " + e); break; - - default: logger.info(type + " " + e + pretty(o)); + + default: + logger.info(type + " " + e + pretty(o)); } break; } log(type, e, o); } - + String serviceSeparator(Object o) { return (o instanceof String) ? "\n" : " "; } - + void method(Event type, Event e, Object o, Object o2) { if (!true) { methodcall(type, e, o); - } - else { + } else { funcall(type, e, o, o2); } } - + void methodcall(Event type, Event e, Object o) { try { getQueryProcess().event(type, e, o); } catch (EngineException ex) { - java.util.logging.Logger.getLogger(EventLogger.class.getName()).log(Level.SEVERE, null, ex); - } + logger.error("An unexpected error has occurred", ex); } } - + /** * Manage update event with LDScript function + * * @public us:insert(edge) * @public us:delete(edge) * When insert, o = target edge, o2 = null @@ -147,40 +149,32 @@ void funcall(Event type, Event e, Object o, Object o2) { case Process: switch (e) { case Insert: - //funcall(INSERT_FUN, (Edge)o); - insert((Edge)o); + insert((Edge) o); break; case Delete: - //funcall(DELETE_FUN, (Edge) ((o2 == null) ? o : o2)); - delete((Edge)((o2 == null) ? o : o2)); + delete((Edge) ((o2 == null) ? o : o2)); break; } } } catch (EngineException ex) { - java.util.logging.Logger.getLogger(EventLogger.class.getName()).log(Level.SEVERE, null, ex); - } - } - - IDatatype funcall(String name, Edge edge) throws EngineException { - return getQueryProcess().funcall(name, DatatypeMap.createObject(edge)); + logger.error("An unexpected error has occurred", ex); } } - + DatatypeValue insert(Edge edge) throws EngineException { return DatatypeMap.TRUE; } - + DatatypeValue delete(Edge edge) throws EngineException { return getQueryProcess().getVisitor().delete(edge); } - + QueryProcess getQueryProcess() { - if (exec == null){ + if (exec == null) { exec = QueryProcess.create(getEventManager().getGraph()); try { exec.getCreateEval().setVisitor(new QuerySolverVisitor(exec.getCreateEval())); } catch (EngineException ex) { - java.util.logging.Logger.getLogger(EventLogger.class.getName()).log(Level.SEVERE, null, ex); - } + logger.error("An unexpected error has occurred", ex); } } return exec; } @@ -189,23 +183,24 @@ void log(Event type, Event e, Object o) { switch (type) { case Start: break; - + case Finish: - switch(e) { - case Rule: logRule(e); - break; - - case IndexNodeManager: - case IndexNodeManagerReduce: + switch (e) { + case Rule: + logRule(e); + break; + + case IndexNodeManager: + case IndexNodeManagerReduce: logNodeManager((o == null) ? getNodeMgr() : (NodeManager) o); - break; + break; } break; - + case Process: break; } - + switch (e) { case InferenceEngine: logInference(type); @@ -216,35 +211,39 @@ void log(Event type, Event e, Object o) { String pretty(Object o) { return (o == null) ? "" : " " + o; } - + void logLoadStep() { logger.info(String.format("Loading: %s : %s", new Date(), mgr.getGraph().size())); } void logInference(Event e) { switch (e) { - case Start: logger.info("Graph size before: " + mgr.getGraph().size()); break; - case Finish:logger.info("Graph size after: " + mgr.getGraph().size()); break; + case Start: + logger.info("Graph size before: " + mgr.getGraph().size()); + break; + case Finish: + logger.info("Graph size after: " + mgr.getGraph().size()); + break; } } - + void logNodeManager(NodeManager nm) { - logger.info(String.format("index: %s ; subject: %s ; predicate: %s ; ratio (p/s): %s ; graph: %s" , - nm.getIndex(), nm.size() , nm.count(), - (nm.size() > 0) ? ((float) nm.count()) / nm.size() : 0, - mgr.getGraph().size())); + logger.info(String.format("index: %s ; subject: %s ; predicate: %s ; ratio (p/s): %s ; graph: %s", + nm.getIndex(), nm.size(), nm.count(), + (nm.size() > 0) ? ((float) nm.count()) / nm.size() : 0, + mgr.getGraph().size())); } - + NodeManager getNodeMgr() { return mgr.getGraph().getNodeManager(); } - + EventManager getEventManager() { return mgr; } - + void logRule(Event e) { - logger.info("Graph size after rule: " + mgr.getGraph().size()); + logger.info("Graph size after rule: " + mgr.getGraph().size()); } /** diff --git a/src/main/java/fr/inria/corese/core/EventManager.java b/src/main/java/fr/inria/corese/core/EventManager.java index 06396c20c..9e65b76ef 100644 --- a/src/main/java/fr/inria/corese/core/EventManager.java +++ b/src/main/java/fr/inria/corese/core/EventManager.java @@ -1,36 +1,33 @@ package fr.inria.corese.core; -import fr.inria.corese.core.compiler.parser.Transformer; import fr.inria.corese.core.api.Engine; -import fr.inria.corese.core.logic.Entailment; -import fr.inria.corese.core.util.Property; -import static fr.inria.corese.core.util.Property.Value.LOG_NODE_INDEX; +import fr.inria.corese.core.compiler.parser.Transformer; import fr.inria.corese.core.kgram.api.core.Edge; +import fr.inria.corese.core.logic.Entailment; import fr.inria.corese.core.sparql.triple.parser.ASTExtension; -import org.slf4j.LoggerFactory; +import fr.inria.corese.core.util.Property; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static fr.inria.corese.core.util.Property.Value.LOG_NODE_INDEX; /** * Event Manager for consistency and trace * Update and Inference are tracked * Debug mode traces events * Show and hide events. - * - * @author Olivier Corby, Wimmics INRIA I3S, 2017 * + * @author Olivier Corby, Wimmics INRIA I3S, 2017 */ public class EventManager implements EventHandler { - private static Logger logger = LoggerFactory.getLogger(EventManager.class); - + private static final Logger logger = LoggerFactory.getLogger(EventManager.class); + EventLogger log; private Graph graph; private boolean isEntail = true; private boolean isUpdate = false; private boolean isDelete = false; private boolean deletion = false; - - - EventLogger log; // User defined Event Handler private EventHandler handler; @@ -38,36 +35,44 @@ public class EventManager implements EventHandler { graph = g; setEventHandler(this); } - - public void setMethod(boolean b){ + + public void setMethod(boolean b) { getLog().setMethod(b); } - + public void show(Event e) { getLog().show(e, true); } + public void show(Event e, boolean status) { getLog().show(e, status); } + public void hide(Event e) { getLog().hide(e, true); } + public void hide(Event e, boolean status) { getLog().hide(e, status); } + public void focus() { - getLog().focus(); + getLog().focus(); } - - + + Graph getGraph() { return graph; } + public void setGraph(Graph graph) { + this.graph = graph; + } + void send(Event type, Event e) { send(type, e, null); } - + void send(Event type, Event e, Object o) { switch (type) { case Start: @@ -81,31 +86,33 @@ void send(Event type, Event e, Object o) { break; } } - + public void start(Event e) { start(e, null); } - + public void finish(Event e) { finish(e, null); } - + public void process(Event e) { process(e, null); } - + public void process(Event e, Object o1, Object o2) { - //trace(Process, e, o1, o2); - switch(e) { - case Insert: - setUpdate(true); break; - case Delete: - setDelete(true); break; - case Finish: - finish(); break; + switch (e) { + case Insert: + setUpdate(true); + break; + case Delete: + setDelete(true); + break; + case Finish: + finish(); + break; } } - + public void process(Event e, Edge o1) { switch (e) { case Insert: @@ -114,182 +121,177 @@ public void process(Event e, Edge o1) { break; } } - + public void process(Event e, Edge target, Edge query) { - switch(e) { - case Delete: + switch (e) { + case Delete: getEventHandler().delete(query, target); - setDelete(true); break; + setDelete(true); + break; } } - - /***************** + + /* * EventHandler ****************/ @Override - public void delete(Edge q, Edge t) { + public void delete(Edge q, Edge t) { } - + @Override public void insert(Edge e) { - } - - - + } + public void start(Event e, Object o) { switch (e) { case Query: - // sparql query + // sparql query // (empty) where part of delete/insert data/where case RuleEngine: case WorkflowParser: // index graph + entailment getGraph().init(); break; - + case InitQuery: // fake select where init query exec on load for init Visitor case InitUpdateQuery: // fake select where init query exec on global update query for init Visitor break; - + case Format: // RDF/JSON Format require graph index case Process: // specific action require graph index // basic index graph getGraph().indexGraph(); - break; + break; case Update: // global update query getGraph().startUpdate(); break; - - case UpdateStep: + + case UpdateStep: // one step in update query - break; - + break; + case BasicUpdate: // copy, move, etc. getGraph().init(); break; - + case LoadUpdate: case LoadAPI: // sequence of load can be done without graph index - // specific query which require graph index perform + // specific query which require graph index perform // getGraph().init() or getGraph().indexGraph() here getGraph().startLoad(); break; - - case Delete: + + case Delete: case Insert: - break; - - case Construct: - break; - + break; + + case Construct: + break; + case ActivateEntailment: setEntail(true); break; - - // Update create/drop kg:rule/kg:entailment + + // Update create/drop kg:rule/kg:entailment case ActivateRDFSEntailment: setEntailment(true); setEntail(true); break; - - case ActivateRuleEngine: - getWorkflow().setActivate(Engine.RULE_ENGINE, true); - setEntail(true); + + case ActivateRuleEngine: + getWorkflow().setActivate(Engine.Type.RULE_ENGINE, true); + setEntail(true); break; - + case InferenceEngine: break; - + case CleanOntology: break; - + case IndexNodeManager: log(LOG_NODE_INDEX, Event.Start, e, o); break; - } + } } - public void finish(Event e, Object o) { - switch (e) { - // insert after delete may require up to date NodeIndex - // we must compute node index after delete - case Delete: - case Insert: - getGraph().indexGraph(); - break; - - case LoadUpdate: - // SPARQL Update load + switch (e) { + // insert after delete may require up to date NodeIndex + // we must compute node index after delete + case Delete: + case Insert: + getGraph().indexGraph(); + break; + + case LoadUpdate: + // SPARQL Update load getGraph().finishUpdate(); - break; - + break; + case LoadAPI: // Java function load() // there may be several load(), do not index graph yet // next sparql query will do it getGraph().finishUpdate(); - break; - - case UpdateStep: - // one step in update query + break; + + case UpdateStep: + // one step in update query getGraph().finishUpdate(); - break; - - case Construct: + break; + + case Construct: getGraph().indexGraph(); getGraph().finishUpdate(); break; - + case Rule: break; - + case ActivateRDFSEntailment: setEntailment(false); break; - - case ActivateRuleEngine: - getWorkflow().setActivate(Engine.RULE_ENGINE, false); + + case ActivateRuleEngine: + getWorkflow().setActivate(Engine.Type.RULE_ENGINE, false); break; - + case RuleEngine: getGraph().finishRuleEngine(); break; - + case InferenceEngine: break; - + case CleanOntology: break; - + case IndexMetadata: break; - + case IndexNodeManager: log(LOG_NODE_INDEX, Event.Finish, e, o); break; } } - - - - + Workflow getWorkflow() { return getGraph().getWorkflow(); } - + Entailment getEntailment() { return getWorkflow().getEntailment(); } - + void setEntailment(boolean b) { if (getEntailment() != null) { getEntailment().setActivate(b); @@ -305,8 +307,7 @@ void log(Property.Value prop, Event type, Event e, Object o) { public void process(Event e, Object o) { process(e, o, null); } - - + /** * GUI reset Corese * Clean old environment @@ -317,15 +318,18 @@ public void finish() { } Transformer.removeLinkedFunction(); } - - + void initStatus() { - isEntail = true; - isUpdate = false; - isDelete = false; - setDeletion(false); + isEntail = true; + isUpdate = false; + isDelete = false; + setDeletion(false); } - + + public boolean isUpdate() { + return isUpdate; + } + void setUpdate(boolean b) { isUpdate = b; if (isUpdate) { @@ -333,11 +337,11 @@ void setUpdate(boolean b) { getGraph().eventUpdate(); } } - - public boolean isUpdate() { - return isUpdate; + + public boolean isDelete() { + return isDelete; } - + void setDelete(boolean b) { setUpdate(b); isDelete = b; @@ -345,23 +349,23 @@ void setDelete(boolean b) { setDeletion(true); } } - - public boolean isDelete() { - return isDelete; - } - + boolean isDeletion() { return deletion; } - - void setEntail(boolean b) { - isEntail = b; + + public void setDeletion(boolean deletion) { + this.deletion = deletion; } public boolean isEntail() { return isEntail; } + void setEntail(boolean b) { + isEntail = b; + } + EventLogger getLog() { if (log == null) { log = new EventLogger(this); @@ -369,14 +373,6 @@ EventLogger getLog() { return log; } - public void setDeletion(boolean deletion) { - this.deletion = deletion; - } - - public void setGraph(Graph graph) { - this.graph = graph; - } - public EventHandler getEventHandler() { return handler; } @@ -384,5 +380,5 @@ public EventHandler getEventHandler() { public void setEventHandler(EventHandler handler) { this.handler = handler; } - + } diff --git a/src/main/java/fr/inria/corese/core/Graph.java b/src/main/java/fr/inria/corese/core/Graph.java index fb797350d..0af9fa025 100755 --- a/src/main/java/fr/inria/corese/core/Graph.java +++ b/src/main/java/fr/inria/corese/core/Graph.java @@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -79,6 +80,7 @@ public class Graph extends GraphObject implements RDFS.SUBCLASSOF, RDFS.LABEL, RDF.TYPE, RDF.FIRST, RDF.REST }; + private static final Logger logger = LoggerFactory.getLogger(Graph.class); public static boolean valueOut = !true; public static String BLANK = "_:b"; public static String TRIPLE_REF = "_:t"; @@ -100,12 +102,13 @@ public class Graph extends GraphObject implements static long blankid = 0; static long triplerefid = 0; static boolean byIndexDefault = true; - private static Logger logger = LoggerFactory.getLogger(Graph.class); static { setCompareIndex(true); } + // skolem + private final String key; /** * Synchronization: *

@@ -120,17 +123,18 @@ public class Graph extends GraphObject implements // edge Index for RuleEngine where edge are sorted newest first EdgeManagerIndexer ruleEdgeIndex; // predefined individual Node such as kg:default named graph - HashMap system; + private ConcurrentHashMap nodeSystem; // key -> URI Node ; member of graph nodes (subject/object) - Hashtable individual; + private ConcurrentHashMap individual; // label -> Blank Node ; member of graph nodes (subject/object) - Hashtable blank; + private ConcurrentHashMap nodeBlank; // Triple Reference Node - Hashtable triple; - // named graph id nodes: key -> named graph id Node (possibly not subject/object Node) - Hashtable graph; + private ConcurrentHashMap triple; + // named graph id nodes: key -> named graph id Node (possibly not subject/object + // Node) + private ConcurrentHashMap graph; // property nodes: label -> property Node (possibly not subject/object Node) - Hashtable property; + private ConcurrentHashMap property; // key -> Node for value management in external memory Map vliteral; ValueResolver values; @@ -156,12 +160,13 @@ public class Graph extends GraphObject implements DataStore dataStore; List edgeChangeListeners = new ArrayList<>(); // List of subject/object/graph Index - // Index is HashMap: PredicateNode -> List of Edge with PredicateNode as predicate + // Index is HashMap: PredicateNode -> List of Edge with PredicateNode as + // predicate // In the Index, edge does not contain the predicate Node to spare memory // List of edge is sorted by Node index, each Node is allocated an integer index // Index of subject: edge list sorted by subject/object/graph - // Index of object: edge list sorted by object/subject/graph - // Index of graph: edge list sorted by graph/subject/object + // Index of object: edge list sorted by object/subject/graph + // Index of graph: edge list sorted by graph/subject/object private ArrayList tables; // Index of subject with index=0 private EdgeManagerIndexer subjectIndex; @@ -177,8 +182,6 @@ public class Graph extends GraphObject implements private Distance classDistance, propertyDistance; private boolean isSkolem = SKOLEM_DEFAULT; private int tagCount = 0; - // skolem - private String key; // name of this graph private String name; // @deprecated @@ -194,14 +197,11 @@ public class Graph extends GraphObject implements // true when there is a specific Edge Index for RuleEngine private boolean hasRuleEdgeList = false; // predefined Node for specific named Graph - private Node // rule entailment named graph - ruleGraph, + private Node ruleGraph; // rule entailment named graph // rule error named graph (cf RuleEngine OWL RL inconsistency) - constraintGraph, + private Node constraintGraph; // kg:default named graph - defaultGraph, - // RDFS entailment named graph - entailGraph; + private Node defaultGraph; // List of predefined (graph) Node private ArrayList systemNode; // @todo external memory literal value manager @@ -229,30 +229,34 @@ public Graph(int length) { setSubjectIndex(getIndex(0)); // Note: - // nodeManager allocate different Node to 1, 01, 1.0 - // indexManager allocate same Node index to 1, 01 (and also 1.0 as corese default mode) + // nodeManager allocate different Node to 1, 01, 1.0 + // indexManager allocate same Node index to 1, 01 (and also 1.0 as corese + // default mode) // Literals (all of them) comparator = CompareNode and compareTo() - // different Node allocated when different value or different datatype or different label + // different Node allocated when different value or different datatype or + // different label setLiteralNodeManager(Collections.synchronizedSortedMap(new TreeNode())); // Literal numbers and booleans to manage Node index: // comparator = CompareIndex and compare() // 1, 01, 1.0 have same index, 1 double has different index // same index means that SPARQL perform a join on nodes with same index - // when DatatypeMap.SPARQLCompliant = false (true), 1 and 1.0 have same (different) index - // corese default is false, which means that corese.core.sparql perform a join on 1 and 1.0 (which is not standard) + // when DatatypeMap.SPARQLCompliant = false (true), 1 and 1.0 have same + // (different) index + // corese default is false, which means that corese.core.sparql perform a join + // on 1 and 1.0 (which is not standard) setLiteralIndexManager(Collections.synchronizedSortedMap(new TreeNode(DatatypeMap.DATATYPE_ENTAILMENT))); // deprecated: vliteral = Collections.synchronizedMap(new HashMap<>()); // URI Node - individual = new Hashtable<>(); + individual = new ConcurrentHashMap<>(); // Blank Node - blank = new Hashtable<>(); + nodeBlank = new ConcurrentHashMap<>(); // rdf star triple reference node - triple = new Hashtable<>(); + triple = new ConcurrentHashMap<>(); // Named Graph Node - graph = new Hashtable<>(); + graph = new ConcurrentHashMap<>(); // Property Node - property = new Hashtable<>(); + property = new ConcurrentHashMap<>(); // Index of nodes of named graphs // Use case: SPARQL Property Path @@ -559,22 +563,22 @@ public TreeNode treeNode() { } /** - * System Node are predefined such as kg:default Node for default graph They + * nodeSystemNode are predefined such as kg:default Node for default graph They * have an index but they are not yet stored in any graph table but system * table They are retrieved by getResource, getNode, getGraph, getProperty * on demand */ void initSystem() { - system = new HashMap<>(); + nodeSystem= new ConcurrentHashMap<>(); systemNode = new ArrayList<>(); for (String uri : PREDEFINED) { Node n = createSystemNode(uri); - system.put(uri, n); + nodeSystem.put(uri, n); systemNode.add(n); } - defaultGraph = system.get(Entailment.DEFAULT); - ruleGraph = system.get(Entailment.RULE); - constraintGraph = system.get(Entailment.CONSTRAINT); + defaultGraph = nodeSystem.get(Entailment.DEFAULT); + ruleGraph = nodeSystem.get(Entailment.RULE); + constraintGraph = nodeSystem.get(Entailment.CONSTRAINT); } Node createSystemNode(String label) { @@ -585,7 +589,7 @@ Node createSystemNode(String label) { } Node getSystemNode(String name) { - return system.get(name); + return nodeSystem.get(name); } @Override @@ -805,7 +809,7 @@ public String toRDF() { sb.appendPNL("kg:graph ", graph.size()); sb.appendPNL("kg:property ", getSubjectIndex().size()); sb.appendPNL("kg:uri ", individual.size()); - sb.appendPNL("kg:bnode ", blank.size()); + sb.appendPNL("kg:bnode ", nodeBlank.size()); sb.appendPNL("kg:triple ", triple.size()); sb.appendPNL("kg:literal ", getLiteralNodeManager().size()); sb.appendPNL("kg:nodeManager ", getNodeManager().isEffective()); @@ -831,7 +835,7 @@ public NodeManager getNodeManager() { } /** - * Generate an RDF Graph that describes the KGRAM system and the current RDF + * Generate an RDF Graph that describes the KGRAM nodeSystem and the current RDF * graph */ public Graphable describe() { @@ -937,9 +941,10 @@ public static void setRDFStar(boolean b) { /** * EventManager call init() before query execution - * First time: Index graph: edge list sorted and reduced, compute graph node index - * Next time: recompute graph node index - * All time: Perform entailment. + * First time: Index graph: edge list sorted and reduced, compute graph node + * index + * Next time: recompute graph node index + * All time: Perform entailment. */ public synchronized void init() { getEventManager().start(Event.InitGraph, isIndexable()); @@ -1037,6 +1042,10 @@ public EdgeManagerIndexer getIndex() { return getSubjectIndex(); } + public int getIndexSize() { + return getIndex().size(); + } + void startUpdate() { } @@ -1052,7 +1061,7 @@ public void startLoad() { if (size() == 0 || Property.getBooleanValue(Property.Value.GRAPH_INDEX_LOAD_SKIP)) { // graph is empty, optimize loading as if the graph were not indexed // because in this case, edges are added directly - //logger.info("Set graph as not indexed"); + // logger.info("Set graph as not indexed"); setIndexed(false); } } @@ -1344,7 +1353,7 @@ void add(Node p, List list) { for (EdgeManagerIndexer ei : getIndexList()) { ei.add(p, list); } - //getEventManager().process(Event.Insert); + // getEventManager().process(Event.Insert); for (Edge e : list) { getEventManager().process(Event.Insert, e); } @@ -1522,7 +1531,7 @@ public int nbIndividuals() { } public int nbBlanks() { - return blank.size(); + return nodeBlank.size(); } public int nbTriples() { @@ -1717,13 +1726,13 @@ public Node getTripleNode(IDatatype dt, boolean create, boolean add) { } public Node getLiteralNode(IDatatype dt, boolean create, boolean add) { - String key = getKey(dt); - Node node = getLiteralNode(key, dt); + String keyString = getKey(dt); + Node node = getLiteralNode(keyString, dt); if (node != null) { return node; } if (create) { - node = createNode(key, dt); + node = createNode(keyString, dt); if (add) { addLiteralNode(dt, node); } @@ -1755,7 +1764,7 @@ Node getResource(String key, String name) { // resource or blank public boolean isIndividual(Node node) { return individual.containsKey(getID(node)) - || blank.containsKey(node.getLabel()) + || nodeBlank.containsKey(node.getLabel()) || triple.containsKey(node.getLabel()); } @@ -1786,7 +1795,7 @@ public Node getBlankNode(String name) { } public Node getBlankNodeBasic(String name) { - return blank.get(name); + return nodeBlank.get(name); } // named graph id may be a bnode @@ -1799,7 +1808,7 @@ public Node getTripleNode(String name) { } void addBlankNode(IDatatype dt, Node node) { - blank.put(node.getLabel(), node); + nodeBlank.put(node.getLabel(), node); } void addTripleNode(IDatatype dt, Node node) { @@ -1883,8 +1892,8 @@ Node basicAddResource(String label) { return node; } IDatatype dt = DatatypeMap.createResource(label); - String key = getID(label); - node = createNode(key, dt); + String keyString = getID(label); + node = createNode(keyString, dt); add(dt, node); return node; } @@ -2077,14 +2086,14 @@ Node getGraphNode(String key, String label) { public void addGraphNode(Node gNode) { if (!containsCoreseNode(gNode)) { - //graph.put(gNode.getLabel(), gNode); + // graph.put(gNode.getLabel(), gNode); graph.put(getID(gNode), gNode); indexNode(gNode.getValue(), gNode); } } public boolean containsCoreseNode(Node node) { - //return graph.containsKey(node.getLabel()); + // return graph.containsKey(node.getLabel()); return graph.containsKey(getID(node)); } @@ -2148,10 +2157,10 @@ public Iterable iterate(Node s, Node p, Node o, List from) { public Iterable insert(Node s, Node p, Node o, List contexts) { if (contexts == null || contexts.isEmpty()) { - Edge edge = insert(s, p, o); + insert(s, p, o); } else { for (Node g : contexts) { - Edge edge = insert(g, s, p, o); + insert(g, s, p, o); } } return emptyEdgeList; @@ -2159,10 +2168,10 @@ public Iterable insert(Node s, Node p, Node o, List contexts) { public Iterable delete(Node s, Node p, Node o, List contexts) { if (contexts == null || contexts.isEmpty()) { - List edge = delete(s, p, o); + delete(s, p, o); } else { for (Node g : contexts) { - List edge = delete(g, s, p, o); + delete(g, s, p, o); } } return emptyEdgeList; @@ -2270,7 +2279,7 @@ public Iterable getAllEdges(Node predicate, Node node, Node node2, int n) } } if (meta.isEmpty()) { - return new ArrayList(); + return new ArrayList<>(); } return meta; } @@ -2318,7 +2327,7 @@ public boolean hasEdge(Node node, int i) { } public List getList(Node node) { - List list = new ArrayList(); + List list = new ArrayList<>(); list(node, list); return list; } @@ -2375,15 +2384,15 @@ public ArrayList reclist(Node node) { Edge first = getEdge(RDF.FIRST, node, 0); Edge rest = getEdge(RDF.REST, node, 0); if (first == null || rest == null) { - return null; + return new ArrayList<>(); } ArrayList list = reclist(rest.getNode(1)); if (list == null) { - return null; + return new ArrayList<>(); } Node val = first.getNode(1); - if (val.isBlank() && !val.isTriple()) { + if ((val.isBlank() || val.getDatatypeValue().isSkolem()) && !val.isTriple()) { // may be a list ArrayList ll = reclist(val); if (ll == null) { @@ -2428,9 +2437,9 @@ public EdgeManagerIndexer getIndex(int n) { case ILIST: return ruleEdgeIndex; } -// if (n + 1 >= tables.size()) { -// //setIndex(n, new EdgeIndex(this, n)); -// } + // if (n + 1 >= tables.size()) { + // //setIndex(n, new EdgeIndex(this, n)); + // } return getIndexList().get(n); } @@ -2450,7 +2459,7 @@ public Iterable getEdges(Node node, int n) { // without NodeManager public Iterable getSortedEdgesBasic(Node node, int n) { - MetaIterator meta = new MetaIterator(); + MetaIterator meta = new MetaIterator<>(); for (Node pred : getSortedProperties()) { Iterable it = getIndex(n).getEdges(pred, node); @@ -2459,7 +2468,7 @@ public Iterable getSortedEdgesBasic(Node node, int n) { } } if (meta.isEmpty()) { - return new ArrayList(); + return new ArrayList<>(); } return meta; } @@ -2610,19 +2619,19 @@ public Iterable getNodes() { } public Iterable getBlankNodes() { - return blank.values(); + return nodeBlank.values(); } public Iterable getTripleNodes() { return triple.values(); } - public Hashtable getTripleNodeMap() { + public Map getTripleNodeMap() { return triple; } /** - * resource & blank TODO: a node may have been deleted (by a delete triple) + * resource & blank TODO: a node may have been deleted (by a delete triple) * but still be in the table */ public Iterable getRBNodes() { @@ -2673,7 +2682,7 @@ public Iterable getAllNodeIterator2() { * not exactly graph vertex with rdf star * * @note: consider nodes from nested triple - * although they are just quoted + * although they are just quoted */ public Iterable getNodeIterator() { MetaIterator meta = new MetaIterator<>(); @@ -2811,7 +2820,7 @@ void index(IDatatype dt, Node node) { } } - //check if store dt to file + // check if store dt to file boolean storable(IDatatype dt) { // check storage manager @@ -2907,7 +2916,7 @@ public boolean compare(Graph g2, boolean isGraph, boolean detail) { public List split() { if (graph.size() == 1) { - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList<>(); list.add(this); return list; } @@ -2924,7 +2933,7 @@ List gSplit() { g.addEdgeWithNode(ent); } - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList<>(); for (Graph g : map.values()) { list.add(g); } @@ -2934,7 +2943,7 @@ List gSplit() { } public List getEdgeList(Node n) { - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList<>(); for (Edge e : getEdges(n, 0)) { list.add(e); } @@ -2945,7 +2954,7 @@ public List getEdgeList(Node n) { * Without rule entailment */ public List getEdgeListSimple(Node n) { - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList<>(); for (Edge e : getEdges(n, 0)) { if (!getProxy().isRule(e)) { list.add(e); @@ -2980,8 +2989,8 @@ public List delete(Edge edge) { } if (res != null) { - logger.info("" + edge); - logger.info("" + res); + logger.info("{}", edge); + logger.info("{}", res); deleted(res); } return res; @@ -3007,8 +3016,8 @@ public List delete(Edge edge, List from) { } if (res != null) { - logger.info("" + edge.getEdgeLabel()); - logger.info("" + res); + logger.info("Edge label: {}", edge.getEdgeLabel()); + logger.info("Result: {}", res); deleted(res); } return res; @@ -3096,7 +3105,7 @@ public void clear() { void clearNodes() { individual.clear(); - blank.clear(); + nodeBlank.clear(); triple.clear(); getLiteralNodeManager().clear(); property.clear(); @@ -3369,10 +3378,7 @@ public List delete(IDatatype source, IDatatype subject, IDatatype predicat public Edge addEdge(Node source, Node subject, Node predicate, Node value) { Edge e = fac.create(source, subject, predicate, value); Edge ee = addEdge(e); - if (ee != null) { - return ee; - } - return null; + return ee; } public Edge addEdge(Node subject, Node predicate, Node value) { @@ -3389,11 +3395,8 @@ public Edge addEdge(Node source, Node predicate, List list) { e = fac.create(source, predicate, list); } - Edge ee = addEdge(e); - if (ee != null) { - return ee; - } - return null; + e = addEdge(e); + return e; } /** @@ -3534,10 +3537,12 @@ public String reference(Node n) { return String.format("b%s", dt.getLabel()); } // dates may also have same index but different labels, see isDate() above - // date with Z and date with +00:00 have same index (same value) but different labels + // date with Z and date with +00:00 have same index (same value) but different + // labels // they should have different ID if (dt.isDate()) { - if (DatatypeMap.getTZ(dt).equals("Z")) { + Object tz = DatatypeMap.getTZ(dt); + if (tz != null && "Z".equals(tz.toString())) { return String.format("d%s", n.getIndex()); } } @@ -3782,8 +3787,8 @@ public boolean isFormerMetadata() { /** * @Draft For each triple pattern: Search if there exists graph name, - * subject, property, object in the graph with similar URI - * mode=message¶m=sv:distance~n => levenshtein distance <= n + * subject, property, object in the graph with similar URI + * mode=message¶m=sv:distance~n => levenshtein distance <= n */ public JSONObject match(ASTQuery ast) { return match(ast, 1); @@ -3868,11 +3873,12 @@ public TreeNode() { TreeNode(boolean entailment) { super((entailment) ? // with datatype entailment - // index(1) = index(01) = index(1.0) - // same value => same index - // integer|decimal vs integer|decimal => same index - // integer|decimal vs double|float => different index - new CompareWithDatatypeEntailment() : + // index(1) = index(01) = index(1.0) + // same value => same index + // integer|decimal vs integer|decimal => same index + // integer|decimal vs double|float => different index + new CompareWithDatatypeEntailment() + : // without datatype entailment // index(1) = index(01) != index(1.0) // different datatype => different index @@ -3889,7 +3895,8 @@ boolean contains(Node node) { } /** - * Comparator for Node allocation where 1 and 01 have different Node with same Node index + * Comparator for Node allocation where 1 and 01 have different Node with same + * Node index * This Comparator enables to retrieve an occurrence of a given Literal * already existing in graph in such a way that two occurrences of same * Literal be represented by same Node It represents (1 integer) and (01 diff --git a/src/main/java/fr/inria/corese/core/GraphCompare.java b/src/main/java/fr/inria/corese/core/GraphCompare.java index 5a6e6a386..d1172671a 100644 --- a/src/main/java/fr/inria/corese/core/GraphCompare.java +++ b/src/main/java/fr/inria/corese/core/GraphCompare.java @@ -12,7 +12,7 @@ * @author Olivier Corby, Wimmics INRIA I3S, 2016 */ public class GraphCompare { - private static Logger logger = LoggerFactory.getLogger(GraphCompare.class); + private static final Logger logger = LoggerFactory.getLogger(GraphCompare.class); Graph g1, g2; @@ -101,7 +101,7 @@ public boolean compare(boolean isGraph, boolean detail) { */ boolean compare(Graph g2, Node pred2, TBN t, Edge ent1, boolean isGraph) { Iterable l2 = g2.getEdges(pred2); - Iterator it = l2.iterator(); + for (Edge ent2 : l2) { if (compare(ent1, ent2, t, isGraph)) { return true; diff --git a/src/main/java/fr/inria/corese/core/GraphDistance.java b/src/main/java/fr/inria/corese/core/GraphDistance.java index a42ebc153..b2c6f16e2 100644 --- a/src/main/java/fr/inria/corese/core/GraphDistance.java +++ b/src/main/java/fr/inria/corese/core/GraphDistance.java @@ -16,30 +16,29 @@ public class GraphDistance { private Graph graph; private JSONObject json; private NSManager nsm; - public enum Mode {URI, NAME, DEFAULT}; private Mode mode = Mode.DEFAULT; - + public GraphDistance(Graph g) { graph = g; setJson(new JSONObject()); } - + public GraphDistance(Graph g, Mode m) { this(g); setMode(m); } - + public JSONObject match(ASTQuery ast) { return match(ast, DISTANCE); } - + public JSONObject match(ASTQuery ast, int distance) { setNsm(ast.getNSM()); - for (Constant node : ast.getConstantNodeList()) { + for (Constant node : ast.getConstantNodeList()) { if (node.isURI() && getGraph().getNode(node.getDatatypeValue()) == null) { match(getGraph().getNodes(), node.getDatatypeValue(), distance); - } + } } for (Constant name : ast.getPredicateList()) { @@ -47,123 +46,117 @@ public JSONObject match(ASTQuery ast, int distance) { match(getGraph().getProperties(), name.getDatatypeValue(), distance); } } - + for (Constant name : ast.getConstantGraphList()) { if (getGraph().getGraphNode(name.getLabel()) == null) { match(getGraph().getGraphNodes(), name.getDatatypeValue(), distance); } } - + return getJson(); } - - + void match(Iterable it, IDatatype dt, int distance) { String label = dt.getLabel(); - String name = getNsm().nstrip(label); + String name = NSManager.nstrip(label); int minLabel = Integer.MAX_VALUE; - double minName = Double.MAX_VALUE; + double minName = Double.MAX_VALUE; String closeLabel = label; - String closeName = label; - + String closeName = label; + for (var node : it) { int dist = urlDistance(label, node.getLabel()); - + if (dist == 0) { return; } - + if (dist < minLabel) { minLabel = dist; closeLabel = node.getLabel(); } - - String name2 = getNsm().nstrip(node.getLabel()); + + String name2 = NSManager.nstrip(node.getLabel()); double dist2 = nameDistance(name, name2); - + if (dist2 < minName) { minName = dist2; closeName = node.getLabel(); - } + } } - + switch (getMode()) { - case NAME: + case NAME: if (minName <= distance) { getJson().put(label, closeName); } break; - + case URI: if (minLabel <= distance) { getJson().put(label, closeLabel); } break; - + case DEFAULT: if (minName < minLabel) { getJson().put(label, closeName); - } - else if (!closeLabel.equals(label)) { + } else if (!closeLabel.equals(label)) { getJson().put(label, closeLabel); - } - } + } + } } - public int distance (String l1, String l2) { + public int distance(String l1, String l2) { return LevenshteinDistance.getDefaultInstance().apply(l1, l2); - } + } // levenshtein distance - public int urlDistance (String l1, String l2) { + public int urlDistance(String l1, String l2) { return distance(l1, l2); - } - + } + boolean containWithoutCase(String l1, String l2) { return containWithCase(l1.toLowerCase(), l2.toLowerCase()); } - + boolean containWithCase(String l1, String l2) { return l1.contains(l2) || l2.contains(l1); } - + // ameliorated levenshtein distance - public double nameDistance (String l1, String l2) { + public double nameDistance(String l1, String l2) { if (l1.equals(l2)) { return 0; } // same name without case: better than any other distance - if (l1.toLowerCase().equals(l2.toLowerCase())) { + if (l1.equalsIgnoreCase(l2)) { return 0.3; } // distance when one name contain other name is less than // same distance when no one contain the other - // prefLabel: label considered better than prepare + // prefLabel: label considered better than prepare if (containWithoutCase(l1, l2)) { return distance(l1.toLowerCase(), l2.toLowerCase()) - 0.3; } return distance(l1, l2); - } - - - + } + public JSONObject cardinality(ASTQuery ast) { JSONObject json = new JSONObject(); - + for (Constant name : ast.getPredicateList()) { Node pred = getGraph().getPropertyNode(name.getLabel()); if (pred == null) { json.put(name.getLabel(), 0); - } - else { + } else { json.put(name.getLabel(), getGraph().getIndex().size(pred)); } } - + return json; } - public Graph getGraph() { return graph; @@ -196,5 +189,7 @@ public Mode getMode() { public void setMode(Mode mode) { this.mode = mode; } - + + public enum Mode {URI, NAME, DEFAULT} + } diff --git a/src/main/java/fr/inria/corese/core/GraphObject.java b/src/main/java/fr/inria/corese/core/GraphObject.java index 548fa4ce8..234a9a2cc 100644 --- a/src/main/java/fr/inria/corese/core/GraphObject.java +++ b/src/main/java/fr/inria/corese/core/GraphObject.java @@ -8,9 +8,7 @@ import fr.inria.corese.core.kgram.core.PointerObject; /** - * * @author Olivier Corby, Wimmics INRIA I3S, 2015 - * */ public class GraphObject extends PointerObject { diff --git a/src/main/java/fr/inria/corese/core/Index.java b/src/main/java/fr/inria/corese/core/Index.java index b5fba6774..9bd2ba0a6 100644 --- a/src/main/java/fr/inria/corese/core/Index.java +++ b/src/main/java/fr/inria/corese/core/Index.java @@ -1,114 +1,114 @@ package fr.inria.corese.core; - import fr.inria.corese.core.index.NodeManager; import fr.inria.corese.core.index.PredicateList; +import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.api.core.Node; + import java.util.List; -import fr.inria.corese.core.kgram.api.core.Edge; /** - * Interface for Index for Graph - * - * @author Olivier Corby, Edelweiss INRIA 2010 + * Interface for Index for Graph * + * @author Olivier Corby, Edelweiss INRIA 2010 */ public interface Index { - - String toRDF(); - - int getIndex(); - - int size(); - - int cardinality(); - - int duplicate(); - - void index(); - - void compact(); - - void index(Node pred); - - void indexNode(); - - void indexNodeManager(); - - void setByIndex(boolean b); - - void declareUpdate(boolean b); - - Iterable getProperties(); - - Iterable getSortedProperties(); - PredicateList getSortedPredicates(); - - int nbProperties(); - - boolean same(Node n1, Node n2); - - Edge add(Edge edge); - - Edge add(Edge edge, boolean duplicate); - - void add(Node p, List list); - - Edge delete(Edge edge); - - Edge delete(Node pred, Edge edge); - - void delete(Node pred); - - Edge find(Edge edge); - - boolean exist(Edge edge); - - boolean exist(Node p, Node n1, Node n2); - - void declare(Edge edge); - - void declare(Edge edge, boolean duplicate); - - int size(Node pred); - - Iterable getSortedEdges(Node node); - - Iterable getEdges(); - - Iterable get(Node pred); - - Iterable getEdges(Node pred, Node node); - - Iterable getEdges(Node pred, Node node, int position); - - Iterable getEdges(Node pred, Node node, Node node2); - - NodeManager getNodeManager(); - - void finishUpdate(); - - // ************** Update - - - void clear(); - - void clean(); - - void clearCache(); - - void clearIndex(Node pred); - - void clear(Node gNode); - - void copy(Node g1, Node g2); - - void add(Node g1, Node g2); - - void move(Node g1, Node g2); - - void setDuplicateEntailment(boolean value); + + String toRDF(); + + int getIndex(); + + int size(); + + int cardinality(); + + int duplicate(); + + void index(); + + void compact(); + + void index(Node pred); + + void indexNode(); + + void indexNodeManager(); + + void setByIndex(boolean b); + + void declareUpdate(boolean b); + + Iterable getProperties(); + + Iterable getSortedProperties(); + + PredicateList getSortedPredicates(); + + int nbProperties(); + + boolean same(Node n1, Node n2); + + Edge add(Edge edge); + + Edge add(Edge edge, boolean duplicate); + + void add(Node p, List list); + + Edge delete(Edge edge); + + Edge delete(Node pred, Edge edge); + + void delete(Node pred); + + Edge find(Edge edge); + + boolean exist(Edge edge); + + boolean exist(Node p, Node n1, Node n2); + + void declare(Edge edge); + + void declare(Edge edge, boolean duplicate); + + int size(Node pred); + + Iterable getSortedEdges(Node node); + + Iterable getEdges(); + + Iterable get(Node pred); + + Iterable getEdges(Node pred, Node node); + + Iterable getEdges(Node pred, Node node, int position); + + Iterable getEdges(Node pred, Node node, Node node2); + + NodeManager getNodeManager(); + + void finishUpdate(); + + // ************** Update + + + void clear(); + + void clean(); + + void clearCache(); + + void clearIndex(Node pred); + + void clear(Node gNode); + + void copy(Node g1, Node g2); + + void add(Node g1, Node g2); + + void move(Node g1, Node g2); + + void setDuplicateEntailment(boolean value); } diff --git a/src/main/java/fr/inria/corese/core/NodeGraph.java b/src/main/java/fr/inria/corese/core/NodeGraph.java index 5ef5c5880..390e668ce 100644 --- a/src/main/java/fr/inria/corese/core/NodeGraph.java +++ b/src/main/java/fr/inria/corese/core/NodeGraph.java @@ -5,9 +5,8 @@ /** * Node that contain the named graph of node, only for PP query. - * - * @author Olivier Corby, Wimmics INRIA I3S, 2018 * + * @author Olivier Corby, Wimmics INRIA I3S, 2018 */ public class NodeGraph extends NodeImpl { Node node, graph; @@ -15,22 +14,22 @@ public class NodeGraph extends NodeImpl { public NodeGraph(IDatatype val) { super(val); } - + public NodeGraph(Node node, Node graph) { this(node.getDatatypeValue()); this.node = node; this.graph = graph; setIndex(node.getIndex()); } - + @Override public Node getNode() { return node; } - - @Override + + @Override public Node getGraph() { return graph; } - + } diff --git a/src/main/java/fr/inria/corese/core/NodeGraphIndex.java b/src/main/java/fr/inria/corese/core/NodeGraphIndex.java index 190210369..c7a1d5072 100644 --- a/src/main/java/fr/inria/corese/core/NodeGraphIndex.java +++ b/src/main/java/fr/inria/corese/core/NodeGraphIndex.java @@ -1,28 +1,20 @@ package fr.inria.corese.core; -import java.util.ArrayList; -import java.util.HashMap; - import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.tool.DistinctNode; import fr.inria.corese.core.kgram.tool.MetaIterator; +import java.util.ArrayList; +import java.util.HashMap; + /** - * * Manage Nodes of a graph, for each graph name * * @author Olivier Corby, Wimmics INRIA 2018 - * */ public class NodeGraphIndex { - class NodeTable extends HashMap { - } - - class GraphTable extends HashMap { - } - GraphTable table; NodeGraphIndex() { @@ -57,7 +49,7 @@ void add(Node graph, Node node) { gt.put(node, new NodeGraph(node, graph)); } } - + boolean contains(Node graph, Node node) { NodeTable gt = table.get(graph); if (gt == null) { @@ -93,7 +85,7 @@ public Iterable getNodes() { } return meta; } - + // return iterable of NodeGraph(node, graph) // MUST perform n.getNode() to get the node // return distinct nodes @@ -101,9 +93,14 @@ public Iterable getDistinctNodes() { return new DistinctNode(getNodes()); } - public HashMap getGraphTable() { return table; } + class NodeTable extends HashMap { + } + + class GraphTable extends HashMap { + } + } diff --git a/src/main/java/fr/inria/corese/core/NodeImpl.java b/src/main/java/fr/inria/corese/core/NodeImpl.java index 755691525..e8cbd641c 100755 --- a/src/main/java/fr/inria/corese/core/NodeImpl.java +++ b/src/main/java/fr/inria/corese/core/NodeImpl.java @@ -1,22 +1,20 @@ package fr.inria.corese.core; -import fr.inria.corese.core.sparql.api.IDatatype; +import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.api.core.TripleStore; -import java.util.Objects; -import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.path.Path; +import fr.inria.corese.core.sparql.api.IDatatype; + +import java.util.Objects; /** * Node * * @author Olivier Corby, Edelweiss INRIA 2010 - * */ -public class NodeImpl extends GraphObject implements Node - //, Comparable -{ +public class NodeImpl extends GraphObject implements Node { // true means graph nodes are IDatatype instead of NodeImpl // todo: duplicate IDatatype when insert node in new graph, e.g. construct @@ -25,12 +23,13 @@ public class NodeImpl extends GraphObject implements Node int index = -1; IDatatype dt; - public NodeImpl() {} - + public NodeImpl() { + } + NodeImpl(IDatatype val) { dt = val; } - + NodeImpl(IDatatype val, Graph g) { graph = g; dt = val; @@ -49,7 +48,7 @@ public static Node create(IDatatype val, Graph g) { } return new NodeImpl(val, g); } - + static Node createDatatype(IDatatype val, Graph g) { if (val.getTripleStore() != null && val.getTripleStore() != g) { val = val.copy(); @@ -65,7 +64,7 @@ public String toString() { @Override public int compare(Node node) { - return getValue().compareTo( node.getValue()); + return getValue().compareTo(node.getValue()); } @Override @@ -73,6 +72,11 @@ public int getIndex() { return index; } + @Override + public void setIndex(int n) { + index = n; + } + @Override public String getLabel() { return getValue().getLabel(); @@ -82,12 +86,12 @@ public String getLabel() { public IDatatype getValue() { return dt; } - + @Override public IDatatype getDatatypeValue() { return dt; } - + @Override public void setDatatypeValue(IDatatype dt) { this.dt = dt; @@ -107,20 +111,20 @@ public boolean isConstant() { public boolean isVariable() { return false; } - + @Override - public boolean isFuture(){ + public boolean isFuture() { return dt.isFuture(); } @Override public boolean same(Node node) { - return getValue().sameTerm( node.getValue()); + return getValue().sameTerm(node.getValue()); } - - @Override + + @Override public boolean match(Node node) { - return getValue().match( node.getValue()); + return getValue().match(node.getValue()); } @Override @@ -134,16 +138,7 @@ public boolean equals(Object obj) { @Override public int hashCode() { - return Objects.hashCode(this.dt); -// int hash = 7; -// // hash = 67 * hash + (this.key != null ? this.key.hashCode() : 0); -// hash = 67 * hash + (this.dt != null ? this.dt.hashCode() : 0); -// return hash; - } - - @Override - public void setIndex(int n) { - index = n; + return Objects.hashCode(this.dt); } @Override @@ -163,31 +158,20 @@ public Node getNode() { @Override public Object getNodeObject() { - return dt.getNodeObject(); + return dt.getNodeObject(); } @Override public void setObject(Object o) { dt.setObject(o); } - + @Override - public Path getPath() { + public Path getPath() { return dt.getPath(); } -// @Override -// public Object getProperty(int p) { -// return null; -// } -// -// @Override -// public void setProperty(int p, Object o) { -// } - - - @Override public String getKey() { return null; @@ -195,7 +179,7 @@ public String getKey() { @Override public void setKey(String str) { - + } @@ -208,9 +192,4 @@ public Iterable getLoop() { public TripleStore getTripleStore() { return graph; } - -// @Override -// public int compareTo(NodeImpl o) { -// return o.dt.compareTo(dt); -// } } diff --git a/src/main/java/fr/inria/corese/core/NodeIterator.java b/src/main/java/fr/inria/corese/core/NodeIterator.java index e039f5e6f..129cdecc1 100644 --- a/src/main/java/fr/inria/corese/core/NodeIterator.java +++ b/src/main/java/fr/inria/corese/core/NodeIterator.java @@ -1,47 +1,46 @@ package fr.inria.corese.core; -import java.util.Iterator; - -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.api.core.Edge; +import fr.inria.corese.core.kgram.api.core.Node; + +import java.util.Iterator; public class NodeIterator implements Iterable, Iterator { - - Iterable ie; - Iterator it; - int index; - - NodeIterator(Iterable it, int n){ - ie = it; - index = n; - } - - public static NodeIterator create(Iterable it, int n){ - return new NodeIterator(it, n); - } - - @Override - public Iterator iterator() { - it = ie.iterator(); - return this; - } - - @Override - public boolean hasNext() { - return it.hasNext(); - } - - @Override - public Node next() { - Edge ent = it.next(); - if (ent == null) return null; - return ent.getNode(index); - } - - @Override - public void remove() { - } - - + + Iterable ie; + Iterator it; + int index; + + NodeIterator(Iterable it, int n) { + ie = it; + index = n; + } + + public static NodeIterator create(Iterable it, int n) { + return new NodeIterator(it, n); + } + + @Override + public Iterator iterator() { + it = ie.iterator(); + return this; + } + + @Override + public boolean hasNext() { + return it.hasNext(); + } + + @Override + public Node next() { + Edge ent = it.next(); + if (ent == null) return null; + return ent.getNode(index); + } + + @Override + public void remove() { + } + } diff --git a/src/main/java/fr/inria/corese/core/Serializer.java b/src/main/java/fr/inria/corese/core/Serializer.java index a3040800b..0a09488f9 100644 --- a/src/main/java/fr/inria/corese/core/Serializer.java +++ b/src/main/java/fr/inria/corese/core/Serializer.java @@ -2,9 +2,8 @@ /** * Serialize a Java Object in RDF Turtle - * - * @author Olivier Corby, Wimmics INRIA I3S, 2014 * + * @author Olivier Corby, Wimmics INRIA I3S, 2014 */ public class Serializer { @@ -29,16 +28,16 @@ public void appendNL(Object s1, Object s2) { append(s1, s2); append(NL); } - - public void nl(){ + + public void nl() { sb.append(NL); } - + public void appendNL(Object s1) { sb.append(s1); sb.append(NL); } - + public void appendPNL(Object s1) { sb.append(s1); append(" ; "); @@ -49,17 +48,17 @@ public void appendPNL(Object s1, Object s2) { append(s1, s2); append(" ;", NL); } - - public void appendP(Object s1, Object s2) { + + public void appendP(Object s1, Object s2) { append(s1, s2); append(" ; "); } - - public void open(String type){ + + public void open(String type) { appendPNL("[] a ", type); } - - public void close(){ + + public void close() { appendNL("."); } diff --git a/src/main/java/fr/inria/corese/core/Start.java b/src/main/java/fr/inria/corese/core/Start.java deleted file mode 100644 index aadcbcf1b..000000000 --- a/src/main/java/fr/inria/corese/core/Start.java +++ /dev/null @@ -1,233 +0,0 @@ -package fr.inria.corese.core; - -import java.util.Date; -import java.util.ArrayList; - -import fr.inria.corese.core.sparql.exceptions.EngineException; -import fr.inria.corese.core.sparql.triple.parser.NSManager; -import fr.inria.corese.core.kgram.core.Mappings; -import fr.inria.corese.core.query.QueryProcess; -import fr.inria.corese.core.rule.RuleEngine; -import fr.inria.corese.core.load.Load; -import fr.inria.corese.core.load.LoadException; -import fr.inria.corese.core.load.QueryLoad; -import fr.inria.corese.core.print.ResultFormat; -import fr.inria.corese.core.shacl.Shacl; -import fr.inria.corese.core.transform.Transformer; -import fr.inria.corese.core.sparql.api.IDatatype; -import fr.inria.corese.core.sparql.datatype.DatatypeMap; -import fr.inria.corese.core.sparql.triple.function.term.Binding; -import fr.inria.corese.core.sparql.triple.parser.Access; -import java.util.logging.Level; -import java.util.logging.Logger; - -public class Start { - - ArrayList load = new ArrayList<>(); - ArrayList query = new ArrayList<>(); - ArrayList loadquery = new ArrayList<>(); - ArrayList sttl = new ArrayList<>(); - ArrayList shacl = new ArrayList<>(); - NSManager nsm = NSManager.create(); - boolean debugRule = false; - boolean rdfs = false; - boolean owl = false; - boolean display = true; - boolean verbose = false; - boolean execShacl = false; - String param = null; - - /** - * Corese as command line take path and query as argument load the docs from - * path java -cp corese.jar fr.inria.corese.core.Start -load - * dataset.rdf -query "select * where {?x ?p ?y}" java -cp - * kggui-3.2.1-SNAPSHOT-jar-with-dependencies.jar - * fr.inria.corese.kgtool.Start -load rdf: -sttl st:turtle st:rdfxml - * st:json - * - */ - public static void main(String[] args) throws LoadException { - Start st = new Start(); - st.process(args); - st.start(); - } - - void process(String[] args) { - int i = 0; - while (i < args.length) { - if (args[i].equals("-rdfs")) { - i++; - rdfs = true; - } - else if (args[i].equals("-owl")) { - i++; - owl = true; - } - else if (args[i].equals("-load")) { - i++; - while (i < args.length && !args[i].startsWith("-")) { - load.add(expand(args[i++])); - } - } else if (args[i].equals("-query")) { - i++; - while (i < args.length && !args[i].startsWith("-")) { - query.add(args[i++]); - } - } - else if (args[i].equals("-loadquery")) { - i++; - while (i < args.length && !args[i].startsWith("-")) { - loadquery.add(args[i++]); - } - } - else if (args[i].equals("-sttl")) { - i++; - while (i < args.length && !args[i].startsWith("-")) { - sttl.add(expand(args[i++])); - } - } - else if (args[i].equals("-shacl")) { - i++; - while (i < args.length && !args[i].startsWith("-")) { - shacl.add(expand(args[i++])); - } - } - else if (args[i].equals("-execshacl")) { - execShacl = true; - i++; - } - else if (args[i].equals("-su")) { - Access.skip(true); - i++; - } - else if (args[i].equals("-var")) { - i++; - // -arg var=val;var=val - // global var for SPARQL query LDSCript - param = args[i++]; - } - else if (args[i].equals("-s") || args[i].equals("-silent")) { - i++; - display = false; - } - } - } - - String expand(String str) { - return nsm.toNamespaceBN(str); - } - - void start() throws LoadException { - Date d1 = new Date(); - Graph g = Graph.create(rdfs); - Load ld = Load.create(g); - - for (String doc : load) { - try { - ld.parseDir(doc); - } catch (LoadException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - - if (owl){ - RuleEngine re = RuleEngine.create(g); - re.setProfile(RuleEngine.OWL_RL); - try { - re.process(); - } catch (EngineException ex) { - Logger.getLogger(Start.class.getName()).log(Level.SEVERE, null, ex); - } - } - - Date d2 = new Date(); - try { - QueryProcess exec = QueryProcess.create(g); - - for (String q : query) { - Mappings map = exec.query(q, param(param)); - ResultFormat f = ResultFormat.create(map); - if (display) { - System.out.println(f); - } - } - - for (String file : loadquery) { - QueryLoad ql = QueryLoad.create(); - String q = ql.readWE(file); - if (verbose) { - System.out.println(q); - System.out.println(); - } - Mappings map = exec.query(q, param(param)); - ResultFormat f = ResultFormat.create(map); - System.out.println(f); - } - - } catch (EngineException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - for (String shape : shacl) { - try { - shacl(g, shape); - } catch (EngineException ex) { - Logger.getLogger(Start.class.getName()).log(Level.SEVERE, null, ex); - } - } - - if (execShacl) { - try { - execShacl(g); - - } catch (EngineException ex) { - Logger.getLogger(Start.class.getName()).log(Level.SEVERE, null, ex); - } - } - - for (String stl : sttl) { - Transformer t = Transformer.create(g, stl); - try { - System.out.println(t.transform()); - } catch (EngineException ex) { - Logger.getLogger(Start.class.getName()).log(Level.SEVERE, null, ex); - } - } - } - - // var=val;var=val - Binding param(String param) { - Binding b = Binding.create(); - if (param != null) { - String[] list = param.split(";"); - - for (String elem : list) { - String[] decl = elem.split("="); - String var = decl[0]; - if (!var.startsWith("?")) { - var = "?".concat(var); - } - b.setVariable(var, DatatypeMap.newInstance(decl[1])); - } - } - return b; - } - - void shacl(Graph g, String shape) throws LoadException, EngineException { - Shacl sh = new Shacl(g); - Graph gg = Graph.create(); - Load load = Load.create(gg); - load.parse(shape); - Graph res = sh.eval(gg); - System.out.println("shacl: " + shape); - System.out.println(Transformer.turtle(res)); - } - - void execShacl(Graph g) throws LoadException, EngineException { - Shacl sh = new Shacl(g); - Graph res = sh.eval(); - System.out.println(Transformer.turtle(res)); - } -} diff --git a/src/main/java/fr/inria/corese/core/ValueResolverImpl.java b/src/main/java/fr/inria/corese/core/ValueResolverImpl.java index 41fdbb6ed..7063e7e33 100644 --- a/src/main/java/fr/inria/corese/core/ValueResolverImpl.java +++ b/src/main/java/fr/inria/corese/core/ValueResolverImpl.java @@ -1,25 +1,24 @@ package fr.inria.corese.core; -import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.api.ValueResolver; +import fr.inria.corese.core.sparql.api.IDatatype; +import org.slf4j.LoggerFactory; + import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.HashMap; -import org.slf4j.LoggerFactory; -//import javax.xml.bind.annotation.adapters.HexBinaryAdapter; /** * Manage Node values in a table: key -> IDatatype key is MD5 hash of IDatatype * label * * @author Olivier Corby, Wimmics Inria I3S, 2013 - * */ public class ValueResolverImpl implements ValueResolver { + private final String NAME = "MD5"; HashMap tvalues; MessageDigest hasher; - private String NAME = "MD5"; int count = 0; public ValueResolverImpl() { @@ -31,8 +30,7 @@ public ValueResolverImpl() { } } - - + @Override public int size() { return tvalues.size(); @@ -47,20 +45,18 @@ public IDatatype getValue(String key) { public void setValue(String key, IDatatype dt) { tvalues.put(key, dt); } - + @Override public String getKey(IDatatype dt) { String str = dt.getID(); String key = getKey(str); return key.intern(); } - + @Override synchronized public String getKey(String str) { byte[] hash = hasher.digest(str.getBytes()); - - // String tmp = (new HexBinaryAdapter()).marshal(hash); - + StringBuilder hashString = new StringBuilder(); for (int i = 0; i < hash.length; i++) { String hex = Integer.toHexString(hash[i]); @@ -73,26 +69,18 @@ synchronized public String getKey(String str) { } String res = hashString.toString(); - count++; - // System.out.println("VR: " + res.equals(tmp) + " " + res + " " + tmp); + count++; return res; } - - - - - - - - + + public int getCount() { return count; } synchronized public byte[] hashByte(String str) { - byte[] hash = hasher.digest(str.getBytes()); - return hash; + return hasher.digest(str.getBytes()); } } diff --git a/src/main/java/fr/inria/corese/core/Workflow.java b/src/main/java/fr/inria/corese/core/Workflow.java index af04d3e26..5cfcfbc62 100644 --- a/src/main/java/fr/inria/corese/core/Workflow.java +++ b/src/main/java/fr/inria/corese/core/Workflow.java @@ -1,37 +1,34 @@ package fr.inria.corese.core; -import java.util.ArrayList; -import java.util.List; - +import fr.inria.corese.core.api.Engine; import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.api.core.Node; -import fr.inria.corese.core.api.Engine; import fr.inria.corese.core.logic.Entailment; import fr.inria.corese.core.sparql.exceptions.EngineException; -import org.slf4j.LoggerFactory; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; /** - * * Manage a set of inference engines Loop until no inference is performed It is * automatically called when isUpdate==true to perform inference and restore * consistency - * */ public class Workflow implements Engine { - private static Logger logger = LoggerFactory.getLogger(Workflow.class); + private static final Logger logger = LoggerFactory.getLogger(Workflow.class); Graph graph; ArrayList engines; + boolean isIdle = true; + boolean isActivate = true; + boolean isClearEntailment = false; // RDFS entailment private Entailment inference; - boolean isDebug = false, - isIdle = true, - isActivate = true, - isClearEntailment = false; Workflow(Graph g) { - engines = new ArrayList(); + engines = new ArrayList<>(); graph = g; } @@ -50,10 +47,6 @@ public void removeEngine(Engine e) { engines.remove(e); } - public void setDebug(boolean b) { - isDebug = b; - } - public void setClearEntailment(boolean b) { isClearEntailment = b; } @@ -82,15 +75,15 @@ public synchronized boolean process(Engine e) throws EngineException { } return b; } - + boolean isAvailable() { - return isBasicAvailable() && engines.size() > 0; + return isBasicAvailable() && !engines.isEmpty(); } - - boolean isBasicAvailable() { - return isActivate && isIdle ; + + boolean isBasicAvailable() { + return isActivate && isIdle; } - + EventManager getEventManager() { return graph.getEventManager(); } @@ -115,7 +108,7 @@ boolean run() throws EngineException { isSuccess = true; count++; } - } + } } } @@ -127,17 +120,13 @@ boolean run() throws EngineException { * Run engine and submitted engines until no inference is performed */ boolean run(Engine e) throws EngineException { - int size = 0; + boolean isSuccess = false; int count = 2; while (count > 1) { count = 0; - if (isDebug) { - System.out.println("** W run: " + e.getClass().getName()); - } - if (e.isActivate()) { boolean b = e.process(); if (b) { @@ -199,26 +188,26 @@ public void remove() { } @Override - public void setActivate(boolean b) { - isActivate = b; + public boolean isActivate() { + return isActivate; } @Override - public boolean isActivate() { - return isActivate; + public void setActivate(boolean b) { + isActivate = b; } @Override - public int type() { - return WORKFLOW_ENGINE; + public Type type() { + return Type.WORKFLOW_ENGINE; } public void clear() { engines.clear(); } - public void removeEngine(int type) { - for (int i = 0; i < engines.size();) { + public void removeEngine(Type type) { + for (int i = 0; i < engines.size(); ) { if (engines.get(i).type() == type) { engines.remove(engines.get(i)); } else { @@ -227,7 +216,7 @@ public void removeEngine(int type) { } } - public void setActivate(int type, boolean b) { + public void setActivate(Type type, boolean b) { for (Engine e : engines) { if (e.type() == type) { diff --git a/src/main/java/fr/inria/corese/core/api/DataBroker.java b/src/main/java/fr/inria/corese/core/api/DataBroker.java index 65ce662eb..dc9f53f30 100644 --- a/src/main/java/fr/inria/corese/core/api/DataBroker.java +++ b/src/main/java/fr/inria/corese/core/api/DataBroker.java @@ -1,15 +1,15 @@ package fr.inria.corese.core.api; import fr.inria.corese.core.Graph; -import java.util.List; - import fr.inria.corese.core.NodeImpl; -import fr.inria.corese.core.logic.RDF; -import fr.inria.corese.core.storage.api.dataManager.DataManager; import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.core.Query; +import fr.inria.corese.core.logic.RDF; import fr.inria.corese.core.sparql.datatype.DatatypeMap; +import fr.inria.corese.core.storage.api.dataManager.DataManager; + +import java.util.List; /** * Broker between ProducerImpl and graph DataManager diff --git a/src/main/java/fr/inria/corese/core/api/DataBrokerConstruct.java b/src/main/java/fr/inria/corese/core/api/DataBrokerConstruct.java index 97a3951ea..5dd401172 100644 --- a/src/main/java/fr/inria/corese/core/api/DataBrokerConstruct.java +++ b/src/main/java/fr/inria/corese/core/api/DataBrokerConstruct.java @@ -1,8 +1,5 @@ package fr.inria.corese.core.api; -import java.util.ArrayList; -import java.util.List; - import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.core.Query; @@ -14,6 +11,9 @@ import fr.inria.corese.core.sparql.triple.parser.Constant; import fr.inria.corese.core.sparql.triple.update.Basic; +import java.util.ArrayList; +import java.util.List; + /** * Broker between GraphManager and graph DataManager for sparql query construct * and sparql update Refined by core.producer.DataBrokerConstructLocal for @@ -23,7 +23,6 @@ public interface DataBrokerConstruct extends DataBroker { default void startRuleEngine() { - // System.out.println("DataBrokerConstruct startRuleEngine"); } default void endRuleEngine() { @@ -59,7 +58,7 @@ default boolean exist(Node property, Node subject, Node object) { /** * Edge may be an rdf star triple, asserted or nested * RDF star triple design - * <> q v -> <> t q v + * <<s p o>> q v -> <<edge(s p o t)>> t q v * s p o {| q v |} -> edge(s p o t) t q v * g1 s p o t g2 s p o t * t is additional Node, similar to subject/object @@ -73,13 +72,13 @@ default boolean exist(Node property, Node subject, Node object) { * IDatatype dt = t.getDatatypeValue() * dt.isTriple() == true|false * dt.getEdge() = s p o t - * + *

* operation find, insert, delete may have as argument a rdf star edge * where subject/object may be a reference node and/or edge may have reference * node * DataManager must process these subject/object/reference using the api above - * for example: find/insert/delete t q v where t = <> - * Note that it can be recursive: t = <<<> r u>> + * for example: find/insert/delete t q v where t = <<s p o>> + * Note that it can be recursive: t = <<<<s p o>> r u>> * . */ diff --git a/src/main/java/fr/inria/corese/core/api/Engine.java b/src/main/java/fr/inria/corese/core/api/Engine.java index e3e22abd5..ba33ddf9d 100644 --- a/src/main/java/fr/inria/corese/core/api/Engine.java +++ b/src/main/java/fr/inria/corese/core/api/Engine.java @@ -5,41 +5,40 @@ import fr.inria.corese.core.sparql.exceptions.EngineException; /** - * * @author Olivier Corby, Wimmics INRIA 2012 */ public interface Engine { - - static final int UNDEF = -1; - static final int RDFS_ENGINE = 0; - static final int RULE_ENGINE = 1; - static final int QUERY_ENGINE = 2; - static final int WORKFLOW_ENGINE = 3; - - - // temporarily desactivate - void setActivate(boolean b); - - boolean isActivate(); - - void init(); - - // return true if some new entailment have been performed - boolean process() throws EngineException ; - - // remove entailments - void remove(); - - // some edges have been deleted - void onDelete(); - - // edge inserted - void onInsert(Node gNode, Edge edge); - - // graph have been cleared - void onClear(); - - int type(); + + public enum Type { + RDFS_ENGINE, + RULE_ENGINE, + QUERY_ENGINE, + WORKFLOW_ENGINE + } + + boolean isActivate(); + + // temporarily desactivate + void setActivate(boolean b); + + void init(); + + // return true if some new entailment have been performed + boolean process() throws EngineException; + + // remove entailments + void remove(); + + // some edges have been deleted + void onDelete(); + + // edge inserted + void onInsert(Node gNode, Edge edge); + + // graph have been cleared + void onClear(); + + Type type(); } diff --git a/src/main/java/fr/inria/corese/core/api/GraphListener.java b/src/main/java/fr/inria/corese/core/api/GraphListener.java index 937e3b1ee..0a064cb68 100644 --- a/src/main/java/fr/inria/corese/core/api/GraphListener.java +++ b/src/main/java/fr/inria/corese/core/api/GraphListener.java @@ -1,24 +1,32 @@ package fr.inria.corese.core.api; -import fr.inria.corese.core.kgram.core.Mappings; -import fr.inria.corese.core.kgram.core.Query; import fr.inria.corese.core.Graph; import fr.inria.corese.core.kgram.api.core.Edge; +import fr.inria.corese.core.kgram.core.Mappings; +import fr.inria.corese.core.kgram.core.Query; public interface GraphListener { - - default void addSource(Graph g) {} - - default boolean onInsert(Graph g, Edge ent) { return true; } - - default void insert(Graph g, Edge ent) {} - - default void delete(Graph g, Edge ent) {} - - default void start(Graph g, Query q) {} - - default void finish(Graph g, Query q, Mappings m) {} - - default void load(String path) {} + + default void addSource(Graph g) { + } + + default boolean onInsert(Graph g, Edge ent) { + return true; + } + + default void insert(Graph g, Edge ent) { + } + + default void delete(Graph g, Edge ent) { + } + + default void start(Graph g, Query q) { + } + + default void finish(Graph g, Query q, Mappings m) { + } + + default void load(String path) { + } } diff --git a/src/main/java/fr/inria/corese/core/api/IGraph.java b/src/main/java/fr/inria/corese/core/api/IGraph.java index f57957fc9..2b765197d 100644 --- a/src/main/java/fr/inria/corese/core/api/IGraph.java +++ b/src/main/java/fr/inria/corese/core/api/IGraph.java @@ -1,42 +1,41 @@ package fr.inria.corese.core.api; -import fr.inria.corese.core.sparql.api.IDatatype; -import fr.inria.corese.core.kgram.api.core.Edge; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Index; import fr.inria.corese.core.kgram.api.core.Edge; +import fr.inria.corese.core.kgram.api.core.Node; +import fr.inria.corese.core.sparql.api.IDatatype; public interface IGraph { - Iterable getIndexList(); + Iterable getIndexList(); - boolean hasEntailment(); + boolean hasEntailment(); - boolean isType(Edge edge); + boolean isType(Edge edge); - Iterable getEdges(Node predicate, Node node, Node node2, int n); + Iterable getEdges(Node predicate, Node node, Node node2, int n); - Iterable getEdges(Node predicate, Node node, int n); + Iterable getEdges(Node predicate, Node node, int n); - boolean isGraphNode(Node src); + boolean isGraphNode(Node src); - Node getGraphNode(String label); + Node getGraphNode(String label); - Node getPropertyNode(String name); + Node getPropertyNode(String name); - Iterable getProperties(); + Iterable getProperties(); - Node copy(Node node); + Node copy(Node node); - Iterable getNodes(Node gNode); + Iterable getNodes(Node gNode); - Iterable getAllNodes(); + Iterable getAllNodes(); - Iterable getGraphNodes(); + Iterable getGraphNodes(); - Node getNode(IDatatype dt, boolean b, boolean c); + Node getNode(IDatatype dt, boolean b, boolean c); - void init(); + void init(); } diff --git a/src/main/java/fr/inria/corese/core/api/Loader.java b/src/main/java/fr/inria/corese/core/api/Loader.java index 5fc7774be..a73d03808 100755 --- a/src/main/java/fr/inria/corese/core/api/Loader.java +++ b/src/main/java/fr/inria/corese/core/api/Loader.java @@ -1,11 +1,55 @@ package fr.inria.corese.core.api; -import fr.inria.corese.core.rule.RuleEngine; import fr.inria.corese.core.load.LoadException; +import fr.inria.corese.core.rule.RuleEngine; + import java.io.InputStream; public interface Loader { - public enum format { + String JSONLD_FORMAT_STR = "application/ld+json"; + String JSON_FORMAT_STR = "application/json"; + String RDFXML_FORMAT_STR = "application/rdf+xml"; + String NQUADS_FORMAT_STR = "text/n-quads"; + String TRIG_FORMAT_STR = "text/trig"; + String NT_FORMAT_STR = "text/n3"; + String TURTLE_FORMAT_STR = "text/turtle"; + String HTML_FORMAT_STR = "text/html"; + String ALL_FORMAT_STR = + "text/turtle;q=1.0, application/rdf+xml;q=0.9, application/ld+json;q=0.7, application/json;q=0.6"; + + void init(Object o); + + boolean isRule(String path); + + void parse(String path) throws LoadException; + + void parse(String path, String source) throws LoadException; + + void parse(String path, String source, String base, Loader.format format) throws LoadException; + + @Deprecated + void load(String path); + + @Deprecated + void load(String path, String source); + + @Deprecated + void load(String path, String base, String source, Loader.format format) throws LoadException; + + @Deprecated + void load(InputStream stream, String str) throws LoadException; + + @Deprecated + void loadWE(String path) throws LoadException; + + @Deprecated + void loadWE(String path, String source) throws LoadException; + + RuleEngine getRuleEngine(); + + format getFormat(String path); + + enum format { RDFXML_FORMAT, RDFA_FORMAT, TURTLE_FORMAT, @@ -22,49 +66,5 @@ public enum format { JSON_FORMAT } - static final String JSONLD_FORMAT_STR = "application/ld+json"; - static final String JSON_FORMAT_STR = "application/json"; - static final String RDFXML_FORMAT_STR = "application/rdf+xml"; - static final String NQUADS_FORMAT_STR = "text/n-quads"; - static final String TRIG_FORMAT_STR = "text/trig"; - static final String NT_FORMAT_STR = "text/n3"; - static final String TURTLE_FORMAT_STR = "text/turtle"; - static final String HTML_FORMAT_STR = "text/html"; - static final String ALL_FORMAT_STR = - "text/turtle;q=1.0, application/rdf+xml;q=0.9, application/ld+json;q=0.7, application/json;q=0.6"; - - void init(Object o); - - boolean isRule(String path); - - void parse(String path) throws LoadException; - - void parse(String path, String source) throws LoadException; - - void parse(String path, String source, String base, Loader.format format) throws LoadException; - - - @Deprecated - void load(String path); - - @Deprecated - void load(String path, String source); - - @Deprecated - void load(String path, String base, String source, Loader.format format) throws LoadException; - - @Deprecated - void load(InputStream stream, String str) throws LoadException; - - @Deprecated - void loadWE(String path) throws LoadException; - - @Deprecated - void loadWE(String path, String source) throws LoadException; - - RuleEngine getRuleEngine(); - - format getFormat(String path); - } diff --git a/src/main/java/fr/inria/corese/core/api/Log.java b/src/main/java/fr/inria/corese/core/api/Log.java index ec52beb67..ae00f6478 100644 --- a/src/main/java/fr/inria/corese/core/api/Log.java +++ b/src/main/java/fr/inria/corese/core/api/Log.java @@ -5,17 +5,17 @@ public interface Log { - enum Operation { - LOAD, QUERY, UPDATE - } - - void reset(); - - void log(Log.Operation type, Object obj); - - void log(Log.Operation type, Object obj1, Object obj2); - - List get(Log.Operation type); - - + void reset(); + + void log(Log.Operation type, Object obj); + + void log(Log.Operation type, Object obj1, Object obj2); + + List get(Log.Operation type); + + enum Operation { + LOAD, QUERY, UPDATE + } + + } diff --git a/src/main/java/fr/inria/corese/core/api/QueryGraphVisitor.java b/src/main/java/fr/inria/corese/core/api/QueryGraphVisitor.java index 6cff60fd8..8d6c121bf 100644 --- a/src/main/java/fr/inria/corese/core/api/QueryGraphVisitor.java +++ b/src/main/java/fr/inria/corese/core/api/QueryGraphVisitor.java @@ -1,25 +1,23 @@ package fr.inria.corese.core.api; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.kgram.core.Query; import fr.inria.corese.core.Graph; import fr.inria.corese.core.kgram.api.core.Edge; +import fr.inria.corese.core.kgram.core.Query; +import fr.inria.corese.core.sparql.triple.parser.ASTQuery; /** - * - * Visitor Design Pattern to rewrite an RDF Graph into a SPARQL BGP Query Graph - * + * Visitor Design Pattern to rewrite an RDF Graph into a SPARQL BGP Query Graph */ public interface QueryGraphVisitor { - + default Graph visit(Graph g) { return g; } - + default ASTQuery visit(ASTQuery ast) { return ast; } - + default Edge visit(Edge ent) { return ent; } diff --git a/src/main/java/fr/inria/corese/core/api/Tagger.java b/src/main/java/fr/inria/corese/core/api/Tagger.java index ea199eae0..5fcb26e00 100644 --- a/src/main/java/fr/inria/corese/core/api/Tagger.java +++ b/src/main/java/fr/inria/corese/core/api/Tagger.java @@ -1,7 +1,7 @@ package fr.inria.corese.core.api; public interface Tagger { - - String tag(); + + String tag(); } diff --git a/src/main/java/fr/inria/corese/core/api/ValueResolver.java b/src/main/java/fr/inria/corese/core/api/ValueResolver.java index 83fabceee..600db5556 100644 --- a/src/main/java/fr/inria/corese/core/api/ValueResolver.java +++ b/src/main/java/fr/inria/corese/core/api/ValueResolver.java @@ -7,19 +7,18 @@ import fr.inria.corese.core.sparql.api.IDatatype; /** - * * @author Olivier Corby, Wimmics Inria I3S, 2013 */ public interface ValueResolver { - String getKey(String str); + String getKey(String str); - String getKey(IDatatype dt); + String getKey(IDatatype dt); - void setValue(String key, IDatatype dt); + void setValue(String key, IDatatype dt); + + IDatatype getValue(String key); + + int size(); - IDatatype getValue(String key); - - int size(); - } diff --git a/src/main/java/fr/inria/corese/core/approximate/algorithm/ISimAlgorithm.java b/src/main/java/fr/inria/corese/core/approximate/algorithm/ISimAlgorithm.java deleted file mode 100644 index 10aa9744f..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/algorithm/ISimAlgorithm.java +++ /dev/null @@ -1,26 +0,0 @@ -package fr.inria.corese.core.approximate.algorithm; - -/** - * Interface for implementing the similarity measurement algorithms - * - * @author Fuqi Song, WImmics Inria I3S - * @date 27 août 2015 - */ -public interface ISimAlgorithm { - - public final static int NA = Integer.MIN_VALUE;//not calculated - - public final static double MIN = 0.0d; - public final static double MAX = 1.0d; - - //double calculate(String s1, String s2); - /** - * Calculate the similarity between strings s1 and s2 - * - * @param s1 - * @param s2 - * @param parameters - * @return - */ - double calculate(String s1, String s2, String parameters); -} diff --git a/src/main/java/fr/inria/corese/core/approximate/algorithm/Parameters.java b/src/main/java/fr/inria/corese/core/approximate/algorithm/Parameters.java deleted file mode 100644 index 77c7927eb..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/algorithm/Parameters.java +++ /dev/null @@ -1,62 +0,0 @@ -package fr.inria.corese.core.approximate.algorithm; - -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.compiler.parser.Pragma; -import java.net.URL; -import java.util.List; - -/** - * Options - * - * @author Fuqi Song, Wimmics Inria I3S - * @date 16 nov. 2015 - */ -public class Parameters { - - private static final URL R_WN_PATH = Parameters.class.getClassLoader().getResource("wordnet"); - public static String WN_PATH = (R_WN_PATH == null) ? null : R_WN_PATH.getPath(); - - private static final URL R_POS_TAGGER = Parameters.class.getClassLoader().getResource("tagger"); - public static String POS_TAGGER = (R_POS_TAGGER == null) ? null : R_POS_TAGGER.getPath() + "/english-left3words-distsim.tagger"; - - public static String WN_VER = "3.0"; - public static String DEF_STRING_METRIC = "Lin"; - public static double THRESHOLD = 0.1; - - public static void init(ASTQuery ast) { - //WordNet and POS tagger - //WordNet dict path - List wnp = ast.getApproximateSearchOptions(Pragma.WN_PATH); - if (check(wnp)) { - WN_PATH = wnp.get(0); - } - - //wordnet version - List wnv = ast.getApproximateSearchOptions(Pragma.WN_VERSION); - if (check(wnv)) { - WN_VER = wnv.get(0); - } - - //pos tagger - List pos = ast.getApproximateSearchOptions(Pragma.POS_TAGGER); - if (check(pos)) { - POS_TAGGER = pos.get(0); - } - - //String metric - List metric = ast.getApproximateSearchOptions(Pragma.STRING_METRIC); - if (check(metric)) { - DEF_STRING_METRIC = metric.get(0); - } - - //threshold - List threshold = ast.getApproximateSearchOptions(Pragma.THRESHOLD); - if (check(threshold)) { - THRESHOLD = Double.valueOf(threshold.get(0)); - } - } - - private static boolean check(List list) { - return list != null && !list.isEmpty(); - } -} diff --git a/src/main/java/fr/inria/corese/core/approximate/algorithm/SimAlgorithmFactory.java b/src/main/java/fr/inria/corese/core/approximate/algorithm/SimAlgorithmFactory.java deleted file mode 100644 index e1c2e1afe..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/algorithm/SimAlgorithmFactory.java +++ /dev/null @@ -1,80 +0,0 @@ -package fr.inria.corese.core.approximate.algorithm; - -import fr.inria.corese.core.approximate.strategy.AlgType; -import fr.inria.corese.core.approximate.strategy.ApproximateStrategy; -import fr.inria.corese.core.approximate.algorithm.impl.CombinedAlgorithm; -import fr.inria.corese.core.approximate.algorithm.impl.Equality; -import fr.inria.corese.core.approximate.algorithm.impl.JaroWinkler; -import fr.inria.corese.core.approximate.algorithm.impl.NGram; -import fr.inria.corese.core.approximate.strategy.Priority; -import java.util.LinkedList; -import java.util.List; - -/** - * Generate instance of similarity measurement algorithm - * - * @author Fuqi Song, Wimmics Inria I3S - * @date 23 sept. 2015 - */ -public class SimAlgorithmFactory { - - public static ISimAlgorithm create(String name) { - AlgType alg = ApproximateStrategy.valueOf(name); - return alg == null ? null : create(alg); - } - - /** - * Create an instance of algorithm using the given type of algorithm - * - * @param type - * @return - */ - public static ISimAlgorithm create(AlgType type) { - switch (type) { - - case ng: - return new NGram(); - case eq: - return new Equality(); - case jw: - return new JaroWinkler(); - case ch: - //integrate the old algorithm - //return new ClassHieararchy(alg); - default: - return null; - } - } - - /** - * Generate a combined similarity measurement algorithm - * - * @param algs - * @param defWeights - * @return - */ - public static ISimAlgorithm createCombined(String algs, boolean defWeights) { - return createCombined(ApproximateStrategy.getAlgorithmList(algs), defWeights); - } - - /** - * Create a combined similarity measurement algorithm - * - * @param algs - * @param defWeights - * @return - */ - public static ISimAlgorithm createCombined(List algs, boolean defWeights) { - List algList = new LinkedList(); - - for (AlgType at : algs) { - ISimAlgorithm alg = create(at); - if (alg != null) { - algList.add(alg); - } - } - - double[] weights = defWeights ? Priority.getDefaultWeights(algList.size()) : Priority.getWeightByAlgorithm(algList); - return new CombinedAlgorithm(algList, weights); - } -} diff --git a/src/main/java/fr/inria/corese/core/approximate/algorithm/Utils.java b/src/main/java/fr/inria/corese/core/approximate/algorithm/Utils.java deleted file mode 100644 index 06166059e..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/algorithm/Utils.java +++ /dev/null @@ -1,48 +0,0 @@ -package fr.inria.corese.core.approximate.algorithm; - -/** - * Utils class - * - * @author Fuqi Song, Wimmics Inria I3S - * @date 15 oct. 2015 - */ -public class Utils { - - private final static boolean SHOW_MSG = !true; - - /** - * Format a double using default format "##.####" - * - * @param d - * @return - */ - public static String format(double d) { - return String.format("%2.4f", d).replace(',', '.'); // Had to add the replace to force replace the "," - } - - /** - * Split a URL into prefix+suffix - * (to be elaborated ...) - * @param uri - * @return - */ - public static String[] split(String uri) { - int index = uri.lastIndexOf("#"); - if (index == -1) { - index = uri.lastIndexOf("/"); - } - - String prefix = (index == -1) ? "" : uri.substring(0, index + 1); - String suffix = (index == -1) ? uri : uri.substring(index + 1); - return new String[]{prefix, suffix}; - } - - /** - * Check if a string is null or empty - * @param s - * @return - */ - public static boolean empty(String s) { - return s == null || s.length() == 0; - } -} diff --git a/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/BaseAlgorithm.java b/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/BaseAlgorithm.java deleted file mode 100644 index fd60897c8..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/BaseAlgorithm.java +++ /dev/null @@ -1,48 +0,0 @@ -package fr.inria.corese.core.approximate.algorithm.impl; - -import fr.inria.corese.core.approximate.strategy.AlgType; -import fr.inria.corese.core.approximate.algorithm.ISimAlgorithm; -import fr.inria.corese.core.approximate.algorithm.Utils; - -/** - * Base Algorithm - * - * @author Fuqi Song, Wimmics Inria I3S - * @date 24 sept. 2015 - */ -public class BaseAlgorithm implements ISimAlgorithm { - - private final AlgType type; - public final static String OPTION_URI = "uri"; - - /** - * Constructor with default type 'empty' - */ - BaseAlgorithm() { - this(AlgType.empty); - } - - /** - * Constructor with given type - * - * @param type - */ - public BaseAlgorithm(AlgType type) { - this.type = type; - } - - /** - * Return type of algorithm - * - * @return - */ - public AlgType getType() { - return this.type; - } - - @Override - public double calculate(String s1, String s2, String parameters) { - return MIN; - } - -} diff --git a/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/ClassHierarchy.java b/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/ClassHierarchy.java deleted file mode 100644 index e1ea99712..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/ClassHierarchy.java +++ /dev/null @@ -1,16 +0,0 @@ -package fr.inria.corese.core.approximate.algorithm.impl; - -import fr.inria.corese.core.approximate.strategy.AlgType; - -/** - * Class Hierarchy (to be intregared ... or not...) - * - * @author Fuqi Song, Wimmics Inria I3S - * @date 13 oct. 2015 - */ -public class ClassHierarchy extends BaseAlgorithm{ - - public ClassHierarchy() { - super(AlgType.ch); - } -} diff --git a/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/CombinedAlgorithm.java b/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/CombinedAlgorithm.java deleted file mode 100644 index 4ea8eda89..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/CombinedAlgorithm.java +++ /dev/null @@ -1,54 +0,0 @@ -package fr.inria.corese.core.approximate.algorithm.impl; - -import fr.inria.corese.core.approximate.strategy.Priority; -import fr.inria.corese.core.approximate.strategy.AlgType; -import fr.inria.corese.core.approximate.algorithm.ISimAlgorithm; -import java.util.List; - -/** - * Combined algorithm (composed of several algorithms) - * - * @author Fuqi Song, Wimmics Inria I3S - * @date 27 août 2015 - */ -public class CombinedAlgorithm extends BaseAlgorithm { - - private final List algs; - private final double[] weights; - - /** - * Construct a combined algorithm using given list of algorithms and default weights - * - * @param algs - */ - public CombinedAlgorithm(List algs) { - this(algs, null); - } - - /** - * Construct a combined algorithm using given list of algorithms and weights - * @param algs - * @param weights2 - */ - public CombinedAlgorithm(List algs, double[] weights2) { - super(AlgType.mult); - this.algs = algs; - this.weights = weights2; - } - - @Override - public double calculate(String s1, String s2, String parameter) { - if (algs.isEmpty()) { - return NA; - } - - //normally, the parameter needs to be processed beofre passing to each - //specific algorithm - double[] similarity = new double[algs.size()]; - for (int i = 0; i < this.algs.size(); i++) { - similarity[i] = this.algs.get(i).calculate(s1, s2, parameter); - } - - return Priority.sum(similarity, this.weights); - } -} diff --git a/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/Equality.java b/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/Equality.java deleted file mode 100644 index 5430789c6..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/Equality.java +++ /dev/null @@ -1,23 +0,0 @@ -package fr.inria.corese.core.approximate.algorithm.impl; - -import fr.inria.corese.core.approximate.algorithm.Utils; -import static fr.inria.corese.core.approximate.strategy.AlgType.eq; - -/** - * Equality.java - * - * @author Fuqi Song, Wimmics Inria I3S - * @date 17 nov. 2015 - */ -public class Equality extends BaseAlgorithm { - - public Equality() { - super(eq); - } - - @Override - public double calculate(String s1, String s2, String paramter) { - double sim = MAX; - return sim; - } -} diff --git a/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/Jaro.java b/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/Jaro.java deleted file mode 100644 index 5cd59bbe0..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/Jaro.java +++ /dev/null @@ -1,97 +0,0 @@ -package fr.inria.corese.core.approximate.algorithm.impl; - -import fr.inria.corese.core.approximate.strategy.AlgType; - -/** - * Jaro distance metric (Jaro, 1989, 1995) - * - * @author Fuqi Song, Wimmics Inria I3S - * @date 13 oct. 2015 - */ -public class Jaro extends BaseAlgorithm { - - public Jaro() { - super(AlgType.jw); - } - - /** - * gets the similarity of the two strings using Jaro distance. - * - * @param s1 the first input string - * @param s2 the second input string - * @param parameter - * @return a value between 0-1 of the similarity - */ - @Override - public double calculate(String s1, String s2, String parameter) { - return calculate(s1, s2); - } - - private double calculate(final String s1, final String s2) { - - //get half the length of the string rounded up - (this is the distance used for acceptable transpositions) - final int halflen = ((Math.min(s1.length(), s2.length())) / 2) + ((Math.min(s1.length(), s2.length())) % 2); - - //get common characters - final StringBuffer common1 = getCommonCharacters(s1, s2, halflen); - final StringBuffer common2 = getCommonCharacters(s2, s1, halflen); - - //check for zero in common - if (common1.length() == 0 || common2.length() == 0) { - return 0.0f; - } - - //get the number of transpositions - int transpositions = 0; - int n = Math.min(common1.length(), common2.length()); - for (int i = 0; i < n; i++) { - if (common1.charAt(i) != common2.charAt(i)) { - transpositions++; - } - } - transpositions /= 2.0f; - - //calculate jaro metric - return (common1.length() / ((float) s1.length()) - + common2.length() / ((float) s2.length()) - + (common1.length() - transpositions) / ((float) common1.length())) / 3.0f; - } - - /** - * returns a string buffer of characters from string1 within string2 if they - * are of a given distance seperation from the position in string1. - * - * @param string1 - * @param string2 - * @param distanceSep - * @return a string buffer of characters from string1 within string2 if they - * are of a given distance seperation from the position in string1 - */ - private StringBuffer getCommonCharacters(final String string1, final String string2, final int distanceSep) { - //create a return buffer of characters - final StringBuffer returnCommons = new StringBuffer(); - //create a copy of string2 for processing - final StringBuffer copy = new StringBuffer(string2); - //iterate over string1 - int n = string1.length(); - int m = string2.length(); - for (int i = 0; i < n; i++) { - final char ch = string1.charAt(i); - //set boolean for quick loop exit if found - boolean foundIt = false; - //compare char with range of characters to either side - - for (int j = Math.max(0, i - distanceSep); !foundIt && j < Math.min(i + distanceSep, m - 1); j++) { - //check if found - if (String.valueOf(copy.charAt(j)).equalsIgnoreCase(String.valueOf(ch))) { - foundIt = true; - //append character found - returnCommons.append(ch); - //alter copied string2 for processing - copy.setCharAt(j, (char) 0); - } - } - } - return returnCommons; - } -} diff --git a/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/JaroWinkler.java b/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/JaroWinkler.java deleted file mode 100644 index 9e4b7275d..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/JaroWinkler.java +++ /dev/null @@ -1,38 +0,0 @@ -package fr.inria.corese.core.approximate.algorithm.impl; - -import fr.inria.corese.core.approximate.algorithm.Utils; - -/** - * Jaro–Winkler distance (Winkler, 1990) based on Jaro - * - * @author Fuqi Song, Wimmics Inria I3S - * @date 13 oct. 2015 - */ -public class JaroWinkler extends Jaro { - - @Override - public double calculate(String s1, String s2, String parameter) { - double sim = MAX; - if (!s1.equalsIgnoreCase(s2)) { - //jaro algorithm - double jaroSim = super.calculate(s1, s2, parameter); - - int prefix = getCommonPrefix(s1, s2); - sim = jaroSim + prefix * (0.1 * (1.0 - jaroSim)); - } - - return sim; - } - - private int getCommonPrefix(String s1, String s2) { - int cp = 0; - for (int i = 0; i < 4 & i < s1.length() & i < s2.length(); i++) { - if (String.valueOf(s1.charAt(i)).equalsIgnoreCase(String.valueOf(s2.charAt(i)))) { - cp++; - } else { - break; - } - } - return cp; - } -} diff --git a/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/NGram.java b/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/NGram.java deleted file mode 100644 index 051b2c1e0..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/algorithm/impl/NGram.java +++ /dev/null @@ -1,79 +0,0 @@ -package fr.inria.corese.core.approximate.algorithm.impl; - -import fr.inria.corese.core.approximate.strategy.AlgType; -import fr.inria.corese.core.approximate.algorithm.Utils; -import java.util.HashMap; -import java.util.Map; - -/** - * N-Gram similarity measurement algorithm - * - * @author Fuqi Song, Wimmics Inria I3S - * @date 27 août 2015 - */ -public class NGram extends BaseAlgorithm { - - private final static int NG = 3;//default - private int n; - - public NGram() { - this(NG); - } - - public NGram(int n) { - super(AlgType.ng); - this.n = n; - } - - @Override - public double calculate(String s1, String s2, String parameter) { - double sim = this.calculate(s1, s2); - return sim; - } - - private double calculate(String s1, String s2) { - double sim = MAX; - if (!s1.equalsIgnoreCase(s2)) { - Map res1 = tokenize(s1, n); - Map res2 = tokenize(s2, n); - - int c = common(res1, res2); - //int u = Math.max(s1.length(), s2.length()) - n + 1; - int u = res1.size() + res2.size() - c; - //u = u > 0 ? u : 1; - sim = (double) c / (double) u; - } - return sim; - } - - private int common(Map tokens1, Map tokens2) { - int res = 0; - - for (String t1 : tokens1.keySet()) { - if (tokens2.keySet().contains(t1)) { - res++; - } - } - - return res; - } - - private Map tokenize(String c, int n) { - Map tokens = new HashMap(); - - String spacer = ""; - c = spacer + c + spacer; - - for (int i = 0; i < c.length(); i++) { - if (i <= (c.length() - n)) { - String t = c.substring(i, n + i).toLowerCase(); - if (tokens.containsKey(t)) { - tokens.put(t, tokens.get(t) + 1); - } else { - tokens.put(t, 1); - } - } - } - return tokens; - } -} diff --git a/src/main/java/fr/inria/corese/core/approximate/ext/ASTRewriter.java b/src/main/java/fr/inria/corese/core/approximate/ext/ASTRewriter.java deleted file mode 100644 index e1a41e418..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/ext/ASTRewriter.java +++ /dev/null @@ -1,259 +0,0 @@ -package fr.inria.corese.core.approximate.ext; - -import fr.inria.corese.core.sparql.api.IDatatype; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.Atom; -import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; -import fr.inria.corese.core.sparql.triple.parser.Constant; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.Metadata; -import fr.inria.corese.core.sparql.triple.parser.Optional; -import fr.inria.corese.core.sparql.triple.parser.Processor; -import fr.inria.corese.core.sparql.triple.parser.Term; -import fr.inria.corese.core.sparql.triple.parser.Triple; -import fr.inria.corese.core.sparql.triple.parser.Variable; -import fr.inria.corese.core.compiler.api.QueryVisitor; -import fr.inria.corese.core.kgram.core.Query; -import fr.inria.corese.core.approximate.algorithm.Parameters; -import static fr.inria.corese.core.approximate.ext.ASTRewriter.S; -import fr.inria.corese.core.approximate.strategy.ApproximateStrategy; -import fr.inria.corese.core.approximate.strategy.StrategyType; -import static fr.inria.corese.core.approximate.strategy.StrategyType.CLASS_HIERARCHY; -import static fr.inria.corese.core.approximate.strategy.StrategyType.URI_EQUALITY; -import static fr.inria.corese.core.approximate.strategy.StrategyType.LITERAL_LEX; -import static fr.inria.corese.core.approximate.strategy.StrategyType.PROPERTY_EQUALITY; -import static fr.inria.corese.core.approximate.strategy.StrategyType.URI_LEX; -import static fr.inria.corese.core.approximate.strategy.StrategyType.URI_WN; -import fr.inria.corese.core.logic.OWL; -import fr.inria.corese.core.logic.RDF; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * - * AST rewriting: according to different rules, modify the original SPARQL by - * adding triple patterns/filters, etc - * - * @author Fuqi Song, Wimmics Inria I3S - * @date 5 oct. 2015 - */ -public class ASTRewriter implements QueryVisitor { - - final static int S = 1, P = 2, O = 3; - private final static String VAR = "?_var_"; - public final static String APPROXIMATE = Processor.APPROXIMATE; - private int countVar = 0; - private ASTQuery ast; - ApproximateStrategy strategy; - boolean relaxProperty = !true, - relaxURI = !true, - relaxLiteral = true; - - @Override - public void visit(Query query) { - //throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public void visit(ASTQuery ast) { - if (!ast.isRelax()) { - return; - } - this.ast = ast; - init(); - strategy = new ApproximateStrategy(); - this.initOptions(ast); - visit(ast.getBody()); - } - - // @relax kg:uri_literal_property - void init(){ - List list = ast.getMetadata().getValues(Metadata.RELAX); - if (list == null){ - return; - } - if (! list.isEmpty()){ - // let user decide about literal - relaxLiteral = !true; - } - for (String str : list){ - String name = str.toLowerCase(); - if (name.equals(Metadata.RELAX_URI) || name.contains("*")){ - relaxURI = true; - } - if (name.equals(Metadata.RELAX_PROPERTY) || name.contains("*")){ - relaxProperty = true; - } - if (name.equals(Metadata.RELAX_LITERAL) || name.contains("*")){ - relaxLiteral = true; - } - } - } - - private void visit(Exp exp) { - List exTemp = new ArrayList(); - exTemp.addAll(exp.getBody()); - - for (Exp e : exTemp) { - if (e.isFilter()) {} - if (e.isTriple()){ - process(exp, e.getTriple()); - } - else for (Exp ee : e) { - visit(ee); - } - } - } - - private void process(Exp exp, Triple t) { - - //1 pre process, choose strategies for each atom - Map map = new HashMap(); - - init(t, t.getSubject(), S, map); - init(t, t.getPredicate(), P, map); - init(t, t.getObject(), O, map); - - //2 rewrite triples in AST - List filters = new ArrayList<>(); - List options = new ArrayList(); - - rewrite(map.get(S), filters, options); - if (relaxProperty){ - rewrite(map.get(P), filters, options); - } - rewrite(map.get(O), filters, options); - - for (Exp filter : filters) { - exp.add(filter); - } - - for (Optional option : options) { - exp.add(option); - } - } - - //choose the Strategy for the URI and put them into a list - private void init(Triple triple, Atom atom, int pos, Map map) { - if (atom == null) { - return; - } - - List lst = new ArrayList(); - IDatatype dt = atom.getDatatypeValue(); - - if (dt.isURI()) { - if (! relaxURI && pos != P ){ - return; - } - //S P O - add(lst, URI_WN); - add(lst, URI_LEX); - add(lst, URI_EQUALITY); - - if (pos == P && !atom.getName().equalsIgnoreCase(RDF.TYPE)) { //property does not have rdfs:label & rdfs:comment - add(lst, PROPERTY_EQUALITY); - } - else if (pos == O && triple.isType()) { - add(lst, CLASS_HIERARCHY); - } - } - else if (dt.isLiteral() && relaxLiteral){ - if (dt.getCode() == IDatatype.STRING || - dt.getCode() == IDatatype.LITERAL ){ //(dt.getDatatypeURI().equals(xsdstring) ) { - add(lst, LITERAL_LEX); - } - } - - if (!lst.isEmpty()) { - map.put(pos, new TripleWrapper(triple, pos, lst)); - } - } - - //approximate the name of URI - //ex, kg:john, kg:Johnny - //applicable to: subject, predicate and object - private void rewrite(TripleWrapper tw, List filters, List options) { - if (tw == null) { - return; - } - - Variable var = new Variable(VAR + countVar++); - - //1. get strategies in group G1 and merge them in one filter - List merge = strategy.getMergableStrategies(tw.getStrategies()); - if (!merge.isEmpty()) { - //2.2 generate filters with functions - filters.add(createFilter(var, tw.getAtom(), strategy.getAlgorithmString(merge))); - } - - //2. iterate other strategies - for (StrategyType st : tw.getStrategies()) { - if (merge.contains(st)) { - continue; - } - - String label; - Triple t1, t2; - Optional opt = new Optional(); - switch (st) { - case PROPERTY_EQUALITY: - case URI_EQUALITY: - label = (st == URI_EQUALITY) ? OWL.SAMEAS : OWL.EQUIVALENTPROPERTY; - //create two addional triple pattern {x eq y} - t1 = (ast.createTriple(var, Constant.create(label), tw.getAtom())); - t2 = (ast.createTriple(tw.getAtom(), Constant.create(label), var)); - - //the filter can be omitted, because the similarity (equality =1) - //create optional {t1, t2} - opt.add(BasicGraphPattern.create(t1, t2)); - options.add(opt); - break; -// case URI_LABEL: -// case URI_COMMENT: -// label = (st == URI_COMMENT) ? RDFS.COMMENT : RDFS.LABEL; -// Variable text1 = variable(false); -// Variable text2 = variable(false); -// -// //create two addional triple pattern: {x rdfs:label y} or {x rdfs:comment y} -// t1 = ast.createTriple(var, Constant.create(label), text1); -// t2 = ast.createTriple(tw.getAtom(), Constant.create(label), text2); -// BasicGraphPattern bgp = BasicGraphPattern.create(t1, t2); -// -// //create a filter -// bgp.add(Triple.create(ast.createOperator("!=", var, tw.getAtom()))); -// Exp filter = filter(text1, text2, ApproximateStrategy.getAlgrithmString(st), var, tw.getAtom()); -// bgp.add(filter); -// opt.add(bgp); -// ast.getBody().add(opt); -// break; - } - } - - //2.3 replace uri with vairable - tw.setAtom(var); - } - - //add a filter with a specific function and parameters - private Exp createFilter(Variable var, Atom atom, String algs) { - Term function = Term.function(APPROXIMATE); - function.add(var); - function.add(atom); - function.add(Constant.createString(algs)); //, qrdfsLiteral)); - function.add(Constant.create(Parameters.THRESHOLD)); - return ASTQuery.createFilter(function); - } - - private void initOptions(ASTQuery ast) { - strategy.init(ast); - Parameters.init(ast); - } - - private void add(List list, StrategyType st) { - if (strategy.check(st)) { - list.add(st); - } - } -} diff --git a/src/main/java/fr/inria/corese/core/approximate/ext/AppxSearchPlugin.java b/src/main/java/fr/inria/corese/core/approximate/ext/AppxSearchPlugin.java deleted file mode 100644 index bbd235ac4..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/ext/AppxSearchPlugin.java +++ /dev/null @@ -1,174 +0,0 @@ -package fr.inria.corese.core.approximate.ext; - -import fr.inria.corese.core.sparql.api.IDatatype; -import fr.inria.corese.core.sparql.datatype.CoreseStringLiteral; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.kgram.api.core.Expr; -import fr.inria.corese.core.kgram.api.core.ExprType; -import fr.inria.corese.core.kgram.api.query.Environment; -import fr.inria.corese.core.kgram.api.query.Producer; -import fr.inria.corese.core.kgram.tool.ApproximateSearchEnv; -import fr.inria.corese.core.approximate.algorithm.ISimAlgorithm; -import fr.inria.corese.core.approximate.algorithm.SimAlgorithmFactory; -import static fr.inria.corese.core.approximate.algorithm.Utils.format; -import fr.inria.corese.core.approximate.algorithm.impl.BaseAlgorithm; -import fr.inria.corese.core.query.PluginImpl; - -/** - * Plugin implementation for approximate search - * - * @author Fuqi Song, Wimmics Inria I3S - * @date 1 oct. 2015 - */ -public class AppxSearchPlugin implements ExprType { - - static final IDatatype TRUE = PluginImpl.TRUE; - static final IDatatype FALSE = PluginImpl.FALSE; - private final PluginImpl plugin; - - public AppxSearchPlugin(PluginImpl p) { - this.plugin = p; - } - - public IDatatype eval(Expr exp, Environment env, Producer p) { - switch (exp.oper()) { - case APP_SIM: - ApproximateSearchEnv appxEnv = env.getAppxSearchEnv(); - double d = appxEnv.aggregate(env); - IDatatype sim = plugin.getValue(d); - return sim; - default: - return null; - } - } - - public IDatatype eval(Expr exp, Environment env, Producer p, Object[] args) { - IDatatype[] param = (IDatatype[]) args; - switch (exp.oper()) { - - case APPROXIMATE: - //0. check parameters - return eval(exp, env, param); - - default: - return null; - } - } - - // Use approximate as a filter function - private IDatatype match(IDatatype dt1, IDatatype dt2, String parameter, String algs, double threshold) { - String s1 = stringValue(dt1); - String s2 = stringValue(dt2); - if (s1.equalsIgnoreCase(s2)) { - return TRUE; - } - ISimAlgorithm alg = SimAlgorithmFactory.createCombined(algs, true); - double sim = alg.calculate(s1, s2, parameter); - - return (sim > threshold) ? TRUE : FALSE; - } - - String stringValue(IDatatype dt){ - if (dt.hasLang()){ - return dt.stringValue().concat("@").concat(dt.getLang()); - } - return dt.stringValue(); - } - - // Use 'approximate' as appx search and calculate similarity - private IDatatype approximate(IDatatype dt1, IDatatype dt2, String parameter, String algs, double threshold, Environment env, Expr exp) { - //0. initialize - String s1 = stringValue(dt1); - String s2 = stringValue(dt2); - Expr var = exp.getExp(0); - ApproximateSearchEnv appxEnv = env.getAppxSearchEnv(); - - Double combinedSim; - Double singleSim = appxEnv.getSimilarity(var, dt1, algs);//check appx env to see if already computed - - boolean notExisted = (singleSim == null); - - //1 calculation to get current similarity and overall similarity - if (s1.equalsIgnoreCase(s2)) { - singleSim = ISimAlgorithm.MAX; - combinedSim = ISimAlgorithm.MAX; - } else { - if (notExisted) { //2.1.2 otherwise, re-calculate - ISimAlgorithm alg = SimAlgorithmFactory.createCombined(algs, false); - singleSim = alg.calculate(s1, s2, parameter); - } - combinedSim = appxEnv.aggregate(env, var, singleSim); - } - - //3 finalize - boolean filtered = combinedSim > threshold; - - if (notExisted) { - appxEnv.add(var, dt2, dt1, algs, singleSim); - } - return filtered ? TRUE : FALSE; - } - - - /** - * filter approximate(var1, var2, 'ng-jw-wn-eq-mult', 0.2, true) - args[0] = var 1 - args[1] = uri - args[2] = alg list - args[3] = threshold - args[4] = false|true. - */ - private IDatatype eval(Expr exp, Environment env, IDatatype[] args) { - if (args.length != 4) { - return FALSE; - } - - IDatatype dt1 = args[0]; - IDatatype dt2 = args[1]; - if (dt1.stringValue() == null || dt2.stringValue() == null) { - return null; - } - //IF the types are different, then return FALSE directly - boolean match = match(dt1.getCode(), dt2.getCode()); - if (! match){ - return FALSE; - } - - if (!(args[2] instanceof CoreseStringLiteral) - || !args[3].isNumber()) { - return FALSE; - } - - String algs = args[2].stringValue(); - double threshold = args[3].doubleValue(); - - String parameter = null; - if (dt1.isURI()) { - parameter = BaseAlgorithm.OPTION_URI; - } - - ASTQuery ast = env.getQuery().getAST(); - //is approximate search - //TRUE: only calculate once, does not compute the value of similarity - //FALSE: need to compute the value of similarity - if (ast.isRelax()) { - return this.approximate(dt1, dt2, parameter, algs, threshold, env, exp); - } else { - return this.match(dt1, dt2, parameter, algs, threshold); - } - - } - - boolean match(int c1, int c2){ - if (c1 == c2){ - return true; - } - if ((c1 == IDatatype.STRING && c2 == IDatatype.LITERAL) || - (c2 == IDatatype.STRING && c1 == IDatatype.LITERAL)){ - return true; - } - - return false; - } - -} diff --git a/src/main/java/fr/inria/corese/core/approximate/ext/TripleWrapper.java b/src/main/java/fr/inria/corese/core/approximate/ext/TripleWrapper.java deleted file mode 100644 index d3eeccc63..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/ext/TripleWrapper.java +++ /dev/null @@ -1,93 +0,0 @@ -package fr.inria.corese.core.approximate.ext; - -import fr.inria.corese.core.sparql.triple.parser.Atom; -import fr.inria.corese.core.sparql.triple.parser.Triple; -import fr.inria.corese.core.sparql.triple.parser.Variable; -import static fr.inria.corese.core.approximate.ext.ASTRewriter.O; -import static fr.inria.corese.core.approximate.ext.ASTRewriter.P; -import static fr.inria.corese.core.approximate.ext.ASTRewriter.S; -import fr.inria.corese.core.approximate.strategy.StrategyType; -import java.util.ArrayList; -import java.util.List; - -/** - * TripleWrapper.java - * - * @author Fuqi Song, Wimmics Inria I3S - * @date 30 nov. 2015 - */ -class TripleWrapper { - - private final Triple triple; - private final int position; - private final List strategy; - - public TripleWrapper(Triple triple, int position, List strategy) { - this.triple = triple; - this.position = position; - this.strategy = strategy; - } - - public TripleWrapper(Triple triple, int position) { - this(triple, position, new ArrayList()); - } - - public Atom getAtom() { - switch (position) { - case S: - return this.triple.getSubject(); - case P: - return this.triple.getPredicate(); - case O: - return this.triple.getObject(); - default: - return null; - } - } - - public void setAtom(Variable var) { - switch (position) { - case S: - triple.setSubject(var); - break; - case P: - triple.setPredicate(var); - break; - case O: - triple.setObject(var); - break; - default: - } - } - - public void addStrategy(StrategyType strategy) { - this.strategy.add(strategy); - } - - public int getPosition() { - return position; - } - - public Triple getTriple() { - return triple; - } - - public List getStrategies() { - return strategy; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - - sb.append(this.triple).append("\t"); - sb.append(this.getAtom()).append(",\t"); - sb.append(this.getPosition()).append(",\t"); - sb.append("["); - for (StrategyType st : strategy) { - sb.append(st.name()).append(", "); - } - sb.append("]"); - return sb.toString(); - } -} diff --git a/src/main/java/fr/inria/corese/core/approximate/strategy/AlgType.java b/src/main/java/fr/inria/corese/core/approximate/strategy/AlgType.java deleted file mode 100644 index af9cf99e0..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/strategy/AlgType.java +++ /dev/null @@ -1,29 +0,0 @@ -package fr.inria.corese.core.approximate.strategy; - -import java.util.Arrays; -import java.util.List; - -/** - * Enumeration of types of similarity measurement algorithms - * - * @author fsong - */ -public enum AlgType { - - empty,//no algorithm implemented - ng, //n-gram - jw, //jaro-winkler (edit distance) - ch, //class hierarchy (empty now) - wn, //wordnet - eq, //equality - mult; //combiend algorithm - - /** - * Return the list of all types of single algorithms - * - * @return - */ - public static List allValues() { - return Arrays.asList(new AlgType[]{ng, jw, ch, wn, eq}); - } -} diff --git a/src/main/java/fr/inria/corese/core/approximate/strategy/ApproximateStrategy.java b/src/main/java/fr/inria/corese/core/approximate/strategy/ApproximateStrategy.java deleted file mode 100644 index 8e2262d14..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/strategy/ApproximateStrategy.java +++ /dev/null @@ -1,253 +0,0 @@ -package fr.inria.corese.core.approximate.strategy; - -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.compiler.parser.Pragma; -import static fr.inria.corese.core.approximate.strategy.AlgType.ch; -import static fr.inria.corese.core.approximate.strategy.AlgType.eq; -import static fr.inria.corese.core.approximate.strategy.AlgType.jw; -import static fr.inria.corese.core.approximate.strategy.AlgType.ng; -import static fr.inria.corese.core.approximate.strategy.AlgType.wn; -import static fr.inria.corese.core.approximate.strategy.StrategyType.CLASS_HIERARCHY; -import static fr.inria.corese.core.approximate.strategy.StrategyType.LITERAL_LEX; -import static fr.inria.corese.core.approximate.strategy.StrategyType.LITERAL_WN; -import static fr.inria.corese.core.approximate.strategy.StrategyType.PROPERTY_EQUALITY; -import static fr.inria.corese.core.approximate.strategy.StrategyType.URI_LEX; -import static fr.inria.corese.core.approximate.strategy.StrategyType.URI_EQUALITY; -import static fr.inria.corese.core.approximate.strategy.StrategyType.URI_WN; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Define the strategies - * - * @author Fuqi Song, Wimmics Inria I3S - * @date 5 oct. 2015 - */ -public class ApproximateStrategy { - - private final static Logger logger = LoggerFactory.getLogger(ApproximateStrategy.class); - public final static String SEPARATOR = "-"; - - //default strategy-algorithm map - private final static Map> defaultStrategyMap = new EnumMap>(StrategyType.class); - //real strategy-algorithm map applied - private Map> strategyMap = new EnumMap>(StrategyType.class); - - private final static List mergableStrategy; //the strateiges that can be merged into filter - private final static List defaultStrategy; - private List strategyList = null; //strategies to be applied - private List algorithmList = null; //algorithm list to be applied - - //private static Priority priority = new Priority(); - static { - //*** DEFAULT MAP STRATEGY - ALGORITHMS - defaultStrategyMap.put(URI_LEX, Arrays.asList(new AlgType[]{ng, jw}));//S P O - defaultStrategyMap.put(URI_WN, Arrays.asList(new AlgType[]{wn}));//S P O - defaultStrategyMap.put(URI_EQUALITY, Arrays.asList(new AlgType[]{eq}));//S P O - - defaultStrategyMap.put(PROPERTY_EQUALITY, Arrays.asList(new AlgType[]{eq}));//P - defaultStrategyMap.put(CLASS_HIERARCHY, Arrays.asList(new AlgType[]{ch}));//A rdf:type B - - defaultStrategyMap.put(LITERAL_WN, Arrays.asList(new AlgType[]{wn}));//O@literal@xsd:string@en - defaultStrategyMap.put(LITERAL_LEX, Arrays.asList(new AlgType[]{ng, jw}));//O@literal@xsd:string - - // strategyMap = defaultStrategyMap; - - mergableStrategy = Arrays.asList(new StrategyType[]{URI_LEX, URI_WN, CLASS_HIERARCHY, LITERAL_WN, LITERAL_LEX}); - - defaultStrategy = new ArrayList(); - defaultStrategy.add(URI_LEX); - defaultStrategy.add(LITERAL_LEX); - } - - /** - * Initialize the strategy and algorithms using Pragma from AST - * @param ast - */ - public void init(ASTQuery ast) { - //kg:strategy, option: strategies used - List strategyOption = ast.getApproximateSearchOptions(Pragma.STRATEGY); - strategyList = parse(strategyOption, StrategyType.class); - - // kg:algorithm, option: algorithms to use - List algorithmOption = ast.getApproximateSearchOptions(Pragma.ALGORITHM); - algorithmList = parse(algorithmOption, AlgType.class); - - // kg:priority, option: algorithm priortiy ** - List priorityAlgorithmOption = ast.getApproximateSearchOptions(Pragma.PRIORITY_ALGORITHM); - List algorithmPriorities = parse(priorityAlgorithmOption, Double.class); - Priority.init(algorithmPriorities, algorithmList); - - // filter algorithms according to the settings above - filter(strategyList, algorithmList); - } - - //setup the real strategy-algorithm to be applied, according to the default - //strategy-algorithm list and options from Pragma@AST - private void filter(List ls, List la) { - strategyMap = new EnumMap>(StrategyType.class); - - for (StrategyType st : ls) { - if (!defaultStrategyMap.containsKey(st)) { - continue; - } - List algs = new ArrayList(); - for (AlgType alg : defaultStrategyMap.get(st)) { - if (la.contains(alg)) { - algs.add(alg); - } - } - if (!algs.isEmpty()) { - strategyMap.put(st, algs); - } - } - } - - /** - * Get strategies by group and only return the strategies appeared in the - * given list - * - * @param filter - * @return - */ - public List getMergableStrategies(List filter) { - List lst = new ArrayList(); - for (StrategyType st : mergableStrategy) { - if (filter.contains(st) && check(st)) { - lst.add(st); - } - } - return lst; - } - - /** - * Get list of algorithms that can be used by one strategy - * - * @param strategy - * @return - */ - public List getAlgorithmTypes(StrategyType strategy) { - return strategyMap.containsKey(strategy) ? strategyMap.get(strategy) : new ArrayList(); - } - - public String getAlgorithmString(List lst) { - - List types = new ArrayList(); - for (StrategyType st : lst) { - types.addAll(strategyMap.get(st)); - } - - String algs = ""; - for (int i = 0; i < types.size(); i++) { - algs += types.get(i).name(); - if (i < types.size() - 1) { - algs += SEPARATOR; - } - } - - return algs; - } - - /** - * Convert a string to a list of algorithm instance - * @param algs - * @return - */ - public static List getAlgorithmList(String algs) { - List list = new ArrayList(); - - if (algs == null || algs.isEmpty()) { - return list; - } - - String[] algsArray = algs.split(SEPARATOR); - for (String aa : algsArray) { - AlgType at = valueOf(aa); - if (at != null) { - list.add(at); - } - } - - return list; - } - - /** - * Convert a string name to an instance of algorithm - * @param alg - * @return - */ - public static AlgType valueOf(String alg) { - try { - return AlgType.valueOf(alg); - } catch (IllegalArgumentException e) { - logger.warn("Illegal algorithm name '" + alg + "'. \n" + e.getMessage()); - } - return null; - } - - /** - * parse a list of strings to the specified type T - * - * @param - * @param options - * @param type - * @return - */ - private List parse(List options, Class type) { - List list; - - if (options == null || options.isEmpty()) { - if (type.getName().equals(StrategyType.class.getName())) { - //list = (List) StrategyType.allValues(); - list = (List) defaultStrategy; - } else if (type.getName().equals(AlgType.class.getName())) { - list = (List) AlgType.allValues(); - } else { - list = null; - } - - return list; - } - - list = new ArrayList(); - for (String aa : options) { - T t; - try { - if (type.getName().equals(StrategyType.class.getName())) { - t = (T) StrategyType.valueOf(aa); - } else if (type.getName().equals(AlgType.class.getName())) { - t = (T) AlgType.valueOf(aa); - } else { - t = (T) Double.valueOf(aa); - } - list.add(t); - } catch (IllegalArgumentException e) { - logger.warn("Approximate search: '" + aa + "' is not defined"); - } - } - return list; - } - - /** - * Check whether a given strategy is authroized to use - * @param strategy - * @return - */ - public boolean check(StrategyType strategy) { - if (!strategyList.contains(strategy)) { - return false; - } - - for (AlgType at : getAlgorithmTypes(strategy)) { - if (!algorithmList.contains(at)) { - return false; - } - } - return true; - } -} diff --git a/src/main/java/fr/inria/corese/core/approximate/strategy/Priority.java b/src/main/java/fr/inria/corese/core/approximate/strategy/Priority.java deleted file mode 100644 index 55720efdf..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/strategy/Priority.java +++ /dev/null @@ -1,106 +0,0 @@ -package fr.inria.corese.core.approximate.strategy; - -import fr.inria.corese.core.approximate.algorithm.ISimAlgorithm; -import fr.inria.corese.core.approximate.algorithm.impl.BaseAlgorithm; -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.List; -import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Class for generating the weights of each algorithm based on their priorities - * - * @author Fuqi Song, Wimmics Inria I3S - * @date 12 oct. 2015 - */ -public class Priority { - - private final static Logger logger = LoggerFactory.getLogger(Priority.class); - // private static final Map strategyMap = new EnumMap(StrategyType.class); - private static final Map algorithmMap = new EnumMap(AlgType.class); - - public static void init(List values, List target) { - if (values != null && values.size() != target.size()) { - logger.warn("Warning: size of 'kg:priority' does not correspond to the number of its target!"); - values = null; - } - - for (int i = 0; i < target.size(); i++) { - double value = (values == null) ? 1 : values.get(i); - algorithmMap.put(target.get(i), value); - } - } - - public static double[] getWeightByAlgorithmType(List types) { - return normalize(priority(types)); - } - - //"ng-ss-ch-eq" -> [0.1, 0.2, 0.3, 0.4] - public static double[] getWeightByAlgorithm(List algs) { - List types = new ArrayList(); - for (ISimAlgorithm alg : algs) { - types.add(((BaseAlgorithm) alg).getType()); - } - - return getWeightByAlgorithmType(types); - } - - //{ng, ss, ch} -> [1, 3, 4] - private static double[] priority(List algs) { - double[] p = new double[algs.size()]; - for (int i = 0; i < algs.size(); i++) { - p[i] = algorithmMap.get(algs.get(i)); - } - return p; - } - - //[2, 4, 6, 8] -> 20 - public static double sum(double[] nums) { - double sum = 0; - for (double num : nums) { - sum += num; - } - return sum; - } - - //[2, 4, 6, 8] x [0.1, 0.2, 0.3, 0.4] -> sum([0.2, 0.8, 1.8, 3.2]) -> 6d - public static double sum(double[] nums, double[] weights) { - double sum = 0; - if (nums.length != weights.length) { - return sum; - } - - for (int i = 0; i < nums.length; i++) { - sum += nums[i] * weights[i]; - } - return sum; - } - - //[2, 4, 6, 8] -> [0.1, 0.2, 0.3, 0.4] - public static double[] normalize(double[] nums) { - double sum = sum(nums); - if (sum <= 0) { - return null; - } - - double[] norm = new double[nums.length]; - for (int i = 0; i < nums.length; i++) { - norm[i] = nums[i] / sum; - } - return norm; - } - - public static double[] getDefaultWeights(int size) { - if (size < 1) { - return null; - } - - double[] num = new double[size]; - for (int i = 0; i < size; i++) { - num[i] = 1.0 / size; - } - return num; - } -} diff --git a/src/main/java/fr/inria/corese/core/approximate/strategy/StrategyType.java b/src/main/java/fr/inria/corese/core/approximate/strategy/StrategyType.java deleted file mode 100644 index 5bf540f9b..000000000 --- a/src/main/java/fr/inria/corese/core/approximate/strategy/StrategyType.java +++ /dev/null @@ -1,35 +0,0 @@ -package fr.inria.corese.core.approximate.strategy; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Strategy types - * - * @author Fuqi Song, Wimmics Inria I3S - * @date 7 oct. 2015 - */ -public enum StrategyType { - - //URI - URI_LEX, - URI_WN, - URI_EQUALITY, - PROPERTY_EQUALITY, - - //class hierarchy - CLASS_HIERARCHY, - - //literal - LITERAL_WN, - LITERAL_LEX; - - /** - * Return all values - * @return - */ - public static List allValues() { - return Arrays.asList(StrategyType.values()); - } -} diff --git a/src/main/java/fr/inria/corese/core/compiler/eval/Custom.java b/src/main/java/fr/inria/corese/core/compiler/eval/Custom.java index 4b25ec366..ec47fd5c5 100644 --- a/src/main/java/fr/inria/corese/core/compiler/eval/Custom.java +++ b/src/main/java/fr/inria/corese/core/compiler/eval/Custom.java @@ -1,85 +1,79 @@ package fr.inria.corese.core.compiler.eval; -import fr.inria.corese.core.sparql.api.IDatatype; -import fr.inria.corese.core.sparql.datatype.DatatypeMap; -import fr.inria.corese.core.sparql.exceptions.CoreseDatatypeException; import fr.inria.corese.core.kgram.api.core.Expr; import fr.inria.corese.core.kgram.api.query.Environment; import fr.inria.corese.core.kgram.api.query.Producer; +import fr.inria.corese.core.sparql.api.IDatatype; +import fr.inria.corese.core.sparql.datatype.DatatypeMap; +import fr.inria.corese.core.sparql.exceptions.CoreseDatatypeException; +import org.slf4j.LoggerFactory; + import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.List; -import org.slf4j.LoggerFactory; /** - * SPARQL Java extension functions + * SPARQL Java extension functions * cs:test() - * prefix cs: - * @author Olivier Corby, Wimmics INRIA I3S, 2015 + * prefix cs: <http://ns.inria.fr/sparql-custom/> * + * @author Olivier Corby, Wimmics INRIA I3S, 2015 */ public class Custom { - + public IDatatype eval(Expr exp, Environment env, Producer p, Object[] param) { try { return evalWE(exp, env, p, param); - } catch (NoSuchMethodException ex) { - LoggerFactory.getLogger(Custom.class.getName()).error(ex.getMessage()); - } catch (IllegalAccessException ex) { - LoggerFactory.getLogger(Custom.class.getName()).error(ex.getMessage()); - } catch (IllegalArgumentException ex) { - LoggerFactory.getLogger(Custom.class.getName()).error(ex.getMessage()); - } catch (InvocationTargetException ex) { + } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { LoggerFactory.getLogger(Custom.class.getName()).error(ex.getMessage()); } return null; } - - IDatatype evalWE(Expr exp, Environment env, Producer p, Object[] param) - throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{ + + IDatatype evalWE(Expr exp, Environment env, Producer p, Object[] param) + throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Class[] signature = getSignature(param.length); Method m = getClass().getMethod(exp.getShortName(), signature); Object res = m.invoke(this, param); return (IDatatype) res; } - - Class[] getSignature(int n){ + + Class[] getSignature(int n) { Class[] signature = new Class[n]; for (int i = 0; i < signature.length; i++) { signature[i] = IDatatype.class; } return signature; } - - public IDatatype test(IDatatype dt){ + + public IDatatype test(IDatatype dt) { return dt; } - - public IDatatype fib(IDatatype dt){ + + public IDatatype fib(IDatatype dt) { int n = dt.intValue(); - if (n <= 2){ + if (n <= 2) { return DatatypeMap.newInstance(1); - } - else { + } else { return fib(DatatypeMap.newInstance(n - 1)).plus(fib(DatatypeMap.newInstance(n - 2))); } } - - public IDatatype fibon(IDatatype dt){ - return DatatypeMap.newInstance(fibo(dt.intValue())); - } - int fibo(int n){ - if (n <= 2){ + public IDatatype fibon(IDatatype dt) { + return DatatypeMap.newInstance(fibo(dt.intValue())); + } + + int fibo(int n) { + if (n <= 2) { return 1; } - return fibo(n - 1) + fibo (n -2); + return fibo(n - 1) + fibo(n - 2); } - - - public IDatatype sort(IDatatype list){ - if (list.isList()){ + + + public IDatatype sort(IDatatype list) { + if (list.isList()) { try { sort(list.getValues()); } catch (CoreseDatatypeException ex) { @@ -88,7 +82,7 @@ public IDatatype sort(IDatatype list){ } return list; } - + void sort(List l) throws CoreseDatatypeException { for (int i = l.size() - 1; i > 0; i--) { for (int j = 0; j < i; j++) { diff --git a/src/main/java/fr/inria/corese/core/compiler/eval/Hash.java b/src/main/java/fr/inria/corese/core/compiler/eval/Hash.java index adf2c88a4..58b86a3c4 100644 --- a/src/main/java/fr/inria/corese/core/compiler/eval/Hash.java +++ b/src/main/java/fr/inria/corese/core/compiler/eval/Hash.java @@ -1,75 +1,56 @@ package fr.inria.corese.core.compiler.eval; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; -//import fr.cryptohash.*; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + /** * Use cryptographic library from saphir2 project - * + *

* http://www.saphir2.com/sphlib/ - * */ public class Hash { - private static Logger logger = LoggerFactory.getLogger(Hash.class); + private static final Logger logger = LoggerFactory.getLogger(Hash.class); + + String name; + + public Hash(String n) { + name = n; + } + + public String hash(String str) { + + byte[] uniqueKey = str.getBytes(); + byte[] hash = null; + + try { + hash = MessageDigest.getInstance(name).digest(uniqueKey); + } catch (NoSuchAlgorithmException e) { + logger.error("No support in this VM: " + name); + return null; + } - //static String SHA224 = "SHA-224"; - String name; - - public Hash(String n){ - name = n; - } - - public String hash(String str){ -// if (name.equals(SHA224)){ -// return sha224(str); -// } - - byte[] uniqueKey = str.getBytes(); - byte[] hash = null; + return toString(hash); + } - try { - hash = MessageDigest.getInstance(name).digest(uniqueKey); - } - catch (NoSuchAlgorithmException e){ - logger.error("No support in this VM: " + name); - return null; - } - String res = toString(hash); - return res; - } - -// String sha224(String str){ -// SHA224 hash = new SHA224(); -// byte[] data = str.getBytes(); -// byte[] out = hash.digest(data); -// if (out == null) return null; -// String res = toString(out); -// return res; -// } + String toString(byte[] hash) { + StringBuilder hashString = new StringBuilder(); + for (byte b : hash) { + String hex = Integer.toHexString(b); + if (hex.length() == 1) { + hashString.append('0'); + hashString.append(hex.charAt(hex.length() - 1)); + } else { + hashString.append(hex.substring(hex.length() - 2)); + } + } - - String toString(byte[] hash){ - StringBuilder hashString = new StringBuilder(); - for (int i = 0; i < hash.length; i++){ - String hex = Integer.toHexString(hash[i]); - if (hex.length() == 1){ - hashString.append('0'); - hashString.append(hex.charAt(hex.length() - 1)); - } - else { - hashString.append(hex.substring(hex.length() - 2)); - } - } + return hashString.toString(); + } - String res = hashString.toString(); - return res; - } - } diff --git a/src/main/java/fr/inria/corese/core/compiler/eval/Interpreter.java b/src/main/java/fr/inria/corese/core/compiler/eval/Interpreter.java index 4bbd1f6d4..aa1b7e530 100644 --- a/src/main/java/fr/inria/corese/core/compiler/eval/Interpreter.java +++ b/src/main/java/fr/inria/corese/core/compiler/eval/Interpreter.java @@ -6,15 +6,9 @@ import fr.inria.corese.core.kgram.api.query.Evaluator; import fr.inria.corese.core.kgram.api.query.Producer; import fr.inria.corese.core.kgram.core.Eval; -import fr.inria.corese.core.kgram.core.Exp; import fr.inria.corese.core.kgram.core.Query; import fr.inria.corese.core.kgram.event.ResultListener; -import fr.inria.corese.core.sparql.api.Computer; -import fr.inria.corese.core.sparql.api.ComputerProxy; -import fr.inria.corese.core.sparql.api.GraphProcessor; -import fr.inria.corese.core.sparql.api.IDatatype; -import fr.inria.corese.core.sparql.api.TransformProcessor; -import fr.inria.corese.core.sparql.api.TransformVisitor; +import fr.inria.corese.core.sparql.api.*; import fr.inria.corese.core.sparql.exceptions.EngineException; import fr.inria.corese.core.sparql.triple.function.term.Binding; import fr.inria.corese.core.sparql.triple.parser.ASTExtension; @@ -31,42 +25,29 @@ */ public class Interpreter implements Computer, Evaluator, ExprType { - public static boolean testNewEval = false; - private static Logger logger = LoggerFactory.getLogger(Interpreter.class); - static final String MEMORY = Exp.KGRAM + "memory"; - static final String STACK = Exp.KGRAM + "stack"; - public static int DEFAULT_MODE = KGRAM_MODE; static final IDatatype[] EMPTY = new IDatatype[0]; - //protected ProxyInterpreter proxy; - // fr.inria.corese.core.query.PluginImpl - private ProxyInterpreter plugin; + private static final Logger logger = LoggerFactory.getLogger(Interpreter.class); + public static boolean testNewEval = false; + public static Mode DEFAULT_MODE = Mode.KGRAM_MODE; + public static int count = 0; Producer producer; Eval kgram; ResultListener listener; - int mode = DEFAULT_MODE; + Mode mode = DEFAULT_MODE; boolean hasListener = false; - boolean isDebug = false; - public static int count = 0; - IDatatype ERROR_VALUE = null; + // fr.inria.corese.core.query.PluginImpl + private ProxyInterpreter plugin; public Interpreter() { } - // for PluginImpl - public void setPlugin(ProxyInterpreter plugin) { - this.plugin = plugin; - if (plugin.getEvaluator() == null) { - plugin.setEvaluator(this); - } - } - public static ASTExtension createExtension() { return new ASTExtension(); } public static ASTExtension getCreateExtension(Query q) { - ASTExtension ext = q.getExtension();; + ASTExtension ext = q.getExtension(); if (ext == null) { ext = createExtension(); q.setExtension(ext); @@ -74,30 +55,17 @@ public static ASTExtension getCreateExtension(Query q) { return ext; } - @Override - public void setProducer(Producer p) { - producer = p; - } - public Producer getProducer() { return producer; } @Override - public void setKGRAM(Eval o) { - //kgram = o; + public void setProducer(Producer p) { + producer = p; } @Override - public void setDebug(boolean b) { - isDebug = b; - } - - Eval getEval(Environment env) { - if (env.getEval() == null) { - logger.warn("env.getEval() = null"); - } - return env.getEval(); + public void setKGRAM(Eval o) { } @Override @@ -105,148 +73,30 @@ public void addResultListener(ResultListener rl) { listener = rl; hasListener = rl != null; } - + @Override public Evaluator getEvaluator() { return this; } - -// Eval createEval(Eval currentEval, Expr exp, Environment env, Producer p) { -// Exp pat = env.getQuery().getPattern(exp); -// Memory memory = currentEval.createMemory(env, pat); -// if (memory == null) { -// return null; -// } -// // producer below must be original Producer, it is used for cast purpose -// Eval eval = currentEval.copy(memory, p, exp.isSystem()); -// eval.setSubEval(true); -// return eval; -// } - - /** - * filter exists { } exists statement is also used to embed LDScript nested - * query in this case it is tagged as system - */ -// @Override -// public IDatatype exist(Expr exp, Environment env, Producer p) throws EngineException { -// try { -// if (hasListener) { -// listener.listen(exp); -// } -// if (exp.arity() == 1) { -// // argument return a graph on which we evaluate the exists -// //IDatatype res = eval(exp.getExp(0), env, p); -// IDatatype res = exp.getExp(0).evalWE(this, env.getBind(), env, p); -// if (res == ERROR_VALUE) { -// return ERROR_VALUE; -// } -// if (p.isProducer((Node) res)) { -// p = p.getProducer((Node) res, env); -// } -// } -// Query q = env.getQuery(); -// Exp pat = q.getPattern(exp); -// Node gNode = env.getGraphNode(); -// Eval currentEval = getEval(env); -// Mappings map = null; -// -// // in case of // evaluation of a pattern -// synchronized (exp) { -// if (exp.isSystem()) { -// // system generated for LDScript nested query -// // e.g. for (?m in select where) {} -// // is compiled with internal system exists -// // for (?m in exists {select where}){} -// Exp sub = pat.get(0).get(0); -// -// if (sub.isQuery()) { -// Query qq = sub.getQuery(); -// qq.setFun(true); -// if (qq.isConstruct() || qq.isUpdate()) { -// Mappings m = currentEval.getSPARQLEngine().eval(gNode, qq, getMapping(env, qq), p); -// return DatatypeMap.createObject((m.getGraph() == null) ? p.getGraph() : m.getGraph()); -// } -// if (qq.getService() != null) { -// // @federate let (?m = select where) -// Mappings m = currentEval.getSPARQLEngine().eval(qq, getMapping(env, qq), p); -// return DatatypeMap.createObject(m); -// } else { -// // let (?m = select where) -// if (testNewEval) { -// map = currentEval.getSPARQLEngine().eval(gNode, qq, getMapping(env, qq), p); -// } else { -// Eval eval = createEval(currentEval, exp, env, p); -// if (eval == null) { -// return null; -// } -// map = eval.subEval(qq, gNode, Stack.create(sub), 0); -// } -// } -// } else { -// // never happen -// return null; -// } -// } else { -// // SPARQL exists {} -// Eval eval = createEval(currentEval, exp, env, p); -// if (eval == null) { -// return null; -// } -// eval.setLimit(1); -// map = eval.subEval(q, gNode, Stack.create(pat), 0); -// } -// } -// -// boolean b = map.size() > 0; -// -// if (exp.isSystem()) { -// return DatatypeMap.createObject(map); -// } else { -// //report(q, env, map); -// return DatatypeMap.newInstance(b); -// } -// } catch (SparqlException e) { -// throw EngineException.cast(e); -// } -// } - - /** - * Create a mapping with var = val coming from Bind stack - */ -// Mapping getMapping(Environment env, Query q) { -// if (env.hasBind()) { -// // share variables -// Mapping map = Mapping.create(q, env.getBind()); -// // share global variables and ProcessVisitor -// map.setBind(env.getBind()); -// return map; -// } else { -// // share global variables and ProcessVisitor -// return Mapping.create(env.getBind()); -// } -// } - @Override - public void setMode(int m) { - mode = m; - //proxy.setMode(m); - getPlugin().setMode(m); + public Mode getMode() { + return mode; } @Override - public int getMode() { - return mode; + public void setMode(Mode m) { + mode = m; + getPlugin().setMode(m); } @Override public boolean isCompliant() { - return mode == SPARQL_MODE; + return mode == Mode.SPARQL_MODE; } @Override public void start(Environment env) { - //proxy.start(producer, env); } @Override @@ -266,8 +116,6 @@ public void finish(Environment env) { getPlugin().finish(producer, env); } - - public ProxyInterpreter getComputerPlugin() { return getPlugin(); } @@ -310,4 +158,12 @@ public ProxyInterpreter getPlugin() { return plugin; } + // for PluginImpl + public void setPlugin(ProxyInterpreter plugin) { + this.plugin = plugin; + if (plugin.getEvaluator() == null) { + plugin.setEvaluator(this); + } + } + } diff --git a/src/main/java/fr/inria/corese/core/compiler/eval/ProxyInterpreter.java b/src/main/java/fr/inria/corese/core/compiler/eval/ProxyInterpreter.java index 0049a0385..f59881833 100644 --- a/src/main/java/fr/inria/corese/core/compiler/eval/ProxyInterpreter.java +++ b/src/main/java/fr/inria/corese/core/compiler/eval/ProxyInterpreter.java @@ -1,123 +1,71 @@ package fr.inria.corese.core.compiler.eval; -import fr.inria.corese.core.sparql.api.ComputerProxy; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import fr.inria.corese.core.sparql.api.IDatatype; -import fr.inria.corese.core.sparql.datatype.DatatypeMap; -import fr.inria.corese.core.sparql.triple.parser.NSManager; import fr.inria.corese.core.kgram.api.core.Expr; import fr.inria.corese.core.kgram.api.core.ExprType; import fr.inria.corese.core.kgram.api.query.Environment; +import fr.inria.corese.core.kgram.api.query.Evaluator; import fr.inria.corese.core.kgram.api.query.Producer; -import fr.inria.corese.core.kgram.event.EvalListener; -import fr.inria.corese.core.sparql.api.GraphProcessor; import fr.inria.corese.core.kgram.core.Eval; +import fr.inria.corese.core.sparql.api.ComputerProxy; +import fr.inria.corese.core.sparql.api.GraphProcessor; +import fr.inria.corese.core.sparql.api.IDatatype; +import fr.inria.corese.core.sparql.datatype.DatatypeMap; import fr.inria.corese.core.sparql.exceptions.EngineException; import fr.inria.corese.core.sparql.triple.function.script.Function; import fr.inria.corese.core.sparql.triple.parser.Context; +import fr.inria.corese.core.sparql.triple.parser.NSManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * Evaluator of operators & functions of filter language + * Evaluator of operators & functions of filter language * implemented by fr.inria.corese.core.query.PluginImpl - * + * * @author Olivier Corby, Edelweiss, INRIA 2010 - * */ public abstract class ProxyInterpreter implements ExprType { - private static final String URN_UUID = "urn:uuid:"; - private static Logger logger = LoggerFactory.getLogger(ProxyInterpreter.class); - public static final IDatatype TRUE = DatatypeMap.TRUE; - public static final IDatatype FALSE = DatatypeMap.FALSE; - public static final IDatatype UNDEF = DatatypeMap.UNBOUND; - - static final String UTF8 = "UTF-8"; - public static final String RDFNS = NSManager.RDF; //"http://www.w3.org/1999/02/22-rdf-syntax-ns#"; - public static final String RDFTYPE = RDFNS + "type"; - private static final String USER_DISPLAY = NSManager.USER + "display"; + public static final String RDFNS = NSManager.RDF; + private static final Logger logger = LoggerFactory.getLogger(ProxyInterpreter.class); public static int count = 0; - //ProxyInterpreter plugin; - Custom custom; - SQLFun sql; + protected IDatatype EMPTY = DatatypeMap.newStringBuilder(""); Interpreter eval; + int number = 0; private Producer producer; - EvalListener el; // for LDScript java compiling only private Environment environment; - int number = 0; - // KGRAM is relax wrt to string vs literal vs uri input arg of functions - // eg regex() concat() strdt() - // setMode(SPARQL_MODE) - boolean SPARQLCompliant = false; - protected IDatatype EMPTY = DatatypeMap.newStringBuilder(""); - public ProxyInterpreter() { -// sql = new SQLFun(); -// custom = new Custom(); - //setPlugin(this); - } - - public void setEvaluator(Interpreter ev) { - eval = ev; -// if (plugin != null) { -// plugin.setEvaluator(ev); -// } + protected ProxyInterpreter() { } public Interpreter getEvaluator() { return eval; } -// public void setPlugin(ProxyInterpreter p) { -// plugin = p; -// //plugin.setEvaluator(eval); -// } - -// public ProxyInterpreter getPlugin() { -// return plugin; -// } -// -// public ProxyInterpreter getComputerPlugin() { -// return plugin; -// } + public void setEvaluator(Interpreter ev) { + eval = ev; + } public GraphProcessor getGraphProcessor() { - //return plugin.getGraphProcessor(); return null; } public ComputerProxy getComputerTransform() { - //return plugin.getComputerTransform(); return null; } - public void setMode(int mode) { -// switch (mode) { -// -// case Evaluator.SPARQL_MODE: -// SPARQLCompliant = true; -// break; -// -// case Evaluator.KGRAM_MODE: -// SPARQLCompliant = false; -// break; -// } -// plugin.setMode(mode); - } + public abstract void setMode(Evaluator.Mode mode); public void start() { number = 0; } - + public Producer getProducer() { return producer; } - + // for Core & Extension public void setProducer(Producer producer) { this.producer = producer; @@ -125,9 +73,9 @@ public void setProducer(Producer producer) { public IDatatype getValue(boolean b) { if (b) { - return TRUE; + return DatatypeMap.TRUE; } else { - return FALSE; + return DatatypeMap.FALSE; } } @@ -157,38 +105,28 @@ public IDatatype getValue(String value) { } public Function getDefine(Expr exp, Environment env, String name, int n) throws EngineException { - //return plugin.getDefine(exp, env, name, n); return null; } - public void start(Producer p, Environment env) { - //plugin.start(p, env); - } + public abstract void start(Producer p, Environment env); - public void finish(Producer p, Environment env) { - //plugin.finish(p, env); - } + public abstract void finish(Producer p, Environment env); -// public IDatatype getBufferedValue(StringBuilder sb, Environment env) { -// //return plugin.getBufferedValue(sb, env); -// return null; -// } - public Environment getEnvironment() { return environment; } + // for Core & Extension + public void setEnvironment(Environment environment) { + this.environment = environment; + } + public Context getContext() { - return ((Interpreter) getEval().getEvaluator()).getContext(getEnvironment().getBind(), getEnvironment(), getProducer()); + return getEval().getEvaluator().getContext(getEnvironment().getBind(), getEnvironment(), getProducer()); } public Eval getEval() { return getEnvironment().getEval(); } - - // for Core & Extension - public void setEnvironment(Environment environment) { - this.environment = environment; - } } diff --git a/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolver.java b/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolver.java index 030b59dce..4bdf77505 100755 --- a/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolver.java +++ b/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolver.java @@ -1,65 +1,43 @@ package fr.inria.corese.core.compiler.eval; -import fr.inria.corese.core.sparql.api.IDatatype; -import fr.inria.corese.core.sparql.triple.parser.Dataset; -import java.util.ArrayList; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.Atom; -import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; -import fr.inria.corese.core.sparql.triple.parser.Constant; -import fr.inria.corese.core.sparql.triple.parser.Metadata; -import fr.inria.corese.core.sparql.triple.parser.NSManager; -import fr.inria.corese.core.sparql.triple.parser.Triple; -import fr.inria.corese.core.sparql.triple.function.term.Binding; import fr.inria.corese.core.compiler.api.QueryVisitor; import fr.inria.corese.core.compiler.parser.Pragma; import fr.inria.corese.core.compiler.parser.Transformer; import fr.inria.corese.core.kgram.api.core.Node; -import fr.inria.corese.core.kgram.api.query.Environment; -import fr.inria.corese.core.kgram.api.query.Matcher; -import fr.inria.corese.core.kgram.api.query.ProcessVisitor; -import fr.inria.corese.core.kgram.api.query.Producer; -import fr.inria.corese.core.kgram.api.query.Provider; -import fr.inria.corese.core.kgram.api.query.SPARQLEngine; -import fr.inria.corese.core.kgram.core.Eval; -import fr.inria.corese.core.kgram.core.Mapping; -import fr.inria.corese.core.kgram.core.Mappings; +import fr.inria.corese.core.kgram.api.query.*; import fr.inria.corese.core.kgram.core.Query; -import fr.inria.corese.core.kgram.core.Sorter; -import fr.inria.corese.core.kgram.core.SparqlException; +import fr.inria.corese.core.kgram.core.*; import fr.inria.corese.core.kgram.event.EventListener; import fr.inria.corese.core.kgram.event.EventManager; import fr.inria.corese.core.kgram.event.ResultListener; import fr.inria.corese.core.kgram.tool.MetaProducer; +import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.datatype.DatatypeMap; import fr.inria.corese.core.sparql.exceptions.EngineException; -import fr.inria.corese.core.sparql.triple.parser.Access; +import fr.inria.corese.core.sparql.triple.function.term.Binding; +import fr.inria.corese.core.sparql.triple.parser.*; import fr.inria.corese.core.sparql.triple.parser.Access.Feature; import fr.inria.corese.core.sparql.triple.parser.Access.Level; -import fr.inria.corese.core.sparql.triple.parser.AccessRight; -import fr.inria.corese.core.sparql.triple.parser.Context; import fr.inria.corese.core.sparql.triple.parser.context.ContextLog; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; /** * Evaluator of SPARQL query by KGRAM Ready to use Package with KGRAM and SPARQL - * Parser & Transformer + * Parser & Transformer * * @author Olivier Corby, Edelweiss, INRIA 2010 - * */ public class QuerySolver implements SPARQLEngine { - private static Logger logger = LoggerFactory.getLogger(QuerySolver.class); public static final String MAIN_FUN = NSManager.EXT + "main"; - public static final int STD_ENTAILMENT = 0; public static final int RDF_ENTAILMENT = 1; public static final int RDFS_ENTAILMENT = 2; + private static final Logger logger = LoggerFactory.getLogger(QuerySolver.class); public static int QUERY_PLAN = Query.QP_DEFAULT; public static boolean BGP_DEFAULT = false; public static boolean ALGEBRA_DEFAULT = false; @@ -67,11 +45,8 @@ public class QuerySolver implements SPARQLEngine { // true: do not join 1 and 1.0 // true: from named without from is sparql compliant public static boolean SPARQL_COMPLIANT_DEFAULT = false; - private static boolean visitorable = false; - static String NAMESPACES; - private static Metadata defaultMetadata; - + private static boolean visitorable = false; protected EventManager manager; protected ResultListener listener; protected Producer producer; @@ -80,17 +55,22 @@ public class QuerySolver implements SPARQLEngine { protected Matcher matcher; protected Sorter sort; protected List visit; - private List serviceList; - // use case: reuse federated visitor source selection - private Mappings mappings; - boolean isListGroup = false, isListPath = true, isCountPath = false, isCheckLoop = false, isDebug = false, - isOptimize = false, + isOptimize = false, isSPARQLCompliant = SPARQL_COMPLIANT_DEFAULT; + boolean isSequence = false; + int slice = Query.DEFAULT_SLICE; + // set default base for SPARQL Query + // it is overloaded if query has a base (cf prefix/base) + // use case: expand from in manifest.ttl + String defaultBase; + Eval current; + // use case: reuse federated visitor source selection + private Mappings mappings; private boolean isGenerateMain = true; private boolean isSynchronized = false; private boolean isPathType = false; @@ -105,31 +85,12 @@ public class QuerySolver implements SPARQLEngine { private boolean isMatchBlank = false; // skolemize construct/describe result graphs (and only them) private boolean isSkolem = false; - private boolean isDetail = false; - - boolean isSequence = false; - - int slice = Query.DEFAULT_SLICE; - //private int mode = INIT_SERVER_MODE; - - // set default base for SPARQL Query - // it is overloaded if query has a base (cf prefix/base) - // use case: expand from in manifest.ttl - String defaultBase; - private BasicGraphPattern pragma; private Metadata metadata; private Binding binding; - - static int count = 0; - - private AccessRight accessRight; - - static boolean test = true; private int planner = QUERY_PLAN; private boolean isUseBind = false; - Eval current; public QuerySolver() { } @@ -149,6 +110,33 @@ public static void setPlanDefault(int n) { QUERY_PLAN = n; } + public static void defaultNamespaces(String ns) { + NAMESPACES = ns; + } + + public static void definePrefix(String pref, String ns) { + if (NAMESPACES == null) { + NAMESPACES = ""; + } + NAMESPACES += pref + " " + ns + " "; + } + + public static void testAlgebra(boolean b) { + BGP_DEFAULT = b; + ALGEBRA_DEFAULT = b; + } + + public static boolean isVisitorable() { + return visitorable; + } + + /** + * @param aVisitorable the visitorable to set + */ + public static void setVisitorable(boolean aVisitorable) { + visitorable = aVisitorable; + } + public void add(Producer prod) { MetaProducer meta; if (producer instanceof MetaProducer) { @@ -165,15 +153,15 @@ public void add(Producer prod) { public void set(Sorter s) { sort = s; } - + public ContextLog getLog(Mappings map) { return getLog(); } - + public ContextLog getLog() { return getCreateBinding().getCreateLog(); } - + public ContextLog getCreateLog() { return getCreateBinding().getCreateLog(); } @@ -205,25 +193,19 @@ public Provider getProvider() { return provider; } - public void setSPARQL1(boolean b) { - } - - public static void defaultSPARQL1(boolean b) { - } - public void setDefaultBase(String str) { setBase(str); } - public void setBase(String str) { - defaultBase = str; - } - public String getBase() { return defaultBase; } - public Transformer transformer() { + public void setBase(String str) { + defaultBase = str; + } + + public Transformer transformer() { Transformer transformer = Transformer.create(); transformer.setSPARQLEngine(this); if (sort != null) { @@ -241,32 +223,29 @@ public Transformer transformer() { public Mappings basicQuery(ASTQuery ast) throws EngineException { return basicQuery(ast, null, null); } - + public Mappings basicQuery(ASTQuery ast, Context ct) throws EngineException { return basicQuery(ast, null, Dataset.create(ct)); } - - /** - * Dataset may contain Binding and/or Context + + /** + * Dataset may contain Binding and/or Context * Prepare Mapping with Binding/Context for Eval query processing * Binding records Context if any * Note that st:get/st:set consider Context in Query (cf PluginTransform getContext()) - * ProviderService consider Context in Binding - * Hence we have Context both in Query and in Binding - * + * ProviderService consider Context in Binding + * Hence we have Context both in Query and in Binding */ public Mapping completeMappings(Query q, Mapping m, Dataset ds) { - if (q.getContext()!=null && ds==null) { + if (q.getContext() != null && ds == null) { // use case: federate visitor create context ds = Dataset.create(q.getContext()); } - if (ds != null) { - if (ds.getBinding() != null || ds.getContext() != null) { - if (m == null) { - m = new Mapping(); - } - return ds.call(m); + if (ds != null && (ds.getBinding() != null || ds.getContext() != null)) { + if (m == null) { + m = new Mapping(); } + return ds.call(m); } return m; } @@ -276,7 +255,7 @@ public Mappings basicQuery(ASTQuery ast, Mapping m, Dataset ds) throws EngineExc m = completeMappings(query, m, ds); return query(query, m); } - + public Mappings query(String squery) throws EngineException { return query(squery, null, null); } @@ -289,14 +268,14 @@ public Mappings query(String squery, Mapping map, Dataset ds) throws EngineExcep Query query = compile(squery, ds); return query(query, map); } - + public Mappings query(Query query) throws EngineException { return query(query, null); } @Override public Mappings eval(Query query, Mapping m, Producer p) throws SparqlException { - return query((Node) null, query, m); + return query(null, query, m); } @Override @@ -308,7 +287,7 @@ public Mappings eval(Node gNode, Query query, Mapping m, Producer p) throws Spar * Core QueryExec processor */ public Mappings query(Query query, Mapping m) throws EngineException { - return query((Node) null, query, m); + return query(null, query, m); } /** @@ -316,7 +295,6 @@ public Mappings query(Query query, Mapping m) throws EngineException { */ public Mappings query(Node gNode, Query query, Mapping m) throws EngineException { init(query); - debug(query); if (getProducer() instanceof MetaProducer) { query.setDistribute(true); @@ -344,14 +322,14 @@ public Mappings query(Node gNode, Query query, Mapping m) throws EngineException } void before(Query q) { - ASTQuery ast = q.getAST(); + ASTQuery ast = q.getAST(); for (fr.inria.corese.core.sparql.api.QueryVisitor vis : ast.getVisitorList()) { vis.before(q); } } void after(Mappings map) { - ASTQuery ast = map.getQuery().getAST(); + ASTQuery ast = map.getQuery().getAST(); for (fr.inria.corese.core.sparql.api.QueryVisitor vis : ast.getVisitorList()) { vis.after(map); } @@ -371,7 +349,7 @@ public Binding getEnvironmentBinding() { * If a query has been executed, return Environment Binding * otherwise, create a temporary local Binding * Use case: @federate need a Binding - * PRAGMA: + * PRAGMA: * if a query is executed later, the two Binding will differ */ public Binding getCreateBinding() { @@ -384,29 +362,29 @@ public Binding getCreateBinding() { } return bind; } - - public Binding getCreateBinding (Mapping m) { + + public Binding getCreateBinding(Mapping m) { Binding b = getBinding(m); if (b != null) { return b; } return getCreateBinding(); } - + public Binding getBinding(Mapping m) { if (m == null) { return null; } return m.getBind(); } - + public Environment getEnvironment() { if (getCurrentEval() == null) { return null; } return getCurrentEval().getEnvironment(); } - + public Context getContext() { return getCreateBinding().getCreateContext(); } @@ -416,22 +394,21 @@ public void finish() { current.finish(); } } - + public Mappings modifier(Query q, Mappings map) throws SparqlException { if (getCurrentEval() == null) { logger.info("Undefined Eval"); return getCreateEval().modifier(q, map); - } - else { + } else { return getCurrentEval().modifier(q, map); } } - + // defined in QueryProcess - public Eval getCreateEval() throws EngineException{ + public Eval getCreateEval() throws EngineException { return null; } - + public Eval getCurrentEval() { return current; } @@ -440,13 +417,8 @@ public void setCurrentEval(Eval e) { current = e; } -// public void setEval(Eval e) { -// setCurrentEval(e); -// } - void tune(Eval kgram, Query q, Mapping m) { - ASTQuery ast = q.getAST(); -// boolean event = ast.hasMetadata(Metadata.EVENT); + ASTQuery ast = q.getAST(); boolean event = true; // Dataset ds parameter in QueryProcess is set as ast defaultDataset tune(kgram, ast.getDefaultDataset(), m, event); @@ -462,17 +434,16 @@ void tune(Eval kgram) { void tune(Eval kgram, Dataset ds, Mapping m, boolean isVisitor) { if ((isVisitor || isVisitorable()) && isEvent(m)) { - if (ds != null && ds.getVisitor()!= null) { + if (ds != null && ds.getVisitor() != null) { ds.getVisitor().setProcessor(kgram); kgram.setVisitor(ds.getVisitor()); - } - else { + } else { kgram.setVisitor(createProcessVisitor(kgram)); } } kgram.getVisitor().setDefaultValue(DatatypeMap.TRUE); } - + boolean isEvent(Mapping m) { return Access.accept(Feature.EVENT, Access.getLevel(m)); } @@ -490,7 +461,6 @@ Eval makeEval() { } /** - * * @return an Eval able to execute callback functions str contains function * definitions * @throws EngineException @@ -514,26 +484,9 @@ public Eval createEval(Query q) throws EngineException { } @Deprecated - public IDatatype eval(String q) throws EngineException { + public IDatatype eval(String q) { return DatatypeMap.TRUE; } -// -// public IDatatype eval(String q, Dataset ds) throws EngineException { -// return eval(q, MAIN_FUN, ds); -// } -// -// IDatatype eval(String q, String name, Dataset ds) throws EngineException { -// setGenerateMain(false); -// Eval kgram = createEval(q, ds); -// setEval(kgram); -// IDatatype dt = funcall(name); -// return dt; -// } -// -// // overriden by QueryProcess -// public IDatatype funcall(String name, IDatatype... param) throws EngineException { -// return null; -// } void init(Query q) { // use case: OWL RL kg:sparql(query) in a rule @@ -551,9 +504,6 @@ void init(Query q) { q.setCheckLoop(isCheckLoop); q.setDetail(q.isDetail() || isDetail); q.setSlice(slice); - if (isDebug()) { - q.setDebug(isDebug()); - } if (isOptimize) { q.setOptimize(isOptimize); } @@ -580,7 +530,7 @@ public Interpreter getInterpreter() { } public ASTQuery getAST(Query q) { - return q.getAST(); + return q.getAST(); } public ASTQuery getAST(Mappings lm) { @@ -599,17 +549,11 @@ public void addResultListener(ResultListener el) { listener = el; } - public void removeResultListener(ResultListener el) { - if (listener == el) { - listener = null; - } - } - public Query compile(String squery) throws EngineException { return compile(squery, null); } - // rule: construct where + // rule: construct where public Query compileRule(String squery) throws EngineException { return compileRule(squery, null); } @@ -628,21 +572,19 @@ void setParameter(Transformer transformer) { public Query compileRule(String squery, Dataset ds) throws EngineException { Transformer transformer = createTransformer(ds); - Query query = transformer.transform(squery, true); - return query; + return transformer.transform(squery, true); } public Query compile(String squery, Dataset ds) throws EngineException { Transformer transformer = createTransformer(ds); transformer.setSPARQLCompliant(isSPARQLCompliant); - Query query = transformer.transform(squery); - return query; + return transformer.transform(squery); } - + public ASTQuery parse(String q) throws EngineException { return parse(q, (Dataset) null); } - + public ASTQuery parse(String q, Dataset ds) throws EngineException { Transformer transformer = createTransformer(ds); return transformer.parse(q); @@ -655,7 +597,7 @@ Transformer createTransformer(Dataset ds) { transformer.set(ds); return transformer; } - + public Query compile(ASTQuery ast, Dataset ds) throws EngineException { if (ds != null) { ast.setDefaultDataset(ds); @@ -674,7 +616,7 @@ public Query compile(ASTQuery ast) throws EngineException { completeCompile(query); return query; } - + // FederateVisitor set data in ast Log // share it in solver log void completeCompile(Query query) { @@ -683,23 +625,6 @@ void completeCompile(Query query) { } } -// Query compileFilter(String filter) throws EngineException { -// String str = "select * where {} having(" + filter + ")"; -// Query q = compile(str); -// return q; -// } - - - void debug(Query query) { - if (query.isDebug()) { - logger.debug(query.getBody().toString()); - logger.debug("limit " + query.getLimit()); - if (query.isFail()) { - logger.debug("Fail at compile time"); - } - } - } - void events(Eval kgram) { if (manager != null) { for (EventListener el : manager) { @@ -710,7 +635,7 @@ void events(Eval kgram) { } void pragma(Eval kgram, Query query) { - ASTQuery ast = query.getAST(); + ASTQuery ast = query.getAST(); Pragma pg = new Pragma(kgram, query, ast); if (getPragma() != null) { pg.parse(getPragma()); @@ -742,17 +667,6 @@ public void addPragma(Atom subject, Atom property, Atom value) { getPragma().add(Triple.create(subject, property, value)); } - public static void defaultNamespaces(String ns) { - NAMESPACES = ns; - } - - public static void definePrefix(String pref, String ns) { - if (NAMESPACES == null) { - NAMESPACES = ""; - } - NAMESPACES += pref + " " + ns + " "; - } - public void setListGroup(boolean b) { isListGroup = b; } @@ -769,22 +683,22 @@ public void setPathLoop(boolean b) { isCheckLoop = !b; } - public void setSPARQLCompliant(boolean isSPARQLCompliant) { - this.isSPARQLCompliant = isSPARQLCompliant; - } - boolean isSPARQLCompliant() { return isSPARQLCompliant; } - public void setDebug(boolean b) { - isDebug = b; + public void setSPARQLCompliant(boolean isSPARQLCompliant) { + this.isSPARQLCompliant = isSPARQLCompliant; } public boolean isDebug() { return isDebug; } + public void setDebug(boolean b) { + isDebug = b; + } + public void setOptimize(boolean b) { isOptimize = b; } @@ -893,56 +807,30 @@ public void setCachePath(boolean isCachePath) { this.isCachePath = isCachePath; } -// /** -// * @return the mode -// */ -// public int getMode() { -// return mode; -// } -// -// /** -// * @param mode the mode to set -// */ -// public void setMode(int mode) { -// this.mode = mode; -// //initMode(); -// } -// -// static public void setModeDefault(int mode) { -// INIT_SERVER_MODE = mode; -// } - -// public void initMode() { -// } - // true = skip Lock ; false = with Lock @Override public boolean isSynchronized() { return isSynchronized; } - + // true = skip Lock ; false = with Lock @Override public void setSynchronized(boolean isSynchronized) { this.isSynchronized = isSynchronized; } - public boolean isUseBind() { return isUseBind; } - public void setUseBind(boolean isUseBind) { this.isUseBind = isUseBind; } - public boolean isGenerateMain() { return isGenerateMain; } - public void setGenerateMain(boolean isGenerateMain) { this.isGenerateMain = isGenerateMain; } @@ -950,10 +838,11 @@ public void setGenerateMain(boolean isGenerateMain) { public Query parseQuery(String path) throws EngineException { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } - + public Query parseQuery(String path, Level level) throws EngineException { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } + public ASTQuery parse(String path, Level level) throws EngineException { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } @@ -962,12 +851,10 @@ Metadata getActualMetadata() { return getMetadata(); } - public Metadata getMetadata() { return metadata; } - public void setMetadata(Metadata metadata) { this.metadata = metadata; } @@ -976,34 +863,14 @@ public void set(Metadata metadata) { this.metadata = metadata; } - public boolean isRule() { return isRule; } - public void setRule(boolean rule) { this.isRule = rule; } - -// public List getServiceList() { -// return serviceList; -// } -// -// -// public void setServiceList(List serviceList) { -// this.serviceList = serviceList; -// } - -// public void service(String uri) { -// if (getServiceList() == null) { -// setServiceList(new ArrayList()); -// } -// getServiceList().add(Constant.createResource(uri)); -// } - - public boolean isAlgebra() { return algebra; } @@ -1017,17 +884,10 @@ public void setAlgebra(boolean algebra) { this.algebra = algebra; } - public static void testAlgebra(boolean b) { - BGP_DEFAULT = b; - ALGEBRA_DEFAULT = b; - } - - public boolean isBGP() { return isBGP; } - public void setBGP(boolean BGP) { this.isBGP = BGP; } @@ -1036,26 +896,14 @@ public void setBGP(boolean BGP) { public void getLinkedFunction(String uri) throws EngineException { } - - public static boolean isVisitorable() { - return visitorable; - } - - /** - * @param aVisitorable the visitorable to set - */ - public static void setVisitorable(boolean aVisitorable) { - visitorable = aVisitorable; + public Binding getBinding() { + return binding; } public void setBinding(Binding binding) { this.binding = binding; } - public Binding getBinding() { - return binding; - } - public Mappings getMappings() { return mappings; } diff --git a/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolverOverload.java b/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolverOverload.java index 230f64254..c050528f3 100644 --- a/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolverOverload.java +++ b/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolverOverload.java @@ -8,29 +8,27 @@ import fr.inria.corese.core.sparql.triple.parser.NSManager; /** - * * @author Olivier Corby, Wimmics INRIA I3S, 2018 - * */ public class QuerySolverOverload { - public static final String ERROR = "@error"; + public static final String ERROR = "@error"; public static final String EQ = "@eq"; public static final String NE = "@ne"; public static final String LE = "@le"; public static final String LT = "@lt"; public static final String GE = "@ge"; public static final String GT = "@gt"; - - public static final String PLUS = "@plus"; + + public static final String PLUS = "@plus"; public static final String MINUS = "@minus"; - public static final String MULT = "@mult"; + public static final String MULT = "@mult"; public static final String DIVIS = "@divis"; public static final String US = NSManager.USER; public static final String MERROR = US + "error"; - + public static final String MEQ = US + "eq"; public static final String MNE = US + "ne"; public static final String MLE = US + "le"; @@ -38,61 +36,58 @@ public class QuerySolverOverload { public static final String MGE = US + "ge"; public static final String MGT = US + "gt"; - public static final String MPLUS = US + "plus"; + public static final String MPLUS = US + "plus"; public static final String MMINUS = US + "minus"; - public static final String MMULT = US + "mult"; + public static final String MMULT = US + "mult"; public static final String MDIVIS = US + "divis"; public static final String MCOMPARE = US + "compare"; - - static final IDatatype ERROR_DATATYPE = DatatypeMap.newResource(IDatatype.ERROR_DATATYPE); - - private boolean overload = true; + static final IDatatype ERROR_DATATYPE = DatatypeMap.newResource(IDatatype.ERROR_DATATYPE); QuerySolverVisitorBasic visitor; - - + private boolean overload = true; + + QuerySolverOverload(QuerySolverVisitorBasic vis) { visitor = vis; } - - public void setOverload(boolean b) { - overload = b; - } - + public boolean isOverload() { return overload; } - + + public void setOverload(boolean b) { + overload = b; + } boolean overload(Expr exp, IDatatype res, IDatatype dt1, IDatatype dt2) { return overload && isOverload(dt1, dt2); } - - boolean overload(IDatatype dt1, IDatatype dt2) { + + boolean overload(IDatatype dt1, IDatatype dt2) { return overload && isOverload(dt1, dt2); } boolean isOverload(IDatatype dt1, IDatatype dt2) { return datatypeOverload(dt1, dt2) || bnodeOverload(dt1, dt2); } - + boolean bnodeOverload(IDatatype dt1, IDatatype dt2) { return dt1.isBlank() && dt2.isBlank(); } - + boolean datatypeOverload(IDatatype dt1, IDatatype dt2) { - return dt1.isGeneralized()&& dt2.isGeneralized() - && (dt1.getDatatypeURI().equals(dt2.getDatatypeURI()) || compatible(dt1, dt2)); + return dt1.isGeneralized() && dt2.isGeneralized() + && (dt1.getDatatypeURI().equals(dt2.getDatatypeURI()) || compatible(dt1, dt2)); } - + // placeholder to determine if datatypes are compatible // length in km and length in m are compatible // use case: xt:datatype(us:km, us:length) // use case: xt:datatype(us:m, us:length) boolean compatible(IDatatype dt1, IDatatype dt2) { String t1 = visitor.getSuperType(dt1.getDatatype()); - String t2 = visitor.getSuperType(dt2.getDatatype()); + String t2 = visitor.getSuperType(dt2.getDatatype()); return t1 != null && t2 != null && t1.equals(t2); } @@ -114,23 +109,23 @@ IDatatype overload(Eval eval, Expr exp, IDatatype res, IDatatype[] param) { return error(eval, exp, param); } // std result - return res; + return res; } return dt; } - + int compare(Eval eval, int res, IDatatype... param) { - IDatatype dt = visitor.methodBasic(eval, MCOMPARE, param); + IDatatype dt = visitor.methodBasic(eval, MCOMPARE, param); if (dt == null) { return res; } return dt.intValue(); } - - + + /** - * a = b return null - * 1) try @type dt:error function us:eq(?e, ?a, ?b) + * a = b return null + * 1) try @type dt:error function us:eq(?e, ?a, ?b) * 2) then try @type dt:error function us:error(?e, a, ?b) */ IDatatype overloadErrorMethod(Eval eval, Expr exp, IDatatype[] param) { @@ -146,23 +141,6 @@ IDatatype overloadErrorMethod(Eval eval, Expr exp, IDatatype[] param) { return val; } - /** - * a = b return null 1) try @eq function us:feq(?e, ?a, ?b) 2) otherwise try - * @error function us:error(?e, a, ?b) - */ - IDatatype overloadError(Eval eval, Expr exp, IDatatype[] param) { - String name = getName(exp, param); - IDatatype[] values = toArray(param, exp); - if (name == null) { - return visitor.callbackBasic(eval, ERROR, values); - } - IDatatype val = visitor.callbackBasic(eval, name, values); - if (val == null) { - val = visitor.callbackBasic(eval, ERROR, values); - } - return val; - } - IDatatype[] toArray(IDatatype[] args, Object... lobj) { IDatatype[] param = new IDatatype[args.length + lobj.length]; int i = 0; @@ -175,25 +153,12 @@ IDatatype[] toArray(IDatatype[] args, Object... lobj) { return param; } - IDatatype overloadFunction(Eval eval, Expr exp, IDatatype[] param) { - String name = getName(exp, param); - if (name == null) { - return null; - } - return visitor.callback(eval, name, param); - } - IDatatype overloadMethod(Eval eval, Expr exp, IDatatype[] param) { String name = getMethodName(exp); if (name == null) { return null; } - return visitor.method(eval, name, param); - } - - IDatatype kind(IDatatype dt) { - IDatatype kind = DatatypeMap.kind(dt); - return kind; + return visitor.method(eval, name, param); } String getMethodName(Expr exp) { @@ -220,14 +185,14 @@ String getMethodName(Expr exp) { return MMULT; case ExprType.DIV: return MDIVIS; - + default: // concat() -> us:concat() return US.concat(exp.getLabel()); } //return null; } - + String getName(Expr exp, IDatatype[] param) { switch (exp.oper()) { case ExprType.EQ: @@ -242,7 +207,7 @@ String getName(Expr exp, IDatatype[] param) { return GE; case ExprType.GT: return GT; - + case ExprType.PLUS: return PLUS; case ExprType.MINUS: @@ -250,7 +215,7 @@ String getName(Expr exp, IDatatype[] param) { case ExprType.MULT: return MULT; case ExprType.DIV: - return DIVIS; + return DIVIS; } return null; } diff --git a/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolverVisitor.java b/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolverVisitor.java index e0332f9b6..7e6cb6ae0 100644 --- a/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolverVisitor.java +++ b/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolverVisitor.java @@ -3,18 +3,15 @@ import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.api.core.Expr; import fr.inria.corese.core.kgram.api.core.Node; -import fr.inria.corese.core.kgram.core.Eval; -import fr.inria.corese.core.kgram.core.Exp; -import fr.inria.corese.core.kgram.core.Mapping; -import fr.inria.corese.core.kgram.core.Mappings; -import fr.inria.corese.core.kgram.core.Query; +import fr.inria.corese.core.kgram.core.*; import fr.inria.corese.core.kgram.path.Path; import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.datatype.DatatypeMap; -import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.List; + /** * Callback manager for LDScript functions with specific annotations Eval SPARQL * processor calls before() and after() @@ -31,7 +28,7 @@ */ public class QuerySolverVisitor extends QuerySolverVisitorBasic { - private static Logger logger = LoggerFactory.getLogger(QuerySolverVisitor.class); + private static final Logger logger = LoggerFactory.getLogger(QuerySolverVisitor.class); public QuerySolverVisitor() {} @@ -324,8 +321,7 @@ public boolean filter(Eval eval, Node g, Expr e, boolean b) { @Override public IDatatype function(Eval eval, Expr funcall, Expr fundef) { if (isFunction()) { - IDatatype dt = callback(eval, FUNCTION, toArray(funcall, fundef)); - return dt; + return callback(eval, FUNCTION, toArray(funcall, fundef)); } return null; } @@ -341,7 +337,7 @@ public boolean having(Eval eval, Expr e, boolean b) { } @Override - public IDatatype select(Eval eval, Expr e, IDatatype dt) { + public IDatatype select(Eval eval, Expr e, IDatatype dt) { IDatatype val = callback(eval, SELECT, toArray(e, dt)); return dt; } @@ -356,7 +352,7 @@ public IDatatype aggregate(Eval eval, Expr e, IDatatype dt) { @Override public IDatatype error(Eval eval, Expr exp, IDatatype[] args) { - return overload.error(eval, exp, (IDatatype[]) args); + return overload.error(eval, exp, args); } @Override @@ -367,7 +363,7 @@ public boolean overload(Expr exp, IDatatype res, IDatatype dt1, IDatatype dt2) { @Override public IDatatype overload(Eval eval, Expr exp, IDatatype res, IDatatype[] args) { - return overload.overload(eval, exp, res, (IDatatype[]) args); + return overload.overload(eval, exp, res, args); } @Override diff --git a/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolverVisitorBasic.java b/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolverVisitorBasic.java index 6f0dbdcc9..ff333b6cf 100644 --- a/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolverVisitorBasic.java +++ b/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolverVisitorBasic.java @@ -2,55 +2,41 @@ import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.api.core.Expr; -import fr.inria.corese.core.kgram.api.core.PointerType; -import fr.inria.corese.core.kgram.api.query.Environment; -import fr.inria.corese.core.kgram.api.query.Evaluator; -import fr.inria.corese.core.kgram.api.query.Hierarchy; -import fr.inria.corese.core.kgram.api.query.ProcessVisitor; -import fr.inria.corese.core.kgram.api.query.Producer; +import fr.inria.corese.core.kgram.api.query.*; import fr.inria.corese.core.kgram.core.Eval; import fr.inria.corese.core.kgram.core.PointerObject; import fr.inria.corese.core.kgram.core.Query; -import fr.inria.corese.core.sparql.api.Computer; import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.datatype.DatatypeMap; import fr.inria.corese.core.sparql.exceptions.EngineException; +import fr.inria.corese.core.sparql.triple.function.extension.ListSort; import fr.inria.corese.core.sparql.triple.function.script.Funcall; import fr.inria.corese.core.sparql.triple.function.script.Function; -import fr.inria.corese.core.sparql.triple.function.term.Binding; -import fr.inria.corese.core.sparql.triple.function.extension.ListSort; import fr.inria.corese.core.sparql.triple.function.script.LDScript; import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.NSManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Callback manager for LDScript functions with specific annotations Eval SPARQL * processor calls before() and after() * + * @author Olivier Corby, Wimmics INRIA I3S, 2018 * @before function us:before(?q) {} * @after function us:after(?m) {} * @produce function us:produce(?q) {} * @candidate function us:candidate(?q, ?e) {} * @result function us:result(?m) {} * @solution function us:solution(?m) {} - * - * @author Olivier Corby, Wimmics INRIA I3S, 2018 - * */ public class QuerySolverVisitorBasic extends PointerObject implements ProcessVisitor { - private static Logger logger = LoggerFactory.getLogger(QuerySolverVisitor.class); - - public static boolean REENTRANT_DEFAULT = false; - public static final String RECURSION = "@recursion"; public static final String VERBOSE = "@verbose"; - public static final String SHARE = "@share"; public static final String TRACE = "@display"; public static final String PREPARE = "@prepare"; @@ -73,7 +59,6 @@ public class QuerySolverVisitorBasic extends PointerObject implements ProcessVis public static final String START = "@start"; public static final String FINISH = "@finish"; public static final String OVERLOAD = "@overload"; - public static final String LIMIT = "@limit"; public static final String TIMEOUT = "@timeout"; public static final String SLICE = "@slice"; @@ -104,41 +89,30 @@ public class QuerySolverVisitorBasic extends PointerObject implements ProcessVis public static final String DELETE = "@delete"; public static final String UPDATE = "@update"; public static final int UPDATE_ARITY = 3; - public static final String INIT_PARAM = "@initParam"; public static final String INIT_SERVER = "@initServer"; - public static final String BEFORE_REQUEST = "@beforeRequest"; - public static final String AFTER_REQUEST = "@afterRequest"; - public static final String BEFORE_TRANSFORMER = "@beforeTransformer"; public static final String AFTER_TRANSFORMER = "@afterTransformer"; public static final String BEFORE_WORKFLOW = "@beforeWorkflow"; public static final String AFTER_WORKFLOW = "@afterWorkflow"; - - static final String USER = NSManager.USER; - static final String PRODUCE_METHOD = USER + "produce"; - static final String[] EVENT_LIST = { - BEFORE, AFTER, START, FINISH, PRODUCE, RESULT, STATEMENT, CANDIDATE, PATH, STEP, VALUES, BIND, - BGP, JOIN, OPTIONAL, MINUS, UNION, FILTER, SELECT, SERVICE, QUERY, GRAPH, - AGGREGATE, HAVING, FUNCTION, ORDERBY, DISTINCT + BEFORE, AFTER, START, FINISH, PRODUCE, RESULT, STATEMENT, CANDIDATE, PATH, STEP, VALUES, BIND, + BGP, JOIN, OPTIONAL, MINUS, UNION, FILTER, SELECT, SERVICE, QUERY, GRAPH, + AGGREGATE, HAVING, FUNCTION, ORDERBY, DISTINCT }; - + private static final Logger logger = LoggerFactory.getLogger(QuerySolverVisitorBasic.class); + public static boolean REENTRANT_DEFAULT = false; private static boolean event = true; - - private boolean active = false; - private boolean reentrant = REENTRANT_DEFAULT; boolean select = false; - private boolean shareable = false; - private boolean debug = false; - private boolean verbose = false; - private boolean function = false; - - private Eval eval; Query query; ASTQuery ast; HashMap distinct; QuerySolverOverload overload; + private boolean active = false; + private boolean reentrant = REENTRANT_DEFAULT; + private boolean shareable = false; + private boolean function = false; + private Eval eval; public QuerySolverVisitorBasic() { distinct = new HashMap<>(); @@ -150,9 +124,18 @@ public QuerySolverVisitorBasic(Eval e) { eval = e; } - @Override - public void setProcessor(Eval e) { - setEval(e); + /** + * @return the event + */ + public static boolean isEvent() { + return event; + } + + /** + * @param aEvent the event to set + */ + public static void setEvent(boolean aEvent) { + event = aEvent; } @Override @@ -160,16 +143,15 @@ public Eval getProcessor() { return getEval(); } + @Override + public void setProcessor(Eval e) { + setEval(e); + } + Hierarchy getHierarchy() { return getEnvironment().getExtension().getHierarchy(); } - // datatype(us:km, us:length) -// public IDatatype datatype(IDatatype type, IDatatype sup) { -// getHierarchy().defSuperType(type, sup); -// return type; -// } - //@Override public IDatatype datatype(IDatatype type, IDatatype sup) { getHierarchy().defSuperType(type, sup); return type; @@ -179,9 +161,6 @@ List getSuperTypes(IDatatype type) { return getHierarchy().getSuperTypes(null, type); } -// String getSuperType(IDatatype dt) { -// return getSuperType ((IDatatype) dt); -// } String getSuperType(IDatatype type) { List list = getSuperTypes(type); if (list == null || list.isEmpty()) { @@ -190,19 +169,10 @@ String getSuperType(IDatatype type) { return list.get(list.size() - 1); } - // Draft for testing - void test() { - IDatatype dt = DatatypeMap.map(); - dt.set(DatatypeMap.newInstance("test"), DatatypeMap.newInstance(10)); - Binding b = getEnvironment().getBind(); - b.setVariable("?global", dt); - } - void initialize() { // Visitor shared among different query processing: // query in function, transformer setShareable(ast.hasMetadata(SHARE)); - setVerbose(ast.hasMetadata(VERBOSE)); setFunction(define(FUNCTION, 2)); if (ast.hasMetadata(RECURSION)) { // Visitor still active inside event function @@ -232,53 +202,19 @@ boolean accept(String name) { return true; } - public void setOverload(boolean b) { - overload.setOverload(b); - } - public boolean isOverload() { return overload.isOverload(); } + public void setOverload(boolean b) { + overload.setOverload(b); + } + public boolean define(String name, int arity) { Expr exp = getDefineMetadata(getEnvironment(), name, arity); return (exp != null); } - void trace(Eval ev, String metadata, IDatatype[] param) { - if (isVerbose()) { - //mytrace(ev, metadata, param); - trace(metadata, param); - } - } - - void trace(String metadata, IDatatype[] param) { - System.out.println(metadata); - for (IDatatype dt : param) { - if (dt != null) { - trace(dt); - System.out.println(); - } - } - } - - void trace(IDatatype dt) { - if (dt.isPointer()) { - if (dt.pointerType() == PointerType.GRAPH) { - System.out.println(dt); - } else { - System.out.println(dt.getPointerObject()); - } - } else { - System.out.println(dt); - } - } - - IDatatype mytrace(Eval eval, String metadata, IDatatype[] param) { - callbackSimple(eval, TRACE, toArray(metadata)); - return callbackSimple(eval, TRACE, param); - } - /** * @before function us:before(?q) call function us:before set Visitor as * inactive during function call to prevent loop and also in case where @@ -292,7 +228,6 @@ public IDatatype callback(Eval ev, String metadata, IDatatype[] param) { if (isRunning() || !isEvent() || !accept(metadata)) { return null; } - trace(ev, metadata, param); Function function = getDefineMetadata(getEnvironment(), metadata, param.length); if (function != null) { // prevent infinite loop in case where there is a query in the function @@ -312,23 +247,21 @@ public IDatatype callback(Eval ev, String metadata, IDatatype[] param) { * ?b */ public IDatatype callbackBasic(Eval ev, String metadata, IDatatype[] param) { - trace(ev, metadata, param); return callbackSimple(ev, metadata, param); } - + Function getDefineMetadata(Environment env, String metadata, int n) { return new LDScript().getDefineMetadata(env, metadata, n); } - + Function getDefineMethod(Environment env, String name, IDatatype type, IDatatype[] param) { return new LDScript().getDefineMethod(env, name, type, param); } - + Function getDefine(Environment env, String name, int n) { return new LDScript().getDefine(env, name, n); } - IDatatype callbackSimple(Eval ev, String metadata, IDatatype[] param) { Function function = getDefineMetadata(getEnvironment(), metadata, param.length); if (function != null) { @@ -347,7 +280,7 @@ IDatatype sort(Eval ev, String metadata, IDatatype[] param) { if (function != null) { // prevent infinite loop in case where there is a query in the function setActive(true); - IDatatype dt = new ListSort("sort").sort((Computer) ev.getEvaluator(), ev.getEnvironment().getBind(), ev.getEnvironment(), + IDatatype dt = new ListSort("sort").sort(ev.getEvaluator(), ev.getEnvironment().getBind(), ev.getEnvironment(), ev.getProducer(), function, param[0]); setActive(false); return dt; @@ -380,15 +313,14 @@ public IDatatype methodBasic(Eval ev, String name, IDatatype[] param) { public IDatatype methodBasic(Eval ev, String name, IDatatype type, IDatatype[] param) { Function exp = getDefineMethod(getEnvironment(), name, type, param); if (exp != null) { - IDatatype dt = call(exp, param, ev.getEvaluator(), ev.getEnvironment(), ev.getProducer()); - return dt; + return call(exp, param, ev.getEvaluator(), ev.getEnvironment(), ev.getProducer()); } return null; } IDatatype call(Function fun, IDatatype[] param, Evaluator eval, Environment env, Producer p) { try { - return new Funcall(fun.getFunction().getLabel()).callWE((Computer) eval, env.getBind(), env, p, fun, param); + return new Funcall(fun.getFunction().getLabel()).callWE(eval, env.getBind(), env, p, fun, param); } catch (EngineException ex) { logger.error(ex.getMessage()); return null; @@ -465,20 +397,6 @@ public void sleep(boolean b) { setActive(b); } - /** - * @return the debug - */ - public boolean isDebug() { - return debug; - } - - /** - * @param debug the debug to set - */ - public void setDebug(boolean debug) { - this.debug = debug; - } - /** * @return the reentrant */ @@ -493,20 +411,6 @@ public void setReentrant(boolean reentrant) { this.reentrant = reentrant; } - /** - * @return the verbose - */ - public boolean isVerbose() { - return verbose; - } - - /** - * @param verbose the verbose to set - */ - public void setVerbose(boolean verbose) { - this.verbose = verbose; - } - /** * @return the function */ @@ -535,18 +439,4 @@ public void setEval(Eval eval) { this.eval = eval; } - /** - * @return the event - */ - public static boolean isEvent() { - return event; - } - - /** - * @param aEvent the event to set - */ - public static void setEvent(boolean aEvent) { - event = aEvent; - } - } diff --git a/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolverVisitorExtension.java b/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolverVisitorExtension.java index 43b72634f..5bb5640c9 100644 --- a/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolverVisitorExtension.java +++ b/src/main/java/fr/inria/corese/core/compiler/eval/QuerySolverVisitorExtension.java @@ -1,36 +1,33 @@ package fr.inria.corese.core.compiler.eval; import fr.inria.corese.core.kgram.api.core.Edge; -import fr.inria.corese.core.kgram.core.Eval; import fr.inria.corese.core.kgram.core.Query; import fr.inria.corese.core.sparql.api.IDatatype; + import java.util.List; /** * Draf example of specific Visitor, e.g. implemented in Java instead of LDScript - * Use case: + * Use case: * for one query: exec.query(q, new QuerySolverVisitorExtension()) * for one query: exec.query(q, Mapping.create(vis)); - * + *

* for all query: QueryProcess.setSolverVisitorName("fr.inria.corese.core.compiler.eval.QuerySolverVisitorExtension"); - * + * * @author Olivier Corby, Wimmics INRIA I3S, 2020 */ public class QuerySolverVisitorExtension extends QuerySolverVisitor { - - public QuerySolverVisitorExtension() {} - - public QuerySolverVisitorExtension(Eval ev) { - super(ev); + + public QuerySolverVisitorExtension() { } - + @Override public IDatatype update(Query q, List delete, List insert) { return super.update(q, delete, insert); } - + @Override public IDatatype insert(IDatatype path, Edge triple) { - return path; + return path; } } diff --git a/src/main/java/fr/inria/corese/core/compiler/eval/SQLFun.java b/src/main/java/fr/inria/corese/core/compiler/eval/SQLFun.java index 1ae25f106..efb6fc1a8 100755 --- a/src/main/java/fr/inria/corese/core/compiler/eval/SQLFun.java +++ b/src/main/java/fr/inria/corese/core/compiler/eval/SQLFun.java @@ -1,70 +1,73 @@ package fr.inria.corese.core.compiler.eval; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - import fr.inria.corese.core.sparql.api.IDatatype; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.*; public class SQLFun { - - static final String DERBY_DRIVER = "org.apache.derby.jdbc.ClientDriver"; - static Object driver; + static final String DERBY_DRIVER = "org.apache.derby.jdbc.ClientDriver"; + private static final Logger logger = LoggerFactory.getLogger(SQLFun.class); + static Object driver; + + /** + * Executes an SQL query using a specified database driver. + * The Connection and Statement are managed with try-with-resources to ensure closure. + * Note: The returned ResultSet must be closed by the caller. + * + * @param uri The database connection URI. + * @param dd The database driver class name. + * @param login The database login username. + * @param passwd The database password. + * @param query The SQL query to execute. + * @return A ResultSet containing the query results, or null if an error occurs. + */ + public ResultSet sql(IDatatype uri, IDatatype dd, + IDatatype login, IDatatype passwd, IDatatype query) { + if (driver == null) { + // first time + try { + // remember driver is loaded + driver = Class.forName(dd.getLabel()).newInstance(); + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { + logger.error("Failed to load database driver: {}", dd.getLabel(), e); + return null; + } + } + return sql(uri, login, passwd, query); + } + + /** + * Executes an SQL query using the default Derby driver or an already loaded driver. + * The Connection and Statement are managed with try-with-resources to ensure closure. + * Note: The returned ResultSet must be closed by the caller. + * + * @param uri The database connection URI. + * @param login The database login username. + * @param passwd The database password. + * @param query The SQL query to execute. + * @return A ResultSet containing the query results, or null if an error occurs. + */ + public ResultSet sql(IDatatype uri, + IDatatype login, IDatatype passwd, IDatatype query) { + try { + if (driver == null) { + try { + driver = Class.forName(DERBY_DRIVER).newInstance(); + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) { + logger.error("Failed to load default Derby driver: {}", DERBY_DRIVER, e); + return null; + } + } - public ResultSet sql(IDatatype uri, IDatatype dd, - IDatatype login, IDatatype passwd, IDatatype query){ - if (driver == null){ - // first time - try { - // remember driver is loaded - driver = Class.forName(dd.getLabel()).newInstance(); - } catch (InstantiationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ClassNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - return sql(uri, login, passwd, query); - } - - public ResultSet sql(IDatatype uri, - IDatatype login, IDatatype passwd, IDatatype query){ - try { - if (driver == null){ - try { - // default is derby - driver = Class.forName(DERBY_DRIVER).newInstance(); - } catch (InstantiationException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ClassNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - Connection con = - DriverManager.getConnection(uri.getLabel(), login.getLabel(), passwd.getLabel()); - Statement stmt = con.createStatement(); - ResultSet rs = stmt.executeQuery(query.getLabel()); - return rs; + try (final Connection con = DriverManager.getConnection(uri.getLabel(), login.getLabel(), passwd.getLabel()); + final Statement stmt = con.createStatement()) { + return stmt.executeQuery(query.getLabel()); + } + } catch (SQLException e) { + logger.error("SQL error occurred during query execution: {}", query.getLabel(), e); } - catch (SQLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } return null; - } - - - + } } diff --git a/src/main/java/fr/inria/corese/core/compiler/eval/SQLResult.java b/src/main/java/fr/inria/corese/core/compiler/eval/SQLResult.java index 49a9cbdd6..851145748 100644 --- a/src/main/java/fr/inria/corese/core/compiler/eval/SQLResult.java +++ b/src/main/java/fr/inria/corese/core/compiler/eval/SQLResult.java @@ -3,25 +3,25 @@ import java.sql.ResultSet; public class SQLResult { - - ResultSet rs; - boolean isSort = false; - - SQLResult (ResultSet r){ - rs = r; - } - - public SQLResult (ResultSet r, boolean b){ - rs = r; - isSort = b; - } - - public ResultSet getResultSet(){ - return rs; - } - - public boolean isSort(){ - return isSort; - } + + ResultSet rs; + boolean isSort = false; + + SQLResult(ResultSet r) { + rs = r; + } + + public SQLResult(ResultSet r, boolean b) { + rs = r; + isSort = b; + } + + public ResultSet getResultSet() { + return rs; + } + + public boolean isSort() { + return isSort; + } } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/BGP2URI.java b/src/main/java/fr/inria/corese/core/compiler/federate/BGP2URI.java index 8dbe40eb2..57851d4fe 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/BGP2URI.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/BGP2URI.java @@ -1,8 +1,8 @@ package fr.inria.corese.core.compiler.federate; import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; + import java.util.ArrayList; -import java.util.Comparator; import java.util.HashMap; import java.util.List; @@ -33,11 +33,7 @@ List sortKeyList() { } List sort(List list) { - list.sort(new Comparator<>() { - public int compare(BasicGraphPattern bgp1, BasicGraphPattern bgp2) { - return -Integer.compare(bgp1.size(), bgp2.size()); - } - }); + list.sort((bgp1, bgp2) -> -Integer.compare(bgp1.size(), bgp2.size())); return list; } @@ -69,10 +65,8 @@ List partition() { // intersection of bgp with other bgp boolean intersect(BasicGraphPattern bgp) { for (BasicGraphPattern exp : keySet()) { - if (exp != bgp) { - if (!bgp.intersectionTriple(exp).isEmpty()) { - return true; - } + if (exp != bgp && (!bgp.intersectionTriple(exp).isEmpty())) { + return true; } } return false; diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/FederateVisitor.java b/src/main/java/fr/inria/corese/core/compiler/federate/FederateVisitor.java index a168c42de..0b4e79ee0 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/FederateVisitor.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/FederateVisitor.java @@ -1,71 +1,44 @@ package fr.inria.corese.core.compiler.federate; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.Atom; -import fr.inria.corese.core.sparql.triple.parser.Constant; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.Expression; -import fr.inria.corese.core.sparql.triple.parser.Metadata; -import fr.inria.corese.core.sparql.triple.parser.Service; -import fr.inria.corese.core.sparql.triple.parser.Source; -import fr.inria.corese.core.sparql.triple.parser.Triple; -import fr.inria.corese.core.sparql.triple.parser.Variable; import fr.inria.corese.core.compiler.api.QueryVisitor; import fr.inria.corese.core.compiler.eval.QuerySolver; -import fr.inria.corese.core.compiler.federate.util.RewriteError; import fr.inria.corese.core.compiler.federate.util.RewriteErrorManager; import fr.inria.corese.core.kgram.core.Mappings; import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.datatype.RDF; import fr.inria.corese.core.sparql.exceptions.EngineException; -import fr.inria.corese.core.sparql.triple.parser.ASTSelector; -import fr.inria.corese.core.sparql.triple.parser.Context; -import fr.inria.corese.core.sparql.triple.parser.Dataset; -import static fr.inria.corese.core.sparql.triple.parser.Metadata.FED_BGP; -import static fr.inria.corese.core.sparql.triple.parser.Metadata.FED_COMPLETE; -import static fr.inria.corese.core.sparql.triple.parser.Metadata.FED_JOIN; -import static fr.inria.corese.core.sparql.triple.parser.Metadata.FED_OPTIONAL; -import static fr.inria.corese.core.sparql.triple.parser.Metadata.FED_MINUS; -import static fr.inria.corese.core.sparql.triple.parser.Metadata.FED_PARTITION; -import static fr.inria.corese.core.sparql.triple.parser.Metadata.FED_UNDEFINED; -import fr.inria.corese.core.sparql.triple.parser.Processor; -import fr.inria.corese.core.sparql.triple.parser.Term; -import fr.inria.corese.core.sparql.triple.parser.URLParam; -import fr.inria.corese.core.sparql.triple.parser.URLServer; +import fr.inria.corese.core.sparql.triple.parser.*; import fr.inria.corese.core.sparql.triple.parser.visitor.ASTParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import org.slf4j.LoggerFactory; -import org.slf4j.Logger; + +import static fr.inria.corese.core.sparql.triple.parser.Metadata.*; /** * Prototype for federated query * - * @federate - * select * where { } + * @author Olivier Corby, Wimmics INRIA I3S, 2018 + * @federate + * select * where { } * Recursively rewrite every triple t as: * service { t } Generalized service statement with several URI - * Returns the union of Mappings + * Returns the union of Mappings * PRAGMA: - * Property Path evaluated in each of the services but not on the union + * Property Path evaluated in each of the services but not on the union * (hence PP is not federated) * graph ?g { } by default is evaluated as federated onto servers - * @skip kg:distributeNamed : - * named graph as a whole on each server - * - * @author Olivier Corby, Wimmics INRIA I3S, 2018 - * + * @skip kg:distributeNamed : + * named graph as a whole on each server */ public class FederateVisitor implements QueryVisitor, URLParam { - public static Logger logger = LoggerFactory.getLogger(FederateVisitor.class); - //static final String UNDEF = "?undef_serv"; - public static final String PROXY = "_proxy_"; - // Federation definitions: URL -> list URL - private static HashMap> federation; + public static Logger logger = LoggerFactory.getLogger(FederateVisitor.class); // draft public static boolean TEST_FEDERATE = true; // generate partition of connnected bgp @@ -76,7 +49,7 @@ public class FederateVisitor implements QueryVisitor, URLParam { public static boolean MINUS = true; public static boolean OPTIONAL = true; // skip undefined arg of union optional minus - public static boolean UNDEFINED = true; + public static boolean UNDEFINED = true; // complete partition with list of all triple alone public static boolean COMPLETE_BGP = false; // source selection generate bind (exists {t1 . t2} as ?b) @@ -90,37 +63,63 @@ public class FederateVisitor implements QueryVisitor, URLParam { public static boolean TRACE_FEDERATE = false; // specific processing for rdf list and bnode variable public static boolean PROCESS_LIST = true; - public static int NB_ENDPOINT = 20; - public static double NB_SUCCESS = 0.5; - - // false: evaluate named graph pattern as a whole on each server - // true: evaluate the triples of the named graph pattern on the merge of + public static int NB_ENDPOINT = 20; + public static double NB_SUCCESS = 0.5; + public static List BLACKLIST; + public static List BLACKLIST_EXCEPT; + // predicate such as owl:sameAs that split bgp connectivity + public static List DEFAULT_SPLIT; + // Federation definitions: URL -> list URL + private static HashMap> federation; + + static { + federation = new HashMap<>(); + DEFAULT_SPLIT = new ArrayList<>(); + // can be removed with @split us:test or with FEDERATE_SPLIT = <> + DEFAULT_SPLIT.add(RDF.OWL_SAME_AS); + BLACKLIST = new ArrayList<>(); + BLACKLIST_EXCEPT = new ArrayList<>(); + } + + // predicate such as owl:sameAs that split bgp connectivity + public List split; + // false: evaluate named graph pattern as a whole on each server + // true: evaluate the triples of the named graph pattern on the merge of // the named graphs of the servers boolean distributeNamed = true; // same in case of select from where boolean distributeDefault = false; - // service selection for triples - private boolean select = true; - // consider filter in source selection - private boolean selectFilter = SELECT_FILTER; // group connected triples with same service into connected service s { BGP } boolean group = true; - // in optional/minus/union: group every triples with same service into one service s { BGP } - private boolean merge = true; // factorize unique service in optional/minus/union - boolean simplify = true; - // Heuristics: Group and restrict federated services on the intersection of their URL list - private boolean mergeService = false; + boolean simplify = true; // rewrite filter exist {} boolean exist = true; - // insert a service inside a service - private boolean bounce = false; boolean verbose = false; // rewrite service uri {} as values var {uri} . service var {} boolean variable = false; // generate (count(*) as ?c) boolean aggregate = false; boolean provenance = false; + ASTQuery ast; + Stack stack; + QuerySolver exec; + // Rewrite service (uri) { } as values var { (uri) } service var { } + RewriteService rs; + RewriteList rewriteList; + // Group several services with same URI into one service + RewriteNamedGraph rewriteNamed; + List empty; + // service selection for triples + private boolean select = true; + // consider filter in source selection + private boolean selectFilter = SELECT_FILTER; + // in optional/minus/union: group every triples with same service into one service s { BGP } + private boolean merge = true; + // Heuristics: Group and restrict federated services on the intersection of their URL list + private boolean mergeService = false; + // insert a service inside a service + private boolean bounce = false; // draft query graph index private boolean index = false; // generate one service for the whole body (no recursive rewrite) @@ -139,54 +138,29 @@ public class FederateVisitor implements QueryVisitor, URLParam { private boolean federateClass = true; // in union/optional/minus, skip arg with undefined service private boolean federateUndefine = UNDEFINED; - public static List BLACKLIST; - public static List BLACKLIST_EXCEPT; - // predicate such as owl:sameAs that split bgp connectivity - public static List DEFAULT_SPLIT; private List include; private List exclude; - // predicate such as owl:sameAs that split bgp connectivity - public List split; private List indexURLList; - private int nbEndpoint = NB_ENDPOINT; + private int nbEndpoint = NB_ENDPOINT; private double nbSuccess = NB_SUCCESS; - - ASTQuery ast; - Stack stack; // generate and evaluate triple selection query private Selector selector; // Record triple selection result private ASTSelector astSelector; - QuerySolver exec; // Group triple patterns that share a unique service URI into one service URI private PrepareBGP groupBGP; // Rewrite BGP as service {} private RewriteTriple rewriteTriple; - // Rewrite service (uri) { } as values var { (uri) } service var { } - RewriteService rs; - RewriteList rewriteList; - // Group several services with same URI into one service - RewriteNamedGraph rewriteNamed; private RewriteErrorManager errorManager; private Simplify sim; - List empty; // Federation URL private URLServer url; // use case: reuse federated visitor source selection private Mappings mappings; private Mappings selection; private Mappings discovery; - - static { - federation = new HashMap<>(); - DEFAULT_SPLIT = new ArrayList<>(); - // can be removed with @split us:test or with FEDERATE_SPLIT = <> - DEFAULT_SPLIT.add(RDF.OWL_SAME_AS); - BLACKLIST = new ArrayList<>(); - BLACKLIST_EXCEPT = new ArrayList<>(); - } - - public FederateVisitor(QuerySolver e){ + + public FederateVisitor(QuerySolver e) { stack = new Stack(); exec = e; groupBGP = new PrepareBGP(this); @@ -200,77 +174,120 @@ public FederateVisitor(QuerySolver e){ exclude = new ArrayList<>(); split = DEFAULT_SPLIT; } - + + public static synchronized boolean blacklist(String uri) { + if (!BLACKLIST.contains(uri) && + !BLACKLIST_EXCEPT.contains(uri)) { + BLACKLIST.add(uri); + return true; + } + return false; + } + + public static boolean isBlackListed(String uri) { + return BLACKLIST.contains(uri); + } + + public static List getBlacklist() { + return BLACKLIST; + } + + public static void defineFederation(String name, List list) { + List serviceList = new ArrayList<>(); + for (String url : list) { + serviceList.add(Constant.createResource(url)); + } + defFederation(name, serviceList); + } + + public static void declareFederation(String name, List list) { + List serviceList = new ArrayList<>(); + for (IDatatype url : list) { + serviceList.add(Constant.create(url)); + } + defFederation(name, serviceList); + } + + public static void defFederation(String name, List list) { + getFederation().put(name, list); + } + + /** + * @return the federation + */ + public static HashMap> getFederation() { + return federation; + } + + public static void setFederation(HashMap> aFederation) { + federation = aFederation; + } + + public static List getFederation(String name) { + return getFederation().get(name); + } + /** * Query Visitor just before compiling AST */ @Override - public void visit(ASTQuery ast) { + public void visit(ASTQuery ast) { process(ast); ast.setFederateVisit(true); report(ast); } - + @Override public void visit(fr.inria.corese.core.kgram.core.Query query) { query.setFederate(true); - ASTQuery ast = query.getAST(); - ast.getLog().setAST(ast); - exec.getLog().setAST(ast); + ASTQuery queryAST = query.getAST(); + queryAST.getLog().setAST(queryAST); + exec.getLog().setAST(queryAST); query.setSelection(getMappings()); query.setDiscorevy(getDiscovery()); } - + // before solver query exec @Override public void before(fr.inria.corese.core.kgram.core.Query q) { - + } - + @Override public void after(Mappings map) { - if (provenance) { - Provenance prov = getProvenance(map); - System.out.println(prov); - } } - + // start function void process(ASTQuery ast) { this.ast = ast; option(); - if (! init()) { + if (!init()) { return; } - getGroupBGP().setDebug(ast.isDebug()); - + if (isSparql()) { // select where { BGP } -> select where { service URLs { BGP } } - verbose("\nbefore:\n%s", ast.getBody()); sparql(ast); - } - else { + } else { if (ast.getContext() != null) { // tune service URL with Context ast.setServiceList(tune(ast.getContext(), ast.getServiceList())); - } + } boolean suc = true; if (isSelect()) { // triple selection suc = sourceSelection(ast); } - verbose("\nbefore:\n%s", ast.getBody()); - + if (suc) { rewrite(ast); - } - else { + } else { logger.info("Source selection fail"); } } after(ast); } - + // return false when two connected triple that are in only one endpoint // do not join according to source selection boolean sourceSelection(ASTQuery ast) { @@ -300,46 +317,24 @@ boolean sourceSelection(ASTQuery ast) { } return suc; } - + void after(ASTQuery ast) { - error(ast); - verbose(ast); - } - - void error(ASTQuery ast) { - if (!getErrorManager().getErrorList().isEmpty()) { - for (RewriteError err : getErrorManager().getErrorList()) { - logger.error(err.toString()); - } - } - if (ast.hasUndefinedService()) { - logger.error("Query rewrite fail due to undefined triple"); - ast.setFail(true); - } - } - - void verbose(ASTQuery ast) { - if (verbose) { - System.out.println("\nafter:"); - System.out.println(ast.getMetadata()); - System.out.println(ast.getBody()); - System.out.println(); - } + } - + // possibly process @report: generate variable ?_service_report void report(ASTQuery ast) { ASTParser walk = new ASTParser(ast).report(); ast.process(walk); } - + // Federation definition - boolean init() { - if (ast.hasMetadata(Metadata.FEDERATION)) { - List list = ast.getMetadata().getValues(Metadata.FEDERATION); + boolean init() { + if (ast.hasMetadata(Metadata.Type.FEDERATION)) { + List list = ast.getMetadata().getValues(Metadata.Type.FEDERATION); List serviceList; boolean define = true; - + if (list == null) { define = false; // source discovery @@ -356,41 +351,39 @@ boolean init() { return false; } } - + if (list.isEmpty() && getInclude().isEmpty()) { logger.info("Candidate and include endpoint empty"); return false; - } - else if (list.size() == 1 && define) { + } else if (list.size() == 1 && define) { // refer to federation serviceList = getFederation().get(list.get(0)); setURL(new URLServer(list.get(0))); - + if (serviceList == null) { logger.info("Undefined federation: " + list.get(0)); - //return false; serviceList = new ArrayList<>(); serviceList.add(Constant.createResource(list.get(0))); } - + } else { // define federation serviceList = new ArrayList<>(); - int start = (define)?1:0; - + int start = (define) ? 1 : 0; + for (int i = start; i < list.size(); i++) { String uri = list.get(i); - if (accept(uri)){ + if (accept(uri)) { serviceList.add(Constant.createResource(uri)); } } - + for (String uri : getInclude()) { - if (! list.contains(uri) && accept(uri)) { + if (!list.contains(uri) && accept(uri)) { serviceList.add(Constant.createResource(uri)); } } - + if (define) { defFederation(list.get(0), serviceList); } @@ -398,12 +391,12 @@ else if (list.size() == 1 && define) { ast.setServiceList(serviceList); // same as Transformer federate() // use case: come here from corese server federate mode - ast.defService((String)null); + ast.defService((String) null); } return true; } - + boolean accept(String uri) { boolean b = !BLACKLIST.contains(uri) && !getExclude().contains(uri); if (!b) { @@ -412,40 +405,23 @@ boolean accept(String uri) { return b; } - public static synchronized boolean blacklist(String uri) { - if (! BLACKLIST.contains(uri) && - ! BLACKLIST_EXCEPT.contains(uri)) { - BLACKLIST.add(uri); - return true; - } - return false; - } - - public static boolean isBlackListed(String uri) { - return BLACKLIST.contains(uri); - } - - public static List getBlacklist() { - return BLACKLIST; - } - public Provenance getProvenance(Mappings map) { Provenance prov = new Provenance(rs.getServiceList(), map); map.setProvenance(prov); return prov; } - - + /** - * Metadata: + * Metadata: * default is true: + * * @skip kg:select kg:group kg:simplify kg:distributeNamed * default is false: * @type kg:exist kg:verbose */ - void option() { + void option() { logger.info(ast.getMetadata().toString()); - if (ast.hasMetadataValue(Metadata.TYPE, Metadata.VERBOSE)) { + if (ast.hasMetadataValue(Metadata.Type.TYPE, Metadata.VERBOSE)) { verbose = true; } if (skip(Metadata.DISTRIBUTE_NAMED)) { @@ -469,27 +445,27 @@ void option() { if (skip(Metadata.EXIST)) { exist = false; } - if (ast.hasMetadata(Metadata.MERGE_SERVICE)) { + if (ast.hasMetadata(Metadata.Type.MERGE_SERVICE)) { setMergeService(true); } - if (ast.hasMetadata(Metadata.BOUNCE)) { + if (ast.hasMetadata(Metadata.Type.BOUNCE)) { bounce = true; } - if (ast.hasMetadata(Metadata.VARIABLE) || ast.hasMetadata(Metadata.PUBLIC)) { + if (ast.hasMetadata(Metadata.Type.VARIABLE) || ast.hasMetadata(Metadata.Type.PUBLIC)) { variable = true; } - if (ast.hasMetadata(Metadata.SERVER)) { + if (ast.hasMetadata(Metadata.Type.SERVER)) { variable = true; aggregate = true; } - if (ast.hasMetadata(Metadata.PROVENANCE)) { + if (ast.hasMetadata(Metadata.Type.PROVENANCE)) { variable = true; provenance = true; } - if (ast.hasMetadata(Metadata.SPARQL)) { + if (ast.hasMetadata(Metadata.Type.SPARQL)) { setSparql(true); } - + setFederateBGP(getValue(FED_BGP, isFederateBGP())); setFederateJoin(getValue(FED_JOIN, isFederateJoin())); setFederatePartition(getValue(FED_PARTITION, isFederatePartition())); @@ -497,60 +473,59 @@ void option() { setFederateOptional(getValue(FED_OPTIONAL, isFederateOptional())); setFederateMinus(getValue(FED_MINUS, isFederateMinus())); setFederateUndefined(getValue(FED_UNDEFINED, isFederateUndefined())); - - if (ast.getMetaValue(Metadata.FED_CLASS) !=null) { + + if (ast.getMetaValue(Metadata.FED_CLASS) != null) { setFederateClass(ast.getMetaValue(Metadata.FED_CLASS).booleanValue()); } - if (ast.getMetaValue(Metadata.FED_SUCCESS) !=null) { + if (ast.getMetaValue(Metadata.FED_SUCCESS) != null) { // success rate for source discovery // 0.5 means half of the predicates are required // to consider an endpoint setNbSuccess(ast.getMetaValue(Metadata.FED_SUCCESS).doubleValue()); } - if (ast.getMetaValue(Metadata.FED_LENGTH) !=null) { + if (ast.getMetaValue(Metadata.FED_LENGTH) != null) { // number of endpoint url considered from source discovery setNbEndpoint(ast.getMetaValue(Metadata.FED_LENGTH).intValue()); } - if (ast.hasMetadata(Metadata.FED_INCLUDE)) { + if (ast.hasMetadata(Metadata.FED_INCLUDE)) { // add endpoint uri to result of index source discovery setInclude(ast.getMetadata().getValues(Metadata.FED_INCLUDE)); logger.info("Include: " + getInclude()); } - if (ast.hasMetadata(Metadata.FED_EXCLUDE)) { + if (ast.hasMetadata(Metadata.FED_EXCLUDE)) { // remove endpoint uri from result of index source discovery setExclude(ast.getMetadata().getValues(Metadata.FED_EXCLUDE)); } - if (ast.hasMetadata(Metadata.INDEX)) { + if (ast.hasMetadata(Metadata.Type.INDEX)) { // federate query with index for source discovery // @index - setIndexURLList(ast.getMetadata().getValues(Metadata.INDEX)); - logger.info("Index URL: "+ getIndexURLList()); + setIndexURLList(ast.getMetadata().getValues(Metadata.Type.INDEX)); + logger.info("Index URL: " + getIndexURLList()); } - + if (ast.hasMetadata(Metadata.FED_WHITELIST)) { - if (ast.hasMetadataValue(Metadata.FED_WHITELIST)) { - for (String uri : ast.getMetadata().getValues(Metadata.FED_WHITELIST)) { - getBlacklist().remove(uri); - } - } - else { - getBlacklist().clear(); - } - } - - if (ast.hasMetadataValue(Metadata.SPLIT)) { + if (ast.hasMetadataValue(Metadata.FED_WHITELIST)) { + for (String uri : ast.getMetadata().getValues(Metadata.FED_WHITELIST)) { + getBlacklist().remove(uri); + } + } else { + getBlacklist().clear(); + } + } + + if (ast.hasMetadataValue(Metadata.Type.SPLIT)) { // @split owl:sameAs - setSplit(ast.getMetadata().getValues(Metadata.SPLIT)); - logger.info("Split: "+ getSplit()); + setSplit(ast.getMetadata().getValues(Metadata.Type.SPLIT)); + logger.info("Split: " + getSplit()); } - + option(ast.getDataset()); - - if (ast.getContext()!=null) { + + if (ast.getContext() != null) { option(ast.getContext()); } } - + void option(Dataset ds) { if (!ds.getIndex().isEmpty()) { // federate query with index for source discovery @@ -559,44 +534,44 @@ void option(Dataset ds) { logger.info("Index URL: " + getIndexURLList()); } } - + // option from service parameter sv:federateLength=20 // service parameter prefixed with sv: are available in ast context void option(Context ct) { IDatatype dt = ct.getFirst(FED_LENGTH); if (dt != null) { - setNbEndpoint(Integer.valueOf(dt.stringValue())); + setNbEndpoint(Integer.parseInt(dt.stringValue())); } dt = ct.getFirst(FED_SUCCESS); if (dt != null) { - setNbSuccess(Double.valueOf(dt.stringValue())); + setNbSuccess(Double.parseDouble(dt.stringValue())); } dt = ct.get(FED_INCLUDE); - + if (dt != null) { for (IDatatype uri : dt) { - if (! getInclude().contains(uri.getLabel())) { + if (!getInclude().contains(uri.getLabel())) { getInclude().add(uri.getLabel()); } } } } - + boolean getValue(String meta, boolean b) { - if (ast.getMetaValue(meta)!=null) { + if (ast.getMetaValue(meta) != null) { return ast.getMetaValue(meta).booleanValue(); } return b; } - + boolean skip(String name) { - return ast.hasMetadataValue(Metadata.SKIP, name); + return ast.hasMetadataValue(Metadata.Type.SKIP, name); } - + boolean isExist() { return exist; } - + /** * Rewrite query body with one service clause with federation URLs */ @@ -609,13 +584,13 @@ void sparql(ASTQuery ast) { Service serv = Service.create(list, body); ast.setBody(ast.bgp(serv)); // TODO: check inherit limit ??? offset ??? - complete(ast); + complete(ast); // include external values clause inside body prepare(ast); variable(ast); - finish(ast); + finish(ast); } - + /** * Complete URL of SPARQL endpoints of federation with information from context * For example: mode=share&mode=debug @@ -627,7 +602,6 @@ List tune(Context c, List list) { String uri = at.getConstant().getLongName(); if (c.accept(uri)) { uri = c.tune(uri); - System.out.println("Fed tune: " + uri); alist.add(Constant.createResource(uri)); } } @@ -635,14 +609,14 @@ List tune(Context c, List list) { } return list; } - + boolean isShareable(Context c) { return (c.hasValue(MODE) && c.hasValue(SHARE)) || c.hasValue(ACCEPT) || c.hasValue(REJECT) || c.hasValue(EXPORT); } - + /** - * Main rewrite function + * Main rewrite function */ void rewrite(ASTQuery ast) { prepare(ast); @@ -652,26 +626,26 @@ void rewrite(ASTQuery ast) { variable(ast); finish(ast); } - + void finish(ASTQuery ast) { ast.getVisitorList().add(this); } - + void prepare(ASTQuery ast) { if (ast.getValues() != null) { ast.where().add(0, ast.getValues()); ast.setValues(null); } } - + void complete(ASTQuery ast) { setLimit(ast); } - + void graph(ASTQuery ast) { new RewriteServiceGraph(this).process(ast); } - + /** * Unique service inherits query limit if any */ @@ -687,7 +661,7 @@ void setLimit(ASTQuery ast) { } } } - + // @variable // rewrite service (uri) {} as values ?serv { (uri) } service ?serv {} void variable(ASTQuery ast) { @@ -699,7 +673,7 @@ void variable(ASTQuery ast) { } } } - + /** * select ?serv_1 ?serv_n (count(*) as ?count) * where {} @@ -713,19 +687,19 @@ void aggregate(ASTQuery ast, List valList) { Variable var = Variable.create("?count"); ast.defSelect(var, fun); } - + /** * ast is global or subquery * name is embedding named graph if any */ - void rewrite(Atom name, ASTQuery ast) { + void rewrite(Atom name, ASTQuery ast) { for (Expression exp : ast.getModifierExpressions()) { rewriteFilter(name, exp); - } + } rewrite(name, ast.getBody()); - + } - + /** * Core rewrite function * Recursively rewrite triple t as: service { t } Add @@ -735,55 +709,49 @@ void rewrite(Atom name, ASTQuery ast) { Exp rewrite(Atom namedGraph, Exp body) { return rewrite(namedGraph, body, body); } - + Exp rewrite(Atom namedGraph, Exp main, Exp body) { ArrayList filterList = new ArrayList<>(); - + if (group && body.isBGP()) { // BGP body may be modified // rewrite triples into service URI { t1 t2 } - // possibly several service with same URI where each bgp is connected + // possibly several service with same URI where each bgp is connected // these service clauses will not be rewritten afterward // triple with several URI not rewritten yet // filterList is list of filter/bind that have been copied in service // @todo: filter boolean suc = rewriteList.process(body); - if (! suc) { + if (!suc) { // @todo: fail } - // if isFederateBGP(), compute uri2bgp + // if isFederateBGP(), compute uri2bgp // and do not rewrite anything yet (effective) // else rewrite triple as service (deprecated) - URI2BGPList uri2bgp = - getGroupBGP().process(namedGraph, main, body, filterList); - - if (isTraceFederate()) { - trace("body first phase:\n%s", body); - uri2bgp.trace(); - } - + URI2BGPList uri2bgp = + getGroupBGP().process(namedGraph, main, body, filterList); + if (isFederateBGP()) { // rewrite connected bgp with several uri as service // filter that have been copied in specific bgp service // have been removed from body and copied into filterList Exp exp = new RewriteBGPList(this, uri2bgp) .process(namedGraph, body, filterList); - + if (exp != null) { // rewritten bgp inserted in body // triples that have been rewritten will be removed below if (exp.isUnion()) { body.add(exp); - } - else { + } else { body.addAll(exp); } } - } + } } - - ArrayList expandList = new ArrayList<> (); - + + ArrayList expandList = new ArrayList<>(); + for (int i = 0; i < body.size(); i++) { // rewrite remaining triples into service with several URI Exp exp = body.get(i); @@ -794,7 +762,7 @@ Exp rewrite(Atom namedGraph, Exp main, Exp body) { // keep it } else if (exp.isFilter() || exp.isBind()) { // rewrite exists { } - if (! filterList.contains(exp)){ + if (!filterList.contains(exp)) { // not already processed // rewrite filter exists BGP and bind (exists BGP as var) as service rewriteFilter(namedGraph, exp.getFilter()); @@ -817,33 +785,32 @@ Exp rewrite(Atom namedGraph, Exp main, Exp body) { Exp res = rewrite(exp.getNamedGraph()); if (distributeNamed) { expandList.add(res); - } + } body.set(i, res); - } - else if (exp.isBinaryExp()) { + } else if (exp.isBinaryExp()) { // recursively rewrite arguments exp = rewrite(namedGraph, exp); if (simplify) { exp = getSimplify().simplify(exp); - } + } i = insert(body, exp, i); - + } else { // BGP rewrite(namedGraph, body, exp); } - } - + } + // remove filters that have been copied into services for (Exp filter : filterList) { body.getBody().remove(filter); } - + if (!expandList.isEmpty()) { // named graph expansion rewriteNamed.expand(body, expandList); } - + if (body.isBGP()) { // merge different service and graph with same url getSimplify().process(body); @@ -851,28 +818,18 @@ else if (exp.isBinaryExp()) { bind(body); // move filter in appropriate service moveFilter(body); - sort(body); + sort(body); if (isMergeService()) { // draft not default behavior body = new SimplifyService().simplify(body); - sort(body); - } + sort(body); + } } - + return body; } - void verbose(String mes, Object... obj) { - if (verbose) { - trace(mes, obj); - } - } - - void trace(String mes, Object... obj) { - System.out.println(String.format(mes, obj)); - } - int insert(Exp body, Exp exp, int i) { if (exp.isBGP()) { // optional|minus rewritten @@ -880,7 +837,7 @@ int insert(Exp body, Exp exp, int i) { // service s1 {A} service s2 {B} optional/minus {service s2 C} // -> exp = {service s1 {A} . service s2 {B optional/minus C}} body.set(i, exp.get(0)); // s1 - if (exp.size()==2) { + if (exp.size() == 2) { body.add(i + 1, exp.get(1)); // s2 i++; } @@ -889,14 +846,14 @@ int insert(Exp body, Exp exp, int i) { } return i; } - - /** + + /** * Move bind (exp as var) into appropriate service uri { } if any */ void bind(Exp body) { ArrayList list = new ArrayList<>(); for (Exp exp : body) { - if (exp.isBind() && ! exp.getFilter().isTermExistRec()) { + if (exp.isBind() && !exp.getFilter().isTermExistRec()) { boolean b = getGroupBGP().move(exp, body); if (b) { list.add(exp); @@ -907,56 +864,51 @@ void bind(Exp body) { body.getBody().remove(exp); } } - - + /** - * Move filter into appropriate service + * Move filter into appropriate service */ boolean moveFilter(Exp body) { return getGroupBGP().moveFilter(body); } - + void filter(Exp body, Exp bgp) { filter(body, bgp, new ArrayList<>()); } - // copy relevant filter from body into bgp + // copy relevant filter from body into bgp void filter(Exp body, Exp bgp, List list) { List varList = bgp.getInscopeVariables(); for (Exp exp : body) { if (exp.isFilter()) { if (exp.getFilter().isTermExistRec()) { // skip - } - else if (exp.getFilter().isBound(varList) && + } else if (exp.getFilter().isBound(varList) && !bgp.getBody().contains(exp)) { bgp.add(exp); - + if (!list.contains(exp)) { list.add(exp); } - } + } } } } - + void sort(Exp exp) { new Sorter(this).process(exp); } - - - ASTQuery getAST() { - return ast; - } - - + + ASTQuery getAST() { + return ast; + } + // exp = graph name { bgp } Exp rewrite(Source exp) { if (isFederateBGP()) { // 1) bgp partition { e_i } computed without named graph // 2) generate service S { graph name { e_i } } - Exp res = rewrite(exp.getSource(), exp.getBodyExp()); - return res; + return rewrite(exp.getSource(), exp.getBodyExp()); } /** * former case: @@ -971,18 +923,17 @@ else if (distributeNamed) { return rewriteNamed.simpleNamed(ast, exp); } } - + // no endpoint URL for triple t void error(Triple t, String mes) { logger.error(mes); error(t); } - + void error(Triple t) { logger.error("Undefined triple: " + t); - //ast.setFail(true); } - + List getAtomList(List list) { ArrayList alist = new ArrayList<>(); for (String str : list) { @@ -990,24 +941,24 @@ List getAtomList(List list) { } return alist; } - + List getServiceList(Triple t) { - if (t.isPath()){ + if (t.isPath()) { return getServiceListPath(t); } return getServiceListTriple(t); } - - List getServiceListTriple(Triple t) { + + List getServiceListTriple(Triple t) { if (isSelect()) { - List list = getPredicateService(t); - if (list != null && ! list.isEmpty()) { + List list = getPredicateService(t); + if (list != null && !list.isEmpty()) { return list; } } return getDefaultServiceList(); } - + List getPredicateService(Triple t) { List list = getAstSelector().getPredicateService(t); if (list == null) { @@ -1020,7 +971,7 @@ List getPredicateService(Triple t) { List getServiceListPath(Triple t) { List serviceList = getAstSelector().getPredicateService(t); - if (serviceList==null) { + if (serviceList == null) { // path t was not tested because it has no constant return getServiceListPathPredicate(t); } @@ -1029,10 +980,10 @@ List getServiceListPath(Triple t) { } return serviceList; } - + List getServiceListPathPredicate(Triple t) { List serviceList = new ArrayList<>(); - + for (Constant p : t.getRegex().getPredicateList()) { for (Atom serv : getServiceListBasic(p)) { add(serviceList, serv); @@ -1043,16 +994,16 @@ List getServiceListPathPredicate(Triple t) { } return serviceList; } - + void add(List list, Atom at) { - if (! list.contains(at)) { + if (!list.contains(at)) { list.add(at); } } - - List getServiceListBasic(Constant p) { + + List getServiceListBasic(Constant p) { if (isSelect()) { - List list = getAstSelector().getPredicateService(p); //getSelector().getPredicateService(p); + List list = getAstSelector().getPredicateService(p); if (list == null) { return new ArrayList<>(0); } @@ -1060,18 +1011,17 @@ List getServiceListBasic(Constant p) { } return getDefaultServiceList(); } - - List getServiceList(Constant p) { + + List getServiceList(Constant p) { if (isSelect()) { - List list = getAstSelector().getPredicateService(p); - if (list != null && ! list.isEmpty()) { + List list = getAstSelector().getPredicateService(p); + if (list != null && !list.isEmpty()) { return list; } } return getDefaultServiceList(); } - - + // when there is no service for a triple List getDefaultServiceList() { if (isSelect()) { @@ -1079,33 +1029,28 @@ List getDefaultServiceList() { } return ast.getServiceList(); } - + List undefinedService() { - ArrayList list = new ArrayList<>(); - //list.add(Variable.create(UNDEF)); - return list; + return new ArrayList<>(); } - + Service service(List list, Exp exp) { return Service.create(list, exp, false); } - + // accept for create join test boolean createJoinTest(Triple t) { if (t.isPath()) { - return SELECT_JOIN_PATH; + return SELECT_JOIN_PATH; } return true; } - + boolean acceptWithoutJoinTest(Triple t) { - if (t.isPath() && !SELECT_JOIN_PATH) { - // there is no join test for path: accept it - return true; - } - return false; + // there is no join test for path: accept it + return t.isPath() && !SELECT_JOIN_PATH; } - + boolean rewriteFilter(Atom name, Expression exp) { boolean exist = false; if (exp.isTerm()) { @@ -1122,13 +1067,13 @@ boolean rewriteFilter(Atom name, Expression exp) { } return exist; } - - /* + + /* * Rewrite filter exists { t } * as: * filter exists { service { t } } * PRAGMA: it returns all Mappings whereas in this case - * it could return only one. However, in the general case: + * it could return only one. However, in the general case: * exists { t1 t2 } it must return all Mappings. */ void rewriteExist(Atom name, Expression exp) { @@ -1136,8 +1081,6 @@ void rewriteExist(Atom name, Expression exp) { rewrite(name, body); getSimplify().simplifyFilterExist(body); } - - /** * Find filters bound by t in body, except exists {} Add them to bgp @@ -1145,11 +1088,11 @@ void rewriteExist(Atom name, Expression exp) { void filter(Exp body, Triple t, Exp bgp, List list) { for (Exp exp : body) { if (exp.isFilter()) { - if (! isRecExist(exp)) { + if (!isRecExist(exp)) { Expression f = exp.getFilter(); - if (t.bind(f) && ! bgp.getBody().contains(exp)) { + if (t.bind(f) && !bgp.getBody().contains(exp)) { bgp.add(exp); - if (! list.contains(exp)) { + if (!list.contains(exp)) { list.add(exp); } } @@ -1157,72 +1100,32 @@ void filter(Exp body, Triple t, Exp bgp, List list) { } } } - + boolean isRecExist(Exp f) { return f.getFilter().isTermExistRec(); } - + boolean isExist(Exp f) { return f.getFilter().isTermExist(); } boolean isNotExist(Exp f) { - return f.getFilter().isNotTermExist() ; + return f.getFilter().isNotTermExist(); } - + public boolean isBounce() { return bounce; } - - public static void defineFederation(String name, List list) { - List serviceList = new ArrayList<>(); - for (String url : list) { - serviceList.add(Constant.createResource(url)); - } - defFederation(name, serviceList); - } - - public static void declareFederation(String name, List list) { - List serviceList = new ArrayList<>(); - for (IDatatype url : list) { - serviceList.add(Constant.create(url)); - } - defFederation(name, serviceList); - } - - public static void defFederation(String name, List list) { - getFederation().put(name, list); - } - - /** - * @return the federation - */ - public static HashMap> getFederation() { - return federation; - } - - public static List getFederation(String name) { - return getFederation().get(name); - } - - public List getFederationFilter(String name) { - List list = getFederation().get(name); - if (list == null) { - return null; - } - return list; - } - - public static void setFederation(HashMap> aFederation) { - federation = aFederation; + public List getFederationFilter(String name) { + return getFederation().get(name); } public boolean isMerge() { return merge; } - + public void setMerge(boolean merge) { this.merge = merge; } @@ -1231,37 +1134,37 @@ public boolean isSelectFilter() { return selectFilter; } - + public void setSelectFilter(boolean selectFilter) { this.selectFilter = selectFilter; } - + public boolean isIndex() { return index; } - + public void setIndex(boolean index) { this.index = index; } - + public boolean isSparql() { return sparql; } - + public void setSparql(boolean sparql) { this.sparql = sparql; } - + public URLServer getURL() { return url; } - + public void setURL(URLServer url) { this.url = url; } @@ -1297,7 +1200,7 @@ public boolean isSelect() { public void setSelect(boolean select) { this.select = select; } - + public PrepareBGP getGroupBGP() { return groupBGP; } @@ -1305,9 +1208,9 @@ public PrepareBGP getGroupBGP() { public void setGroupBGP(PrepareBGP rew) { this.groupBGP = rew; } - + RewriteTriple getRewriteTriple() { - return rewriteTriple; + return rewriteTriple; } public void setRewriteTriple(RewriteTriple rwt) { @@ -1395,7 +1298,7 @@ public RewriteErrorManager getErrorManager() { public void setErrorManager(RewriteErrorManager errorManager) { this.errorManager = errorManager; } - + public Simplify getSimplify() { return sim; } @@ -1451,7 +1354,7 @@ public List getIndexURLList() { public void setIndexURLList(List indexURLList) { this.indexURLList = indexURLList; } - + public boolean isSplit(Triple t) { return getSplit().contains(t.getProperty().getLabel()); } @@ -1504,5 +1407,5 @@ public void setFederateMinus(boolean federateMinus) { this.federateMinus = federateMinus; } - + } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/PrepareBGP.java b/src/main/java/fr/inria/corese/core/compiler/federate/PrepareBGP.java index aa3187a4a..5c9e0910d 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/PrepareBGP.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/PrepareBGP.java @@ -1,63 +1,56 @@ package fr.inria.corese.core.compiler.federate; -import static fr.inria.corese.core.compiler.federate.util.RewriteErrorMessage.FILTER_EXISTS; -import fr.inria.corese.core.sparql.triple.parser.Atom; -import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; -import fr.inria.corese.core.sparql.triple.parser.Constant; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.Expression; -import fr.inria.corese.core.sparql.triple.parser.Service; -import fr.inria.corese.core.sparql.triple.parser.Term; -import fr.inria.corese.core.sparql.triple.parser.Triple; -import fr.inria.corese.core.sparql.triple.parser.Variable; -import fr.inria.corese.core.sparql.triple.parser.VariableScope; +import fr.inria.corese.core.sparql.triple.parser.*; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import static fr.inria.corese.core.compiler.federate.util.RewriteErrorMessage.FILTER_EXISTS; + /** * Group connected triple in bgp wrt service url * * @author Olivier Corby, Wimmics INRIA I3S, 2018 - * */ public class PrepareBGP extends Util { static final String FAKE_URI = "http://ns.inria.fr/_fake_"; private FederateVisitor visitor; - private boolean debug = false; private boolean skipSameAs = true; PrepareBGP(FederateVisitor vis) { visitor = vis; } - + // create map: URI -> (BGP1 .. BGPn) // create BGP for triples that share same service URI // group connected triples with one URI in uri2bgpList // (triple with several URI in FAKE_URI URI here) // group connected triples with several URI in uriList2bgpList + /** - * modify the body (replace triples by BGPs) + * modify the body (replace triples by BGPs) * copy bind (exp as var) if possible and copy filters if possible * filterList: list to be filled with bind & filters that are copied into service * TODO: bind (exp as var) could also be assignToConnectedBGP + * * @return BGP list of connected triples with several service URI */ URI2BGPList process - (Atom name, Exp main, Exp body, List filterList) { - - URI2BGPList uri2bgpList = new URI2BGPList(getVisitor()) + (Atom name, Exp main, Exp body, List filterList) { + + URI2BGPList uri2bgpList = new URI2BGPList(getVisitor()) .setJoin(join(main, body)); - + URI2BGPList uriList2bgpList = new URI2BGPList(getVisitor()) .setJoin(join(main, body)); - + uri2bgpList.setUriList2bgp(uriList2bgpList); List localFilterList = new ArrayList<>(); - + // create map: URI -> (BGP1 .. BGPn) // create BGP for triples that share same service URI // new version: @@ -66,56 +59,56 @@ public class PrepareBGP extends Util { // group connected triples with one URI in uri2bgpList // (triple with several URI in FAKE_URI URI here) assign(body, uri2bgpList, uriList2bgpList, localFilterList); - + // PRAGMA: the rest of the function process former case // where we distinguished one/several uri // not used for new case with bgp and several uri - + // merge BGP of arguments of optional/minus/union // merge BGP when filter need it merge(main, uri2bgpList, localFilterList); // create map: triple -> BGP with one URI HashMap triple2bgp = record(uri2bgpList); - + // create map: BGP -> Service with one URI // for each triple member of BGP with one URI // replace triple in body by service URI { BGP } // remove all such triples - HashMap bgp2Service = + HashMap bgp2Service = triple2ServiceWithOneURI(name, body, triple2bgp, uri2bgpList); - + // create local fake service for triple with several URI // just for processing filter below - List bgpListWithSeveralURI = + List bgpListWithSeveralURI = uri2bgpList.get(FAKE_URI); - + for (BasicGraphPattern bgp : bgpListWithSeveralURI) { Service serv = Service.create(Constant.createResource(FAKE_URI), bgp); bgp2Service.put(bgp, serv); } - - boolean tripleFilter = ! uri2bgpList.getMap().isEmpty(); + + boolean tripleFilter = !uri2bgpList.getMap().isEmpty(); // push bind (exp as var) into appropriate service clause where exp variables are bound // succcess means that no bind() stay outside service clauses boolean success = bind(name, body, bgp2Service, filterList, tripleFilter); // push filter into appropriate service clause where filter variables are bound filter(name, body, bgp2Service, filterList, success && tripleFilter); - + uri2bgpList.complete(); return uri2bgpList; } - + // right exp of optional/minus do not use select join to create bgp list // it means that connected triples remain in same bgp even if they do not join // this is a heuristics in favor of simplification of A optional/minus B boolean join(Exp main, Exp body) { - if ((main.isOptional()|| main.isMinus()) && body == main.get(1)) { + if ((main.isOptional() || main.isMinus()) && body == main.get(1)) { return false; } - return getVisitor().USE_JOIN; + return FederateVisitor.USE_JOIN; } - + // create map URI -> (BGP1 .. BGPn) // group connected triples with one URI in uri2bgpList // (triple with several URI in FAKE_URI URI here) @@ -130,9 +123,6 @@ void assign(Exp body, URI2BGPList uri2bgpList, URI2BGPList uriList2bgpList, List } else if (exp.isTriple()) { Triple triple = exp.getTriple(); List list = getVisitor().getServiceList(triple); - if (list.isEmpty()) { - //getVisitor().error(triple, "triple 2 bgp"); - } if (getVisitor().isFederateBGP()) { // do not distinguish one vs several URI // list of connected BGP of triple with any nb URI @@ -154,17 +144,16 @@ void assign(Exp body, URI2BGPList uri2bgpList, URI2BGPList uriList2bgpList, List } } } - - + + // create map triple -> BGP HashMap record(URI2BGPList uri2bgpList) { - HashMap triple2bgp = new HashMap<>(); + HashMap triple2bgp = new HashMap<>(); for (String uri : uri2bgpList.getMap().keySet()) { if (uri.equals(FAKE_URI)) { // several URI - } - else { + } else { // one URI List list = uri2bgpList.get(uri); for (BasicGraphPattern bgp : list) { @@ -174,17 +163,17 @@ HashMap record(URI2BGPList uri2bgpList) { } } } - + return triple2bgp; } - + // for each triple member of BGP with one URI // replace first triple by service URI { BGP } HashMap triple2ServiceWithOneURI - (Atom name, Exp body, - HashMap triple2bgp, - URI2BGPList uri2bgpList) { - + (Atom name, Exp body, + HashMap triple2bgp, + URI2BGPList uri2bgpList) { + HashMap bgp2Service = new HashMap<>(); for (int i = 0; i < body.size(); i++) { @@ -202,12 +191,11 @@ HashMap record(URI2BGPList uri2bgpList) { // do it once for first triple of this BGP bgp2Service.put(bgp, serv); uri2bgpList.addServiceWithOneURI(serv); - + if (getVisitor().isFederateBGP()) { // do nothing yet, // RewriteBGPList will complete with serv - } - else { + } else { // replace first triple of BGP by service BGP // other such triple are removed below as they are in BGP body.set(i, serv); @@ -216,15 +204,15 @@ HashMap record(URI2BGPList uri2bgpList) { } } } - + // remove triples member of a created service with one URI for (Triple t : triple2bgp.keySet()) { body.getBody().remove(t); } - + return bgp2Service; } - + void merge(Exp main, URI2BGPList uri2bgpList, List localFilterList) { if (getVisitor().isMerge()) { if (main.isBinaryExp()) { @@ -241,25 +229,24 @@ void merge(Exp main, URI2BGPList uri2bgpList, List localFilterList) /** * Add triple in appropriate BGP in serv -> (BGP1 , BGPn) where triple is - * connected to BGP + * connected to BGP * merge BGPs that are connected with triple. */ void assignTripleToConnectedBGP(URI2BGPList map, Triple triple, List uriList) { if (getVisitor().isSplit(triple)) { // owl:sameAs will be processed later as a lonely missing triple // in order not to screw up bgp connectivity building - } - else { + } else { basicAssignTripleToConnectedBGP(map, triple, uriList); } } - + void basicAssignTripleToConnectedBGP(URI2BGPList map, Triple triple, List uriList) { for (Atom uri : uriList) { map.assignTripleToConnectedBGP(triple, uri.getLabel()); } } - + void filter(Atom name, Exp body, HashMap bgpList, List filterList, boolean tripleFilter) { // copy filters from body into BGP who bind all filter variables @@ -289,15 +276,11 @@ boolean bind(Atom name, Exp body, HashMap bgpList, L // copy bind(exp as var) from body into BGP who bind all exp variables for (Exp exp : body) { if (exp.isBind()) { -// if (visitor.isRecExist(exp)) { -// success = false; -// } if (getVisitor().isRecExist(exp)) { if (getVisitor().isExist() && tripleFilter && accept(exp)) { boolean move = filterExist(name, body, bgpList, filterList, exp); success &= move; - } - else { + } else { success = false; } } else { @@ -310,7 +293,7 @@ boolean bind(Atom name, Exp body, HashMap bgpList, L } /** - * exp is filter or bind (exp as var) + * exp is filter or bind (exp as var) * try to move it in service clause where * its variables are bound */ @@ -322,8 +305,7 @@ boolean move(Exp filterExp, HashMap bgpList, List bgpList, List varList) { if (filterExp.getFilter().isBound(varList)) { if (filterExp.isBind()) { return varList.contains(filterExp.getBind().getVariable()); - } - else { + } else { return true; } } return false; } - - void trace(String mes, Object... obj) { - System.out.println(String.format(mes, obj)); - } /** * First phase: service with one URI * Copy filter exists into appropriate service URI, first phase (service with one URI) * filter exists service with one URI can be merged into bgp service with same URI - * - * body = service URI { BGP } filter exists { EXP } -> - * service URI { BGP } filter exists { service URI { EXP } } -> + *

+ * body = service URI { BGP } filter exists { EXP } -> + * service URI { BGP } filter exists { service URI { EXP } } -> * service URI { BGP filter exists { EXP } } - * + *

* TODO: does not work if there were existing service before rewrite because * they are not in bgpMap In this case, this function is not called TODO: * does not work if some triples are not yet in a service clause because we @@ -370,7 +347,7 @@ boolean filterExist(Atom name, Exp body, HashMap bgp Expression filter = filterExist.getFilter(); // rewrite exists {} with service clause inside getVisitor().rewriteFilter(name, filter); - Term termExist = filterExist.getFilter().getTermExist(); + Term termExist = filterExist.getFilter().getTermExist(); Exp bgpExist = termExist.getExistBGP(); if (bgpExist.size() == 1 && bgpExist.get(0).isService()) { @@ -393,11 +370,6 @@ boolean filterExist(Atom name, Exp body, HashMap bgp // intersection of BGP and exists variables List currentIntersection = intersectionVariable(existVarList, bgpVarList); - if (isDebug()) { - System.out.println("R: bgp: " + bgpVarList + " exist: " + existVarList); - System.out.println("Intersection: " + currentIntersection); - } - if (servExist.getServiceName().equals(servBGP.getServiceName())) { // bgp service and exists service with same URI if (equal(currentIntersection, existVarList)) { @@ -433,7 +405,6 @@ else if (!currentIntersection.isEmpty()) { if (bgpList.size() == 1) { // there is one bgp service with same URI as filter exists service // merge filter exists into bgp with same service URI - if (isDebug()) System.out.println("move1: " + filterExist); // remove service from filter exists termExist.setExistBGP(servExist.getBodyExp()); // move filter exist into relevant bgp service @@ -447,9 +418,9 @@ else if (!currentIntersection.isEmpty()) { } return false; } - + /** - * Move filter into appropriate service + * Move filter into appropriate service */ boolean moveFilter(Exp body) { boolean suc = true; @@ -462,20 +433,18 @@ boolean moveFilter(Exp body) { // service uri {} where filter variables are bound appropriately if (b) { list.add(exp); - } - else { + } else { // filter exists with service clause remain // on its own suc = false; getVisitor().getErrorManager() .add(FILTER_EXISTS, exp); } - } - else { - boolean b = move(exp, body); + } else { + boolean b = move(exp, body); if (b) { list.add(exp); - } + } } } } @@ -484,9 +453,9 @@ boolean moveFilter(Exp body) { } return suc; } - + /** - * Second phase: + * Second phase: * the whole content of a BGP have been rewritten * Move bind/filter when there is *only one* service which binds it with *inscope* variables * We are not sure that it succeeds but there is one service that can do it @@ -495,12 +464,12 @@ boolean move(Exp filter, Exp body) { boolean move = false; boolean severalURI = false; List list = new ArrayList<>(); - + for (Exp exp : body) { if (exp.isService()) { Service serv = exp.getService(); Exp bgp = serv.getBodyExp(); - if (! bgp.getBody().contains(filter)) { + if (!bgp.getBody().contains(filter)) { List varList = bgp.getInscopeVariables(); if (filter.getFilter().isBound(varList)) { // severalURI = true for service with several URI @@ -516,25 +485,25 @@ boolean move(Exp filter, Exp body) { } return move; } - + /** * Second phase * Copy filter exists { service (URI) { exp }} into appropriate bgp service (URI) { exp } - * when both have same URI list and filter exists variable are bound properly by service + * when both have same URI list and filter exists variable are bound properly by service * the whole content of a BGP have been rewritten, some filter exists remain : try again - * The difference with first phase is that here the service where to copy a filter exists + * The difference with first phase is that here the service where to copy a filter exists * may contain optional, union, etc which may have been simplified and hence merge may be possible now - * Heuristics: + * Heuristics: * when filter exists has several URI, test it on the same endpoint as its outer BGP */ boolean filterExist(Exp filterExist, Exp body) { if (!(visitor.isExist() && accept(filterExist))) { return false; } - Term termExist = filterExist.getFilter().getTermExist(); + Term termExist = filterExist.getFilter().getTermExist(); Exp bgpExist = termExist.getExistBGP(); - + if (bgpExist.size() == 1 && bgpExist.get(0).isService()) { Service servExist = bgpExist.get(0).getService(); @@ -550,18 +519,11 @@ boolean filterExist(Exp filterExist, Exp body) { for (Exp exp : body) { if (exp.isFilter()) { // skip - } - else if (exp.isService()) { + } else if (exp.isService()) { Service service = exp.getService(); List bgpVarList = service.getInscopeVariables(); List currentIntersection = intersectionVariable(existVarList, bgpVarList); - if (isDebug()) { - System.out.println("R: " + existVarList + " " + bgpVarList); - System.out.println("Intersection: " + currentIntersection); - } - - //if (servExist.getServiceName().equals(servBGP.getServiceName())) { if (equalURI(servExist.getServiceList(), service.getServiceList())) { if (equal(currentIntersection, existVarList)) { serviceList.add(service); @@ -587,14 +549,12 @@ else if (!currentIntersection.isEmpty()) { return false; } } - } - else { + } else { return false; } } - - if (serviceList.size() >0) { //== 1) { - if (isDebug()) System.out.println("move2: " + filterExist); + + if (!serviceList.isEmpty()) { // remove service clause from exists (keep service bgp) termExist.setExistBGP(servExist.getBodyExp()); // move exist into relevant service @@ -606,22 +566,6 @@ else if (!currentIntersection.isEmpty()) { } return false; } - - - - /** - * @return the debug - */ - public boolean isDebug() { - return debug; - } - - /** - * @param debug the debug to set - */ - public void setDebug(boolean debug) { - this.debug = debug; - } public FederateVisitor getVisitor() { return visitor; diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/Provenance.java b/src/main/java/fr/inria/corese/core/compiler/federate/Provenance.java index e1b4548e7..9bfe53b6f 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/Provenance.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/Provenance.java @@ -37,9 +37,9 @@ public class Provenance { void init(List serviceList) { for (Service serv : serviceList) { if (serv.getServiceName().isVariable()) { - Variable var = serv.getServiceName().getVariable(); - varList.add(var); - table.put(var, serv.getVariables()); + Variable variable = serv.getServiceName().getVariable(); + varList.add(variable); + table.put(variable, serv.getVariables()); } } } @@ -48,21 +48,6 @@ HashMap> getProvenance() { return table; } - - void display() { - for (Mapping m : map) { - for (Variable var : varList) { - System.out.println(var + " " + m.getValue(var.getLabel())); - for (Variable name : table.get(var)) { - if (!name.equals(var) && m.getValue(name.getLabel()) != null) { - System.out.println(name + " " + m.getValue(name.getLabel())); - } - } - } - System.out.println("__"); - } - } - void aggregate() { group = Group.create(getNodeList()); for (Mapping m : map) { @@ -74,8 +59,8 @@ void aggregate() { public String toString() { StringBuilder sb = new StringBuilder(); for (Mapping m : getServers()) { - for (Variable var : getVariables()) { - DatatypeValue res = m.getValue(var.getLabel()); + for (Variable variable : getVariables()) { + DatatypeValue res = m.getValue(variable.getLabel()); if (res != null) { sb.append(res.stringValue()).append(NL); } @@ -100,8 +85,8 @@ public Mappings getMappings(Mapping m) { public List getServerNames(Mapping m) { ArrayList list = new ArrayList<>(); - for (Variable var : getVariables()) { - Node n = m.getNode(var.getLabel()); + for (Variable variable : getVariables()) { + Node n = m.getNode(variable.getLabel()); if (n != null) { list.add(n); } @@ -110,10 +95,10 @@ public List getServerNames(Mapping m) { } List getNodeList() { - List list = new ArrayList(); + List list = new ArrayList<>(); for (Mapping m : map) { - for (Variable var : varList) { - Node node = m.getQueryNode(var.getLabel()); + for (Variable variable : varList) { + Node node = m.getQueryNode(variable.getLabel()); if (node != null && ! list.contains(node)) { list.add(node); } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/RewriteBGPList.java b/src/main/java/fr/inria/corese/core/compiler/federate/RewriteBGPList.java index 79e5c1fd4..fb21262a3 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/RewriteBGPList.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/RewriteBGPList.java @@ -1,11 +1,7 @@ package fr.inria.corese.core.compiler.federate; -import fr.inria.corese.core.sparql.triple.parser.Atom; -import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.Service; -import fr.inria.corese.core.sparql.triple.parser.Triple; -import fr.inria.corese.core.sparql.triple.parser.Union; +import fr.inria.corese.core.sparql.triple.parser.*; + import java.util.ArrayList; import java.util.List; @@ -36,7 +32,7 @@ public class RewriteBGPList { public static boolean BGP_LIST = true; public static boolean TRACE_BGP_LIST = false; - private static boolean MERGE_EVEN_IF_NOT_CONNECTED = true; + private static final boolean MERGE_EVEN_IF_NOT_CONNECTED = true; private FederateVisitor visitor; // connected bgp of triple with one uri (deprecated) @@ -69,7 +65,6 @@ Exp process(Atom namedGraph, Exp body, ArrayList filterList) { // partition means cover body with partition of triple // complete each partition with missing triple from body List> partitionList = partition(sortedList); - trace(sortedList, partitionList); for (List bgpList : partitionList) { // rewrite each partition of bgp as service {bgp} @@ -110,9 +105,8 @@ Exp process(Atom namedGraph, Exp body, ArrayList filterList) { for (Exp exp : filterList) { body.getBody().remove(exp); } - - Exp union = union(list, 0); - return union; + + return union(list, 0); } // rewrite one bgpList partition of connected bgp as list of service {bgp} @@ -141,7 +135,6 @@ Exp process(Atom namedGraph, Exp body, ArrayList filterList) { if (! contains(bgpList, triple)) { Service service = getVisitor().getRewriteTriple() .rewriteTripleWithSeveralURI(namedGraph, triple, body, filterList); - // getVisitor().filter(body, service.getBodyExp()); exp.add(service); } } @@ -161,10 +154,8 @@ Exp process(Atom namedGraph, Exp body, ArrayList filterList) { // @hint: // merge(true) merge all bgp // merge(false) merge connected bgp only - ctrace("before simplify: %s", exp); getVisitor().getSimplify().merge(exp, isMergeEvenIfNotConnected()); // @todo: filter - ctrace("after simplify: %s", exp); return exp; } @@ -200,14 +191,10 @@ List> partition(List bgpList) { // natural partition with |bgp|>1 and |uri|=1, if any List partition = bgp2uri.partition(); - ctrace("natural partition:\n%s", partition); // remove natural partition from candidate bgpList, if any - List subList = substract(bgpList, partition); - ctrace("start bgpList:\n%s", subList); + List subList = substract(bgpList, partition); // start rec computing with natural partition, if any - rec(subList, partition, res, 0); - ctrace("list: %s", uriList2bgp.getTripleList()); - ctrace("map: %s", bgp2uri); + rec(subList, partition, res, 0); return res; } @@ -248,29 +235,6 @@ void rec(List bgpList, List res, List sortedList, List> alist) { - if (TRACE_BGP_LIST) { - for (BasicGraphPattern bgp : sortedList) { - trace("bgp: %s", bgp); - trace(""); - } - for (List ll : alist) { - trace("partition: %s",ll); - trace(""); - } - } } Exp union(List list, int n) { @@ -307,12 +271,7 @@ void select(List> list) { if (uriList.size()>nbUri) { nbUri = uriList.size(); } - trace("%s\n%s", uriList, bgp); - } - if (count==size && nbUri==1) { - trace("complete"); } - trace("__"); } } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/RewriteList.java b/src/main/java/fr/inria/corese/core/compiler/federate/RewriteList.java index 0d2db9201..4811ff4f2 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/RewriteList.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/RewriteList.java @@ -1,42 +1,39 @@ package fr.inria.corese.core.compiler.federate; -import static fr.inria.corese.core.compiler.federate.util.RewriteErrorMessage.NO_SERVICE; import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.triple.api.FederateMerge; -import fr.inria.corese.core.sparql.triple.parser.Atom; -import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.Metadata; -import fr.inria.corese.core.sparql.triple.parser.Service; -import fr.inria.corese.core.sparql.triple.parser.Triple; -import fr.inria.corese.core.sparql.triple.parser.Union; +import fr.inria.corese.core.sparql.triple.parser.*; + import java.util.ArrayList; import java.util.List; +import static fr.inria.corese.core.compiler.federate.util.RewriteErrorMessage.NO_SERVICE; + /** - * Rewrite rdf list into one service bgp + * Rewrite rdf list into one service bgp * Rewrite bgp with bnode into one service bgp: ?s :p [ :q ?v ] + * * @focus "?var" -> merge triple with variable var in bgp with bnode and var * @focus "?s" * ?s p [q u] . ?s p v * -> add ?s p v in bgp because it share variable ?s */ public class RewriteList implements FederateMerge { - - private FederateVisitor visitor; + IDatatype focus; - - RewriteList(FederateVisitor vis){ + private FederateVisitor visitor; + + RewriteList(FederateVisitor vis) { visitor = vis; } - + // group rdf list in specific service bgp // group connected triple with bnode variable in specific service bgp // modify body // return false when one bgp has no service // @focus "var" -> merge triple with variable var in the same way as bnode variable boolean process(Exp body) { - focus = visitor.getAST().getMetadataDatatypeValue(Metadata.FOCUS); + focus = visitor.getAST().getMetadataDatatypeValue(Metadata.Type.FOCUS); boolean suc = true; if (getVisitor().isProcessList()) { List list = new ArrayList<>(); @@ -46,38 +43,37 @@ boolean process(Exp body) { } return suc; } - + @Override public boolean merge(Triple t) { return hasBlank(t) || submerge(t); } - + boolean hasBlank(Triple t) { return t.getSubject().isBlankNode() || - t.getObject().isBlankNode(); + t.getObject().isBlankNode(); } - - boolean submerge(Triple t) { + + boolean submerge(Triple t) { if (focus == null) { - return false; + return false; } return hasVariable(t, focus.getLabel()); } - + boolean hasVariable(Triple t, String var) { return hasVariable(t.getSubject(), var) || - hasVariable(t.getObject(), var); + hasVariable(t.getObject(), var); } - + boolean hasVariable(Atom at, String var) { if (at.isVariable()) { return var.contains(at.getLabel()); } return false; } - - + boolean bgp2service(Exp body, List list) { boolean suc = true; for (BasicGraphPattern exp : list) { @@ -93,7 +89,7 @@ boolean bgp2service(Exp body, List list) { } return suc; } - + void replace(Exp body, BasicGraphPattern bgp, Exp serviceExp) { for (Exp exp : bgp) { if (exp.isTriple()) { @@ -102,7 +98,7 @@ void replace(Exp body, BasicGraphPattern bgp, Exp serviceExp) { } body.add(serviceExp); } - + // rewrite rdf list as service (S) { bgp } // where all rdf list triple are in all s in S @@ -116,21 +112,19 @@ Exp bgp2service(BasicGraphPattern bgp) { } if (count++ == 0) { uriList = list; - } - else { - uriList = intersection(uriList, list); + } else { + uriList = intersection(uriList, list); } } - + if (uriList.isEmpty()) { return null; } - Service s = Service.create(uriList, bgp); - return s; + return Service.create(uriList, bgp); } - + ArrayList intersection(List l1, List l2) { - ArrayList uriList = new ArrayList<>(); + ArrayList uriList = new ArrayList<>(); for (Atom uri : l1) { if (l2.contains(uri)) { uriList.add(uri); @@ -139,13 +133,12 @@ ArrayList intersection(List l1, List l2) { return uriList; } - + Exp union(List list, int n) { - if (n == list.size()-1) { + if (n == list.size() - 1) { return list.get(n); - } - else { - return Union.create(list.get(n), union(list, n+1)); + } else { + return Union.create(list.get(n), union(list, n + 1)); } } @@ -156,6 +149,6 @@ public FederateVisitor getVisitor() { public void setVisitor(FederateVisitor visitor) { this.visitor = visitor; } - - + + } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/RewriteNamedGraph.java b/src/main/java/fr/inria/corese/core/compiler/federate/RewriteNamedGraph.java index 0ad9f25fb..c631def41 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/RewriteNamedGraph.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/RewriteNamedGraph.java @@ -1,17 +1,7 @@ package fr.inria.corese.core.compiler.federate; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.Atom; -import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; -import fr.inria.corese.core.sparql.triple.parser.Constant; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.Query; -import fr.inria.corese.core.sparql.triple.parser.Service; -import fr.inria.corese.core.sparql.triple.parser.Source; -import fr.inria.corese.core.sparql.triple.parser.URLServer; -import fr.inria.corese.core.sparql.triple.parser.Union; -import fr.inria.corese.core.sparql.triple.parser.Values; -import fr.inria.corese.core.sparql.triple.parser.Variable; +import fr.inria.corese.core.sparql.triple.parser.*; + import java.util.ArrayList; import java.util.List; @@ -19,18 +9,17 @@ * */ public class RewriteNamedGraph { - + ASTQuery ast; FederateVisitor vis; RewriteNamedGraph(FederateVisitor vis) { this.vis = vis; } - - - + + /** - * named graph sent as a whole in service clause + * named graph sent as a whole in service clause */ Exp simpleNamed(ASTQuery ast, Source exp) { // send named graph as is to remote servers @@ -41,73 +30,68 @@ Exp simpleNamed(ASTQuery ast, Source exp) { } return vis.service(ast.getServiceList(), BasicGraphPattern.create(exp)); } - - - Exp rewriteNamed(ASTQuery ast, Source exp) { + + + Exp rewriteNamed(ASTQuery ast, Source exp) { Atom name = exp.getSource(); if (name.isVariable()) { return rewriteNamed(ast, name.getVariable(), exp.getBodyExp(), exp); - } - else { + } else { return vis.rewrite(name.getConstant(), exp.getBodyExp()); } } - - /** - * from named G = {g1 .. gn} -- gi on remote dataset - * graph ?g { exp } -> rewrite as: - * union (g in G) { - * values ?g { g } - * service (si) { select * where { graph g { exp } } } - * @todo - * service {graph ?g {exp}} - * @todo subquery.copy() - */ + + /** + * from named G = {g1 .. gn} -- gi on remote dataset + * graph ?g { exp } -> rewrite as: + * union (g in G) { + * values ?g { g } + * service (si) { select * where { graph g { exp } } } + * + * @todo service {graph ?g {exp}} + * @todo subquery.copy() + */ Exp rewriteNamed(ASTQuery ast, Variable var, Exp body, Source exp) { if (ast.getNamed().isEmpty()) { return simpleNamed(ast, exp); } ArrayList list = new ArrayList<>(); - + for (Constant namedGraph : ast.getNamed()) { Values values = Values.create(var, namedGraph); Exp res = vis.rewrite(namedGraph, body.copy()); res.add(values); list.add(res); } - + return union(list, 0); } - + Exp union(List list, int n) { - if (n == list.size() - 1){ + if (n == list.size() - 1) { return list.get(n); + } else { + return Union.create(list.get(n), union(list, n + 1)); } - else { - return Union.create(list.get(n), union(list, n+1)); - } - } - - - - + } + + /** * expandList contains rewrite of graph ?g { } if any * This function includes the rewritten named graph statement */ void expand(Exp body, ArrayList expandList) { - for (int i = 0; i < body.size(); ) { + for (int i = 0; i < body.size(); ) { Exp exp = body.get(i); if (exp.isBGP() && expandList.contains(exp)) { body.remove(i); for (Exp e : exp) { - if (e.isBGP()){ - for (Exp ee : e){ - body.add(i++, ee); + if (e.isBGP()) { + for (Exp ee : e) { + body.add(i++, ee); } - } - else { + } else { body.add(i++, e); } } @@ -116,5 +100,5 @@ void expand(Exp body, ArrayList expandList) { } } } - + } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/RewriteService.java b/src/main/java/fr/inria/corese/core/compiler/federate/RewriteService.java index e0ed77920..89539bf0d 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/RewriteService.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/RewriteService.java @@ -1,78 +1,66 @@ package fr.inria.corese.core.compiler.federate; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.Metadata; -import fr.inria.corese.core.sparql.triple.parser.Service; -import fr.inria.corese.core.sparql.triple.parser.Values; -import fr.inria.corese.core.sparql.triple.parser.Variable; +import fr.inria.corese.core.sparql.triple.parser.*; + import java.util.ArrayList; import java.util.List; /** * Rewrite service (uri) { } as values ?serv { (uri) } service ?serv { } - * - * @author Olivier Corby, Wimmics INRIA I3S, 2018 * + * @author Olivier Corby, Wimmics INRIA I3S, 2018 */ public class RewriteService { - + FederateVisitor vis; int count = 0; boolean export = false; String name = Service.SERVER_SEED; - ArrayList varList; + ArrayList varList; ArrayList serviceList; - + RewriteService(FederateVisitor vis) { this.vis = vis; varList = new ArrayList<>(); serviceList = new ArrayList<>(); } - + void process(ASTQuery ast) { - if (ast.hasMetadata(Metadata.PUBLIC)) { + if (ast.hasMetadata(Metadata.Type.PUBLIC)) { export = true; } process(ast.getBody()); } - + void process(Exp body) { for (int i = 0; i < body.size(); i++) { Exp exp = body.get(i); if (exp.isService()) { Service s = exp.getService(); - if (! s.getServiceName().isVariable()) { - Variable var = new Variable(name + count++); - varList.add(var); - serviceList.add(s); - s.setServiceName(var); - if (true) { - // bind service variable with values - Values values = Values.create(var, s.getServiceConstantList()); - s.clearServiceList(); - body.add(i, values); - i++; - } - else { - // service has variable and server URI list - s.setGenerated(true); - } + if (!s.getServiceName().isVariable()) { + Variable variable = new Variable(name + count++); + varList.add(variable); + serviceList.add(s); + s.setServiceName(variable); + // bind service variable with values + Values values = Values.create(variable, s.getServiceConstantList()); + s.clearServiceList(); + body.add(i, values); + i++; } - } - else { + } else { process(exp); } } } - + List getVarList() { return varList; } - + List getServiceList() { return serviceList; } - + } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/RewriteServiceGraph.java b/src/main/java/fr/inria/corese/core/compiler/federate/RewriteServiceGraph.java index 94b76b448..827adf0a0 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/RewriteServiceGraph.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/RewriteServiceGraph.java @@ -1,96 +1,56 @@ package fr.inria.corese.core.compiler.federate; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.Constant; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.Expression; -import fr.inria.corese.core.sparql.triple.parser.Metadata; -import fr.inria.corese.core.sparql.triple.parser.Service; -import fr.inria.corese.core.sparql.triple.parser.Variable; +import fr.inria.corese.core.sparql.triple.parser.*; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** * Rewrite service { } as service { graph { }} - * Use case: agroportal store is structured with one named graph per ontology - * - * @author Olivier Corby, Wimmics INRIA I3S, 2019 + * Use case: agroportal store is structured with one named graph per ontology * + * @author Olivier Corby, Wimmics INRIA I3S, 2019 */ public class RewriteServiceGraph { - + FederateVisitor vis; int count = 0; boolean export = false; String name = "?_serv_"; - ArrayList varList; + ArrayList varList; ArrayList serviceList; ASTQuery ast; ServiceGraph map; - - class ServiceGraph { - - HashMap > map; - - ServiceGraph(){ - map = new HashMap<>(); - } - - - void declare(Constant service, Constant graph) { - List list = map.get(service.getLabel()); - if (list == null) { - list = new ArrayList<>(); - map.put(service.getLabel(), list); - } - if (! list.contains(graph)) { - list.add(graph); - } - } - - List getGraphList(Constant service) { - return map.get(service.getLabel()); - } - - Constant getGraph(Constant service) { - List list = map.get(service.getLabel()); - if (list == null) { - return null; - } - return list.get(0); - } - - } - + RewriteServiceGraph(FederateVisitor vis) { this.vis = vis; map = new ServiceGraph(); } - + void process(ASTQuery ast) { this.ast = ast; init(); rewrite(ast); } - + void init() { - List list = ast.getMetadata().getValues(Metadata.GRAPH); + List list = ast.getMetadata().getValues(Metadata.Type.GRAPH); if (list != null) { for (int i = 0; i < list.size(); i++) { declare(list.get(i++), list.get(i)); } } } - + void declare(String service, String graph) { map.declare(Constant.createResource(service), Constant.createResource(graph)); } - + void rewrite(ASTQuery ast) { rewrite(ast.getBody()); } - + void rewrite(Exp body) { for (int i = 0; i < body.size(); i++) { Exp exp = body.get(i); @@ -102,41 +62,67 @@ void rewrite(Exp body) { rewrite(s, graph); } } - } - else if (exp.isFilter() || exp.isBind()) { + } else if (exp.isFilter() || exp.isBind()) { rewrite(exp.getFilter()); - } - else if (exp.isQuery()) { + } else if (exp.isQuery()) { rewrite(exp.getAST()); - } - else { + } else { rewrite(exp); } } } - - void rewrite(Expression exp){ + + void rewrite(Expression exp) { if (exp.isTermExist()) { rewrite(exp.getTerm().getExistBGP()); - } - else if (exp.isTerm()) { + } else if (exp.isTerm()) { for (Expression ee : exp.getArgs()) { rewrite(ee); } } } - + void rewrite(Service s, Constant graph) { s.setBodyExp(ast.bgp(ast.graph(graph, s.getBodyExp()))); } - + List getVarList() { return varList; } - + List getServiceList() { return serviceList; } - + + class ServiceGraph { + + HashMap> map; + + ServiceGraph() { + map = new HashMap<>(); + } + + + void declare(Constant service, Constant graph) { + List list = map.computeIfAbsent(service.getLabel(), k -> new ArrayList<>()); + if (!list.contains(graph)) { + list.add(graph); + } + } + + List getGraphList(Constant service) { + return map.get(service.getLabel()); + } + + Constant getGraph(Constant service) { + List list = map.get(service.getLabel()); + if (list == null) { + return null; + } + return list.get(0); + } + + } + } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/RewriteServiceSelect.java b/src/main/java/fr/inria/corese/core/compiler/federate/RewriteServiceSelect.java index ddc66350d..597b6029d 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/RewriteServiceSelect.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/RewriteServiceSelect.java @@ -1,48 +1,43 @@ package fr.inria.corese.core.compiler.federate; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.Metadata; -import fr.inria.corese.core.sparql.triple.parser.Query; -import fr.inria.corese.core.sparql.triple.parser.Service; +import fr.inria.corese.core.sparql.triple.parser.*; /** * Rewrite service s { exp } as service s { select * where { exp } } */ public class RewriteServiceSelect { ASTQuery ast; - - RewriteServiceSelect(FederateVisitor vis) { + + RewriteServiceSelect(FederateVisitor vis) { } - - + + void process(ASTQuery ast) { this.ast = ast; process(ast.getBody()); } - + void process(Exp body) { for (int i = 0; i < body.size(); i++) { Exp exp = body.get(i); if (exp.isService()) { Service s = exp.getService(); - if (! s.getBodyExp().isQuery()) { + if (!s.getBodyExp().isQuery()) { Query q = getQuery(s); s.setBodyExp(q); } } } } - + Query getQuery(Service s) { ASTQuery aa = ast.subCreate(); aa.setBody(s.getBodyExp()); aa.setSelectAll(true); - if (ast.getMetaValue(Metadata.LIMIT)!=null) { + if (ast.getMetaValue(Metadata.Type.LIMIT) != null) { aa.setLimit(ast.getLimit()); } - Query q = Query.create(aa); - return q; + return Query.create(aa); } - + } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/RewriteTriple.java b/src/main/java/fr/inria/corese/core/compiler/federate/RewriteTriple.java index a84d4eff3..641632fe7 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/RewriteTriple.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/RewriteTriple.java @@ -1,46 +1,37 @@ package fr.inria.corese.core.compiler.federate; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.Atom; -import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; -import fr.inria.corese.core.sparql.triple.parser.Constant; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.Union; -import fr.inria.corese.core.sparql.triple.parser.Query; -import fr.inria.corese.core.sparql.triple.parser.Service; -import fr.inria.corese.core.sparql.triple.parser.Source; -import fr.inria.corese.core.sparql.triple.parser.Triple; +import fr.inria.corese.core.sparql.triple.parser.*; + import java.util.List; /** - * Rewrite one triple into one service with several URI + * Rewrite one triple into one service with several URI * from, from named and named graph have two rewrite solutions * 1- service s { select from g where exp } * 2- service s { graph g exp } - * solution 1 does not conform to SPARQL standard because + * solution 1 does not conform to SPARQL standard because * dataset in subquery is forbidden - * - * @author Olivier Corby, Wimmics INRIA I3S, 2018 * + * @author Olivier Corby, Wimmics INRIA I3S, 2018 */ public class RewriteTriple { - + FederateVisitor vis; // true: graph g exp; false: select from g where exp boolean withGraph = true; - + RewriteTriple(FederateVisitor vis) { this.vis = vis; } /** - * Rewrite Triple t as: + * Rewrite Triple t as: * -- name == null - * service { t } - * -- name == null && query = select from g1 gn + * service { t } + * -- name == null && query = select from g1 gn * service { graph g1 { t } union graph gn { t } } * -- name == g - * service { graph g { t } } + * service { graph g { t } } * Add filters of body bound by t in the BGP, except exists filters. */ Service rewriteTripleWithSeveralURI(Atom name, Triple t, Exp body, List list) { @@ -63,8 +54,7 @@ Service rewrite(Atom namedGraph, BasicGraphPattern bgp, List serviceList) if (namedGraph == null) { if (vis.isFederateBGP()) { exp = bgp; - } - else if (getAST().getDataset().hasFrom()) { + } else if (getAST().getDataset().hasFrom()) { // select from gi where bgp exp = from(bgp); } else { @@ -73,23 +63,22 @@ else if (getAST().getDataset().hasFrom()) { } else { // graph name { bgp } exp = named(namedGraph, bgp); - } - Service s = vis.service(serviceList, bgp(exp)); - return s; + } + return vis.service(serviceList, bgp(exp)); } - + Exp bgp(Exp exp) { if (exp.isBGP()) { return exp; } return BasicGraphPattern.create(exp); } - + // graph name { bgp } Exp named(Atom name, BasicGraphPattern bgp) { return graphNamed(name, bgp); - } - + } + // select from where bgp Exp from(BasicGraphPattern bgp) { if (getAST().getFrom().size() == 1) { @@ -97,48 +86,46 @@ Exp from(BasicGraphPattern bgp) { } return graphFrom(bgp.copy()); } - - - + + Exp graphNamed(Atom name, BasicGraphPattern bgp) { return Source.create(name, bgp); } - + /** - * for all t in bgp, for all g in from : + * for all t in bgp, for all g in from : * graph g1 { t1 } union .. graph gn { t1 } * graph g1 { tm } union .. graph gn { tm } - */ + */ Exp graphFrom(Exp bgp) { int i = 0; for (Exp exp : bgp) { - if (! exp.isFilter()) { - Exp union = graphUnion(BasicGraphPattern.create(exp), getAST().getFrom()); + if (!exp.isFilter()) { + Exp union = graphUnion(BasicGraphPattern.create(exp), getAST().getFrom()); bgp.set(i, bgpSelectDistinct(union)); } i++; } return bgp; } - + Exp basicGraphFrom(Exp bgp) { - Source src = Source.create(getAST().getFrom().get(0), bgp); - return src; + return Source.create(getAST().getFrom().get(0), bgp); } - + Exp bgpSelectDistinct(Exp exp) { if (exp.isGraph()) { return exp; } return BasicGraphPattern.create(distinct(exp)); } - + Exp distinct(Exp exp) { Query q = query(BasicGraphPattern.create(exp)); q.getAST().setDistinct(true); return q; } - + Exp graphUnion(Exp exp, List from) { Source src = Source.create(from.get(0), exp); if (from.size() == 1) { @@ -154,7 +141,7 @@ Exp graphUnion(Exp exp, List from) { } return union; } - + Query query(Exp exp) { ASTQuery as = getAST().subCreate(); @@ -162,8 +149,8 @@ Query query(Exp exp) { as.setSelectAll(true); return Query.create(as); } - - + + /** * Find filters bound by t in body, except exists {} Add them to bgp */ @@ -172,11 +159,10 @@ void filter(Exp body, Triple t, Exp bgp, List list) { if (exp.isFilter()) { if (vis.isRecExist(exp)) { // skip - } - else { - if (t.bind(exp.getFilter()) && ! bgp.getBody().contains(exp)) { + } else { + if (t.bind(exp.getFilter()) && !bgp.getBody().contains(exp)) { bgp.add(exp); - if (! list.contains(exp)) { + if (!list.contains(exp)) { list.add(exp); } } @@ -184,9 +170,9 @@ void filter(Exp body, Triple t, Exp bgp, List list) { } } } - - - /** + + + /** * @return the ast */ public ASTQuery getAST() { @@ -198,8 +184,8 @@ Exp selectNamed(Atom name, BasicGraphPattern bgp) { q.getAST().getDataset().addFrom(name.getConstant()); return BasicGraphPattern.create(q); } - - // select from uri { bgp } + + // select from uri { bgp } Exp selectFrom(BasicGraphPattern bgp) { Query q = query(bgp); q.getAST().getDataset().setFrom(getAST().getFrom()); diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/Selector.java b/src/main/java/fr/inria/corese/core/compiler/federate/Selector.java index 9634c51ef..209e5d74b 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/Selector.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/Selector.java @@ -1,111 +1,96 @@ package fr.inria.corese.core.compiler.federate; -import fr.inria.corese.core.sparql.api.IDatatype; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.Atom; -import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; -import fr.inria.corese.core.sparql.triple.parser.Binding; -import fr.inria.corese.core.sparql.triple.parser.Constant; -import fr.inria.corese.core.sparql.triple.parser.Service; -import fr.inria.corese.core.sparql.triple.parser.Triple; -import fr.inria.corese.core.sparql.triple.parser.Values; -import fr.inria.corese.core.sparql.triple.parser.Variable; import fr.inria.corese.core.compiler.eval.QuerySolver; import fr.inria.corese.core.kgram.core.Mapping; import fr.inria.corese.core.kgram.core.Mappings; +import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.exceptions.EngineException; import fr.inria.corese.core.sparql.triple.cst.LogKey; -import fr.inria.corese.core.sparql.triple.parser.ASTSelector; -import fr.inria.corese.core.sparql.triple.parser.Context; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.Metadata; -import fr.inria.corese.core.sparql.triple.parser.Optional; -import fr.inria.corese.core.sparql.triple.parser.Processor; -import fr.inria.corese.core.sparql.triple.parser.Query; -import fr.inria.corese.core.sparql.triple.parser.Source; -import fr.inria.corese.core.sparql.triple.parser.Term; +import fr.inria.corese.core.sparql.triple.parser.*; import fr.inria.corese.core.sparql.triple.parser.visitor.ASTParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * * Ask remote endpoints if they contain predicates of the federated query * Build a table: triple | predicate -> ( uri ) - * - * @author Olivier Corby, Wimmics INRIA I3S, 2018 * + * @author Olivier Corby, Wimmics INRIA I3S, 2018 */ public class Selector { - - public static Logger logger = LoggerFactory.getLogger(Selector.class); + private static final String SERVER_VAR = "?serv"; private static final String BNODE_ID = "_:fbn"; + public static Logger logger = LoggerFactory.getLogger(Selector.class); public static boolean SELECT_EXIST = true; //public static int NB_ENDPOINT = 10; - - private FederateVisitor vis; ASTQuery ast; - private ASTSelector astSelector; HashMap predicateVariable; HashMap tripleVariable; HashMap bgpVariable; - private QuerySolver exec; - // use case: reuse federated visitor source selection - private Mappings mappings; boolean sparql10 = false; boolean count = false; - boolean trace = false; int bnode = 0; + private FederateVisitor vis; + private ASTSelector astSelector; + private QuerySolver exec; + // use case: reuse federated visitor source selection + private Mappings mappings; private int nbEndpoint = FederateVisitor.NB_ENDPOINT; private double nbSuccess = FederateVisitor.NB_SUCCESS; - + Selector(FederateVisitor vis, QuerySolver e, ASTQuery ast) { this.ast = ast; this.vis = vis; exec = e; init(); } - + + public static double time(Date d1, Date d2) { + return (d2.getTime() - d1.getTime()) / 1000.0; + } + + public static double time(Date d1) { + return time(d1, new Date()); + } + void init() { setAstSelector(new ASTSelector()); predicateVariable = new HashMap<>(); - tripleVariable = new HashMap<>(); - bgpVariable = new HashMap<>(); - if (ast.hasMetadata(Metadata.SPARQL10)) { + tripleVariable = new HashMap<>(); + bgpVariable = new HashMap<>(); + if (ast.hasMetadata(Metadata.Type.SPARQL10)) { sparql10 = true; } - - count = ast.hasMetadata(Metadata.COUNT); - trace = ast.hasMetadata(Metadata.TRACE); + + count = ast.hasMetadata(Metadata.Type.COUNT); } - boolean process() throws EngineException { - return process11(getURIList()); + return process11(getURIList()); } - - List getURIList() throws EngineException{ - List list = ast.getServiceListConstant(); - return list; + + List getURIList() { + return ast.getServiceListConstant(); } - + List getIndexURIList() throws EngineException { return getIndexURIList(getIndexURL()); } - + // @todo: nb endpoint sublist List getIndexURIList(List urlList) throws EngineException { - if (urlList!=null && !urlList.isEmpty()) { + if (urlList != null && !urlList.isEmpty()) { ArrayList list = new ArrayList<>(); - + for (String url : urlList) { List alist = getIndexURIList(url); - + for (String res : alist) { if (!list.contains(res)) { list.add(res); @@ -116,9 +101,9 @@ List getIndexURIList(List urlList) throws EngineException { } return getIndexURIList(); } - + List getIndexURIList(String url) throws EngineException { - if (url==null) { + if (url == null) { url = getIndexURL(); } List list = getBasicIndexURIList(url); @@ -126,12 +111,12 @@ List getIndexURIList(String url) throws EngineException { list = list.subList(0, Math.min(list.size(), getNbEndpoint())); return list; } - + // default index url String getIndexURL() { return SelectorIndex.INDEX_URL; } - + // query graph index for source discovery List getBasicIndexURIList(String url) throws EngineException { Date d1 = new Date(); @@ -141,19 +126,19 @@ List getBasicIndexURIList(String url) throws EngineException { .setNbSuccess(getNbSuccess()) .process(); Context ct = Context.create().setDiscovery(true); - Mappings map = getQuerySolver().basicQuery(a, ct); - traceLog(map); + Mappings map = getQuerySolver().basicQuery(a, ct); + getVisitor().setDiscovery(map); - List list = map.getStringValueList(SERVER_VAR); - + List list = map.getStringValueList(SERVER_VAR); + log(url, a, map); - logger.info("Source discovery:\n"+map); + logger.info("Source discovery:\n" + map); logger.info("Source discovery URL list:\n" + list); logger.info("Source discovery time: " + time(d1)); - + return list; } - + void log(String url, ASTQuery a, Mappings map) { getQuerySolver().getLog().setASTIndex(a); getQuerySolver().getLog().setIndexMap(map); @@ -161,85 +146,72 @@ void log(String url, ASTQuery a, Mappings map) { ast.getLog().setASTIndex(a); ast.getLog().setIndexMap(map); ast.getLog().set(LogKey.INDEX, url); - //ast.getLog().setExceptionList(getQuerySolver().getLog().getExceptionList()); } - - public static double time(Date d1, Date d2) { - return (d2.getTime() - d1.getTime()) / 1000.0; - } - - public static double time(Date d1) { - return time(d1, new Date()); - } - + boolean process11(List list) throws EngineException { if (list.isEmpty()) { logger.info("URL list is empty"); return false; } - Date d1 = new Date(); ASTQuery aa = createSelector(list, false); metadata(aa); Mappings map; - + if (getMappings() == null) { // compute selection Context ct = Context.create().setSelection(true); // source selection inherit timeout if any as parameter sv:timeout=1000 - ct.inherit(ast.getContext()); + ct.inherit(ast.getContext()); if (getVisitor().isFederateIndex()) { ct.setFederateIndex(true); - } + } map = getQuerySolver().basicQuery(aa, ct); - traceLog(map); + getVisitor().setMappings(map); - } - else { + } else { // reuse selection map = getMappings(); } - + getQuerySolver().getLog().setASTSelect(aa); getQuerySolver().getLog().setSelectMap(map); - + ast.getLog().setASTSelect(aa); ast.getLog().setSelectMap(map); ast.getLog().setExceptionList(getQuerySolver().getLog().getExceptionList()); - + for (Mapping m : map) { - IDatatype serv = m.getValue(SERVER_VAR); - + IDatatype serv = m.getValue(SERVER_VAR); + // table: predicate -> exists boolean variable for (String pred : predicateVariable.keySet()) { - String var = predicateVariable.get(pred); - IDatatype val = m.getValue(var); + String varString = predicateVariable.get(pred); + IDatatype val = m.getValue(varString); if (val != null && val.booleanValue()) { getPredicateService().get(pred).add(Constant.create(serv)); } } - + // table: triple -> exists boolean variable for (Triple t : tripleVariable.keySet()) { - String var = tripleVariable.get(t); - IDatatype val = m.getValue(var); + String varString = tripleVariable.get(t); + IDatatype val = m.getValue(varString); if (val != null && val.booleanValue()) { getTripleService().get(t).add(Constant.create(serv)); } } - + // table: bgp -> exists boolean variable // map: {t1 t2} -> (uri) list of uri where join(t1, t2) = true for (BasicGraphPattern bgp : bgpVariable.keySet()) { - String var = bgpVariable.get(bgp); - IDatatype val = m.getValue(var); + String varString = bgpVariable.get(bgp); + IDatatype val = m.getValue(varString); if (val != null && val.booleanValue()) { getBgpService().get(bgp).add(Constant.create(serv)); } } } - Date d2 = new Date(); - boolean b = getAstSelector().complete(); - trace(map, d1, d2); + boolean b = getAstSelector().complete(); logger.info("Source Selection Join Test Success: " + b); // if selection join failure occurs in optional/minus/union/exists // do not fail, else fail @@ -247,12 +219,6 @@ boolean process11(List list) throws EngineException { // and will not be executed return b; } - - void traceLog(Mappings map) { - for (List list : getQuerySolver().getLog().getLabelList("Server")) { - logger.info(list.toString()); - } - } void metadata(ASTQuery aa) { if (ast.hasMetadata(Metadata.SHOW)) { @@ -260,23 +226,21 @@ void metadata(ASTQuery aa) { meta.add(Metadata.SHOW); aa.setAnnotation(meta); } - if (ast.hasMetadata(Metadata.REPORT)) { - aa.getCreateMetadata().add(Metadata.REPORT); + if (ast.hasMetadata(Metadata.Type.REPORT)) { + aa.getCreateMetadata().add(Metadata.Type.REPORT); ASTParser walk = new ASTParser(aa).report(); aa.process(walk); } - if (ast.getMetaValue(Metadata.TIMEOUT)!=null) { - aa.getCreateMetadata().add(Metadata.TIMEOUT, ast.getMetaValue(Metadata.TIMEOUT)); + if (ast.getMetaValue(Metadata.Type.TIMEOUT) != null) { + aa.getCreateMetadata().add(Metadata.Type.TIMEOUT, ast.getMetaValue(Metadata.Type.TIMEOUT)); } } - - - + List getPredicateService(Constant pred) { return getPredicateService().get(pred.getLabel()); } - + List getPredicateService(Triple t) { List list = getTripleService().get(t); if (list != null) { @@ -287,116 +251,67 @@ List getPredicateService(Triple t) { } return getPredicateService(t.getPredicate().getConstant()); } - - void trace(Mappings map, Date d1, Date d2) { - if (ast.hasMetadata(Metadata.TRACE)) { - System.out.println("Selection Time: " + (d2.getTime() - d1.getTime()) / 1000.0); - } - if (ast.isDebug()) { - System.out.println("Triple Selection"); - for (String pred : getPredicateService().keySet()) { - System.out.println(pred + " " + getPredicateService().get(pred)); - } - for (Triple t : getTripleService().keySet()) { - System.out.println(t + " " + getTripleService().get(t)); - } - } - if (trace) { - System.out.println(map); - } - } - + void declare(Constant p, Variable var) { predicateVariable.put(p.getLabel(), var.getLabel()); - if (! getPredicateService().containsKey(p.getLabel())) { + if (!getPredicateService().containsKey(p.getLabel())) { getPredicateService().put(p.getLabel(), new ArrayList<>()); } } - + void declare(Triple t, Variable var) { tripleVariable.put(t, var.getLabel()); getTripleService().put(t, new ArrayList<>()); } - + void declare(BasicGraphPattern bgp, Variable var) { bgpVariable.put(bgp, var.getLabel()); getBgpService().put(bgp, new ArrayList<>()); } - + /** * select * where { - * values ?serv {s1, sn} - * service ?serv { - * bind (exists { ?s predicate_i ?o } as ?b_i) - * } + * values ?serv {s1, sn} + * service ?serv { + * bind (exists { ?s predicate_i ?o } as ?b_i) * } - */ + * } + */ ASTQuery createSelector(List list, boolean sparql10) { ASTQuery aa = ASTQuery.create(); aa.setSelectAll(true); - aa.setNSM(ast.getNSM()); + aa.setNSM(ast.getNSM()); Variable serv = Variable.create(SERVER_VAR); - + // triple selector - BasicGraphPattern bgp ; - -// if (getVisitor().isIndex()) { -// //bgp = createBGPIndex(serv, aa); -// ASTQuery a = new SelectorIndex(this, ast, -// Constant.create(indexURI), list) -// .process(serv, aa); -// return a; -// } -// else + BasicGraphPattern bgp; + if (sparql10) { bgp = createBGP10(aa); - } - else { + } else { bgp = createBGP(serv, aa); - } - + } + BasicGraphPattern body; if (getVisitor().isIndex()) { // @deprecated body = bgp; - } - else { + } else { Exp service; - if (ast.hasMetadata(Metadata.GRAPH)) { + if (ast.hasMetadata(Metadata.Type.GRAPH)) { service = Source.create(serv, bgp); - } - else { + } else { service = Service.create(serv, bgp); - } - Values values = Values.create(serv, list); - body = aa.bgp(values, service); + } + Values values = Values.create(serv, list); + body = aa.bgp(values, service); } - - aa.setBody(body); - metadata(aa, ast); - return aa; - } - - // not used - ASTQuery createDataset(List list, boolean sparql10) { - ASTQuery aa = ASTQuery.create(); - aa.setSelectAll(true); - aa.setNSM(ast.getNSM()); - - // selector for remote dataset named graph URI list - BasicGraphPattern bgp = BasicGraphPattern.create(Query.create(namedGraph())); - - Variable serv = Variable.create(SERVER_VAR); - Service service = Service.create(serv, bgp); - Values values = Values.create(serv, list); - - BasicGraphPattern body = BasicGraphPattern.create(values, service); + aa.setBody(body); - metadata(aa, ast); return aa; } - + /** * Compute remote dataset named graph URI list * select (group_concat(?g) as ?lg) where { @@ -405,16 +320,16 @@ ASTQuery createDataset(List list, boolean sparql10) { */ ASTQuery namedGraph() { ASTQuery aa = ASTQuery.create(); - + Triple t = Triple.create(Variable.create("?s"), Variable.create("?p"), Variable.create("?o")); BasicGraphPattern ng = BasicGraphPattern.create(t); ASTQuery ang = aa.subCreate(); ang.setBody(ng); ang.setSelectAll(true); ang.setLimit(1); - - - BasicGraphPattern bgp = BasicGraphPattern.create(Query.create(ang)); + + + BasicGraphPattern bgp = BasicGraphPattern.create(Query.create(ang)); Source src = Source.create(Variable.create("?g"), bgp); BasicGraphPattern body = BasicGraphPattern.create(src); aa.setBody(body); @@ -424,37 +339,37 @@ ASTQuery namedGraph() { aa.defSelect(Variable.create("?lg"), agg); return aa; } - + void metadata(ASTQuery aa, ASTQuery ast) { - if (ast.hasMetadata(Metadata.EVENT) || ast.hasMetadata(Metadata.SEQUENCE) || ast.hasMetadata(Metadata.TRACE)) { + if (ast.hasMetadata(Metadata.Type.EVENT) || ast.hasMetadata(Metadata.Type.SEQUENCE) || ast.hasMetadata(Metadata.Type.TRACE)) { Metadata m = new Metadata(); aa.setMetadata(m); - - if (ast.hasMetadata(Metadata.EVENT)) { - m.add(Metadata.EVENT); + + if (ast.hasMetadata(Metadata.Type.EVENT)) { + m.add(Metadata.Type.EVENT); aa.setDefine(ast.getDefine()); aa.setDefineLambda(ast.getDefineLambda()); } - - if (ast.hasMetadata(Metadata.SEQUENCE)) { - m.add(Metadata.SEQUENCE); + + if (ast.hasMetadata(Metadata.Type.SEQUENCE)) { + m.add(Metadata.Type.SEQUENCE); } - - if (ast.hasMetadata(Metadata.TRACE)) { - m.add(Metadata.TRACE); + + if (ast.hasMetadata(Metadata.Type.TRACE)) { + m.add(Metadata.Type.TRACE); } } } - - + + BasicGraphPattern createBGP(Variable serv, ASTQuery aa) { BasicGraphPattern bgp = BasicGraphPattern.create(); - int i = 0; - i = selectPredicate(aa, bgp, i); - selectTriple(aa, bgp, i); + int i = 0; + i = selectPredicate(aa, bgp, i); + selectTriple(aa, bgp, i); return bgp; } - + int selectPredicate(ASTQuery aa, BasicGraphPattern bgp, int i) { for (Constant p : ast.getPredicateList()) { if (p.getLabel().equals(ASTQuery.getRootPropertyURI())) { @@ -477,7 +392,7 @@ int selectPredicate(ASTQuery aa, BasicGraphPattern bgp, int i) { } return i; } - + // consider specific triple such as triple with constant value int selectTriple(ASTQuery aa, BasicGraphPattern bgp, int i) { if (getVisitor().isSelectFilter()) { @@ -493,20 +408,20 @@ int selectTriple(ASTQuery aa, BasicGraphPattern bgp, int i) { // to test existence of join on each endpoint i = selectTripleJoin(aa, bgp, i); } - + return i; } /** * generate exists { s p o filter F } where F variables are bound by s p o * consider also triple with constant - * by default filter limited to subset of filters: + * by default filter limited to subset of filters: * = regex strstarts strcontains */ int selectTripleFilter(ASTQuery aa, BasicGraphPattern bgp, int i) { List list = new SelectorFilter(getVisitor(), ast).process(); HashMap mapNoFilter = new HashMap<>(); - + for (BasicGraphPattern exp : list) { Triple t = exp.get(0).getTriple(); if (exp.size() > 1 || selectable(t)) { @@ -523,54 +438,51 @@ int selectTripleFilter(ASTQuery aa, BasicGraphPattern bgp, int i) { name = getVariable(t, mapNoFilter); mapNoFilter.put(t, t); } - - if (name !=null) { + + if (name != null) { // occurrence of same triple already processed with variable name // do not duplicate exists clause on same triple // reuse former variable name var = new Variable(name); - } - else if (count) { + } else if (count) { var = count(aa, bgp, protect(exp), i++); } else { var = exist(aa, bgp, protect(exp), i++); } - + declare(t, var); } } - + return i; } - + // rewrite bnode with unique bnode ID because // different exists clause must not reuse same bnode !!! BasicGraphPattern protect(BasicGraphPattern bgp) { BasicGraphPattern exp = BasicGraphPattern.create(); HashMap map = new HashMap<>(); - + for (Exp e : bgp) { if (e.isTriple()) { Triple t = e.getTriple(); if (t.getSubject().isBlankNode() || t.getObject().isBlankNode()) { - Triple nt = protect(map, t); + Triple nt = protect(map, t); exp.add(nt); - } - else { + } else { exp.add(t); } - } - else { + } else { exp.add(e); } } - + if (map.isEmpty()) { return bgp; } return exp; } - + Triple protect(HashMap map, Triple t) { Triple nt = t.duplicate(); if (t.getSubject().isBlankNode()) { @@ -581,11 +493,11 @@ Triple protect(HashMap map, Triple t) { } return nt; } - + Triple protect(Triple t) { return protect(new HashMap<>(), t); } - + Atom bnode(HashMap map, Atom node) { Atom bn = map.get(node); if (bn == null) { @@ -594,12 +506,12 @@ Atom bnode(HashMap map, Atom node) { } return bn; } - + Atom bnode() { - return Constant.createBlank(BNODE_ID+bnode++); + return Constant.createBlank(BNODE_ID + bnode++); } - - + + // generate bind (exists {t1 . t2} as ?b) // for each pair of connected triple // to test existence of join on each endpoint @@ -610,12 +522,12 @@ int selectTripleJoin(ASTQuery aa, BasicGraphPattern bgp, int i) { // join bgp should fail or not // map: bgp -> fail getAstSelector().setBgpFail(ares.getBgpFail()); - + for (BasicGraphPattern exp : list) { // exp = {t1 . t2} Variable var; String name = getVariable(exp); - + if (name != null) { // {t1 . t2} already processed // do not duplicate exists {t1 . t2} @@ -649,7 +561,7 @@ int selectTripleBasic(ASTQuery aa, BasicGraphPattern bgp, int i) { } return i; } - + // if triple t1 is already processed with bind (exists {t1} as ?b) // return variable ?b // former occurrence t2 of t1 must have no filter @@ -661,7 +573,7 @@ String getVariable(Triple t1, HashMap mapNoFilter) { } return null; } - + // retrieve occurrence of same bgp = {t1 . t2} // return variable if any String getVariable(BasicGraphPattern bgp) { @@ -672,75 +584,73 @@ String getVariable(BasicGraphPattern bgp) { } return null; } - + boolean selectable(Triple t) { return (t.getSubject().isConstant() || t.getObject().isConstant()); } - + Variable count(ASTQuery aa, BasicGraphPattern bgp, Triple t, int i) { return count(aa, bgp, aa.bgp(t), i); } - + Variable count(ASTQuery aa, BasicGraphPattern bgp, BasicGraphPattern bb, int i) { ASTQuery a = aa.subCreate(); - + Term fun = Term.function(Processor.COUNT); Variable var = a.variable("?c_" + i); a.defSelect(var, fun); - + Term bound = Term.create(">", var, Constant.create(0)); Variable varBound = a.variable("?v_" + i); aa.defSelect(varBound, bound); - + a.setBody(bb); - + bgp.add(a.bgp(Query.create(a))); - + return varBound; } - + Variable exist(ASTQuery aa, BasicGraphPattern bgp, Triple t, int i) { return exist(aa, bgp, aa.bgp(t), i); } - + Variable exist(ASTQuery aa, BasicGraphPattern bgp, BasicGraphPattern bb, int i) { if (SELECT_EXIST) { return selectExist(aa, bgp, bb, i); - } - else { + } else { return basicExist(aa, bgp, bb, i); } } - + Variable basicExist(ASTQuery aa, BasicGraphPattern bgp, BasicGraphPattern bb, int i) { Variable var = aa.variable("?b" + i++); Binding exist = Binding.create(aa.createExist(bb, false), var); bgp.add(exist); return var; } - + Variable selectExist(ASTQuery aa, BasicGraphPattern bgp, BasicGraphPattern bb, int i) { Variable var = aa.variable("?b" + i++); - + ASTQuery a = aa.subCreate(); a.setSelectAll(true); a.setBody(bb); - a.setLimit(1); - + a.setLimit(1); + BasicGraphPattern exp = BasicGraphPattern.create(Query.create(a)); Binding exist = Binding.create(aa.createExist(exp, false), var); bgp.add(exist); return var; } - + /** - * for SPARQL 1.0 + * for SPARQL 1.0 * select * where { * optional { si pi oi } * } limit 1 * } - * */ BasicGraphPattern createBGP10(ASTQuery aa) { ArrayList tripleList = new ArrayList<>(); @@ -756,26 +666,24 @@ BasicGraphPattern createBGP10(ASTQuery aa) { declare(p, var); } } - + Exp option = optional(tripleList); - + ASTQuery a = aa.subCreate(); a.setSelectAll(true); a.setBody(BasicGraphPattern.create(option)); a.setLimit(1); - - BasicGraphPattern bgp = BasicGraphPattern.create(Query.create(a)); - - return bgp; + + return BasicGraphPattern.create(Query.create(a)); } - - /** + + /** * Create BGP to query graph index */ BasicGraphPattern createBGPIndex(Variable serv, ASTQuery aa) { BasicGraphPattern bgp = BasicGraphPattern.create(); int i = 0; - + for (Constant p : ast.getPredicateList()) { if (p.getLabel().equals(ASTQuery.getRootPropertyURI())) { @@ -783,28 +691,28 @@ BasicGraphPattern createBGPIndex(Variable serv, ASTQuery aa) { Constant pns = aa.createQName("idx:namespace"); Constant pdt = aa.createQName("idx:data"); Constant ppr = aa.createQName("idx:predicate"); - - Variable ns = Variable.create("?ns"); - Variable dt = Variable.create("?dt"); - Variable pr = Variable.create("?pr"); - + + Variable ns = Variable.create("?ns"); + Variable dt = Variable.create("?dt"); + Variable pr = Variable.create("?pr"); + Triple t1 = aa.triple(serv, pns, ns); Triple t2 = aa.triple(ns, pdt, dt); Triple t3 = aa.triple(dt, ppr, p); - + // exists { ?serv idx:namespace/idx:data/idx:predicate predicate } - Variable var = exist(aa, bgp, aa.bgp(t3, t2, t1), i); - declare(p, var); - + Variable variable = exist(aa, bgp, aa.bgp(t3, t2, t1), i); + declare(p, variable); + i++; - } + } } - + selectTriple(aa, bgp, i); - + return bgp; } - + Exp optional(List list) { Optional option = new Optional(BasicGraphPattern.create(), BasicGraphPattern.create(list.get(0))); for (int i = 1; i < list.size(); i++) { @@ -815,18 +723,18 @@ Exp optional(List list) { public HashMap> getPredicateService() { return getAstSelector().getPredicateService(); - } + } public HashMap> getTripleService() { return getAstSelector().getTripleService(); } - + // map: bgp -> (uri) // where bgp is join of (two) triples public HashMap> getBgpService() { return getAstSelector().getBgpService(); } - + public ASTSelector getAstSelector() { return astSelector; } @@ -859,8 +767,8 @@ public QuerySolver getQuerySolver() { public void setQuerySolver(QuerySolver exec) { this.exec = exec; } - - /** + + /** * BUG when service 1.0 & service 1.1 and there are triples in 1.1 * the triples of 1.0 are considered as absent although they are present as predicate */ @@ -869,44 +777,36 @@ void process2() throws EngineException { process10(getServiceList(true)); predicateVariable.clear(); process11(getServiceList(false)); - } - else { + } else { process11(ast.getServiceListConstant()); } } + void process10(List list) throws EngineException { - Date d1 = new Date(); ASTQuery aa = createSelector(list, true); Mappings map = getQuerySolver().basicQuery(aa); - if (ast.isDebug()) { - System.out.println(map); - } for (Mapping m : map) { - IDatatype serv = m.getValue(SERVER_VAR); + IDatatype serv = m.getValue(SERVER_VAR); for (String pred : predicateVariable.keySet()) { - String var = predicateVariable.get(pred); - IDatatype val = m.getValue(var); + String variableString = predicateVariable.get(pred); + IDatatype val = m.getValue(variableString); if (val != null) { getPredicateService().get(pred).add(Constant.create(serv)); } } } - - Date d2 = new Date(); - trace(map, d1, d2); } - - List getServiceList(boolean sparql10) { + + List getServiceList(boolean sparql10) { List list = ast.getServiceListConstant(); List res = new ArrayList<>(); for (Constant serv : list) { - if (sparql10){ - if (ast.hasMetadataValue(Metadata.SPARQL10, serv.getLabel())) { + if (sparql10) { + if (ast.hasMetadataValue(Metadata.Type.SPARQL10, serv.getLabel())) { res.add(serv); } - } - else { - if (! ast.hasMetadataValue(Metadata.SPARQL10, serv.getLabel())) { + } else { + if (!ast.hasMetadataValue(Metadata.Type.SPARQL10, serv.getLabel())) { res.add(serv); } } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/SelectorFilter.java b/src/main/java/fr/inria/corese/core/compiler/federate/SelectorFilter.java index 1d42f42ac..de7f8d43c 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/SelectorFilter.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/SelectorFilter.java @@ -1,157 +1,115 @@ package fr.inria.corese.core.compiler.federate; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; -import fr.inria.corese.core.sparql.triple.parser.Binary; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.Expression; -import fr.inria.corese.core.sparql.triple.parser.Triple; -import fr.inria.corese.core.sparql.triple.parser.Union; -import fr.inria.corese.core.sparql.triple.parser.Variable; +import fr.inria.corese.core.sparql.triple.parser.*; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** - * Subset of filter to be considered in source selection and in + * Subset of filter to be considered in source selection and in * sort bgp */ -public class SelectorFilter { - static HashMap map; +public class SelectorFilter { public static String[] OPER_LIST = {"=", "regex", "contains", "strstarts"}; - ASTQuery ast; - private FederateVisitor visitor; - ArrayList res; - // when join bgp fail, query should fail - HashMap bgpFail; - + static HashMap map; + static { init(); } - + + ASTQuery ast; + ArrayList res; + // when join bgp fail, query should fail + HashMap bgpFail; + private FederateVisitor visitor; + SelectorFilter(FederateVisitor vis, ASTQuery ast) { this.ast = ast; visitor = vis; res = new ArrayList<>(); bgpFail = new HashMap<>(); } - + static void init() { map = new HashMap<>(); for (String ope : OPER_LIST) { defineOperator(ope, true); } } - - public static void defineOperator(String oper, boolean b) { + + public static void defineOperator(String oper, boolean b) { map.put(oper, b); } - - public static void rejectOperator(String oper, boolean b) { + + public static void rejectOperator(String oper, boolean b) { map.remove(oper); } - - class JoinResult { - // list of join connected pair {t1 . t2} - private ArrayList bgpList; - // query may fail when bgp {t1 t2} has no join - private HashMap bgpFail; - - JoinResult(ArrayList res, HashMap fail) { - bgpList = res; - bgpFail = fail; - } - - public ArrayList getBgpList() { - return bgpList; - } - public void setBgpList(ArrayList bgpList) { - this.bgpList = bgpList; - } - - public HashMap getBgpFail() { - return bgpFail; - } - - public void setBgpFail(HashMap bgpFail) { - this.bgpFail = bgpFail; - } - - } - /** * Return list of all triples with possibly filters bound by triples * One BGP per triple/filters * Focus on filter (exp = exp) */ List process() { - process(ast); + process(ast); return res; } - + JoinResult processJoin() { - processJoin(ast); + processJoin(ast); JoinResult ares = new JoinResult(res, bgpFail); return ares; } - + void process(ASTQuery ast) { for (Expression exp : ast.getModifierExpressions()) { processFilter(exp); } process(ast.getBody()); } - + void process(Exp body) { if (body.isBGP()) { processBGP(body); - } - else if (body.isQuery()) { + } else if (body.isQuery()) { process(body.getAST()); - } - else for (Exp exp : body) { + } else for (Exp exp : body) { process(exp); } } - + void processBGP(Exp body) { processBGPTriple(body); } - + // By default, basic bgp fail when join fail void processJoin(ASTQuery ast) { processJoin(ast, true); } - + void processJoin(ASTQuery ast, boolean fail) { processJoin(ast.getBody(), fail); } - + void processJoin(Exp body, boolean fail) { if (body.isBGP()) { processBGPJoin(body, fail); - } - else if (body.isOptional()) { - processJoin(body.getOptional(), fail); - } - else if (body.isMinus()) { - processJoin(body.getMinus(), fail); - } - else if (body.isUnion()) { - processJoin(body.getUnion(), fail); - } - else if (body.isQuery()) { + } else if (body.isOptional()) { + processJoin(body.getOptional(), fail); + } else if (body.isMinus()) { + processJoin(body.getMinus(), fail); + } else if (body.isUnion()) { + processJoin(body.getUnion(), fail); + } else if (body.isQuery()) { processJoin(body.getAST(), fail); - } - else if (body.isFilter()) { + } else if (body.isFilter()) { processJoinFilter(body.getFilter()); - } - else for (Exp exp : body) { + } else for (Exp exp : body) { processJoin(exp, fail); } - } - + } + // filter exists { bgp } // participate to bgp join selection in order to benefit // from bgp processing heuristics @@ -171,20 +129,20 @@ boolean processJoinFilter(Expression exp) { } return exist; } - + // exp = exists { bgp } void processJoinExist(Expression exp) { Exp bgp = exp.getTerm().getExist().get(0); processJoin(bgp, false); } - + // optional minus void processJoin(Binary body, boolean fail) { processBGPJoin(body.get(0), fail); processBGPJoin(body.get(1), false); - + if ((body.isOptional() && getVisitor().isFederateOptional()) || - (body.isMinus() && getVisitor().isFederateMinus())) { + (body.isMinus() && getVisitor().isFederateMinus())) { // test join(t1, t2) on triple of both arg of optional/minus // to enable simplification of body BasicGraphPattern bgp = BasicGraphPattern.create(); @@ -193,11 +151,11 @@ void processJoin(Binary body, boolean fail) { processBGPJoin(bgp, false); } } - + // union void processJoin(Union body, boolean fail) { processBGPJoin(body.get(0), false); - processBGPJoin(body.get(1), false); + processBGPJoin(body.get(1), false); } void addTriple(Exp exp, BasicGraphPattern bgp) { @@ -232,39 +190,38 @@ void processBGPJoin(Exp body, boolean fail) { i++; } } - + boolean accept(Triple t1, Triple t2) { if (t1.getPredicate().isVariable() && t2.getPredicate().isVariable()) { - + } return true; } - + // accept for join test boolean accept(Triple t) { - return getVisitor().createJoinTest(t); + return getVisitor().createJoinTest(t); } - + void add(Triple t1, Triple t2, boolean fail) { if (t1.getPredicate().isVariable() && t2.getPredicate().isConstant()) { basicAdd(t2, t1, fail); - } - else { + } else { basicAdd(t1, t2, fail); } } - + void basicAdd(Triple t1, Triple t2, boolean fail) { BasicGraphPattern bgp = BasicGraphPattern.create(t1, t2); BasicGraphPattern key = getKey(bgp); - if (key==bgp) { - res.add(bgp); + if (key == bgp) { + res.add(bgp); } - if (fail) { - bgpFail.put(key, fail); + if (fail) { + bgpFail.put(key, fail); } } - + // return unique key bgp BasicGraphPattern getKey(BasicGraphPattern bgp) { for (BasicGraphPattern exp : res) { @@ -275,7 +232,7 @@ BasicGraphPattern getKey(BasicGraphPattern bgp) { } return bgp; } - + // do not generate "duplicate" pair of triple boolean accept(BasicGraphPattern bgp) { for (BasicGraphPattern exp : res) { @@ -286,60 +243,54 @@ boolean accept(BasicGraphPattern bgp) { } return true; } - - + void processBGPTriple(Exp body) { for (Exp exp : body) { if (exp.isFilter() || exp.isBind()) { processFilter(exp.getFilter()); - } - else if (exp.isTriple()) { + } else if (exp.isTriple()) { process(exp.getTriple(), body); } else { process(exp); } } } - - void processFilter (Expression exp) { + + void processFilter(Expression exp) { if (exp.isTermExist()) { process(exp.getTerm().getExistBGP()); - } - else if (exp.isTerm()) { + } else if (exp.isTerm()) { for (Expression e : exp.getArgs()) { processFilter(e); } } } - + // for each triple: // collect relevant filter or values for triple variables // create a candidate bgp with filter, add bgp in res void process(Triple t, Exp body) { BasicGraphPattern bgp = ast.bgp(t); List list = t.getVariables(); - + if (!list.isEmpty()) { for (Exp exp : body) { if (exp.isFilter() && accept(exp.getFilter())) { if (exp.getFilter().isBound(list)) { bgp.add(exp); } - } - else if (exp.isValues()) { - if (exp.getValuesExp().isBound(list)) { - bgp.add(exp); - } + } else if (exp.isValues() && (exp.getValuesExp().isBound(list))) { + bgp.add(exp); } } } - + res.add(bgp); } - + boolean accept(Expression exp) { Boolean b = map.get(exp.getName().toLowerCase()); - return b!= null && b; + return b != null && b; } public FederateVisitor getVisitor() { @@ -349,6 +300,35 @@ public FederateVisitor getVisitor() { public void setVisitor(FederateVisitor visitor) { this.visitor = visitor; } - - + + class JoinResult { + // list of join connected pair {t1 . t2} + private ArrayList bgpList; + // query may fail when bgp {t1 t2} has no join + private HashMap bgpFail; + + JoinResult(ArrayList res, HashMap fail) { + bgpList = res; + bgpFail = fail; + } + + public ArrayList getBgpList() { + return bgpList; + } + + public void setBgpList(ArrayList bgpList) { + this.bgpList = bgpList; + } + + public HashMap getBgpFail() { + return bgpFail; + } + + public void setBgpFail(HashMap bgpFail) { + this.bgpFail = bgpFail; + } + + } + + } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/SelectorIndex.java b/src/main/java/fr/inria/corese/core/compiler/federate/SelectorIndex.java index 438ca3a58..bedf5d600 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/SelectorIndex.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/SelectorIndex.java @@ -4,22 +4,15 @@ import fr.inria.corese.core.compiler.federate.util.ResourceReader; import fr.inria.corese.core.kgram.core.Query; import fr.inria.corese.core.sparql.exceptions.EngineException; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.Atom; -import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; -import fr.inria.corese.core.sparql.triple.parser.Constant; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.NSManager; -import fr.inria.corese.core.sparql.triple.parser.Service; -import fr.inria.corese.core.sparql.triple.parser.Triple; -import fr.inria.corese.core.sparql.triple.parser.Variable; +import fr.inria.corese.core.sparql.triple.parser.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.HashMap; import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Given federate query, create query to graph index to retrieve candidate endpoint uri list @@ -30,68 +23,47 @@ * Current graph index is: http://prod-dekalog.inria.fr/sparql * There is a default graph index query pattern: DEFAULT_QUERY_PATTERN * There is a Property FEDERATE_INDEX_PATTERN whose value is the path of a query pattern - * By convention the query pattern MUST return distinct values of variable Selector.SERVER_VAR - * + * By convention the query pattern MUST return distinct values of variable Selector.SERVER_VAR */ public class SelectorIndex { - public static Logger logger = LoggerFactory.getLogger(SelectorIndex.class); - final static String INDEX = "index"; - - public static boolean SELECT_ENDPOINT = false; - // default dekalog index - public static String INDEX_URL = "http://prod-dekalog.inria.fr/sparql"; - // local dataset index - public static String INDEX_URL_LOCAL = "http://localhost:8080/index"; - // %1$s = predicate uri // %2$s = bind(n as ?b_i) - public static final String OPTIONAL1 = - "optional {?s void:propertyPartition/void:property <%s> %s}\n"; - - public static final String OPTIONAL_CLASS = - "optional {?s void:classPartition/void:class <%s> %s}\n"; - - public static final String BIND = "bind (%s as ?b_%s)"; - - // %s = exp1+exp2 in bind(exp1+exp2 as ?c) - public static final String BIND_TOTAL = "bind (%s as ?c)"; - + public static final String OPTIONAL1 = + "optional {?s void:propertyPartition/void:property <%s> %s}\n"; + public static final String OPTIONAL_CLASS = + "optional {?s void:classPartition/void:class <%s> %s}\n"; + public static final String BIND = "bind (%s as ?b_%s)"; + // %s = exp1+exp2 in bind(exp1+exp2 as ?c) + public static final String BIND_TOTAL = "bind (%s as ?c)"; // %s = i in expi = coalesce(?b_i, 0) - public static final String EXP = "coalesce(?b_%s, 0)"; - + public static final String EXP = "coalesce(?b_%s, 0)"; // %s = n in filter (?c >= n) where n = number of bound ?bi = number of present predicates in endpoint - public static final String FILTER = "filter (?c >= %s)"; - + public static final String FILTER = "filter (?c >= %s)"; // draft test for property partition - public static final String OPTIONAL2 = - "optional {?s void:classPartition[void:propertyPartition[void:property <%s>]]." + - "bind (1 as ?b_%s) }\n"; - - private static final String FILTER_EXISTS = - "filter exists {?s void:propertyPartition/void:property <%s>}\n"; - - public static String OPTIONAL = OPTIONAL1; - + public static final String OPTIONAL2 = + "optional {?s void:classPartition[void:propertyPartition[void:property <%s>]]." + + "bind (1 as ?b_%s) }\n"; + final static String INDEX = "index"; + private static final String FILTER_EXISTS = + "filter exists {?s void:propertyPartition/void:property <%s>}\n"; // default source discovery query pattern - private static final String DEFAULT_QUERY_PATTERN = + private static final String DEFAULT_QUERY_PATTERN = "/query/indexpatternendpoint.rq"; + public static Logger logger = LoggerFactory.getLogger(SelectorIndex.class); + public static boolean SELECT_ENDPOINT = false; + // default dekalog index + public static String INDEX_URL = "http://prod-dekalog.inria.fr/sparql"; + // local dataset index + public static String INDEX_URL_LOCAL = "http://localhost:8080/index"; + public static String OPTIONAL = OPTIONAL1; // path set by Property FEDERATE_INDEX_PATTERN public static String QUERY_PATTERN = null; - + static HashMap url2predicatePattern; static HashMap url2classPattern; static HashMap url2queryPattern; static HashMap skipPredicate; - - Selector selector; - ASTQuery ast; - String indexURL; - List uriList; - private Service indexService; - int totalValue = 0; - private double nbSuccess = FederateVisitor.NB_SUCCESS; - static { url2predicatePattern = new HashMap<>(); url2classPattern = new HashMap<>(); @@ -99,8 +71,27 @@ public class SelectorIndex { skipPredicate = new HashMap<>(); init(); } - - // define for each index url: + + Selector selector; + ASTQuery ast; + String indexURL; + List uriList; + int totalValue = 0; + private Service indexService; + private double nbSuccess = FederateVisitor.NB_SUCCESS; + + // ast: input federate query + SelectorIndex(Selector s, ASTQuery ast) { + selector = s; + this.ast = ast; + } + + SelectorIndex(Selector s, ASTQuery ast, String uriIndex) { + this(s, ast); + this.indexURL = uriIndex; + } + + // define for each index url: // the sparql query patterns to search predicate p static void init() { definePredicatePattern(INDEX_URL, OPTIONAL); @@ -110,48 +101,54 @@ static void init() { defineClassPattern(INDEX_URL_LOCAL, OPTIONAL_CLASS); definePredicatePattern(INDEX_URL_LOCAL, OPTIONAL); } - + public static void definePredicatePattern(String url, String pattern) { url2predicatePattern.put(url, pattern); } - + public static void defineClassPattern(String url, String pattern) { url2classPattern.put(url, pattern); } - + public static void defineQueryPattern(String url, String pattern) { url2queryPattern.put(url, pattern); } - - // ast: input federate query - SelectorIndex(Selector s, ASTQuery ast) { - selector = s; - this.ast = ast; + + public static void skipPredicate(String predicate) { + skipPredicate.put(predicate, predicate); } - - SelectorIndex(Selector s, ASTQuery ast, String uriIndex) { - this(s, ast); - this.indexURL = uriIndex; + + // path is given by Property FEDERATE_INDEX_PATTERN + // defaut is default graph index query pattern + static String getDefaultPattern(String path, String defaut) { + String pattern = "select * where {%s}"; + try { + if (path == null) { + return new ResourceReader().getResource(defaut); + } else { + return new ResourceReader().readWE(path); + } + } catch (IOException ex) { + logger.error(ex.getMessage()); + } + return pattern; } - - // generate query for endpoint URL source discovery - // with federate query ast as input + // with federate query ast as input // ast evaluation return candidate list of endpoint uri // variable for endpoint url is Selector.SERVER_VAR ASTQuery process() { try { before(); - ASTQuery a = getGraphIndexQuery(); - return a; + return getGraphIndexQuery(); } catch (EngineException ex) { logger.error(ex.getMessage()); return ASTQuery.create(); } } - - // service + + // service // { filter regex(str(?serv), ".fr")} void before() { Exp body = ast.getBody(); @@ -168,14 +165,14 @@ void before() { } } - // generate query for endpoint URL source discovery + // generate query for endpoint URL source discovery // for ast federate query ASTQuery getGraphIndexQuery() throws EngineException { // get query pattern with %s String pattern = getQueryPattern(indexURL); // generate test part to find federate query predicates String test = predicateTest(ast); - + // additional exp coming from // service { exp } if (getIndexService() != null) { @@ -184,49 +181,45 @@ ASTQuery getGraphIndexQuery() throws EngineException { test = test.concat("\n").concat(ee.toString()); } } - + String queryString = String.format(pattern, test); - //System.out.println("pattern:\n"+pattern); - //System.out.println("test:\n"+test); - - logger.info("Index query:\n"+queryString); + + logger.info("Index query:\n" + queryString); Query q = getQuerySolver().compile(queryString); return q.getAST(); } - + QuerySolver getQuerySolver() { return selector.getQuerySolver(); } - + // generate test part to find federate query predicates - String predicateTest(ASTQuery ast) { + String predicateTest(ASTQuery ast) { StringBuilder sb = new StringBuilder(); int i = 0; - + for (Constant p : ast.getPredicateList()) { if (p.getLabel().equals(ASTQuery.getRootPropertyURI())) { - // skip variable predicate - } - else if (skip(p.getLongName())) { - - } - else { - // generate test for predicate + // skip variable predicate + } else if (skip(p.getLongName())) { + + } else { + // generate test for predicate // specific namespace have more value than rdf: rdfs: int value = getValue(p.getLongName()); totalValue += value; sb.append(String.format(getPredicatePattern(indexURL), // predicate - p.getLongName(), + p.getLongName(), // bind (value as ?b_i) - String.format(BIND, value, i), + String.format(BIND, value, i), // in case of variable ?p%3$s i)); i++; } - } - - if (getVisitor().isFederateClass() && getClassPattern(indexURL)!=null) { + } + + if (getVisitor().isFederateClass() && getClassPattern(indexURL) != null) { for (Triple t : ast.getTripleList()) { if (t.isType() && t.getObject().isConstant()) { Atom obj = t.getObject(); @@ -244,12 +237,12 @@ else if (skip(p.getLongName())) { } } } - + // count number of predicates present in endpoint url - count(sb, i); + count(sb, i); return sb.toString(); } - + boolean skip(String predicate) { for (String key : skipPredicate.keySet()) { if (predicate.startsWith(key)) { @@ -258,38 +251,34 @@ boolean skip(String predicate) { } return false; } - - public static void skipPredicate(String predicate) { - skipPredicate.put(predicate, predicate); - } - + // @todo // specific domain namespace: value 3 // skos: owl: foaf: value 2 - // rdf: rdfs: value 1 + // rdf: rdfs: value 1 int getValue(String uri) { if (NSManager.nsm().isSystemURI(uri)) { return 1; } return 2; } - + // count number of predicates present in endpoint url - // endpoint succeed when: + // endpoint succeed when: // endpoint nb predicates >= federate query nb predicates * rate // e.g. it has 0.5 * federate query nb predicates - // NB_SUCCESS can be set by + // NB_SUCCESS can be set by // property FEDERATE_INDEX_SUCCESS 0.75 // annotation @fedSuccess 0.75 // default is 0.5 - void count(StringBuilder sb, int i) { + void count(StringBuilder sb, int i) { // bind (coalesce(?b_i, 0) + coalesce(?b_j, 0) as ?c) sb.append(String.format(BIND_TOTAL, sum(i))); sb.append("\n"); // filter (?c >= n) sb.append(String.format(FILTER, totalValue * getNbSuccess())); } - + // return bind (coalesce(?b_1, 0) + ... coalesce(?b_n) as ?c) // compurte number of fed query predicates found in endpoint StringBuilder sum(int n) { @@ -304,27 +293,11 @@ StringBuilder sum(int n) { } return b; } - - - String generate2(ASTQuery ast) { - StringBuilder sb = new StringBuilder(); - int i = 0; - for (Constant p : ast.getPredicateList()) { - if (p.getLabel().equals(ASTQuery.getRootPropertyURI())) { - } - else { - sb.append(String.format(FILTER_EXISTS,p.getLongName())); - } - } - - return sb.toString(); - } - BasicGraphPattern compile(Variable serv, ASTQuery aa) { BasicGraphPattern bgp = BasicGraphPattern.create(); int i = 0; - + for (Constant p : ast.getPredicateList()) { if (p.getLabel().equals(ASTQuery.getRootPropertyURI())) { @@ -332,29 +305,29 @@ BasicGraphPattern compile(Variable serv, ASTQuery aa) { // ?meta dcterms:modified ?modif . // ?meta kgi:curated ?s . // ?s void:sparqlEndpoint ?serv - + // bind (exists {?s void:propertyPartition/void:property $pred} as ?b) Constant part = aa.createQName("void:propertyPartition"); Constant prop = aa.createQName("void:property"); - - Variable s = Variable.create("?s"); - Variable x = Variable.create("?x"); - + + Variable s = Variable.create("?s"); + Variable x = Variable.create("?x"); + Triple t1 = aa.triple(s, part, x); Triple t2 = aa.triple(x, prop, Constant.create(p.getLongName())); - + // exists { ?serv idx:namespace/idx:data/idx:predicate predicate } - Variable var = selector.exist(aa, bgp, aa.bgp(t1, t2), i); - selector.declare(p, var); - + Variable variable = selector.exist(aa, bgp, aa.bgp(t1, t2), i); + selector.declare(p, variable); + i++; - } + } } - - + + return bgp; } - + String getPredicatePattern(String url) { String str = url2predicatePattern.get(url); if (str == null) { @@ -362,12 +335,11 @@ String getPredicatePattern(String url) { } return str; } - + String getClassPattern(String url) { - String str = url2classPattern.get(url); - return str; + return url2classPattern.get(url); } - + String getQueryPattern(String url) { String str = url2queryPattern.get(url); if (str == null) { @@ -376,22 +348,6 @@ String getQueryPattern(String url) { } return str; } - - // path is given by Property FEDERATE_INDEX_PATTERN - // defaut is default graph index query pattern - static String getDefaultPattern(String path, String defaut) { - String pattern = "select * where {%s}"; - try { - if (path == null) { - return new ResourceReader().getResource(defaut); - } else { - return new ResourceReader().readWE(path); - } - } catch (IOException ex) { - logger.error(ex.getMessage()); - } - return pattern; - } public double getNbSuccess() { return nbSuccess; @@ -409,9 +365,9 @@ public Service getIndexService() { public void setIndexService(Service indexService) { this.indexService = indexService; } - + FederateVisitor getVisitor() { return selector.getVisitor(); } - + } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/Simplify.java b/src/main/java/fr/inria/corese/core/compiler/federate/Simplify.java index 596881287..06bff9b98 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/Simplify.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/Simplify.java @@ -1,135 +1,91 @@ package fr.inria.corese.core.compiler.federate; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.ASTSelector; -import fr.inria.corese.core.sparql.triple.parser.Atom; -import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; -import fr.inria.corese.core.sparql.triple.parser.Constant; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.Metadata; -import fr.inria.corese.core.sparql.triple.parser.Union; -import fr.inria.corese.core.sparql.triple.parser.Query; -import fr.inria.corese.core.sparql.triple.parser.Service; -import fr.inria.corese.core.sparql.triple.parser.Source; -import fr.inria.corese.core.sparql.triple.parser.Triple; -import fr.inria.corese.core.sparql.triple.parser.Variable; +import fr.inria.corese.core.sparql.triple.parser.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Merge several service with same URI into one service - * - * @author Olivier Corby, Wimmics INRIA I3S, 2018 * + * @author Olivier Corby, Wimmics INRIA I3S, 2018 */ public class Simplify extends Util { + private static final boolean MERGE_EVEN_IF_NOT_CONNECTED = false; static Logger logger = LoggerFactory.getLogger(Simplify.class); - private static boolean MERGE_EVEN_IF_NOT_CONNECTED = false; // heuristics to simplify service s bgp1 optional service (S) bgp2 // when all triple of bgp2 // join with connected triple of bgp1 in s // and s memberOf S // heuristics similar to federate bgp, heuristics cover both arg of optional - FederateVisitor visitor; - private boolean debug = false; private boolean mergeEvenIfNotConnected = MERGE_EVEN_IF_NOT_CONNECTED; - + Simplify(FederateVisitor vis) { visitor = vis; } - - class ServiceList { - HashMap> map; - - ServiceList() { - map = new HashMap<>(); - } - - void add(Service serv) { - List l = map.get(serv.getServiceName().getLabel()); - if (l == null) { - l = new ArrayList<>(); - map.put(serv.getServiceName().getLabel(), l); - } - l.add(serv); - } - - HashMap> getMap() { - return map; - } - } - + // main function // exp is binary Exp simplify(Exp exp) { - Exp res = simplifyBinary(exp); - return res; + return simplifyBinary(exp); } // main function Exp process(Exp bgp) { bgp = merge(bgp); - if (visitor.isBounce()){ + if (visitor.isBounce()) { // @deprecated bgp = bounce(bgp); } return bgp; } - - - /** - * BGP { service URI {EXP1} service URI {EXP2} EXP3 } ::= + * BGP { service URI {EXP1} service URI {EXP2} EXP3 } ::= * BGP { service URI {EXP1 EXP2} EXP3 } - * + *

* TODO: merge when there is only one URI ??? - */ - Exp merge(Exp bgp) { + */ + Exp merge(Exp bgp) { return merge(bgp, isMergeEvenIfNotConnected()); } - Exp merge(Exp bgp, boolean mergeEvenIfNotConnected) { + Exp merge(Exp bgp, boolean mergeEvenIfNotConnected) { ServiceList include = new ServiceList(); - ServiceList exclude = new ServiceList(); + ServiceList exclude = new ServiceList(); // create map: service URI -> list (Service) for (Exp exp : bgp) { - if (exp.isService()){ + if (exp.isService()) { if (exp.getService().isFederate()) { // several URI: skip - } - else if (mergeEvenIfNotConnected) { + } else if (mergeEvenIfNotConnected) { include.add(exp.getService()); - } - else if (isTripleFilterOnly(exp.getBodyExp())) { + } else if (isTripleFilterOnly(exp.getBodyExp())) { // do not merge basic BGP with same service URI - // because they are not connected + // because they are not connected exclude.add(exp.getService()); - } - else { + } else { include.add(exp.getService()); } } } - + // group several services with same URI into one service for (List list : include.getMap().values()) { Service first = list.get(0); int i = 0; - boolean mod = false; - + for (Service s : list) { if (i++ > 0) { first.getBodyExp().include(s.getBodyExp()); bgp.getBody().remove(s); - mod = true; } } - + List alist = exclude.getMap().get(first.getServiceName().getLabel()); if (alist != null) { for (Service s : alist) { @@ -137,20 +93,17 @@ else if (isTripleFilterOnly(exp.getBodyExp())) { if (first.getBodyExp().isConnect(s.getBodyExp())) { first.getBodyExp().include(s.getBodyExp()); bgp.getBody().remove(s); - mod = true; } } } - if (true) { // if (mod) { - simplifyGraph2(first.getBodyExp()); - visitor.sort(first.getBodyExp()); - } - } - bgp = move(bgp, exclude); + simplifyGraph2(first.getBodyExp()); + visitor.sort(first.getBodyExp()); + } + bgp = move(bgp, exclude); return bgp; } - + /** * @move rdfs:label * if there is a service s1 with several uri with a triple annotated as @@ -158,7 +111,7 @@ else if (isTripleFilterOnly(exp.getBodyExp())) { * merged with s2 */ Exp move(Exp bgp, ServiceList serviceList) { - if (! visitor.getAST().hasMetadata(Metadata.MOVE)) { + if (!visitor.getAST().hasMetadata(Metadata.Type.MOVE)) { return bgp; } boolean go = true; @@ -181,11 +134,11 @@ Exp move(Exp bgp, ServiceList serviceList) { bgp.getBody().remove(s); } } - + return bgp; } - - Service getCandidate(Service serv, ServiceList map) { + + Service getCandidate(Service serv, ServiceList map) { for (Atom name : serv.getServiceList()) { List list = map.getMap().get(name.getLabel()); if (list != null) { @@ -197,15 +150,15 @@ Service getCandidate(Service serv, ServiceList map) { } return null; } - + Service getCandidate2(Service serv, ServiceList map) { - Service res = null; + Service res = null; for (Atom name : serv.getServiceList()) { List list = map.getMap().get(name.getLabel()); if (list != null) { if (res == null) { res = list.get(0); - if (! serv.getBodyExp().isConnect(res.getBodyExp())) { + if (!serv.getBodyExp().isConnect(res.getBodyExp())) { return null; } } else { @@ -215,7 +168,7 @@ Service getCandidate2(Service serv, ServiceList map) { } return res; } - + boolean isMoveable(Service exp) { Exp body = exp.getBodyExp(); if (!exp.isFederate()) { @@ -228,57 +181,55 @@ boolean isMoveable(Service exp) { return t.getPredicate().isConstant() && isMoveable(t.getPredicate().getConstant()); } - - // TODO: there could be a bind + + // TODO: there could be a bind Triple getUniqueTriple(Exp body) { Triple t = null; for (Exp exp : body) { - if (exp.isFilter()) {} - else if (exp.isTriple()) { + if (exp.isFilter()) { + } else if (exp.isTriple()) { if (t == null) { t = exp.getTriple(); - } - else { + } else { return null; } - } - else { + } else { return null; } } return t; } - + boolean isMoveable(Constant predicate) { - return visitor.getAST().hasMetadata(Metadata.MOVE) - && (visitor.getAST().hasMetadataValue(Metadata.MOVE, predicate.getLabel()) - || visitor.getAST().getMetadata().getValues(Metadata.MOVE) == null); + return visitor.getAST().hasMetadata(Metadata.Type.MOVE) + && (visitor.getAST().hasMetadataValue(Metadata.Type.MOVE, predicate.getLabel()) + || visitor.getAST().getMetadata().getValues(Metadata.Type.MOVE) == null); } - + /** * BGP { service URI1 { EXP1 } service URI2 { EXP2 } } * if URI1 accept bouncing and EXP1.isConnected(EXP2) * -> * BGP { service URI1 { EXP1 service URI2 { EXP2 } } } */ - + Exp bounce(Exp bgp) { - HashMap done = new HashMap(); - HashMap remove = new HashMap(); - + HashMap done = new HashMap<>(); + HashMap remove = new HashMap<>(); + for (int i = 0; i < bgp.size(); i++) { Exp e1 = bgp.get(i); - if (done.get(e1) == null && e1.isService() && ! e1.getService().isFederate()) { + if (done.get(e1) == null && e1.isService() && !e1.getService().isFederate()) { Service s1 = e1.getService(); - + for (int j = i + 1; j < bgp.size(); j++) { Exp e2 = bgp.get(j); - if (done.get(e2) == null && e2.isService() && ! e2.getService().isFederate()) { + if (done.get(e2) == null && e2.isService() && !e2.getService().isFederate()) { Service s2 = e2.getService(); - - if (! s1.getServiceName().equals(s2.getServiceName()) - && s1.getBodyExp().isConnected(s2.getBodyExp())) { - + + if (!s1.getServiceName().equals(s2.getServiceName()) + && s1.getBodyExp().isConnected(s2.getBodyExp())) { + if (bounce(s1)) { s1.getBodyExp().add(s2); done.put(s2, true); @@ -295,19 +246,19 @@ Exp bounce(Exp bgp) { } } } - + for (Service exp : remove.keySet()) { bgp.getBody().remove(exp); } - + return bgp; } - + // @bounce boolean bounce(Service s) { - return visitor.getAST().hasMetadataValue(Metadata.BOUNCE, s.getServiceName().getLabel()); + return visitor.getAST().hasMetadataValue(Metadata.Type.BOUNCE, s.getServiceName().getLabel()); } - + /** * exp contains only triple and filter * TODO: accept bind (exp as var) @@ -316,28 +267,27 @@ boolean isTripleFilterOnly(Exp exp) { for (Exp ee : exp) { if (ee.isFilter() || ee.isTriple()) { // ok - } - else { + } else { return false; } } return true; } - + boolean isUnionTripleOnly(Exp bgp) { if (bgp.size() == 1 && bgp.get(0).isUnion()) { Union union = bgp.get(0).getUnion(); - return isTripleFilterOnly(union.get(0)) && isTripleFilterOnly(union.get(1)) ; + return isTripleFilterOnly(union.get(0)) && isTripleFilterOnly(union.get(1)); } return false; } - + boolean isUnionOrTripleOnly(Exp bgp) { return isUnionTripleOnly(bgp) || isTripleFilterOnly(bgp); } - + // bgp = filter exists { bgp } - // in filter exists, merge services with same URI list + // in filter exists, merge services with same URI list void simplifyFilterExist(Exp bgp) { ArrayList list = new ArrayList<>(); for (int i = 0; i < bgp.size(); i++) { @@ -361,12 +311,11 @@ void simplifyFilterExist(Exp bgp) { bgp.getBody().remove(s); } } - - + // second main function Exp simplifyBinary(Exp exp) { Exp simple = basicSimplify(exp); - + if (simple.isOptional() || simple.isMinus()) { Exp split = split(simple); if (visitor.isFederateUndefined()) { @@ -378,22 +327,20 @@ Exp simplifyBinary(Exp exp) { if (visitor.isFederateUndefined()) { return skipUndefined(simple); } - + return simple; } - + // skip undefined service for union/optional/minus Exp skipUndefined(Exp exp) { if (exp.isUnion()) { return unionUndefined(exp); - } - else if (exp.isOptional()||exp.isMinus()) { + } else if (exp.isOptional() || exp.isMinus()) { return binaryUndefined(exp); } return exp; } - - + /** * service s {e1} optional { service s {e2}} * -> @@ -406,31 +353,28 @@ Exp basicSimplify(Exp exp) { Exp e2 = exp.get(1).get(0); if (e1.isService() && e2.isService()) { Service s1 = e1.getService(); - Service s2 = e2.getService(); + Service s2 = e2.getService(); return simplifyService(exp, s1, s2); } } return exp; } - + Exp simplifyService(Exp exp, Service s1, Service s2) { if (isSimplifyUnion(exp, s1, s2)) { return simplifyUnion(exp, s1, s2); - } - else if (!s1.isFederate() && !s2.isFederate() - && s1.getServiceName().equals(s2.getServiceName())) { - // both service with same uri + } else if (!s1.isFederate() && !s2.isFederate() + && s1.getServiceName().equals(s2.getServiceName())) { + // both service with same uri return merge(exp, s1, s2, s1.getServiceList()); - } - else if (exp.isOptional() && visitor.isFederateOptional()) { + } else if (exp.isOptional() && visitor.isFederateOptional()) { return binary(exp); - } - else if (exp.isMinus()&& visitor.isFederateMinus()) { + } else if (exp.isMinus() && visitor.isFederateMinus()) { return binary(exp); } return exp; } - + // exp = service S1 {bgp1} optional {service S2 {bgp2}} // return service S1 {bgp1 optional {bgp2}} Service merge(Exp exp, Service s1, Service s2, List list) { @@ -440,11 +384,11 @@ Service merge(Exp exp, Service s1, Service s2, List list) { Service s = Service.create(list, BasicGraphPattern.create(simple)); return s; } - + // service S1 {bgp1} optional {service S2 {bgp2}} - // heuristics to simplify optional when triples in bgp2 + // heuristics to simplify optional when triples in bgp2 // are present in service S1 inter S2 - // and for all t in bgp2, connected(t, bgp1) + // and for all t in bgp2, connected(t, bgp1) // => join(t, bgp1, S1 inter S2) == true // -> service S1 {bgp1 optional {bgp2}} // @todo: generalize with several service in right exp @@ -452,13 +396,13 @@ Exp binary(Exp exp) { if (exp.get(0).size() == 1 && exp.get(1).size() == 1) { Exp e1 = exp.get(0).get(0); Exp e2 = exp.get(1).get(0); - + if (e1.isService() && e2.isService()) { Service s1 = e1.getService(); Service s2 = e2.getService(); List inter = intersection(s1, s2); - if (! inter.isEmpty()) { + if (!inter.isEmpty()) { if (join(s1.bgp(), s2.bgp(), inter)) { return merge(exp, s1, s2, s1.getServiceList()); } @@ -467,7 +411,7 @@ Exp binary(Exp exp) { } return exp; } - + boolean join(BasicGraphPattern bgp1, BasicGraphPattern bgp2, List list) { for (Atom uri : list) { if (!join(bgp1, bgp2, uri.getLabel())) { @@ -477,7 +421,6 @@ boolean join(BasicGraphPattern bgp1, BasicGraphPattern bgp2, List list) { return true; } - // for all t in bgp2, connected(t, bgp1) => join(t, bgp1) == true // and at least one such t boolean join(BasicGraphPattern bgp1, BasicGraphPattern bgp2, String uri) { @@ -486,7 +429,7 @@ boolean join(BasicGraphPattern bgp1, BasicGraphPattern bgp2, String uri) { if (e.isTriple()) { Triple t = e.getTriple(); if (bgp1.isConnected(t)) { - join = visitor.getAstSelector().join(bgp1, t, uri); + join = visitor.getAstSelector().join(bgp1, t, uri); if (!join) { return false; } @@ -495,7 +438,7 @@ boolean join(BasicGraphPattern bgp1, BasicGraphPattern bgp2, String uri) { } return join; } - + // case where there is undefined service in one branch Exp unionUndefined(Exp exp) { if (hasUndefinedService(exp.get(0)) @@ -509,26 +452,25 @@ Exp unionUndefined(Exp exp) { } return exp; } - + // optional/minus Exp binaryUndefined(Exp exp) { if (hasUndefinedService(exp.get(1)) && - ! hasUndefinedService(exp.get(0))) { - logger.info("Skip minus|optional exp:\n" + exp.get(1)); + !hasUndefinedService(exp.get(0))) { + logger.info("Skip minus|optional exp:\n" + exp.get(1)); return exp.get(0); } return exp; } - + boolean hasUndefinedService(Exp exp) { return exp.hasUndefinedService(); - } - + } + ASTSelector getSelector() { return visitor.getAstSelector(); } - - + /** * {service S {t1}} union {service S {t2}} * ::= @@ -536,45 +478,43 @@ ASTSelector getSelector() { */ Service simplifyUnion(Exp exp, Service s1, Service s2) { Union union = Union.create(s1.getBodyExp(), s2.getBodyExp()); - Service s = Service.create(s1.getServiceList(), BasicGraphPattern.create(union)); - return s; + return Service.create(s1.getServiceList(), BasicGraphPattern.create(union)); } - + boolean isSimplifyUnion(Exp exp, Service s1, Service s2) { - return exp.isUnion() && s1.isFederate() && s2.isFederate() - && sameURIList(s1, s2) - && isUnionOrTripleOnly(s1.getBodyExp()) && isUnionOrTripleOnly(s2.getBodyExp()); + return exp.isUnion() && s1.isFederate() && s2.isFederate() + && sameURIList(s1, s2) + && isUnionOrTripleOnly(s1.getBodyExp()) && isUnionOrTripleOnly(s2.getBodyExp()); } - + boolean sameURIList(Service s1, Service s2) { return same(s1.getServiceList(), s2.getServiceList()); } - - boolean same(List l1, List l2) { - if (l1.size() != l2.size()) { - return false; - } - for (Atom s : l1) { - if (! l2.contains(s)) { - return false; - } - } - return true; - } - + + boolean same(List l1, List l2) { + if (l1.size() != l2.size()) { + return false; + } + for (Atom s : l1) { + if (!l2.contains(s)) { + return false; + } + } + return true; + } + Exp simplifyService2(Exp exp, Service s1, Service s2) { if (!s1.isFederate() && isMoveable(s2) && s2.getServiceList().contains(s1.getServiceName())) { exp.set(0, s1.getBodyExp()); exp.set(1, s2.getBodyExp()); Exp simple = simplifyGraph(exp); - Service s = Service.create(s1.getServiceName(), - BasicGraphPattern.create(simple)); - return s; + return Service.create(s1.getServiceName(), + BasicGraphPattern.create(simple)); } return exp; } - + /** * select from g { e1 } optional { select from g { e2 } } * -> @@ -584,12 +524,12 @@ Exp simplifySelectFrom(Exp exp) { if (exp.get(0).size() == 1 && exp.get(1).size() == 1) { Exp e1 = exp.get(0).get(0); Exp e2 = exp.get(1).get(0); - if (e1.isQuery() && e2.isQuery()){ + if (e1.isQuery() && e2.isQuery()) { ASTQuery ast1 = e1.getAST(); - ASTQuery ast2 = e2.getAST(); - if (ast1.getFrom().size() == 1 && - ast2.getFrom().size() == 1 && - ast1.getFrom().get(0).equals(ast2.getFrom().get(0)) + ASTQuery ast2 = e2.getAST(); + if (ast1.getFrom().size() == 1 && + ast2.getFrom().size() == 1 && + ast1.getFrom().get(0).equals(ast2.getFrom().get(0)) && ast1.isSelectAll() && ast2.isSelectAll()) { exp.set(0, ast1.getBody()); exp.set(1, ast2.getBody()); @@ -599,10 +539,10 @@ Exp simplifySelectFrom(Exp exp) { } } } - return exp; + return exp; } - /** + /** * graph g { e1 } optional { graph g { e2 } } * -> * graph g { e1 optional { e2 } } @@ -611,21 +551,20 @@ Exp simplifyGraph(Exp exp) { if (exp.get(0).size() == 1 && exp.get(1).size() == 1) { Exp e1 = exp.get(0).get(0); Exp e2 = exp.get(1).get(0); - if (e1.isGraph() && e2.isGraph()){ + if (e1.isGraph() && e2.isGraph()) { Source g1 = e1.getNamedGraph(); - Source g2 = e2.getNamedGraph(); - if (//g1.getSource().isConstant() && - g1.getSource().equals(g2.getSource())) { + Source g2 = e2.getNamedGraph(); + if (//g1.getSource().isConstant() && + g1.getSource().equals(g2.getSource())) { exp.set(0, g1.getBodyExp()); exp.set(1, g2.getBodyExp()); - Source g = Source.create(g1.getSource(), exp); - return g; + return Source.create(g1.getSource(), exp); } } } - return exp; + return exp; } - + Exp simplifyGraph2(Exp exp) { int i = 0; ArrayList list = new ArrayList<>(); @@ -637,7 +576,7 @@ Exp simplifyGraph2(Exp exp) { Source g1 = ee1.getNamedGraph(); Source g2 = ee2.getNamedGraph(); if (//g1.getSource().isConstant() && - g1.getSource().equals(g2.getSource())) { + g1.getSource().equals(g2.getSource())) { Source g = g1.merge(g2); exp.set(i, g); list.add(g2); @@ -654,18 +593,16 @@ Exp simplifyGraph2(Exp exp) { } return exp; } - - + /** - * * service s1 {A} service s2 {B} optional { service s2 {C} } * with condition: x in var(C) & x not in B => x not in A * -> * service s1 {A} service s2 {B optional {C}} - * + *

* service s1 {A} service s2 {B} minus { service s2 {C} } * with condition: x in var(C) & x not in B => x not in A - * -> + * -> * service s1 {A} service s2 {B minus {C}} */ Exp split(Exp exp) { @@ -676,45 +613,42 @@ Exp split(Exp exp) { Service s1 = fst.get(0).getService(); Service s2 = fst.get(1).getService(); Service s3 = rst.get(0).getService(); - + if (splitable(s1, s2, s3)) { return split(exp, s1, s2, s3); - } - else if (splitable(s2, s1, s3)) { + } else if (splitable(s2, s1, s3)) { return split(exp, s2, s1, s3); } } return exp; } - + boolean splitable(Service s1, Service s2, Service s3) { return !s2.isFederate() && !s3.isFederate() && s2.getServiceName().equals(s3.getServiceName()) && gentle(s1, s2, s3); } - + Exp split(Exp exp, Service s1, Service s2, Service s3) { ASTQuery a = visitor.getAST(); Service s = a.service(s2.getServiceName(), copy(a, exp, s2.getBodyExp(), s3.getBodyExp())); - BasicGraphPattern bgp = a.bgp(s1, s); - return bgp; + return a.bgp(s1, s); } - + // condition: x in var(C) & x not in B => x not in A - boolean gentle (Service s1, Service s2, Service s3) { + boolean gentle(Service s1, Service s2, Service s3) { return gentle(s1.getInscopeVariables(), s2.getInscopeVariables(), s3.getInscopeVariables()); } - - + boolean gentle(List l1, List l2, List l3) { for (Variable var : l3) { - if (! l2.contains(var) && l1.contains(var)) { + if (!l2.contains(var) && l1.contains(var)) { return false; } } return true; } - + Exp copy(ASTQuery a, Exp exp, Exp e1, Exp e2) { if (exp.isMinus()) { return a.minus(e1, e2); @@ -727,21 +661,22 @@ public boolean isMergeEvenIfNotConnected() { return mergeEvenIfNotConnected; } - public void setMergeEvenIfNotConnected(boolean mergeEvenIfNotConnected) { - this.mergeEvenIfNotConnected = mergeEvenIfNotConnected; - } - - - - - - - - - - - - - - + class ServiceList { + HashMap> map; + + ServiceList() { + map = new HashMap<>(); + } + + void add(Service serv) { + List l = map.computeIfAbsent(serv.getServiceName().getLabel(), k -> new ArrayList<>()); + l.add(serv); + } + + HashMap> getMap() { + return map; + } + } + + } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/SimplifyService.java b/src/main/java/fr/inria/corese/core/compiler/federate/SimplifyService.java index c79041c64..68825ce64 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/SimplifyService.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/SimplifyService.java @@ -3,35 +3,35 @@ import fr.inria.corese.core.sparql.triple.parser.Atom; import fr.inria.corese.core.sparql.triple.parser.Exp; import fr.inria.corese.core.sparql.triple.parser.Service; + import java.util.ArrayList; import java.util.List; /** * Heuristics: * Group and restrict federated services on the intersection of their URL list - * */ public class SimplifyService extends Util { - - + + Exp simplify(Exp bgp) { Service current = null; List inter = null; List serviceList = new ArrayList<>(); - + for (Exp exp : bgp) { - + if (exp.isService()) { Service s = exp.getService(); List alist = s.getServiceList(); - + if (current == null) { current = s; inter = alist; - } - else { - inter = intersection(inter, alist);s.isConnected(exp); - if (inter.isEmpty() || ! current.getBodyExp().isConnect(s.getBodyExp())) { + } else { + inter = intersection(inter, alist); + s.isConnected(exp); + if (inter.isEmpty() || !current.getBodyExp().isConnect(s.getBodyExp())) { // former service intersection do not share any URL with s // or they are disconnected // start new intersection @@ -46,12 +46,12 @@ Exp simplify(Exp bgp) { } } } - + for (Service s : serviceList) { bgp.getBody().remove(s); } - + return bgp; } - + } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/Sorter.java b/src/main/java/fr/inria/corese/core/compiler/federate/Sorter.java index b9ff82bb6..9f5b19596 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/Sorter.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/Sorter.java @@ -2,33 +2,31 @@ import fr.inria.corese.core.sparql.triple.parser.Exp; import fr.inria.corese.core.sparql.triple.parser.Variable; + import java.util.HashMap; import java.util.List; /** - * Sort services in BGP until successive services share variables + * Sort services in BGP until successive services share variables * if possible * Find best first bgp with constant triple or with filter - * - * @author Olivier Corby, Wimmics INRIA I3S, 2018 * + * @author Olivier Corby, Wimmics INRIA I3S, 2018 */ public class Sorter { - - class Table extends HashMap> { } + FederateVisitor visitor; private SelectorFilter selector; - Sorter(FederateVisitor vis) { visitor = vis; selector = new SelectorFilter(vis, vis.getAST()); } - + void process(Exp bgp) { first(bgp); sort(bgp); } - + /** * Pick the first suitable exp in bgp * exp with a constant term if any. @@ -38,47 +36,46 @@ void first(Exp bgp) { double max = 0; int imax = 0; int i = 0; - + for (Exp exp : bgp) { - res = newSorterResult(); + res = newSorterResult(); hasConstant(exp, res); - hasFilter(exp, res); + hasFilter(exp, res); double score = res.score(); if (exp.isFilter()) { //skip - } - else if (score > max) { + } else if (score > max) { max = score; imax = i; } - + i++; } - + if (imax != 0) { setFirst(bgp, imax); - } + } } - + SorterResult newSorterResult() { return new SorterResult(getSelector()); } - + void setFirst(Exp bgp, int i) { Exp ee = bgp.get(i); bgp.remove(i); bgp.add(0, ee); } - + boolean hasConstant(Exp exp) { SorterResult r = newSorterResult(); hasConstant(exp, r); - return r.getConstantTriple()!=null; + return r.getConstantTriple() != null; } // focus on triple with constant void hasConstant(Exp exp, SorterResult res) { - if (exp.isTriple()) { + if (exp.isTriple()) { res.submit(exp.getTriple()); } else if (exp.isBGP()) { for (Exp ee : exp.getBody()) { @@ -94,118 +91,105 @@ void hasConstant(Exp exp, SorterResult res) { res.union(r1, r2); } else if (exp.isOptional() || exp.isMinus()) { hasConstant(exp.get(0), res); - } - else if (exp.isQuery()) { + } else if (exp.isQuery()) { hasConstant(exp.getAST().getBody(), res); } } - + boolean hasFilter(Exp exp) { return hasFilter(exp, newSorterResult()); } - + boolean hasFilter(Exp exp, SorterResult res) { if (exp.isFilter()) { res.submit(exp.getFilter()); - } - else if (exp.isValues() && exp.getValuesExp().isDefined()) { + } else if (exp.isValues() && exp.getValuesExp().isDefined()) { res.incrFilter(); - } - else if (exp.isBGP()) { + } else if (exp.isBGP()) { for (Exp ee : exp.getBody()) { hasFilter(ee, res); } } else if (exp.isService() || exp.isGraph()) { hasFilter(exp.getBodyExp(), res); } else if (exp.isUnion()) { - if (hasFilter(exp.get(0)) && (hasFilter(exp.get(1)) || hasConstant(exp.get(1)))) { - res.incrFilter(); - } - else if (hasConstant(exp.get(0)) && hasFilter(exp.get(1))) { + if ((hasFilter(exp.get(0)) && (hasFilter(exp.get(1)) || hasConstant(exp.get(1)))) || (hasConstant(exp.get(0)) && hasFilter(exp.get(1)))) { res.incrFilter(); } } else if (exp.isOptional() || exp.isMinus()) { hasFilter(exp.get(0), res); - } - else if (exp.isQuery()) { + } else if (exp.isQuery()) { hasFilter(exp.getAST().getBody(), res); } - return res.nbFilter()>0; - } - - /** - * Order bgp patterns in such a way that two successive patterns share variables - * if possible - * size > 2. - */ + return res.nbFilter() > 0; + } + + /** + * Order bgp patterns in such a way that two successive patterns share variables + * if possible + * size > 2. + */ void sort(Exp bgp) { if (bgp.size() <= 2) { return; } Table table = new Table(); - + for (Exp exp : bgp) { List list = exp.getVariables(); table.put(exp, list); } - + List l1 = table.get(bgp.get(0)); - + // find e2, in the rest of the list, that share variables // with previous patterns. If e2 is not just after e1, move e2 just after e1 for (int i = 0; i < bgp.size(); i++) { - Exp e1 = bgp.get(i); - - for (int j = i+1; j < bgp.size(); j++) { + for (int j = i + 1; j < bgp.size(); j++) { Exp e2 = bgp.get(j); List l2 = table.get(e2); - - if (connected(l1, l2)) { + + if (connected(l1, l2)) { // include variables of e2 into current list of variables l1 include(l1, l2); - if (j > i+1) { + if (j > i + 1) { bgp.remove(j); - bgp.add(i+1, e2); + bgp.add(i + 1, e2); } break; } } } } - + boolean connected(List l1, List l2) { - for (Variable var : l1) { - if (l2.contains(var)) { + for (Variable variable : l1) { + if (l2.contains(variable)) { return true; } } return false; } - + void include(List l1, List l2) { - for (Variable var : l2) { - if (! l1.contains(var)) { - l1.add(var); + for (Variable variable : l2) { + if (!l1.contains(variable)) { + l1.add(variable); } } } - - + boolean sortable(Exp bgp) { for (Exp exp : bgp) { if (exp.isService()) { // ok - } - else if (exp.isBGP() || exp.isBinaryExp()|| exp.isGraph()) { + } else if (exp.isBGP() || exp.isBinaryExp() || exp.isGraph()) { if (sortable(exp)) { // ok - } - else { + } else { return false; } - } - else { - return false ; + } else { + return false; } } return true; @@ -219,4 +203,7 @@ public void setSelector(SelectorFilter selector) { this.selector = selector; } + class Table extends HashMap> { + } + } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/SorterResult.java b/src/main/java/fr/inria/corese/core/compiler/federate/SorterResult.java index 9bfefe21f..451537531 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/SorterResult.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/SorterResult.java @@ -1,10 +1,7 @@ package fr.inria.corese.core.compiler.federate; -import fr.inria.corese.core.sparql.triple.parser.Expression; -import fr.inria.corese.core.sparql.triple.parser.NSManager; -import fr.inria.corese.core.sparql.triple.parser.Triple; -import fr.inria.corese.core.sparql.triple.parser.Variable; -import fr.inria.corese.core.sparql.triple.parser.VariableScope; +import fr.inria.corese.core.sparql.triple.parser.*; + import java.util.List; /** @@ -48,9 +45,7 @@ public void setTriple(Triple triple) { } void addTriple(Triple t) { - if (getTriple() == null) { - setTriple(t); - } else if (subScore(t) > subScore(getTriple())) { + if ((getTriple() == null) || (subScore(t) > subScore(getTriple()))) { // prefer local predicate vs system predicate setTriple(t); } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/Stack.java b/src/main/java/fr/inria/corese/core/compiler/federate/Stack.java index 0f2562f82..f5cadf982 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/Stack.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/Stack.java @@ -1,14 +1,13 @@ package fr.inria.corese.core.compiler.federate; import fr.inria.corese.core.sparql.triple.parser.Variable; + import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; /** - * * @author Olivier Corby, Wimmics INRIA I3S, 2017 - * */ public class Stack implements Iterable { @@ -17,23 +16,23 @@ public class Stack implements Iterable { Stack() { stack = new ArrayList(); } - - Variable get(){ - if (stack.isEmpty()){ + + Variable get() { + if (stack.isEmpty()) { return null; } - return stack.get(stack.size() -1); + return stack.get(stack.size() - 1); } - - void push(Variable var){ + + void push(Variable var) { stack.add(var); } - - void pop(){ - stack.remove(stack.size() -1); + + void pop() { + stack.remove(stack.size() - 1); } - - boolean isEmpty(){ + + boolean isEmpty() { return stack.isEmpty(); } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/URI2BGPList.java b/src/main/java/fr/inria/corese/core/compiler/federate/URI2BGPList.java index d274211c4..df9d9ea56 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/URI2BGPList.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/URI2BGPList.java @@ -1,24 +1,18 @@ package fr.inria.corese.core.compiler.federate; -import fr.inria.corese.core.sparql.triple.parser.ASTSelector; -import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.Expression; -import fr.inria.corese.core.sparql.triple.parser.Service; -import fr.inria.corese.core.sparql.triple.parser.Triple; -import fr.inria.corese.core.sparql.triple.parser.Variable; +import fr.inria.corese.core.sparql.triple.parser.*; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** - * This class has two instances + * This class has two instances * the main instance contains the second one * a) main instance: uri -> (connected bgp) triple with one URI (deprecated) * b) uriList2bgp: uri -> (connected bgp) triple with several URI */ public class URI2BGPList { - public static boolean TRACE_SKIP = false; // uri -> bgp list HashMap> uri2bgp; // bgp -> uri list @@ -30,11 +24,11 @@ public class URI2BGPList { // uriList2bgp instance for triple with several URI private URI2BGPList uriList2bgp; private FederateVisitor visitor; - + // optional does not private boolean join = true; - - + + URI2BGPList(FederateVisitor vis) { uri2bgp = new HashMap<>(); bgp2uri = new BGP2URI(); @@ -42,70 +36,57 @@ public class URI2BGPList { serviceList = new ArrayList<>(); visitor = vis; } - + void complete() { bgp2uri(); - if (getUriList2bgp() !=null) { + if (getUriList2bgp() != null) { getUriList2bgp().bgp2uri(); } } - + /** * Create bgp2uri map: bgp -> list uri - * When several physical occurrences of same (equals) bgp, + * When several physical occurrences of same (equals) bgp, * pick one key bgp that represents all of them */ - void bgp2uri() { + void bgp2uri() { for (String uri : uri2bgp.keySet()) { for (BasicGraphPattern bgp : uri2bgp.get(uri)) { // retrieve key bgp for this bgp // use case: several similar bgp objects represented by // one bgp object BasicGraphPattern key = getBgp2uri().getKey(bgp); - List uriList = getBgp2uri().get(key); - if (uriList == null) { - uriList = new ArrayList<>(); - getBgp2uri().put(key, uriList); - } + List uriList = getBgp2uri().computeIfAbsent(key, k -> new ArrayList<>()); uriList.add(uri); } } } List get(String label) { - List bgpList = uri2bgp.get(label); - if (bgpList == null) { - bgpList = new ArrayList<>(); - uri2bgp.put(label, bgpList); - } - return bgpList; + return uri2bgp.computeIfAbsent(label, k -> new ArrayList<>()); } void add(String label, BasicGraphPattern bgp) { - List bgpList = uri2bgp.get(label); - if (bgpList == null) { - bgpList = new ArrayList<>(); - uri2bgp.put(label, bgpList); - } + List bgpList = uri2bgp.computeIfAbsent(label, k -> new ArrayList<>()); bgpList.add(bgp); } HashMap> getMap() { return uri2bgp; } - + ASTSelector getSelector() { return getVisitor().getAST().getAstSelector(); } - + // does triple t join with each connected triple in bgp boolean join(BasicGraphPattern bgp, Triple t, String uri) { if (getVisitor().acceptWithoutJoinTest(t)) { return true; } - return getSelector().join(bgp, t, uri); + return getSelector().join(bgp, t, uri); } - + // do every pair of connected triple in bgp1 and bgp2 join ? boolean join(BasicGraphPattern bgp1, BasicGraphPattern bgp2, String uri) { for (Exp e : bgp2) { @@ -120,7 +101,7 @@ boolean join(BasicGraphPattern bgp1, BasicGraphPattern bgp2, String uri) { } return true; } - + // assign triple to one bgp of uri, connected with triple // and merge all connected bgp // otherwise create new bgp @@ -128,18 +109,17 @@ void assignTripleToConnectedBGP(Triple triple, String uri) { List bgpList = get(uri); int i = insert(bgpList, triple, uri); - if (i>=0) { + if (i >= 0) { // triple inserted in ith bgp // merge other connected bgp if any merge(bgpList, triple, uri, i); - } - else { + } else { // create new bgp because triple is connected to no existing bgp // or it does not join bgpList.add(BasicGraphPattern.create(triple)); } } - + // find connected bgp where triple join: insert triple in bgp int insert(List bgpList, Triple triple, String uri) { int i = 0; @@ -150,12 +130,6 @@ int insert(List bgpList, Triple triple, String uri) { // source selection confirm that triple join with bgp bgp.add(triple); return i; - } else { - // source selection confirm that triple does not join with bgp - if (TRACE_SKIP) { - trace("bgp join skip connection: %s %s", triple, uri); - trace("%s", bgp); - } } } else { bgp.add(triple); @@ -167,12 +141,12 @@ int insert(List bgpList, Triple triple, String uri) { // no connected bgp with join return -1; } - + // if bgp2 is connected to triple, include it into former ith bgp1 void merge(List bgpList, Triple triple, String uri, int i) { BasicGraphPattern bgp1 = bgpList.get(i); ArrayList toRemove = new ArrayList<>(); - + for (int j = i + 1; j < bgpList.size(); j++) { BasicGraphPattern bgp2 = bgpList.get(j); if (bgp2.isConnected(triple)) { @@ -195,7 +169,7 @@ void merge(List bgpList, Triple triple, String uri, int i) { bgpList.remove(bgp); } } - + // for every URI: merge list of BGP into one BGP // use case: bgp with one URI @@ -269,25 +243,7 @@ public String toString() { } return sb.toString(); } - - void trace() { - // uri -> bgp list, triple with one uri - trace("uri\n%s", this); - // uri -> bgp list, triple with several uri - trace("uri list\n%s", getUriList2bgp()); - trace("bgp2uri:\n"); - - for (BasicGraphPattern bgp - : getUriList2bgp().getBgp2uri().keySet()) { - trace("%s: %s", bgp, - getUriList2bgp().getBgp2uri().get(bgp)); - } - } - - void trace(String mes, Object... obj) { - System.out.println(String.format(mes, obj)); - } - + void add(Triple t) { getTripleList().add(t); } @@ -315,7 +271,7 @@ public BGP2URI getBgp2uri() { public void setBgp2uri(BGP2URI bgp2uri) { this.bgp2uri = bgp2uri; } - + void addServiceWithOneURI(Service s) { getServiceList().add(s); } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/Util.java b/src/main/java/fr/inria/corese/core/compiler/federate/Util.java index e75a52988..5a51e2b44 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/Util.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/Util.java @@ -3,23 +3,15 @@ import fr.inria.corese.core.sparql.triple.parser.Atom; import fr.inria.corese.core.sparql.triple.parser.Service; import fr.inria.corese.core.sparql.triple.parser.Variable; + import java.util.ArrayList; import java.util.List; public class Util { - -// List myIntersection(List l1, List l2) { -// if (l1 == null) { -// return l2; -// } -// return intersection(l1, l2); -// } - List intersection(Service s1, Service s2) { return intersection(s1.getServiceList(), s2.getServiceList()); } - List intersection(List l1, List l2) { List list = new ArrayList<>(); for (Atom at : l1) { @@ -29,27 +21,25 @@ List intersection(List l1, List l2) { } return list; } - - + boolean equalURI(List list1, List list2) { if (list1.size() != list2.size()) { return false; } - for (Atom var : list1) { - if (!list2.contains(var)) { + for (Atom elem : list1) { + if (!list2.contains(elem)) { return false; } } return true; } - boolean equal(List list1, List list2) { if (list1.size() != list2.size()) { return false; } - for (Variable var : list1) { - if (!list2.contains(var)) { + for (Variable elem : list1) { + if (!list2.contains(elem)) { return false; } } @@ -62,21 +52,21 @@ boolean hasIntersection(List list1, List list2) { List intersectionVariable(List list1, List list2) { ArrayList list = new ArrayList<>(); - for (Variable var : list1) { - if (list2.contains(var) && !list.contains(var)) { - list.add(var); + for (Variable elem : list1) { + if (list2.contains(elem) && !list.contains(elem)) { + list.add(elem); } } return list; } boolean includedIn(List list1, List list2) { - for (Variable var : list1) { - if (!list2.contains(var)) { + for (Variable elem : list1) { + if (!list2.contains(elem)) { return false; } } return true; } - + } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/util/ResourceReader.java b/src/main/java/fr/inria/corese/core/compiler/federate/util/ResourceReader.java index 38b91f5a6..46f299360 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/util/ResourceReader.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/util/ResourceReader.java @@ -1,20 +1,13 @@ package fr.inria.corese.core.compiler.federate.util; import fr.inria.corese.core.sparql.triple.parser.NSManager; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; + +import java.io.*; import java.net.MalformedURLException; import java.net.URL; -/** - * - */ public class ResourceReader { - + public String readWE(String name) throws IOException { String query = "", str = ""; Reader fr; @@ -26,19 +19,15 @@ public String readWE(String name) throws IOException { } else { fr = new FileReader(name); } - - if (fr == null) { - throw new IOException(name); - } query = read(fr); - if (query == "") { + if (query.equals("")) { return null; } return query; } - - boolean isURL(String path) { + + boolean isURL(String path) { try { new URL(path); } catch (MalformedURLException e) { @@ -46,17 +35,16 @@ boolean isURL(String path) { } return true; } - + public String getResource(String name) throws IOException { InputStream stream = ResourceReader.class.getResourceAsStream(name); if (stream == null) { throw new IOException(name); } Reader fr = new InputStreamReader(stream); - String str = read(fr); - return str; + return read(fr); } - + String read(Reader fr) throws IOException { BufferedReader fq = new BufferedReader(fr); StringBuilder sb = new StringBuilder(); @@ -75,10 +63,9 @@ String read(Reader fr) throws IOException { isnl = true; } sb.append(str); - //sb.append(NL); } return sb.toString(); } - - + + } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/util/RewriteError.java b/src/main/java/fr/inria/corese/core/compiler/federate/util/RewriteError.java index 66869908a..68ab694e7 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/util/RewriteError.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/util/RewriteError.java @@ -14,12 +14,10 @@ public class RewriteError { exp = e; message = mes; } - + @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(String.format("%s:\n%s",getMessage(), getExp())); - return sb.toString(); + return String.format("%s:\n%s", getMessage(), getExp()); } public Exp getExp() { diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/util/RewriteErrorManager.java b/src/main/java/fr/inria/corese/core/compiler/federate/util/RewriteErrorManager.java index 9840be046..c2d4213be 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/util/RewriteErrorManager.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/util/RewriteErrorManager.java @@ -1,6 +1,7 @@ package fr.inria.corese.core.compiler.federate.util; import fr.inria.corese.core.sparql.triple.parser.Exp; + import java.util.ArrayList; import java.util.List; @@ -15,11 +16,11 @@ public class RewriteErrorManager { public RewriteErrorManager() { errorList = new ArrayList<>(); } - + public void add(String mes, Exp exp) { getErrorList().add(new RewriteError(exp, mes)); } - + @Override public String toString() { StringBuilder sb = new StringBuilder(); @@ -36,6 +37,6 @@ public List getErrorList() { public void setErrorList(List errorList) { this.errorList = errorList; } - - + + } diff --git a/src/main/java/fr/inria/corese/core/compiler/federate/util/RewriteErrorMessage.java b/src/main/java/fr/inria/corese/core/compiler/federate/util/RewriteErrorMessage.java index b50474b9a..07a2604a8 100644 --- a/src/main/java/fr/inria/corese/core/compiler/federate/util/RewriteErrorMessage.java +++ b/src/main/java/fr/inria/corese/core/compiler/federate/util/RewriteErrorMessage.java @@ -4,6 +4,6 @@ * */ public interface RewriteErrorMessage { - static final String FILTER_EXISTS = "Filter exists with service inside"; - static final String NO_SERVICE = "No service for expression"; + String FILTER_EXISTS = "Filter exists with service inside"; + String NO_SERVICE = "No service for expression"; } diff --git a/src/main/java/fr/inria/corese/core/compiler/parser/Checker.java b/src/main/java/fr/inria/corese/core/compiler/parser/Checker.java index f511054bb..9e24a01a9 100644 --- a/src/main/java/fr/inria/corese/core/compiler/parser/Checker.java +++ b/src/main/java/fr/inria/corese/core/compiler/parser/Checker.java @@ -1,15 +1,6 @@ package fr.inria.corese.core.compiler.parser; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.Atom; -import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; -import fr.inria.corese.core.sparql.triple.parser.Constant; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.Union; -import fr.inria.corese.core.sparql.triple.parser.Source; -import fr.inria.corese.core.sparql.triple.parser.Term; -import fr.inria.corese.core.sparql.triple.parser.Triple; -import fr.inria.corese.core.sparql.triple.parser.Variable; +import fr.inria.corese.core.sparql.triple.parser.*; /** * Type Checking. @@ -86,11 +77,11 @@ ASTQuery checkClass(Triple triple) { aa.setAsk(true); Atom c = triple.getArg(1); - Variable var = Variable.create(VAR); + Variable variable = Variable.create(VAR); Triple t1 = Triple.create(c, aa.createQName(RDFTYPE), aa.createQName(RDFSCLASS)); - Triple t2 = Triple.create(c, aa.createQName(RDFSSUBCLASSOF), var); - Triple t3 = Triple.create(var, aa.createQName(RDFSSUBCLASSOF), c); + Triple t2 = Triple.create(c, aa.createQName(RDFSSUBCLASSOF), variable); + Triple t3 = Triple.create(variable, aa.createQName(RDFSSUBCLASSOF), c); Union exp = Union.create(t1, t2); exp = Union.create(exp, t3); @@ -112,7 +103,7 @@ ASTQuery checkProperty(Triple triple) { // check

rdf:type rdf:Property // PB: it may be infered in kg:entailment, hence not really defined in ontology Variable gg = Variable.create(GRAPH); - Variable var = Variable.create(VAR); + Variable variable = Variable.create(VAR); Constant type = aa.createQName(RDFTYPE); Term term = Term.create(NEQ, gg, aa.createQName(ENTAIL)); @@ -123,17 +114,17 @@ ASTQuery checkProperty(Triple triple) { pat.addFilter(term); Source gp = Source.create(gg, pat); - Triple t2 = Triple.create(p, aa.createQName(RDFSDOMAIN), var); - Triple t3 = Triple.create(p, aa.createQName(RDFSRANGE), var); + Triple t2 = Triple.create(p, aa.createQName(RDFSDOMAIN), variable); + Triple t3 = Triple.create(p, aa.createQName(RDFSRANGE), variable); Triple t4 = Triple.create(p, type, aa.createQName(OWLSYMMETRIC)); Triple t5 = Triple.create(p, type, aa.createQName(OWLTRANSITIVE)); - Triple t6 = Triple.create(p, aa.createQName(OWLINVERSEOF), var); - Triple t7 = Triple.create(var, aa.createQName(OWLINVERSEOF), p); + Triple t6 = Triple.create(p, aa.createQName(OWLINVERSEOF), variable); + Triple t7 = Triple.create(variable, aa.createQName(OWLINVERSEOF), p); - Triple t8 = Triple.create(p, aa.createQName(RDFSSUBPROPERTY), var); - Triple t9 = Triple.create(var, aa.createQName(RDFSSUBPROPERTY), p); + Triple t8 = Triple.create(p, aa.createQName(RDFSSUBPROPERTY), variable); + Triple t9 = Triple.create(variable, aa.createQName(RDFSSUBPROPERTY), p); BasicGraphPattern bgp = BasicGraphPattern.create(); bgp.add(gp); diff --git a/src/main/java/fr/inria/corese/core/compiler/parser/Compiler.java b/src/main/java/fr/inria/corese/core/compiler/parser/Compiler.java index dc9164444..25a9c7d15 100755 --- a/src/main/java/fr/inria/corese/core/compiler/parser/Compiler.java +++ b/src/main/java/fr/inria/corese/core/compiler/parser/Compiler.java @@ -23,42 +23,43 @@ public interface Compiler { - void setAST(ASTQuery ast); + void setAST(ASTQuery ast); - boolean isFail(); + boolean isFail(); - Node createNode(String name); + Node createNode(String name); - Node createNode(Atom at); - - Node createNode(Atom at, boolean reuse); + Node createNode(Atom at); - Node getNode(); + Node createNode(Atom at, boolean reuse); - Edge getEdge(); + Node getNode(); - List getFilters(); + Edge getEdge(); - Collection getVariables(); + List getFilters(); - Filter compile(Expression exp) throws EngineException; + Collection getVariables(); - Edge compile(Triple t, boolean insertData); - // rec==true when compile nested triple in values clause - Edge compile(Triple t, boolean insertData, boolean rec); + Filter compile(Expression exp) throws EngineException; - List compileFilter(Expression exp) throws EngineException; + Edge compile(Triple t, boolean insertData); - Regex getRegex(Filter f) throws EngineException ; + // rec==true when compile nested triple in values clause + Edge compile(Triple t, boolean insertData, boolean rec); - String getMode(Filter f); + List compileFilter(Expression exp) throws EngineException; - int getMin(Filter f); + Regex getRegex(Filter f) throws EngineException; - int getMax(Filter f); + String getMode(Filter f); - HashMap getVarTable(); - - void share (Compiler cp); + int getMin(Filter f); + + int getMax(Filter f); + + HashMap getVarTable(); + + void share(Compiler cp); } diff --git a/src/main/java/fr/inria/corese/core/compiler/parser/CompilerFacKgram.java b/src/main/java/fr/inria/corese/core/compiler/parser/CompilerFacKgram.java index e570906ce..67d8200da 100755 --- a/src/main/java/fr/inria/corese/core/compiler/parser/CompilerFacKgram.java +++ b/src/main/java/fr/inria/corese/core/compiler/parser/CompilerFacKgram.java @@ -10,16 +10,13 @@ public class CompilerFacKgram implements CompilerFactory { - public CompilerFacKgram() { - } + public CompilerFacKgram() { + } - public CompilerFacKgram(boolean b) { - } - - @Override - public Compiler newInstance() { - return new CompilerKgram(); - } + @Override + public Compiler newInstance() { + return new CompilerKgram(); + } } diff --git a/src/main/java/fr/inria/corese/core/compiler/parser/CompilerFactory.java b/src/main/java/fr/inria/corese/core/compiler/parser/CompilerFactory.java index 843f35380..e93d6aba5 100755 --- a/src/main/java/fr/inria/corese/core/compiler/parser/CompilerFactory.java +++ b/src/main/java/fr/inria/corese/core/compiler/parser/CompilerFactory.java @@ -2,6 +2,6 @@ public interface CompilerFactory { - Compiler newInstance(); - + Compiler newInstance(); + } diff --git a/src/main/java/fr/inria/corese/core/compiler/parser/CompilerKgram.java b/src/main/java/fr/inria/corese/core/compiler/parser/CompilerKgram.java index fe27e09d3..e4de94a68 100755 --- a/src/main/java/fr/inria/corese/core/compiler/parser/CompilerKgram.java +++ b/src/main/java/fr/inria/corese/core/compiler/parser/CompilerKgram.java @@ -1,20 +1,10 @@ package fr.inria.corese.core.compiler.parser; -import fr.inria.corese.core.kgram.api.core.Edge; -import fr.inria.corese.core.kgram.api.core.ExpType; import fr.inria.corese.core.kgram.api.core.Filter; -import fr.inria.corese.core.kgram.api.core.Node; -import fr.inria.corese.core.kgram.api.core.Regex; +import fr.inria.corese.core.kgram.api.core.*; import fr.inria.corese.core.kgram.tool.Message; import fr.inria.corese.core.sparql.exceptions.EngineException; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.Atom; -import fr.inria.corese.core.sparql.triple.parser.Constant; -import fr.inria.corese.core.sparql.triple.parser.Expression; -import fr.inria.corese.core.sparql.triple.parser.Processor; -import fr.inria.corese.core.sparql.triple.parser.Term; -import fr.inria.corese.core.sparql.triple.parser.Triple; -import fr.inria.corese.core.sparql.triple.parser.Variable; +import fr.inria.corese.core.sparql.triple.parser.*; import java.util.ArrayList; import java.util.Collection; @@ -28,12 +18,10 @@ * @author corby */ public class CompilerKgram implements ExpType, Compiler { - static int count = 0; static final String EQUAL = "="; - + private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CompilerKgram.class); ASTQuery ast; EdgeImpl edge; - Node node; HashMap varTable; HashMap resTable; @@ -48,12 +36,12 @@ public CompilerKgram() { public static CompilerKgram create() { return new CompilerKgram(); } - + @Override public HashMap getVarTable() { return varTable; } - + @Override public void share(Compiler cp) { varTable = cp.getVarTable(); @@ -93,8 +81,7 @@ public Filter compile(Expression exp) throws EngineException { Expression ee = process(exp); Expression cpl = ee.process(ast); if (cpl == null) { - Message.log(Message.REWRITE, exp); - Message.log(ast); + logger.warn(Message.Prefix.REWRITE.getString(), exp, ast); cpl = exp; } cpl.compile(ast); @@ -113,8 +100,7 @@ Expression process(Expression exp) { exp.getArg(0).getName().equals(Processor.XPATH)) { Term list = Term.list(); list.add(exp.getArg(0)); - Term t = Term.create(Processor.IN, exp.getArg(1), list); - return t; + return Term.create(Processor.IN, exp.getArg(1), list); } return exp; } @@ -122,11 +108,11 @@ Expression process(Expression exp) { Node getNode(Atom at) { return getNode(at, false); } - + NodeImpl getNodeImpl(Atom at) { return (NodeImpl) getNode(at, false); } - + @Override public Node createNode(Atom at, boolean isReuse) { return getNode(at, isReuse); @@ -139,8 +125,8 @@ public Node createNode(Atom at, boolean isReuse) { * For resources it is to enable to approximate match a query Class with * different target classes */ - Node getNode(Atom at, boolean isReuse) { - + Node getNode(Atom at, boolean isReuse) { + if (at.isVariable()) { Node node = varTable.get(at.getName()); if (node == null) { @@ -155,8 +141,7 @@ Node getNode(Atom at, boolean isReuse) { resTable.put(at.getName(), node); } return node; - } - else if (at.isBlank()) { + } else if (at.isBlank()) { Node node = bnodeTable.get(at.getName()); if (node == null) { node = new NodeImpl(at); @@ -176,33 +161,33 @@ public Collection getVariables() { public Edge compile(Triple tt, boolean reuse) { return compile(tt, reuse, false); } - + /** - * when rec = true: + * when rec = true: * when triple(t p o) where t is triple reference of triple(a q b t) -> * recursively compile triple(a q b t) * use case: values ?t {<<<> p o>>} */ - + Node getNodeRec(Atom at, boolean reuse, boolean rec) { Node node = getNode(at, reuse); - if (rec && at.isTriple() && at.getTriple()!=null && - node.getEdge()==null) { - Edge edge = compile(at.getTriple(), reuse, rec); - edge.setCreated(true); - node.setEdge(edge); + if (rec && at.isTriple() && at.getTriple() != null && + node.getEdge() == null) { + Edge complileddge = compile(at.getTriple(), reuse, rec); + complileddge.setCreated(true); + node.setEdge(complileddge); } return node; } - + @Override public Edge compile(Triple triple, boolean reuse, boolean rec) { - EdgeImpl edge = new EdgeImpl(triple); - edge.setCreated(rec); + EdgeImpl compiledEdge = new EdgeImpl(triple); + compiledEdge.setCreated(rec); Node subject = getNodeRec(triple.getSubject(), reuse, rec); if (triple.getVariable() != null) { Node variable = getNode(triple.getVariable()); - edge.setEdgeVariable(variable); + compiledEdge.setEdgeVariable(variable); } Node predicate = getNode(triple.getProperty(), reuse); // PRAGMA: @@ -212,15 +197,15 @@ public Edge compile(Triple triple, boolean reuse, boolean rec) { // if it would be same Node, it would need to be bound to same value // TODO: fix it for relax Node object = getNodeRec(triple.getObject(), reuse, rec); - edge.add(subject); - edge.add(object); - edge.setEdgeNode(predicate); + compiledEdge.add(subject); + compiledEdge.add(object); + compiledEdge.setEdgeNode(predicate); if (triple.getArgs() != null) { // tuple(s p o arg1 .. argn) for (Atom arg : triple.getArgs()) { - NodeImpl sup = getNodeImpl(arg); - + NodeImpl sup = getNodeImpl(arg); + if (arg.isVariable()) { sup.setMatchNodeList(arg.getVariable().isMatchNodeList()); sup.setMatchCardinality(arg.getVariable().isMatchCardinality()); @@ -228,13 +213,13 @@ public Edge compile(Triple triple, boolean reuse, boolean rec) { if (sup.isTriple()) { // triple(s p o t) where t is triple reference // t points to target edge - sup.setEdge(edge); + sup.setEdge(compiledEdge); } - edge.add(sup); + compiledEdge.add(sup); } } - return edge; + return compiledEdge; } diff --git a/src/main/java/fr/inria/corese/core/compiler/parser/EdgeImpl.java b/src/main/java/fr/inria/corese/core/compiler/parser/EdgeImpl.java index 852430edf..86c15929c 100755 --- a/src/main/java/fr/inria/corese/core/compiler/parser/EdgeImpl.java +++ b/src/main/java/fr/inria/corese/core/compiler/parser/EdgeImpl.java @@ -1,8 +1,5 @@ package fr.inria.corese.core.compiler.parser; -import java.util.ArrayList; -import java.util.Objects; - import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.api.core.PointerType; @@ -15,11 +12,16 @@ import fr.inria.corese.core.sparql.triple.parser.Triple; import fr.inria.corese.core.sparql.triple.parser.Variable; +import java.util.ArrayList; +import java.util.Objects; + public class EdgeImpl extends PointerObject implements Edge { public static String TOP = RDFS.RootPropertyURI; ArrayList nodes; - Node edgeNode, edgeVariable, mySelf; + Node edgeNode; + Node edgeVariable; + Node mySelf; String label; Triple triple; int index = -1; @@ -61,7 +63,6 @@ public static EdgeImpl create(Node prop, Node sub, Node obj) { edge.add(sub); edge.add(obj); if (prop.isVariable()) { - // edge.setEdgeNode(prop); edge.setEdgeVariable(prop); } else { edge.setEdgeNode(prop); @@ -77,50 +78,39 @@ public String toString() { return basicTriple(); } - String basicTriple() { + String basicTriple() { String str = ""; String name = label; - - if (getTriple()!=null && getTriple().getRegex()!=null) { + + if (getTriple() != null && getTriple().getRegex() != null) { name = getTriple().getRegex().toString(); - } - else if (getEdgeVariable() != null) { + } else if (getEdgeVariable() != null) { name = getEdgeVariable().toString(); } else if (getTriple() != null) { name = getTriple().getProperty().getName(); } - - str += getNode(0); + + str += getNode(0); str += " " + name; for (int i = 1; i < nodes.size(); i++) { - str += " " + getNode(i); + str += " " + getNode(i); } return str; } - + String nestedTriple() { return nestedTripleBasic(); } - - String nestedTripleDebug() { - String str = String.format("<<%s[%s] %s %s[%s]>> [%s]", - getNode(0), getNode(0).isVariable()?getNode(0).getLabel():"", - getPredicateNode(), - getNode(1), getNode(1).isVariable()?getNode(1).getLabel():"", - getNode(Edge.REF_INDEX).getLabel()); - return str; - } - + String nestedTripleBasic() { - String str = String.format("<<%s %s %s>> [%s]", - getNode(0), getPredicateNode(), getNode(1), - getNode(Edge.REF_INDEX).getLabel()); - return str; + return String.format("<<%s %s %s>> [%s]", + getNode(0), getPredicateNode(), getNode(1), + getNode(Edge.REF_INDEX).getLabel()); } @Override public Iterable getLoop() { - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList<>(); for (int i = 0; i <= nodes.size(); i++) { list.add(getValue(null, i)); } @@ -157,8 +147,8 @@ public void setMatchArity(boolean b) { } public Node getPredicateNode() { - Node var = getEdgeVariable(); - return (var == null) ? getEdgeNode() : var; + Node varNode = getEdgeVariable(); + return (varNode == null) ? getEdgeNode() : varNode; } public Triple getTriple() { @@ -173,8 +163,7 @@ Triple triple() { Atom object = ((NodeImpl) nodes.get(1)).getAtom(); Constant property = getName(); Variable variable = getVariable(); - Triple triple = Triple.create(subject, property, variable, object); - return triple; + return Triple.create(subject, property, variable, object); } Constant getName() { @@ -197,15 +186,6 @@ public void add(Node node) { nodes.add(node); } - /** - * - * Query edge node is stored only if it is a variable otherwise it is useless - * and may lead to a pb when match subproperty - */ - public void setEdgeNode(Node n) { - edgeNode = n; - } - @Override public boolean contains(Node n) { return nodes.contains(n); @@ -216,11 +196,23 @@ public Node getEdgeNode() { return edgeNode; } + /** + * Query edge node is stored only if it is a variable otherwise it is useless + * and may lead to a pb when match subproperty + */ + public void setEdgeNode(Node n) { + edgeNode = n; + } + @Override public Node getEdgeVariable() { return edgeVariable; } + public void setEdgeVariable(Node n) { + edgeVariable = n; + } + @Override public Node getProperty() { if (edgeVariable == null) { @@ -229,15 +221,16 @@ public Node getProperty() { return edgeVariable; } - public void setEdgeVariable(Node n) { - edgeVariable = n; - } - @Override public int getEdgeIndex() { return index; } + @Override + public void setEdgeIndex(int n) { + index = n; + } + @Override public String getEdgeLabel() { return label; @@ -258,11 +251,6 @@ public int nbGraphNode() { return nodes.size(); } - @Override - public void setEdgeIndex(int n) { - index = n; - } - @Override public Edge getEdge() { return this; diff --git a/src/main/java/fr/inria/corese/core/compiler/parser/ExpandList.java b/src/main/java/fr/inria/corese/core/compiler/parser/ExpandList.java index e6e072c9e..6c2923ccf 100644 --- a/src/main/java/fr/inria/corese/core/compiler/parser/ExpandList.java +++ b/src/main/java/fr/inria/corese/core/compiler/parser/ExpandList.java @@ -4,25 +4,23 @@ */ package fr.inria.corese.core.compiler.parser; +import fr.inria.corese.core.compiler.api.QueryVisitor; +import fr.inria.corese.core.kgram.core.Query; import fr.inria.corese.core.sparql.triple.parser.ASTQuery; import fr.inria.corese.core.sparql.triple.parser.Exp; import fr.inria.corese.core.sparql.triple.parser.RDFList; -import fr.inria.corese.core.compiler.api.QueryVisitor; -import fr.inria.corese.core.kgram.core.Query; /** * Replace RDF List by Property Path rdf:rest* / rdf:first in SPARQL Query * * @author Olivier Corby, Wimmics Inria I3S, 2013 - * */ public class ExpandList implements QueryVisitor { - - public static ExpandList create(){ + + public static ExpandList create() { return new ExpandList(); } - - + @Override public void visit(ASTQuery ast) { process(ast); @@ -31,26 +29,22 @@ public void visit(ASTQuery ast) { @Override public void visit(Query query) { } - - - void process(ASTQuery ast) { process(ast, ast.getBody()); } void process(ASTQuery ast, Exp exp) { - for (int i = 0; i * Usage: - * + *

* (1) pragma {kg:path kg:expand n} - * + *

* (2) exec.setVisitor(ExpandPath.create(n)); - * - * @author Olivier Corby, Wimmics, INRIA 2012 * + * @author Olivier Corby, Wimmics, INRIA 2012 */ public class ExpandPath implements QueryVisitor { - - private static Logger log = LoggerFactory.getLogger(ExpandPath.class); - - private static final String ROOT = "?_VAR_"; - private static final String NEQ = Term.SNEQ; - private static final String OR = Term.SEOR; - private static final String AND = Term.SEAND; - - int max = 5; - int varCount = 0; - boolean isDebug = false; - ASTQuery ast; - - ExpandPath(int n){ - max = n; - } - - ExpandPath(){ - - } - - public static ExpandPath create(){ - return new ExpandPath(); - } - - public static ExpandPath create(int n){ - return new ExpandPath(n); - } - - public void visit(ASTQuery ast) { - rewrite(ast); - } - - public void visit(Query query) { - - } - - - - /** - * rewrite path to sparql 1.0 BGP - */ - public void rewrite(ASTQuery ast){ - this.ast = ast; - isDebug = ast.isDebug(); - rewrite(ast.getBody()); - - if (ast.isUpdate()){ - rewrite(ast.getUpdate()); - } - } - - - /** - * Query is a SPARQL Update - * rewrite the body of insert delete where - */ - public void rewrite(ASTUpdate update){ - for (Update u : update.getUpdates()){ - if (u.isComposite()){ - Composite c = u.getComposite(); - if (c.getBody() != null){ - rewrite(c.getBody()); - } - } - } - } - - - /** - * Rewrite path as BGP - * Modify exp (no copy is done) - */ - public Exp rewrite(Exp exp){ - if (ast == null){ - ast = ASTQuery.create(); - } - - if (exp.isTriple()){ - Triple t = exp.getTriple(); - if (t.isPath()){ - return rewrite(t, t.getRegex()); - } - } - else if (exp.isQuery()){ - rewrite(exp.getAST().getBody()); + + private static final Logger log = LoggerFactory.getLogger(ExpandPath.class); + + private static final String ROOT = "?_VAR_"; + private static final String NEQ = Term.SNEQ; + private static final String OR = Term.SEOR; + private static final String AND = Term.SEAND; + + int max = 5; + int varCount = 0; + boolean isDebug = false; + ASTQuery ast; + + ExpandPath(int n) { + max = n; + } + + ExpandPath() { + + } + + public static ExpandPath create() { + return new ExpandPath(); + } + + public static ExpandPath create(int n) { + return new ExpandPath(n); + } + + @Override + public void visit(ASTQuery ast) { + rewrite(ast); + } + + @Override + public void visit(Query query) { + + } + + + /** + * rewrite path to sparql 1.0 BGP + */ + public void rewrite(ASTQuery ast) { + this.ast = ast; + isDebug = ast.isDebug(); + rewrite(ast.getBody()); + + if (ast.isUpdate()) { + rewrite(ast.getUpdate()); + } + } + + + /** + * Query is a SPARQL Update + * rewrite the body of insert delete where + */ + public void rewrite(ASTUpdate update) { + for (Update u : update.getUpdates()) { + if (u.isComposite()) { + Composite c = u.getComposite(); + if (c.getBody() != null) { + rewrite(c.getBody()); } - else for (int i=0; i - * ?y exp ?x - */ - private Exp reverse(Triple t, Expression exp){ - Exp e = ast.createPath(t.getArg(1), exp.getArg(0), t.getArg(0)); - return e; - } - - - /** - * e1 | e2 - */ - private Exp alt(Triple t, Expression exp){ - Exp e1 = ast.createPath(t.getArg(0), exp.getArg(0), t.getArg(1)); - Exp e2 = ast.createPath(t.getArg(0), exp.getArg(1), t.getArg(1)); - - BasicGraphPattern bgp1 = BasicGraphPattern.create(e1); - BasicGraphPattern bgp2 = BasicGraphPattern.create(e2); - - Union or = Union.create(bgp1, bgp2); - return or; - } - - /** - * e1 / e2 - * Special cases: - * (1) ?x rdf:type/rdfs:subClassOf* ?c - * -> - * {?x rdf:type ?c} union { ?x rdf:type/rdfs:subClassOf+ ?c} - * (2) rdf:rest* / rdf:first -> rdf:first union rdf:rest+ / rdf:first - */ - private Exp sequence(Triple t, Expression exp){ - Variable var = variable(); - Exp e1 = ast.createPath(t.getArg(0), exp.getArg(0), var); - Exp e2 = ast.createPath(var, exp.getArg(1), t.getArg(1)); - Exp res = BasicGraphPattern.create(e1, e2); - - if (exp.getArg(0).isStar() || exp.getArg(0).isOpt()){ - // use case: rdf:rest*/rdf:first - // add ?x rdf:first ?y - Exp e = ast.createPath(t.getArg(0), exp.getArg(1), t.getArg(1)); - BasicGraphPattern b = BasicGraphPattern.create(e); - res = Union.create(b, res); - } - else if (exp.getArg(1).isStar() || exp.getArg(1).isOpt()){ - // use case: rdf:type/rdfs:subClassOf* - // add ?x rdf:type ?c - Exp e = ast.createPath(t.getArg(0), exp.getArg(0), t.getArg(1)); - BasicGraphPattern b = BasicGraphPattern.create(e); - res = Union.create(b, res); - } - - return res; - } - - - - /** - * Expression loop is exp+ or exp* - * exp* rewritten as exp+ except in the case e1/e2* where it is correctly rewritten - */ - private Exp loop(Triple t, Expression loop){ - return loop(t.getSubject(), loop.getArg(0), t.getObject(), new ArrayList(), max); - } - - - /** - * rec create a path bgp of length n between s and o - * s exp(n) o = - * {s exp o} union {s exp vi . vi exp(n-1) o} - * generate filter to prevent loops on intermediate nodes (vi != vj) - */ - private Exp loop(Atom subject, Expression exp, Atom object, List list, int n){ - - Exp res = ast.createPath(subject, exp, object); - - if (n <= 1){ - return res; - } - - Variable var = variable(); - Term diff = filter(var, list); - list.add(var); - - Exp e1 = ast.createPath(subject, exp, var); - Exp e2 = loop(var, exp, object, list, n-1); - - BasicGraphPattern bgp = BasicGraphPattern.create(e1); - - if (diff != null){ - bgp.add(diff); - } - - bgp.add(e2); - - Union or = Union.create(res, bgp); - return or; - } - - - /** - * Generate filter vi != vj - */ - Term filter(Variable var, List list){ - Term res = null; - - for (Variable v : list){ - Term t = Term.create(NEQ, var, v); - if (res == null){ - res = t; - } - else { - res = Term.create(AND, res, t); - } - } - - return res; - } - - - Term filter(List list){ - Term res = null; - - for (int i = 0; i exp - * See also: special treatment in sequence - */ - private Exp option(Triple t, Expression option){ - Exp res = ast.createPath(t.getSubject(), option.getArg(0), t.getObject()); - return res; - } - - - - /** - * ! ex:p1 - * ! (ex:p1 | ex:p2) - * -> - * ?x ?p ?y . filter(?p != ex:p1) - */ - private Exp not(Triple t, Expression not){ - Expression exp = not.getArg(0); - Variable p = variable(); - Triple tt = Triple.create(t.getSubject(), p, t.getObject()); - BasicGraphPattern bgp = BasicGraphPattern.create(tt); - Expression f = null; - - if (exp.isConstant()){ - // ! p - f = Term.create(NEQ, p, exp); - } - else { - // ! (p1 | p2) - - for (Expression ee : exp.getArgs()){ - Term g = Term.create(NEQ, p, ee); - f = and(f, g); - } - } - - bgp.add(f); - - return bgp; - } - - - - private Expression and(Expression t1, Expression t2){ - if (t1 == null) return t2; - return Term.create(Term.SEAND, t1, t2); - } - - - - - - - - - - - - - - - - - - - - - + } + } + } + + + /** + * Rewrite path as BGP + * Modify exp (no copy is done) + */ + public Exp rewrite(Exp exp) { + if (ast == null) { + ast = ASTQuery.create(); + } + + if (exp.isTriple()) { + Triple t = exp.getTriple(); + if (t.isPath()) { + return rewrite(t, t.getRegex()); + } + } else if (exp.isQuery()) { + rewrite(exp.getAST().getBody()); + } else for (int i = 0; i < exp.size(); i++) { + exp.set(i, rewrite(exp.get(i))); + } + return exp; + } + + private Exp rewrite(Triple path, Expression exp) { + Exp res = null; + + switch (exp.getretype()) { + + case Regex.UNDEF: + if (isDebug) log.debug("** Expand: not rewrite UNDEF Path: " + exp); + + case Regex.LABEL: + res = triple(path, exp); + break; + + case Regex.STAR: + if (isDebug) log.debug("** Expand: rewrite exp* " + exp + " as exp+"); + + case Regex.PLUS: + res = loop(path, exp); + break; + + case Regex.SEQ: + res = sequence(path, exp); + break; + + case Regex.ALT: + res = alt(path, exp); + break; + + case Regex.NOT: + res = not(path, exp); + break; + + case Regex.OPTION: + res = option(path, exp); + break; + + case Regex.REVERSE: + res = reverse(path, exp); + break; + + } + + res = rewrite(res); + return res; + } + + + /** + * Create a fresh new variable + */ + private Variable variable() { + return Variable.create(ROOT + varCount++); + } + + /** + * exp is a property label, generate a simple triple + */ + private Exp triple(Triple t, Expression exp) { + return Triple.create(t.getSubject(), exp.getConstant(), t.getObject()); + } + + + /** + * ?x ^ exp ?y + * -> + * ?y exp ?x + */ + private Exp reverse(Triple t, Expression exp) { + return ast.createPath(t.getArg(1), exp.getArg(0), t.getArg(0)); + } + + + /** + * e1 | e2 + */ + private Exp alt(Triple t, Expression exp) { + Exp e1 = ast.createPath(t.getArg(0), exp.getArg(0), t.getArg(1)); + Exp e2 = ast.createPath(t.getArg(0), exp.getArg(1), t.getArg(1)); + + BasicGraphPattern bgp1 = BasicGraphPattern.create(e1); + BasicGraphPattern bgp2 = BasicGraphPattern.create(e2); + + return Union.create(bgp1, bgp2); + } + + /** + * e1 / e2 + * Special cases: + * (1) ?x rdf:type/rdfs:subClassOf* ?c + * -> + * {?x rdf:type ?c} union { ?x rdf:type/rdfs:subClassOf+ ?c} + * (2) rdf:rest* / rdf:first -> rdf:first union rdf:rest+ / rdf:first + */ + private Exp sequence(Triple t, Expression exp) { + Variable variable = variable(); + Exp e1 = ast.createPath(t.getArg(0), exp.getArg(0), variable); + Exp e2 = ast.createPath(variable, exp.getArg(1), t.getArg(1)); + Exp res = BasicGraphPattern.create(e1, e2); + + if (exp.getArg(0).isStar() || exp.getArg(0).isOpt()) { + // use case: rdf:rest*/rdf:first + // add ?x rdf:first ?y + Exp e = ast.createPath(t.getArg(0), exp.getArg(1), t.getArg(1)); + BasicGraphPattern b = BasicGraphPattern.create(e); + res = Union.create(b, res); + } else if (exp.getArg(1).isStar() || exp.getArg(1).isOpt()) { + // use case: rdf:type/rdfs:subClassOf* + // add ?x rdf:type ?c + Exp e = ast.createPath(t.getArg(0), exp.getArg(0), t.getArg(1)); + BasicGraphPattern b = BasicGraphPattern.create(e); + res = Union.create(b, res); + } + + return res; + } + + + /** + * Expression loop is exp+ or exp* + * exp* rewritten as exp+ except in the case e1/e2* where it is correctly rewritten + */ + private Exp loop(Triple t, Expression loop) { + return loop(t.getSubject(), loop.getArg(0), t.getObject(), new ArrayList<>(), max); + } + + + /** + * rec create a path bgp of length n between s and o + * s exp(n) o = + * {s exp o} union {s exp vi . vi exp(n-1) o} + * generate filter to prevent loops on intermediate nodes (vi != vj) + */ + private Exp loop(Atom subject, Expression exp, Atom object, List list, int n) { + + Exp res = ast.createPath(subject, exp, object); + + if (n <= 1) { + return res; + } + + Variable variable = variable(); + Term diff = filter(variable, list); + list.add(variable); + + Exp e1 = ast.createPath(subject, exp, variable); + Exp e2 = loop(variable, exp, object, list, n - 1); + + BasicGraphPattern bgp = BasicGraphPattern.create(e1); + + if (diff != null) { + bgp.add(diff); + } + + bgp.add(e2); + + return Union.create(res, bgp); + } + + + /** + * Generate filter vi != vj + */ + Term filter(Variable variable, List list) { + Term res = null; + + for (Variable v : list) { + Term t = Term.create(NEQ, variable, v); + if (res == null) { + res = t; + } else { + res = Term.create(AND, res, t); + } + } + + return res; + } + + + Term filter(List list) { + Term res = null; + + for (int i = 0; i < list.size(); i++) { + Variable v1 = list.get(i); + + for (int j = i + 1; j < list.size(); j++) { + Variable v2 = list.get(j); + Term t = Term.create(NEQ, v1, v2); + if (res == null) { + res = t; + } else { + res = Term.create(AND, res, t); + } + } + } + + return res; + } + + + /** + * exp? -> exp + * See also: special treatment in sequence + */ + private Exp option(Triple t, Expression option) { + return ast.createPath(t.getSubject(), option.getArg(0), t.getObject()); + } + + + /** + * ! ex:p1 + * ! (ex:p1 | ex:p2) + * -> + * ?x ?p ?y . filter(?p != ex:p1) + */ + private Exp not(Triple t, Expression not) { + Expression exp = not.getArg(0); + Variable p = variable(); + Triple tt = Triple.create(t.getSubject(), p, t.getObject()); + BasicGraphPattern bgp = BasicGraphPattern.create(tt); + Expression f = null; + + if (exp.isConstant()) { + // ! p + f = Term.create(NEQ, p, exp); + } else { + // ! (p1 | p2) + + for (Expression ee : exp.getArgs()) { + Term g = Term.create(NEQ, p, ee); + f = and(f, g); + } + } + + bgp.add(f); + + return bgp; + } + + + private Expression and(Expression t1, Expression t2) { + if (t1 == null) return t2; + return Term.create(Term.SEAND, t1, t2); + } } diff --git a/src/main/java/fr/inria/corese/core/compiler/parser/Extension.java b/src/main/java/fr/inria/corese/core/compiler/parser/Extension.java index ce7618ea5..9e9687022 100644 --- a/src/main/java/fr/inria/corese/core/compiler/parser/Extension.java +++ b/src/main/java/fr/inria/corese/core/compiler/parser/Extension.java @@ -1,33 +1,32 @@ package fr.inria.corese.core.compiler.parser; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; import fr.inria.corese.core.kgram.core.Query; +import fr.inria.corese.core.sparql.triple.parser.ASTQuery; /** * SPARQL Extension in Pragma - * - * @author Olivier Corby, Edelweiss, INRIA 2011 * + * @author Olivier Corby, Edelweiss, INRIA 2011 */ public class Extension extends Pragma { - - Extension(Query q, ASTQuery a){ - super(q, a); - } - - public static Extension create(Query q){ - return new Extension(q, q.getAST()); - } - - public void parse(fr.inria.corese.core.sparql.triple.parser.Exp exp){ - if (exp.isQuery()){ - - } - else if (exp.isBGP()){ - for (fr.inria.corese.core.sparql.triple.parser.Exp ee : exp.getBody()){ - parse(ee); - } - } - } + + Extension(Query q, ASTQuery a) { + super(q, a); + } + + public static Extension create(Query q) { + return new Extension(q, q.getAST()); + } + + @Override + public void parse(fr.inria.corese.core.sparql.triple.parser.Exp exp) { + if (exp.isQuery()) { + + } else if (exp.isBGP()) { + for (fr.inria.corese.core.sparql.triple.parser.Exp ee : exp.getBody()) { + parse(ee); + } + } + } } diff --git a/src/main/java/fr/inria/corese/core/compiler/parser/FunctionCompiler.java b/src/main/java/fr/inria/corese/core/compiler/parser/FunctionCompiler.java index 9655c2fa2..4f9ce4825 100644 --- a/src/main/java/fr/inria/corese/core/compiler/parser/FunctionCompiler.java +++ b/src/main/java/fr/inria/corese/core/compiler/parser/FunctionCompiler.java @@ -1,6 +1,5 @@ package fr.inria.corese.core.compiler.parser; -import fr.inria.corese.core.compiler.eval.Interpreter; import fr.inria.corese.core.kgram.api.core.Expr; import fr.inria.corese.core.kgram.core.Query; import fr.inria.corese.core.sparql.datatype.DatatypeHierarchy; @@ -9,51 +8,71 @@ import fr.inria.corese.core.sparql.exceptions.UndefinedExpressionException; import fr.inria.corese.core.sparql.triple.function.script.Function; import fr.inria.corese.core.sparql.triple.function.term.TermEval; -import fr.inria.corese.core.sparql.triple.parser.ASTExtension; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.Access; +import fr.inria.corese.core.sparql.triple.parser.*; import fr.inria.corese.core.sparql.triple.parser.Access.Feature; import fr.inria.corese.core.sparql.triple.parser.Access.Level; -import fr.inria.corese.core.sparql.triple.parser.Expression; -import fr.inria.corese.core.sparql.triple.parser.Metadata; -import fr.inria.corese.core.sparql.triple.parser.NSManager; -import java.util.ArrayList; -import java.util.HashMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + /** + * @author Olivier Corby, INRIA I3S 2020 * @import * dereference URL at compile time - * LinkedFunction: + * LinkedFunction: * 1) ff:foo() undefined extension function: dereference URL at compile time - * 2) funcall (ff:foo) undefined extension function: dereference URL at runtime - * + * 2) funcall (ff:foo) undefined extension function: dereference URL at runtime + *

* LinkedFunction : Access.setLinkedFunction(true); * whereas @import is granted - * + *

* Accept/reject namespace for import and LinkedFunction: * AccessNamespace.define(namespace, true|false) - * - * @author Olivier Corby, INRIA I3S 2020 */ public class FunctionCompiler { - private static String NL = "\n"; - private static Logger logger = LoggerFactory.getLogger(FunctionCompiler.class); - private static HashMap loaded; - HashMap imported; - Transformer transformer; + private static final String NL = "\n"; + private static final Logger logger = LoggerFactory.getLogger(FunctionCompiler.class); + private static Map loaded; static { setLoaded(new HashMap<>()); } + HashMap imported; + Transformer transformer; + FunctionCompiler(Transformer t) { transformer = t; imported = new HashMap<>(); } + static void removeLinkedFunction() { + for (String name : getLoaded().values()) { + getExtension().removeNamespace(name); + } + getLoaded().clear(); + } + + public static void clean() { + getLoaded().clear(); + } + + public static Map getLoaded() { + return loaded; + } + + public static void setLoaded(Map aLoaded) { + loaded = aLoaded; + } + + static ASTExtension getExtension() { + return ASTExtension.getSingleton(); + } + void compile(Query q, ASTQuery ast) throws EngineException { imports(q, ast); compileFunction(q, ast); @@ -79,7 +98,7 @@ void define(Query q, ASTQuery ast) throws SafetyException { return; } if (Access.reject(Access.Feature.LDSCRIPT, ast.getLevel()) - || Access.reject(Access.Feature.DEFINE_FUNCTION, ast.getLevel())) { + || Access.reject(Access.Feature.DEFINE_FUNCTION, ast.getLevel())) { throw new SafetyException(TermEval.FUNCTION_DEFINITION_MESS); } @@ -107,38 +126,34 @@ void compile(Query q, ASTQuery ast, Function fun) throws EngineException { q.defineFunction(fun); } - // @import select where + // @import select where void imports(Query q, ASTQuery ast) throws EngineException { - if (ast.hasMetadata(Metadata.IMPORT)) { + if (ast.hasMetadata(Metadata.Type.IMPORT)) { basicImports(q, ast, ast.getMetadata()); } } - + void basicImports(Query q, ASTQuery ast, Metadata m) throws EngineException { - if (m.hasMetadata(Metadata.IMPORT)) { - for (String path : m.getValues(Metadata.IMPORT)) { + if (m.hasMetadata(Metadata.Type.IMPORT)) { + for (String path : m.getValues(Metadata.Type.IMPORT)) { imports(q, ast, path); } } } - + void imports(Query q, ASTQuery ast, String path) throws EngineException { if (Access.accept(Feature.IMPORT_FUNCTION, ast.getLevel(), path)) { basicImports(q, ast, path); - } - else { + } else { throw new SafetyException(TermEval.IMPORT_MESS, path); } } - - - - + /** * After compiling query, there are undefined functions * If authorized, load LinkedFunction * If still undefined, throw Undefined Exception - */ + */ public void undefinedFunction(Query q, ASTQuery ast, Level level) throws EngineException { ArrayList list = new ArrayList<>(); @@ -163,18 +178,17 @@ public void undefinedFunction(Query q, ASTQuery ast, Level level) throws EngineE sb.append(exp.toString()).append(NL); } if (Access.UNDEFINED_EXPRESSION_EXCEPTION) { - throw new UndefinedExpressionException(TermEval.UNDEFINED_EXPRESSION_MESS + NL + sb.toString()); - } - else { + throw new UndefinedExpressionException(TermEval.UNDEFINED_EXPRESSION_MESS + NL + sb); + } else { logger.error(TermEval.UNDEFINED_EXPRESSION_MESS); logger.error(sb.toString()); } } - + boolean acceptLinkedFunction(Level level, String ns) { return Access.accept(Feature.LINKED_FUNCTION, level, ns); } - + boolean getLinkedFunctionBasic(ASTQuery ast, Expression exp) throws EngineException { boolean b = getLinkedFunctionBasic(exp.getLabel(), ast.getLevel()); if (b) { @@ -182,14 +196,16 @@ boolean getLinkedFunctionBasic(ASTQuery ast, Expression exp) throws EngineExcept } return false; } - + boolean getLinkedFunction(String label) throws EngineException { - if (acceptLinkedFunction(Level.USER_DEFAULT, label)) { + if (acceptLinkedFunction(Level.USER_DEFAULT, label)) { return getLinkedFunctionBasic(label); } return false; } - + + // TODO: check isSystem() because it is exported + // @import void basicImports(Query q, ASTQuery ast, String path) throws EngineException { if (imported.containsKey(path)) { @@ -199,17 +215,17 @@ void basicImports(Query q, ASTQuery ast, String path) throws EngineException { logger.info("Import: " + path); } imported.put(path, path); - ASTQuery ast2 = transformer.getSPARQLEngine().parse(path, ast.getLevel()); + ASTQuery ast2 = transformer.getSPARQLEngine().parse(path, ast.getLevel()); compile(q, ast, ast2.getDefine()); define(ast, ast2.getDefine(), q); compile(q, ast, ast2.getDefineLambda()); define(ast, ast2.getDefineLambda(), q); } - + boolean getLinkedFunctionBasic(String label) throws EngineException { return getLinkedFunctionBasic(label, Level.USER_DEFAULT); } - + boolean getLinkedFunctionBasic(String label, Level level) throws EngineException { String path = NSManager.namespace(label); if (getLoaded().containsKey(path)) { @@ -219,32 +235,22 @@ boolean getLinkedFunctionBasic(String label, Level level) throws EngineException getLoaded().put(path, path); Query imp = transformer.getSPARQLEngine().parseQuery(path, level); if (imp != null && imp.hasDefinition()) { - // loaded functions are exported in Interpreter + // loaded functions are exported in Interpreter definePublic(imp.getExtension(), imp); return true; } return false; } - static void removeLinkedFunction() { - for (String name : getLoaded().values()) { - getExtension().removeNamespace(name); - } - getLoaded().clear(); - } - /** * Define function into Extension Export into Interpreter */ void define(ASTQuery ast, ASTExtension aext, Query q) { ASTExtension ext = q.getCreateExtension(); DatatypeHierarchy dh = new DatatypeHierarchy(); - if (q.isDebug()) { - dh.setDebug(true); - } ext.setHierarchy(dh); - boolean pub = ast.hasMetadata(Metadata.PUBLIC); - for (Function exp : aext.getFunList()) { + boolean pub = ast.hasMetadata(Metadata.Type.PUBLIC); + for (Function exp : aext.getFunList()) { ext.define(exp); if (pub || exp.isPublic()) { definePublic(exp, q); @@ -254,7 +260,6 @@ void define(ASTQuery ast, ASTExtension aext, Query q) { } } - // TODO: check isSystem() because it is exported /** * ext is loaded function definitions define them as public * @@ -269,7 +274,7 @@ void definePublic(ASTExtension ext, Query q) { * isDefine = true means export to Interpreter Use case: Transformation * st:profile does not export to Interpreter hence it uses isDefine = false */ - public void definePublic(ASTExtension ext, Query q, boolean isDefine) { + public void definePublic(ASTExtension ext, Query q, boolean isDefine) { for (Expr exp : ext.getFunctionList()) { Function e = (Function) exp; definePublic(e, q, isDefine); @@ -289,28 +294,10 @@ void definePublic(Function fun, Query q, boolean isDefine) { } fun.setPublic(true); if (fun.isSystem()) { - // export function with exists {} + // export function with exists {} fun.getTerm().setPattern(q); } } - - public static void clean() { - getLoaded().clear();; - } - - public static HashMap getLoaded() { - return loaded; - } - - public static void setLoaded(HashMap aLoaded) { - loaded = aLoaded; - } - - - static ASTExtension getExtension() { - //return Interpreter.getExtension(); - return ASTExtension.getSingleton(); - } } diff --git a/src/main/java/fr/inria/corese/core/compiler/parser/NodeImpl.java b/src/main/java/fr/inria/corese/core/compiler/parser/NodeImpl.java index d45a25386..bd719d183 100755 --- a/src/main/java/fr/inria/corese/core/compiler/parser/NodeImpl.java +++ b/src/main/java/fr/inria/corese/core/compiler/parser/NodeImpl.java @@ -7,7 +7,7 @@ public class NodeImpl extends fr.inria.corese.core.kgram.tool.NodeImpl { - + public NodeImpl(Atom at) { super(at); } diff --git a/src/main/java/fr/inria/corese/core/compiler/parser/Pragma.java b/src/main/java/fr/inria/corese/core/compiler/parser/Pragma.java index bbddfd444..b532bfd8c 100755 --- a/src/main/java/fr/inria/corese/core/compiler/parser/Pragma.java +++ b/src/main/java/fr/inria/corese/core/compiler/parser/Pragma.java @@ -1,38 +1,27 @@ package fr.inria.corese.core.compiler.parser; -import java.lang.reflect.InvocationTargetException; - -import fr.inria.corese.core.sparql.api.IDatatype; -import fr.inria.corese.core.sparql.triple.cst.RDFS; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.Atom; -import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; -import fr.inria.corese.core.sparql.triple.parser.Constant; -import fr.inria.corese.core.sparql.triple.parser.Expression; -import fr.inria.corese.core.sparql.triple.parser.RDFList; -import fr.inria.corese.core.sparql.triple.parser.Source; -import fr.inria.corese.core.sparql.triple.parser.Triple; import fr.inria.corese.core.kgram.api.core.ExpType; import fr.inria.corese.core.kgram.api.query.Matcher; import fr.inria.corese.core.kgram.core.Eval; import fr.inria.corese.core.kgram.core.Query; import fr.inria.corese.core.kgram.event.EvalListener; import fr.inria.corese.core.kgram.event.EventListener; -import fr.inria.corese.core.kgram.tool.Message; +import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.exceptions.EngineException; +import fr.inria.corese.core.sparql.triple.cst.RDFS; +import fr.inria.corese.core.sparql.triple.parser.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.lang.reflect.InvocationTargetException; + /** * Pragma processor * * @author Olivier Corby, Edelweiss, INRIA 2010 - * */ public class Pragma { - private static Logger logger = LoggerFactory.getLogger(Pragma.class); - public static final String KG = ExpType.KGRAM; public static final String STL = ExpType.STL; // subject @@ -44,7 +33,6 @@ public class Pragma { public static final String PRAGMA = KG + "pragma"; public static final String GRAPH = KG + "graph"; public static final String APPROXIMATE = KG + "approximate"; - // kgram public static final String OPTIM = KG + "optimize"; public static final String TEST = KG + "test"; @@ -85,9 +73,7 @@ public class Pragma { public static final String TURTLE = KG + "turtle"; public static final String PLAN = KG + "plan"; public static final String STD = KG + "std"; - public static final String HELP = KG + "help"; - public static final String ALGORITHM = KG + "algorithm"; public static final String PRIORITY_ALGORITHM = KG + "priority_a"; public static final String STRATEGY = KG + "strategy"; @@ -97,7 +83,6 @@ public class Pragma { public static final String POS_TAGGER = KG + "pos_tagger"; public static final String STRING_METRIC = KG + "string_metric"; public static final String THRESHOLD = KG + "threshold"; - // match static final String MODE = KG + "mode"; // match mode @@ -107,7 +92,7 @@ public class Pragma { static final String SUBSUME = "subsume"; static final String INFERENCE = "inference"; static final String MIX = "mix"; - + private static final Logger logger = LoggerFactory.getLogger(Pragma.class); protected Eval kgram; protected Query query; protected Transformer transform; @@ -141,10 +126,6 @@ public void parse(Atom g, fr.inria.corese.core.sparql.triple.parser.Exp exp) { for (fr.inria.corese.core.sparql.triple.parser.Exp pragma : exp.getBody()) { - if (query != null && query.isDebug()) { - Message.log(Message.PRAGMA, pragma); - } - if (pragma.isFilter()) { } else if (pragma.isTriple()) { Triple t = pragma.getTriple(); @@ -167,12 +148,10 @@ public void list(Atom g, RDFList list) { } public void compile() throws EngineException { - //System.out.println("** Compile: " + ast.getPragma()); compile(null, ast.getPragma()); } public void compile(BasicGraphPattern p) throws EngineException { - //System.out.println("** Compile: " + ast.getPragma()); compile(null, p); } @@ -180,9 +159,6 @@ public void compile(Atom g, fr.inria.corese.core.sparql.triple.parser.Exp exp) t for (fr.inria.corese.core.sparql.triple.parser.Exp pragma : exp.getBody()) { - if (ast.isDebug()) { - Message.log(Message.PRAGMA, pragma); - } if (pragma.isFilter()) { compile(pragma.getFilter()); } else if (pragma.isTriple()) { @@ -208,7 +184,6 @@ public void compile(Atom g, Triple t, fr.inria.corese.core.sparql.triple.parser. if (subject.equals(PATH)) { if (property.equals(EXPAND)) { - Constant cst = t.getObject().getConstant(); if (odt.isNumber()) { transform.add(ExpandPath.create(odt.intValue())); } else { @@ -224,7 +199,7 @@ public void compile(Atom g, Triple t, fr.inria.corese.core.sparql.triple.parser. if (t.getObject().isBlankNode()) { // kg:kgram kg:relax (foaf:type) RDFList list = getList(t.getObject(), pragma); - if (list!=null) ast.setRelax(list.getList()); + if (list != null) ast.setRelax(list.getList()); } else { ast.addRelax(t.getObject()); } @@ -252,8 +227,7 @@ public void compile(Atom g, Triple t, fr.inria.corese.core.sparql.triple.parser. } String help() { - String query - = "select where {}\n" + return "select where {}\n" + "pragma {\n" + "kg:kgram kg:debug true # debug mode \n" + "kg:kgram kg:list true # list group result \n" @@ -268,8 +242,6 @@ String help() { + "kg:path kg:loop false # path without loop \n" + "kg:query kg:display true # pprint query AST \n" + "}"; - - return query; } public void triple(Atom g, Triple t, fr.inria.corese.core.sparql.triple.parser.Exp pragma) { @@ -277,93 +249,107 @@ public void triple(Atom g, Triple t, fr.inria.corese.core.sparql.triple.parser.E String subject = t.getSubject().getLabel(); String property = t.getProperty().getLabel(); String object = t.getObject().getLabel(); - //if (object == null) object = t.getObject().getName(); - - if (subject.equals(SELF)) { - if (property.equals(TEST)) { - query.setTest(value(object)); - } else if (property.equals(OPTIM)) { - query.setOptimize(value(object)); - } else if (property.equals(DEBUG)) { - query.setDebug(value(object)); - } else if (property.equals(SORT)) { - query.setSort(value(object)); - } else if (property.equals(LISTEN) && value(object)) { - kgram.addEventListener(EvalListener.create()); - } else if (property.equals(LIST)) { - query.setListGroup(value(object)); - } else if (property.equals(DETAIL)) { - query.setDetail(value(object)); - } - } else if (subject.equals(MATCH)) { - if (property.equals(MODE)) { - int mode = getMode(object); - query.setMode(mode); - } else if (property.equals(RDFS.RDFTYPE)) { - // kg:match rdf:type - Matcher match = (Matcher) create(object); - if (match != null) { - kgram.setMatcher(match); + + switch (subject) { + case SELF: + if (property.equals(TEST)) { + query.setTest(value(object)); + } else if (property.equals(OPTIM)) { + query.setOptimize(value(object)); + } else if (property.equals(SORT)) { + query.setSort(value(object)); + } else if (property.equals(LISTEN) && value(object)) { + kgram.addEventListener(EvalListener.create()); + } else if (property.equals(LIST)) { + query.setListGroup(value(object)); + } else if (property.equals(DETAIL)) { + query.setDetail(value(object)); } - } - } else if (subject.equals(LISTEN)) { - if (property.equals(RDFS.RDFTYPE)) { - // kg:listen rdf:type - EventListener el = (EventListener) create(object); - if (el != null) { - kgram.addEventListener(el); + break; + case MATCH: + if (property.equals(MODE)) { + int mode = getMode(object); + query.setMode(mode); + } else if (property.equals(RDFS.RDFTYPE)) { + // kg:match rdf:type + Matcher match = (Matcher) create(object); + if (match != null) { + kgram.setMatcher(match); + } } - } - } else if (subject.equals(PATH)) { - if (property.equals(LIST)) { - query.setListPath(value(object)); - } - if (property.equals(TYPE)) { - query.setPathType(value(object)); - } else if (property.equals(STORE)) { - query.setStorePath(value(object)); - } else if (property.equals(CACHE)) { - query.setCachePath(value(object)); - } else if (property.equals(COUNT)) { - query.setCountPath(value(object)); - } else if (property.equals(LOOP)) { - query.setCheckLoop(!value(object)); - } - } else if (subject.equals(QUERY)) { - if (property.equals(DISPLAY)) { - query.addInfo("AST:\n", ast); - } else if (property.equals(MATCH)) { - query.setMatchBlank(value(object)); - } - } else if (subject.equals(PRAGMA)) { - if (property.equals(HELP) && value(object)) { - query.addInfo(help(), null); - } - } else if (subject.equals(SERVICE)) { - if (property.equals(SLICE)) { - int slice = t.getObject().getDatatypeValue().intValue(); - query.setSlice(slice); - } else if (property.equals(TIMEOUT)) { - Integer value = t.getObject().getDatatypeValue().intValue(); - query.setPragma(TIMEOUT, value); - } - } else if (subject.equals(DISPLAY) || subject.equals(TEMPLATE)) { - if (property.equals(TEMPLATE)) { - query.setPragma(TEMPLATE, object); - } else if (property.equals(MODE)) { - if (object.equals(TURTLE)) { - query.setPragma(TURTLE, TURTLE); + break; + case LISTEN: + if (property.equals(RDFS.RDFTYPE)) { + // kg:listen rdf:type + EventListener el = (EventListener) create(object); + if (el != null) { + kgram.addEventListener(el); + } } - } else if (property.equals(GRAPH)) { - query.setPragma(GRAPH, true); - } + break; + case PATH: + if (property.equals(LIST)) { + query.setListPath(value(object)); + } + switch (property) { + case TYPE: + query.setPathType(value(object)); + break; + case STORE: + query.setStorePath(value(object)); + break; + case CACHE: + query.setCachePath(value(object)); + break; + case COUNT: + query.setCountPath(value(object)); + break; + case LOOP: + query.setCheckLoop(!value(object)); + break; + } + break; + case QUERY: + if (property.equals(DISPLAY)) { + query.addInfo("AST:\n", ast); + } else if (property.equals(MATCH)) { + query.setMatchBlank(value(object)); + } + break; + case PRAGMA: + if (property.equals(HELP) && value(object)) { + query.addInfo(help(), null); + } + break; + case SERVICE: + if (property.equals(SLICE)) { + int slice = t.getObject().getDatatypeValue().intValue(); + query.setSlice(slice); + } else if (property.equals(TIMEOUT)) { + Integer value = t.getObject().getDatatypeValue().intValue(); + query.setPragma(TIMEOUT, value); + } + break; + case DISPLAY: + case TEMPLATE: + switch (property) { + case TEMPLATE: + query.setPragma(TEMPLATE, object); + break; + case MODE: + if (object.equals(TURTLE)) { + query.setPragma(TURTLE, TURTLE); + } + break; + case GRAPH: + query.setPragma(GRAPH, true); + break; + } + break; } } - /** - * - */ RDFList getList(Atom head, fr.inria.corese.core.sparql.triple.parser.Exp pragma) { for (fr.inria.corese.core.sparql.triple.parser.Exp exp : pragma.getBody()) { if (exp.isRDFList()) { @@ -405,29 +391,11 @@ int getMode(String mode) { Object create(String name) { try { - //EventListener el ; - //= (EventListener) Class.forName(object).newInstance(); Class cname = Class.forName(name); Object object = cname.getMethod("create").invoke(cname); return object; - } catch (IllegalAccessException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (ClassNotFoundException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (SecurityException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (NoSuchMethodException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (IllegalArgumentException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InvocationTargetException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + } catch (IllegalAccessException | ClassNotFoundException | SecurityException | NoSuchMethodException | IllegalArgumentException | InvocationTargetException e) { + logger.error("", e); } return null; } diff --git a/src/main/java/fr/inria/corese/core/compiler/parser/QueryProfile.java b/src/main/java/fr/inria/corese/core/compiler/parser/QueryProfile.java index 802caa61b..9b32056d5 100644 --- a/src/main/java/fr/inria/corese/core/compiler/parser/QueryProfile.java +++ b/src/main/java/fr/inria/corese/core/compiler/parser/QueryProfile.java @@ -7,34 +7,33 @@ /** * Detect Query Pattern, that may be optimized - * - * @author Olivier Corby, Wimmics Inria I3S, 2013 * + * @author Olivier Corby, Wimmics Inria I3S, 2013 */ public class QueryProfile { - + Query query; - - QueryProfile(Query q){ + + QueryProfile(Query q) { query = q; } - - void profile(){ + + void profile() { count(query); } - + // select (count(*) as ?c) where {} - void count(Query q){ + void count(Query q) { if (q.getSelectFun().size() == 1 && q.getGroupBy().isEmpty() && q.getLimit() == Integer.MAX_VALUE - && ! q.isTemplate()){ + && !q.isTemplate()) { Exp exp = q.getSelectFun().get(0); Filter f = exp.getFilter(); - if (f != null + if (f != null && f.getExp().oper() == ExprType.COUNT - && ! f.getExp().isDistinct() - && f.getExp().getExpList().isEmpty()){ + && !f.getExp().isDistinct() + && f.getExp().getExpList().isEmpty()) { q.setQueryProfile(Query.COUNT_PROFILE); } } diff --git a/src/main/java/fr/inria/corese/core/compiler/parser/Transformer.java b/src/main/java/fr/inria/corese/core/compiler/parser/Transformer.java index 61b441c8d..2c9dda760 100755 --- a/src/main/java/fr/inria/corese/core/compiler/parser/Transformer.java +++ b/src/main/java/fr/inria/corese/core/compiler/parser/Transformer.java @@ -1,79 +1,66 @@ package fr.inria.corese.core.compiler.parser; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import fr.inria.corese.core.sparql.triple.cst.RDFS; -import fr.inria.corese.core.sparql.triple.parser.*; import fr.inria.corese.core.compiler.api.QueryVisitor; -import fr.inria.corese.core.sparql.triple.parser.Dataset; -import fr.inria.corese.core.sparql.triple.parser.visitor.ASTWalker; -import fr.inria.corese.core.sparql.compiler.java.JavaCompiler; -import fr.inria.corese.core.kgram.api.core.*; -import static fr.inria.corese.core.kgram.api.core.ExpType.NODE; -import fr.inria.corese.core.kgram.core.Exp; -import fr.inria.corese.core.kgram.core.Mapping; -import fr.inria.corese.core.kgram.core.Mappings; -import fr.inria.corese.core.kgram.core.Query; -import fr.inria.corese.core.kgram.core.Sorter; -import fr.inria.corese.core.compiler.federate.FederateVisitor; import fr.inria.corese.core.compiler.eval.QuerySolver; -import static fr.inria.corese.core.compiler.eval.QuerySolver.SPARQL_COMPLIANT_DEFAULT; import fr.inria.corese.core.compiler.eval.QuerySolverVisitor; +import fr.inria.corese.core.compiler.federate.FederateVisitor; import fr.inria.corese.core.compiler.visitor.MetadataVisitor; +import fr.inria.corese.core.kgram.api.core.*; +import fr.inria.corese.core.kgram.core.Exp; +import fr.inria.corese.core.kgram.core.Query; +import fr.inria.corese.core.kgram.core.*; import fr.inria.corese.core.sparql.api.IDatatype; +import fr.inria.corese.core.sparql.compiler.java.JavaCompiler; import fr.inria.corese.core.sparql.exceptions.EngineException; import fr.inria.corese.core.sparql.exceptions.SafetyException; +import fr.inria.corese.core.sparql.triple.cst.RDFS; +import fr.inria.corese.core.sparql.triple.parser.*; import fr.inria.corese.core.sparql.triple.parser.visitor.ASTParser; +import fr.inria.corese.core.sparql.triple.parser.visitor.ASTWalker; import fr.inria.corese.core.sparql.triple.parser.visitor.Record; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; + +import static fr.inria.corese.core.compiler.eval.QuerySolver.SPARQL_COMPLIANT_DEFAULT; /** * Compiler of SPARQL AST to KGRAM Exp Query Use Corese.Core.Sparql parser Use an * abstract compiler to generate target edge/node/filter implementations - * + *

* sub query compiled as distinct edge/node to avoid inappropriate type * inference on nodes, except variable nodes which are shared * * @author Olivier Corby, Edelweiss, INRIA 2009 - * */ public class Transformer implements ExpType { - - private static Logger logger = LoggerFactory.getLogger(Transformer.class); - private static final String LINKED_DATA_PATH_VISITOR = - "fr.inria.corese.core.visitor.ldpath.LinkedDataPath"; + public static final String NL = "\n"; public static final String ROOT = "?_kgram_"; public static final String THIS = "?this"; + public static final String FEDERATE = NSManager.KGRAM + "federate"; + private static final Logger logger = LoggerFactory.getLogger(Transformer.class); + private static final String LINKED_DATA_PATH_VISITOR = + "fr.inria.corese.core.visitor.ldpath.LinkedDataPath"; private static final String EXTENSION = Processor.KGEXTENSION; private static final String EXT_NAMESPACE = NSManager.KGEXT; private static final String EXT_NAMESPACE_QUERY = NSManager.KGEXTCONS; - public static final String FEDERATE = NSManager.KGRAM + "federate"; + + static { + create().init(); + } + int count = 0; CompilerFactory fac; - // ldscript function compiler - private FunctionCompiler functionCompiler; // edge and node compiler, see CompilerKgram Compiler compiler; - // QuerySolver for federated compiler - private QuerySolver sparql; - // Visitor tune compiling - // @metadata: uncertainty, @ldpath: ldpath - // @visitor className: user defined visitor - private List visit; // Refine std query sorter // corese core SorterImpl take cardinality into account Sorter sort; - // use case: reuse federated visitor source selection - private Mappings mappings; - private ASTQuery ast; // Compiler to generate type checker Checker check; // table of type checker (check class/property definition) @@ -81,21 +68,33 @@ public class Transformer implements ExpType { HashMap table; // list of nested subquery ArrayList subQueryList; - int ncount = 0, rcount = 0; + int ncount = 0; + int rcount = 0; boolean //fail = false, - isSPARQLCompliant = SPARQL_COMPLIANT_DEFAULT, - isSPARQL1 = true; + isSPARQLCompliant = SPARQL_COMPLIANT_DEFAULT; + boolean isSPARQL1 = true; + // deprecated + String namespaces; + // ldscript function compiler + private FunctionCompiler functionCompiler; + // QuerySolver for federated compiler + private QuerySolver sparql; + // Visitor tune compiling + // @metadata: uncertainty, @ldpath: ldpath + // @visitor className: user defined visitor + private List visit; + // use case: reuse federated visitor source selection + private Mappings mappings; + private ASTQuery ast; // bind(exp as var) generated by compiler - // not used + // not used private boolean isUseBind = false; private boolean isGenerateMain = true; private boolean isBGP = false; private boolean pathType = false; - // draft alternative interpreter not used + // draft alternative interpreter not used private boolean algebra = false; // deprecated - String namespaces; - // deprecated private String base; // user defined from [named] dataset private Dataset dataset; @@ -106,10 +105,6 @@ public class Transformer implements ExpType { private int planner = Query.STD_PLAN; private int number = 0; - static { - create().init(); - } - Transformer() { table = new HashMap<>(); fac = new CompilerFacKgram(); @@ -132,6 +127,10 @@ public static Transformer create() { return new Transformer(); } + public static void removeLinkedFunction() { + FunctionCompiler.removeLinkedFunction(); + } + /** * Predefined extension functions for SPARQL functions (see Processor) * uri() -> rq:uri @@ -152,14 +151,10 @@ public void set(Dataset ds) { } } - public void setMetadata(Metadata m) { - metadata = m; - } - public void set(Sorter s) { sort = s; } - + List getCreateVisitorList() { if (getVisitorList() == null) { setVisitorList(new ArrayList<>()); @@ -167,7 +162,7 @@ List getCreateVisitorList() { return getVisitorList(); } - public void add(QueryVisitor v) { + public void add(QueryVisitor v) { getCreateVisitorList().add(v); } @@ -184,18 +179,17 @@ public Query transform(String squery) throws EngineException { */ public Query transform(String squery, boolean isRule) throws EngineException { setAST(parse(squery, isRule)); - Query q = transform(getAST()); - return q; + return transform(getAST()); } - + /** * SPARQL parser * parse sparql query and return AST without compiling - */ + */ public ASTQuery parse(String squery) throws EngineException { return parse(squery, false); } - + public ASTQuery parse(String squery, boolean isRule) throws EngineException { ASTQuery ast = ASTQuery.create(squery); ast.setRule(isRule); @@ -208,12 +202,12 @@ public ASTQuery parse(String squery, boolean isRule) throws EngineException { } // isLoad == true : parse Turtle document as sparql where query pattern // -> rdf graph considered as query graph - boolean isLoad = getDataset()!=null && getDataset().isLoad(); + boolean isLoad = getDataset() != null && getDataset().isLoad(); ParserSparql1.create(ast).setLoad(isLoad).parse(); - if (getDataset()!=null && getDataset().getMetadata()!=null) { + if (getDataset() != null && getDataset().getMetadata() != null) { ast.addMetadata(getDataset().getMetadata()); } - if (getMetadata()!=null) { + if (getMetadata() != null) { ast.addMetadata(getMetadata()); } ASTParser walk = new ASTParser(ast).configure(); @@ -221,8 +215,8 @@ public ASTQuery parse(String squery, boolean isRule) throws EngineException { ast.process(walk); return ast; } - - String getDefaultBase() { + + String getDefaultBase() { if (getDataset() != null && getDataset().getBase() != null) { return getDataset().getBase(); } @@ -269,7 +263,7 @@ public Query transform(ASTQuery ast) throws EngineException { federate(ast); // visitor such as uncertainty, ldpath or user defined visit(ast); - + template(ast); Query q = compile(ast); @@ -282,31 +276,26 @@ public Query transform(ASTQuery ast) throws EngineException { if (ast.getContext() != null) { q.setContext(ast.getContext()); } -// if (ast.getTemplateVisitor() != null) { -// // visitor comes from ast defaultDataset -// // Workflow Data record visitor in Dataset -// // query(q, ds) -> ast.setDefaultDataset(ds) -// q.setTemplateVisitor(ast.getTemplateVisitor()); -// } + preprocessTemplateValues(q, ast); // compile select filters - q = transform(q, ast); - getFunctionCompiler().compile(q, ast); - error(q, ast); + q = transform(q, ast); + getFunctionCompiler().compile(q, ast); + error(q, ast); metadata(ast, q); // safety exception validate(ast, q); - + return q; } - + /** * Check static safety exception */ void validate(ASTQuery ast, Query q) throws EngineException { ASTWalker walker = new ASTWalker(ast); ast.process(walker); - + if (!walker.getRecord().isEmpty()) { StringBuilder sb = new StringBuilder(); for (Record rec : walker.getRecord()) { @@ -315,12 +304,12 @@ void validate(ASTQuery ast, Query q) throws EngineException { throw new SafetyException(sb.toString()); } } - - + + public Query transform(Query q, ASTQuery ast) throws EngineException { compiler.setAST(ast); - if (ast.isConstruct() || ast.isDescribe() || ast.isInsert() ) { + if (ast.isConstruct() || ast.isDescribe() || ast.isInsert()) { construct(q, ast); } @@ -345,9 +334,6 @@ public Query transform(Query q, ASTQuery ast) throws EngineException { } q.setSort(ast.isSorted()); - if (ast.isDebug()) { - q.setDebug(ast.isDebug()); - } q.setCheck(ast.isCheck()); q.setRelax(ast.isMore()); q.setPlanProfile(getPlanProfile()); @@ -359,7 +345,7 @@ public Query transform(Query q, ASTQuery ast) throws EngineException { filters(q); relax(q); new QueryProfile(q).profile(); - + q.setSubQueryList(subQueryList); if (getVisitorList() != null) { for (QueryVisitor v : getVisitorList()) { @@ -369,46 +355,43 @@ public Query transform(Query q, ASTQuery ast) throws EngineException { return q; } - - + + void metadata(ASTQuery ast, Query q) { Metadata meta = ast.getMetadata(); if (meta != null) { - if (ast.hasMetadata(Metadata.TRACE)) { - System.out.println(ast.toString()); - } - if (ast.hasMetadata(Metadata.TEST)) { + if (ast.hasMetadata(Metadata.Type.TEST)) { q.setTest(true); } - if (ast.hasMetadata(Metadata.PARALLEL)) { + if (ast.hasMetadata(Metadata.Type.PARALLEL)) { q.setParallel(true); } - if (ast.hasMetadata(Metadata.SEQUENCE)) { + if (ast.hasMetadata(Metadata.Type.SEQUENCE)) { q.setParallel(false); } - if (ast.hasMetadata(Metadata.UPDATE)) { + if (ast.hasMetadata(Metadata.Type.UPDATE)) { q.setDetail(true); } - if (meta.hasMetadata(Metadata.UNLOCK) || - (meta.getDatatypeValue(Metadata.LOCK) != null - && !meta.getDatatypeValue(Metadata.LOCK).booleanValue())) { + if (meta.hasMetadata(Metadata.Type.UNLOCK) || + (meta.getDatatypeValue(Metadata.Type.LOCK) != null + && !meta.getDatatypeValue(Metadata.Type.LOCK).booleanValue())) { q.setLock(false); } - if (ast.hasMetadata(Metadata.PATH_TYPE)) { + if (ast.hasMetadata(Metadata.Type.PATH_TYPE)) { q.setPathType(true); } } // @public @update event function ... if (QuerySolver.isVisitorable() - && ASTExtension.getSingleton().getMetadata(QuerySolverVisitor.UPDATE, QuerySolverVisitor.UPDATE_ARITY) != null) { + && ASTExtension.getSingleton().getMetadata(QuerySolverVisitor.UPDATE, QuerySolverVisitor.UPDATE_ARITY) != null) { q.setDetail(true); - } + } } - + @Deprecated - void toJava(ASTQuery ast) throws EngineException{ - if (ast.hasMetadata(Metadata.COMPILE)){ - String name = ast.getMetadata().getValue(Metadata.COMPILE); + void toJava(ASTQuery ast) throws EngineException { + if (ast.hasMetadata(Metadata.Type.COMPILE)) { + String name = ast.getMetadata().getValue(Metadata.Type.COMPILE); JavaCompiler jc = new JavaCompiler(name); try { jc.compile(ast); @@ -418,7 +401,7 @@ void toJava(ASTQuery ast) throws EngineException{ } } } - + void visit(ASTQuery ast) { visitor(ast); if (getVisitorList() != null) { @@ -431,26 +414,25 @@ void visit(ASTQuery ast) { } } } - + /** * Metadata => Visitor */ void visitor(ASTQuery ast) { - if (ast.hasMetadata(Metadata.METADATA)){ + if (ast.hasMetadata(Metadata.Type.METADATA)) { add(new MetadataVisitor()); } - if (ast.hasMetadata(Metadata.LDPATH)) { - ast.getMetadata().add(Metadata.VISITOR, LINKED_DATA_PATH_VISITOR); + if (ast.hasMetadata(Metadata.Type.LDPATH)) { + ast.getMetadata().add(Metadata.Type.VISITOR, LINKED_DATA_PATH_VISITOR); } - if (ast.hasMetadata(Metadata.VISITOR)) { - for (String name : ast.getMetadata().getValues(Metadata.VISITOR)) { + if (ast.hasMetadata(Metadata.Type.VISITOR)) { + for (String name : ast.getMetadata().getValues(Metadata.Type.VISITOR)) { try { Class visClass = Class.forName(name); Object obj = visClass.getDeclaredConstructor().newInstance(); if (obj instanceof QueryVisitor) { add((QueryVisitor) obj); - } - else { + } else { logger.error("Undefined QueryVisitor: " + name); } } catch (Exception ex) { @@ -459,19 +441,20 @@ void visitor(ASTQuery ast) { } } } - + /** - * use case: - * @federate - * @federate + * use case: + * + * @federate + * @federate * select * where { } * Rewrite every triple t as: service { t } */ void federate(ASTQuery ast) { - if (ast.hasMetadata(Metadata.FEDERATION) && !ast.hasMetadata(Metadata.FEDERATE)) { + if (ast.hasMetadata(Metadata.Type.FEDERATION) && !ast.hasMetadata(Metadata.Type.FEDERATE)) { add(new FederateVisitor(getSPARQLEngine()).setMappings(getMappings())); } - + if (ast.getServiceList() != null && ast.getServiceList().size() > 1) { ast.defService((String) null); add(new FederateVisitor(getSPARQLEngine()).setMappings(getMappings())); @@ -487,7 +470,7 @@ void annotate(ASTQuery ast) { } annotateLocal(ast); } - + void context(ASTQuery ast) { if (ast.getContext().hasValue(Context.STL_METADATA)) { for (IDatatype meta : ast.getContext().get(Context.STL_METADATA).getValues()) { @@ -495,21 +478,21 @@ void context(ASTQuery ast) { } } } - - void annotateLocal(ASTQuery ast){ - if (ast.hasMetadata(Metadata.ALGEBRA)){ + + void annotateLocal(ASTQuery ast) { + if (ast.hasMetadata(Metadata.Type.ALGEBRA)) { // @algebra use case with @db setBGP(true); setAlgebra(true); } - if (ast.hasMetadata(Metadata.PATH_TYPE)){ + if (ast.hasMetadata(Metadata.Type.PATH_TYPE)) { setPathType(true); } } /** - * when exist function xt:main(){} - * -> + * when exist function xt:main(){} + * -> * generate select (xt:main() as ?main) */ void generateMain() { @@ -554,8 +537,8 @@ boolean bound(Values values, Triple t) { if (!t.getArg(1).isVariable()) { return false; } - for (Variable var : values.getVarList()) { - if (var.equals(t.getArg(1))) { + for (Variable variable : values.getVarList()) { + if (variable.equals(t.getArg(1))) { return true; } } @@ -573,11 +556,11 @@ private void preprocessTemplateValues(Query q, ASTQuery ast) throws EngineExcept } ast.getTemplateGroup().compile(ast); - q.setTemplateGroup(Exp.create(FILTER, ast.getTemplateGroup())); + q.setTemplateGroup(Exp.create(Type.FILTER, ast.getTemplateGroup())); Term nl = Term.function(Processor.STL_NL); nl.compile(ast); - q.setTemplateNL(Exp.create(FILTER, nl)); + q.setTemplateNL(Exp.create(Type.FILTER, nl)); for (Variable var : ast.getArgList()) { Node node = compiler.createNode(var); @@ -586,7 +569,7 @@ private void preprocessTemplateValues(Query q, ASTQuery ast) throws EngineExcept q.setPriority(ast.getPriority()); } } - + void error(Query q, ASTQuery ast) throws EngineException { if (ast.isFail()) { q.setFail(true); @@ -597,24 +580,20 @@ void error(Query q, ASTQuery ast) throws EngineException { } getFunctionCompiler().undefinedFunction(q, ast, ast.getLevel()); } - - + + public void imports(Query q, String path) throws EngineException { - getFunctionCompiler().imports(q, q.getAST(), path); + getFunctionCompiler().imports(q, q.getAST(), path); } - + public boolean getLinkedFunction(String label) throws EngineException { return getFunctionCompiler().getLinkedFunction(label); } - + public boolean getLinkedFunctionBasic(String label) throws EngineException { return getFunctionCompiler().getLinkedFunctionBasic(label); } - - public static void removeLinkedFunction() { - FunctionCompiler.removeLinkedFunction(); - } - + /** * isDefine = true means export to Interpreter Use case: Transformation * st:profile does not export to Interpreter hence it uses isDefine = false @@ -622,9 +601,6 @@ public static void removeLinkedFunction() { public void definePublic(ASTExtension ext, Query q, boolean isDefine) { getFunctionCompiler().definePublic(ext, q, isDefine); } - - - void construct(Query q, ASTQuery ast) throws EngineException { validate(ast.getInsert(), ast); @@ -632,16 +608,12 @@ void construct(Query q, ASTQuery ast) throws EngineException { q.setConstruct(cons); if (ast.isInsert()) { q.setInsert(true); - } - else { + } else { q.setConstruct(true); } - //q.setConstruct(true); q.setConstructNodes(cons.getNodes()); } - - /** * Subquery is a construct where */ @@ -650,10 +622,9 @@ Query constructQuery(ASTQuery ast) throws EngineException { t.setAlgebra(isAlgebra()); return t.transform(ast); } - + Query updateQuery(ASTQuery ast) throws EngineException { - Query q = constructQuery(ast); - return q; + return constructQuery(ast); } /** @@ -684,13 +655,12 @@ Query compileQuery(ASTQuery ast) throws EngineException { return q; } - - + /** * For query and subquery Generate a new compiler for each (sub) query in * order to get fresh new nodes */ - Query compile(ASTQuery ast) throws EngineException { + Query compile(ASTQuery ast) throws EngineException { Exp ee = compile(ast.getBody(), false); Query q = Query.create(ee); q.setUseBind(isUseBind()); @@ -702,8 +672,7 @@ Query compile(ASTQuery ast) throws EngineException { return q; } - - + /** * Compile AST statements into KGRAM statements Compile triple into Edge, * filter into Filter @@ -714,7 +683,7 @@ Exp compile(fr.inria.corese.core.sparql.triple.parser.Exp query, boolean opt) th Exp compile(fr.inria.corese.core.sparql.triple.parser.Exp query, boolean opt, int level) throws EngineException { Exp exp = null; - int type = getType(query); + Type type = getType(query); opt = opt || isOption(type); switch (type) { @@ -731,11 +700,9 @@ Exp compile(fr.inria.corese.core.sparql.triple.parser.Exp query, boolean opt, in ASTQuery aa = query.getAST(); if (aa.isConstruct()) { exp = constructQuery(aa); - } - else if (aa.isUpdate()) { + } else if (aa.isUpdate()) { exp = updateQuery(aa); - } - else { + } else { exp = compileQuery(aa); } break; @@ -761,7 +728,7 @@ else if (aa.isUpdate()) { default: - /** + /* * ************************ * * Compile Body @@ -789,24 +756,24 @@ else if (aa.isUpdate()) { } } } - + // PRAGMA: do it after loop above to have filter compiled // bnode scope query.validateBlank(getAST()); - + exp = complete(exp, query, opt); - - if (isAlgebra() && exp.isBGP()){ + + if (isAlgebra() && exp.isBGP()) { // possibly join arguments // deprecated exp.dispatch(); } - + } exp.setNum(incrNumber()); return exp; - } + } Exp compileBind(ASTQuery ast, Binding b) throws EngineException { return compileBind(ast, b.getFilter(), b.getVariable()); @@ -815,11 +782,10 @@ Exp compileBind(ASTQuery ast, Binding b) throws EngineException { Exp compileBind(ASTQuery ast, Expression e, Variable var) throws EngineException { fr.inria.corese.core.kgram.api.core.Filter f = compileSelect(e, ast); Node node = compiler.createNode(var); - Exp exp = Exp.create(BIND); + Exp exp = Exp.create(Type.BIND); exp.setFilter(f); exp.setNode(node); exp.setFunctional(f.isFunctional()); - //ast.setHasFunctional(f.isFunctional()); function(null, exp, var); return exp; } @@ -845,8 +811,8 @@ Exp compile(ASTQuery ast, fr.inria.corese.core.sparql.triple.parser.Exp exp) thr */ Exp compileService(Service service) throws EngineException { Node src = compile(service.getServiceName()); - Exp node = Exp.create(NODE, src); - + Exp node = Exp.create(Type.NODE, src); + fr.inria.corese.core.sparql.triple.parser.Exp body = service.get(0); ASTQuery aa; @@ -866,7 +832,7 @@ Exp compileService(Service service) throws EngineException { q.setService(true); q.setSilent(service.isSilent()); - Exp exp = Exp.create(SERVICE, node, q); + Exp exp = Exp.create(Type.SERVICE, node, q); exp.setSilent(service.isSilent()); exp.setGenerated(service.isGenerated()); @@ -893,7 +859,7 @@ Query create(Exp exp) { return q; } - Exp compileValues(Values val, boolean opt, int level) throws EngineException { + Exp compileValues(Values val, boolean opt, int level) { Exp exp = compileValues(val); if (exp == null) { getAST().setFail(true); @@ -920,31 +886,28 @@ Exp compileValues(Values values) { } } - Exp bind = Exp.create(VALUES); + Exp bind = Exp.create(Type.VALUES); bind.setNodeList(lNode); bind.setMappings(lMap); return bind; } - + // compile final values: select where {} values {} - void values(Query q, ASTQuery ast){ + void values(Query q, ASTQuery ast) { if (ast.getValues() == null) { return; } compileValues(q, ast); - if (q.getValues() != null && isAlgebra()){ - if (q.getBody().size() == 0){ + if (q.getValues() != null && isAlgebra()) { + if (q.getBody().size() == 0) { q.setBody(q.getValues()); - } - else { - Exp exp = Exp.create(JOIN, Exp.create(BGP, q.getValues()), q.getBody()); - q.setBody(Exp.create(BGP, exp)); + } else { + Exp exp = Exp.create(Type.JOIN, Exp.create(Type.BGP, q.getValues()), q.getBody()); + q.setBody(Exp.create(Type.BGP, exp)); } } } - - void compileValues(Query q, ASTQuery ast) { Exp bind = compileValues(ast.getValues()); if (bind == null) { @@ -953,21 +916,16 @@ void compileValues(Query q, ASTQuery ast) { } else { q.setValues(bind); if (ast.getValues().isMoved()) { - //q.setTemplateMappings(bind.getMappings()); q.getValues().setPostpone(true); - } -// else { -// q.setMappings(bind.getMappings()); -// q.setBindingNodes(bind.getNodeList()); -// } + } } } List compileValuesNodes(Values values) { List lNode = new ArrayList<>(); - for (Variable var : values.getVarList()) { - Node qNode = compiler.createNode(var); + for (Variable variable : values.getVarList()) { + Node qNode = compiler.createNode(variable); lNode.add(qNode); } @@ -986,17 +944,16 @@ Node[] getNodes(List lNode) { */ List compileValuesList(List lVal) { List lNode = new ArrayList<>(); - + for (Constant val : lVal) { Node node = null; if (val != null) { - if (val.isTriple() && val.getTriple()!=null) { + if (val.isTriple() && val.getTriple() != null) { Edge edge = compiler.compile(val.getTriple(), true, true); if (edge.hasReferenceNode()) { node = edge.getReferenceNode(); } - } - else { + } else { node = compiler.createNode(val); } } @@ -1023,6 +980,10 @@ public ASTQuery getAST() { return ast; } + public void setAST(ASTQuery ast) { + this.ast = ast; + } + public Compiler getCompiler() { return compiler; } @@ -1062,7 +1023,7 @@ void complete(Query qCurrent, ASTQuery ast) throws EngineException { } void path(Query q, ASTQuery ast) throws EngineException { - if (ast.getRegexTest().size() > 0) { + if (!ast.getRegexTest().isEmpty()) { Node node = compiler.createNode(Variable.create(THIS)); q.setPathNode(node); } @@ -1076,7 +1037,7 @@ void path(Query q, ASTQuery ast) throws EngineException { void having(Query q, ASTQuery ast) throws EngineException { if (ast.getHaving() != null) { fr.inria.corese.core.kgram.api.core.Filter having = compileSelect(ast.getHaving(), ast); - q.setHaving(Exp.create(FILTER, having)); + q.setHaving(Exp.create(Type.FILTER, having)); } } @@ -1095,16 +1056,16 @@ List select(Query qCurrent, ASTQuery ast) throws EngineException { if (ast.isSelectAll() || ast.isConstruct() || ast.isInsert()) { // select * // get nodes from query nodes and edges - select = toExp(qCurrent.selectNodesFromPattern()); + select = toExp(qCurrent.selectNodesFromPattern()); } qCurrent.setSelectFun(select); - for (Variable var : ast.getSelectVar()) { + for (Variable variable : ast.getSelectVar()) { // retrieve var node from query - String varName = var.getName(); - Node node = getNode(qCurrent, var); - Exp exp = Exp.create(NODE, node); + String varName = variable.getName(); + Node node = getNode(qCurrent, variable); + Exp exp = Exp.create(Type.NODE, node); // process filter if any Expression ee = ast.getExpression(varName); @@ -1118,7 +1079,7 @@ List select(Query qCurrent, ASTQuery ast) throws EngineException { exp.setFilter(f); // create node in lNodes for var in filter f if needed checkFilterVariables(qCurrent, f, select, lNodes); - function(qCurrent, exp, var); + function(qCurrent, exp, variable); aggregate(qCurrent, exp, ee, select); } } @@ -1127,41 +1088,39 @@ List select(Query qCurrent, ASTQuery ast) throws EngineException { add(select, exp); - if (lNodes.contains(exp.getNode())) { - // undef variable of former exp is current exp as var - lNodes.remove(exp.getNode()); - } + // undef variable of former exp is current exp as var + lNodes.remove(exp.getNode()); } for (Node node : lNodes) { // additional variables for exp in select (exp as var) - Exp exp = Exp.create(NODE, node); + Exp exp = Exp.create(Type.NODE, node); exp.status(true); select.add(exp); } qCurrent.setSelect(selectNodeList(qCurrent)); - + return select; } - - // compute select node list from list Exp(node, exp) + + // compute select node list from list Exp(node, exp) List selectNodeList(Query q) { List list = new ArrayList<>(); - + for (Exp ee : q.getSelectFun()) { - if (! list.contains(ee.getNode())) { + if (!list.contains(ee.getNode())) { list.add(ee.getNode()); } } return list; } - - - List toExp(List lNode) { + + + List toExp(List lNode) { List lExp = new ArrayList<>(); for (Node node : lNode) { - lExp.add(Exp.create(NODE, node)); + lExp.add(Exp.create(Type.NODE, node)); } return lExp; } @@ -1229,13 +1188,13 @@ void extendAggregate(Query qCurrent, Exp exp, Expression ee) throws EngineExcept } } - Node getNode(Query qCurrent, Variable var) { + Node getNode(Query qCurrent, Variable variable) { Node node = null; if (qCurrent != null) { - node = getProperAndSubSelectNode(qCurrent, var.getName()); + node = getProperAndSubSelectNode(qCurrent, variable.getName()); } if (node == null) { - node = compiler.createNode(var); + node = compiler.createNode(variable); } return node; } @@ -1257,11 +1216,11 @@ Node getProperAndSubSelectNode(Query q, String name) { /** * If filter isFunctionnal() create it's query node list */ - void function(Query qCurrent, Exp exp, Variable var) { + void function(Query qCurrent, Exp exp, Variable variable) { if (exp.getFilter().isFunctional()) { - if (var.getVariableList() != null) { + if (variable.getVariableList() != null) { // sql() as (?x, ?y) - for (Variable vv : var.getVariableList()) { + for (Variable vv : variable.getVariableList()) { Node qNode = getNode(qCurrent, vv); exp.addNode(qNode); } @@ -1285,17 +1244,14 @@ void checkFilterVariables(Query query, fr.inria.corese.core.kgram.api.core.Filte case ExprType.STL_DEFINE: case ExprType.FUNCTION: case ExprType.LET: - //return; - } + } List lVar = f.getVariables(); for (String name : lVar) { Node node = getProperAndSubSelectNode(query, name); - if (node == null) { - if (!containsExp(select, name) && !containsNode(lNodes, name)) { - node = compiler.createNode(name); - lNodes.add(node); - } + if ((node == null) && (!containsExp(select, name) && !containsNode(lNodes, name))) { + node = compiler.createNode(name); + lNodes.add(node); } } } @@ -1354,7 +1310,7 @@ List orderBy(Query qCurrent, List input, ASTQuery ast) throws E ast.addErrorMessage(ASTQuery.ORDER_GROUP_UNDEFINED, ee); node = compiler.createNode(ee.getName()); } - Exp e = Exp.create(NODE, node); + Exp e = Exp.create(Type.NODE, node); if (exp != null && exp.isAggregate()) { // order by ?count @@ -1366,7 +1322,7 @@ List orderBy(Query qCurrent, List input, ASTQuery ast) throws E // TODO: check rewrite fun() as var fr.inria.corese.core.kgram.api.core.Filter f = compile(ee); Node node = createNode(); - Exp exp = Exp.create(NODE, node); + Exp exp = Exp.create(Type.NODE, node); exp.setFilter(f); list.add(exp); } @@ -1379,8 +1335,7 @@ List orderBy(Query qCurrent, List input, ASTQuery ast) throws E */ Node createNode() { String name = getVarName(); - Node node = compiler.createNode(name); - return node; + return compiler.createNode(name); } String getVarName() { @@ -1396,26 +1351,21 @@ List nodes(List from) { } List sort(List list) { - Collections.sort(list, new Comparator() { - public int compare(Node o1, Node o2) { - return o1.compare(o2); - } - }); + list.sort(Node::compare); return list; } - /** - * Add Exp rst into this exp + * Add Exp rst into this exp * If this exp is BGP{e1 .. en} * return: BGP{JOIN{BGP{e1 .. en} rst}} */ - void join(Exp exp, Exp rst, int type) { - if (exp.isBGPAnd() && exp.size() > 0) { + void join(Exp exp, Exp rst, Type type) { + if (exp.isBGPAnd() && exp.size() > 0) { Exp fst = exp.get(0); if (exp.size() == 1) { - if (!fst.isBGPAnd()) { + if (!fst.isBGPAnd()) { fst = Exp.create(type, fst); } } else { @@ -1424,19 +1374,18 @@ void join(Exp exp, Exp rst, int type) { fst.add(ee); } } - Exp body = Exp.create(JOIN, fst, rst); + Exp body = Exp.create(Type.JOIN, fst, rst); exp.getExpList().clear(); exp.add(body); - } - else { + } else { exp.add(rst); } } - - int bgpType(){ - return (isBGP()) ? BGP : AND; + + Type bgpType() { + return (isBGP()) ? Type.BGP : Type.AND; } - + Exp compileEdge(Triple t, boolean opt) throws EngineException { if (isPathType() && t.isType() && t.getObject().isConstant()) { return compilePathType(t); @@ -1447,10 +1396,10 @@ Exp compileEdge(Triple t, boolean opt) throws EngineException { Exp basicCompileEdge(Triple t) throws EngineException { Edge r = compiler.compile(t, getAST().isInsertData()); - Exp exp = Exp.create(EDGE, r); + Exp exp = Exp.create(Type.EDGE, r); if (t.isXPath()) { // deprecated ?x xpath() ?y - exp.setType(EVAL); + exp.setType(Type.EVAL); fr.inria.corese.core.kgram.api.core.Filter xpath = compiler.compile(t.getXPath()); exp.setFilter(xpath); } else if (t.isPath()) { @@ -1461,10 +1410,10 @@ Exp basicCompileEdge(Triple t) throws EngineException { return exp; } - + void path(Triple tt, Exp exp) throws EngineException { - exp.setType(PATH); + exp.setType(Type.PATH); Expression regex = tt.getRegex(); if (regex == null) { // deprecated: there may be a match($path, regex) @@ -1476,7 +1425,6 @@ void path(Triple tt, Exp exp) throws EngineException { } /** - * * Generate rdf:type/rdfs:subClassOf* */ Exp compilePathType(Triple t) throws EngineException { @@ -1508,7 +1456,7 @@ Exp complete(Exp exp, fr.inria.corese.core.sparql.triple.parser.Exp srcexp, bool case GRAPH: compileGraph(getAST(), exp, srcexp.getNamedGraph()); break; - + } return exp; @@ -1548,8 +1496,8 @@ boolean isSystemGraph(String cst) { Exp compileGraph(Exp exp, Atom at) { Node src = compiler.createNode(at, getAST().isInsertData()); // create a NODE kgram expression for graph ?g - Exp node = Exp.create(NODE, src); - Exp gnode = Exp.create(GRAPHNODE, node); + Exp node = Exp.create(Type.NODE, src); + Exp gnode = Exp.create(Type.GRAPHNODE, node); exp.add(0, gnode); return exp; } @@ -1559,12 +1507,12 @@ Exp compileFilter(Expression ee, boolean opt) throws EngineException { Exp exp; if (qvec.size() == 1) { - exp = Exp.create(FILTER, qvec.get(0)); + exp = Exp.create(Type.FILTER, qvec.get(0)); compileExist(qvec.get(0).getExp(), opt); } else { - exp = Exp.create(AND); + exp = Exp.create(Type.AND); for (fr.inria.corese.core.kgram.api.core.Filter qm : qvec) { - Exp f = Exp.create(FILTER, qm); + Exp f = Exp.create(Type.FILTER, qm); compileExist(qm.getExp(), opt); exp.add(f); } @@ -1602,12 +1550,9 @@ void compileExist(Expr exp, boolean opt) throws EngineException { Term term = (Term) exp; Exp pat = compile(term.getExist(), opt); term.setPattern(pat); - } - //else - { - for (Expr ee : exp.getExpList()) { - compileExist(ee, opt); - } + } + for (Expr ee : exp.getExpList()) { + compileExist(ee, opt); } } @@ -1642,7 +1587,7 @@ void processPath(Exp exp, Exp ef) throws EngineException { Node n = e.getEdgeVariable(); List lVar = f.getVariables(); - if (lVar.size() == 0) { + if (lVar.isEmpty()) { return; } if (n == null) { @@ -1659,7 +1604,7 @@ void processPath(Exp exp, Exp ef) throws EngineException { String mode = compiler.getMode(f); if (mode != null) { exp.setObject(mode); - if (mode.indexOf("i") != -1) { + if (mode.contains("i")) { regex = Term.function(Term.SEINV, ((Expression) regex)); } } @@ -1675,7 +1620,7 @@ void processPath(Exp exp, Exp ef) throws EngineException { } } - boolean isOption(int type) { + boolean isOption(Type type) { switch (type) { case OPTION: case OPTIONAL: @@ -1688,50 +1633,47 @@ boolean isOption(int type) { } } - int getType(fr.inria.corese.core.sparql.triple.parser.Exp query) { + ExpType.Type getType(fr.inria.corese.core.sparql.triple.parser.Exp query) { if (query.isFilter()) { - return FILTER; + return ExpType.Type.FILTER; } else if (query.isTriple()) { - return EDGE; + return ExpType.Type.EDGE; } else if (query.isUnion()) { - return UNION; + return ExpType.Type.UNION; } else if (query.isJoin()) { - return JOIN; + return ExpType.Type.JOIN; } else if (query.isOption()) { - return OPTION; + return ExpType.Type.OPTION; } else if (query.isOptional()) { - return OPTIONAL; + return ExpType.Type.OPTIONAL; } else if (query.isMinus()) { - return MINUS; + return ExpType.Type.MINUS; } else if (query.isGraph()) { - return GRAPH; + return ExpType.Type.GRAPH; } else if (query.isService()) { - return SERVICE; + return ExpType.Type.SERVICE; } else if (query.isQuery()) { - return QUERY; + return ExpType.Type.QUERY; } else if (query.isBind()) { - return BIND; + return ExpType.Type.BIND; } else if (query.isValues()) { - return VALUES; + return ExpType.Type.VALUES; } else if (query.isBGP()) { return bgpType(); } else if (query.isAnd()) { - return AND; + return ExpType.Type.AND; } else { - return EMPTY; + return ExpType.Type.EMPTY; } } - int cpType(int type) { + Type cpType(Type type) { switch (type) { default: return type; } } - /** - * ************************************ - */ /** * Generate a complementary Query that checks: definition of class/property */ @@ -1744,8 +1686,7 @@ void check(Triple tt, Edge edge) { qq = tr.transform(aa); add(edge, qq); } catch (EngineException ex) { - java.util.logging.Logger.getLogger(Transformer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); - } + logger.error("An unexpected error has occurred", ex); } } } @@ -1759,14 +1700,14 @@ void add(Edge edge, Query query) { * generate a blank node for each path (PathFinder) */ void filters(Query q) throws EngineException { - ASTQuery ast = q.getAST(); + ASTQuery ast = q.getAST(); Term t = Term.function(Processor.PATHNODE); q.setFilter(Query.PATHNODE, t.compile(ast)); } @Deprecated void relax(Query q) { - ASTQuery ast = q.getAST(); + ASTQuery ast = q.getAST(); for (Expression exp : ast.getRelax()) { if (exp.isConstant()) { Constant p = exp.getConstant(); @@ -1776,7 +1717,7 @@ void relax(Query q) { } } - + /** * check unbound variable in construct/insert/delete */ @@ -1785,7 +1726,7 @@ boolean validate(fr.inria.corese.core.sparql.triple.parser.Exp exp, ASTQuery ast for (fr.inria.corese.core.sparql.triple.parser.Exp ee : exp.getBody()) { boolean b = true; - + if (ee.isTriple()) { b = validate(ee.getTriple(), ast); } else if (ee.isGraph()) { @@ -1846,13 +1787,13 @@ public void setDataset(Dataset dataset) { * Must exp ee be joined with preceding statements ? */ private boolean isJoinable(Exp exp, fr.inria.corese.core.sparql.triple.parser.Exp ee) { - return (isAlgebra()) ? isJoinableAlgebra(exp, ee) : isJoinableBasic(ee) ; + return (isAlgebra()) ? isJoinableAlgebra(exp, ee) : isJoinableBasic(ee); } - + private boolean isJoinableBasic(fr.inria.corese.core.sparql.triple.parser.Exp ee) { return ee.isBGP() || ee.isUnion() || ee.isGraph(); } - + private boolean isJoinableAlgebra(Exp exp, fr.inria.corese.core.sparql.triple.parser.Exp ee) { return ee.isBGP() || ee.isUnion(); } @@ -1869,55 +1810,47 @@ public boolean isUseBind() { return isUseBind; } - public void setUseBind(boolean isUseBind) { + public void setUseBind(boolean isUseBind) { this.isUseBind = isUseBind; } - public boolean isGenerateMain() { + public boolean isGenerateMain() { return isGenerateMain; } - public void setGenerateMain(boolean isGenerateMain) { + public void setGenerateMain(boolean isGenerateMain) { this.isGenerateMain = isGenerateMain; } - public QuerySolver getSPARQLEngine() { + public QuerySolver getSPARQLEngine() { return sparql; } - public void setSPARQLEngine(QuerySolver sparql) { + public void setSPARQLEngine(QuerySolver sparql) { this.sparql = sparql; } -// public List getServiceList() { -// return serviceList; -// } -// -// public void setServiceList(List serviceList) { -// this.serviceList = serviceList; -// } - - public FunctionCompiler getFunctionCompiler() { + public FunctionCompiler getFunctionCompiler() { return functionCompiler; } - public void setFunctionCompiler(FunctionCompiler functionCompiler) { + public void setFunctionCompiler(FunctionCompiler functionCompiler) { this.functionCompiler = functionCompiler; } - + public int getNumber() { return number; } - - int incrNumber() { - return number++; - } public void setNumber(int number) { this.number = number; } + int incrNumber() { + return number++; + } + public boolean isAlgebra() { return algebra; } @@ -1933,7 +1866,7 @@ public boolean isBGP() { public void setBGP(boolean BGP) { this.isBGP = BGP; } - + public boolean isPathType() { return pathType; } @@ -1941,17 +1874,21 @@ public boolean isPathType() { public void setPathType(boolean pathType) { this.pathType = pathType; } - + public BasicGraphPattern getPragma() { return pragma; } + public void setPragma(BasicGraphPattern p) { + pragma = p; + } + public String getBase() { return base; } - public void setAST(ASTQuery ast) { - this.ast = ast; + public void setBase(String ns) { + base = ns; } public List getVisitorList() { @@ -1961,8 +1898,7 @@ public List getVisitorList() { public void setVisitorList(List visit) { this.visit = visit; } - - + public boolean isSPARQLCompliant() { return isSPARQLCompliant; } @@ -1975,18 +1911,6 @@ public void setNamespaces(String ns) { namespaces = ns; } - public void setPragma(BasicGraphPattern p) { - pragma = p; - } - - public void setBase(String ns) { - base = ns; - } - - public void setSPARQL1(boolean b) { - isSPARQL1 = b; - } - public Mappings getMappings() { return mappings; } @@ -1998,6 +1922,10 @@ public void setMappings(Mappings mappings) { public Metadata getMetadata() { return metadata; } - + + public void setMetadata(Metadata m) { + metadata = m; + } + } diff --git a/src/main/java/fr/inria/corese/core/compiler/parser/VisitQuery.java b/src/main/java/fr/inria/corese/core/compiler/parser/VisitQuery.java index dc766e95e..26ffe833b 100644 --- a/src/main/java/fr/inria/corese/core/compiler/parser/VisitQuery.java +++ b/src/main/java/fr/inria/corese/core/compiler/parser/VisitQuery.java @@ -1,25 +1,21 @@ package fr.inria.corese.core.compiler.parser; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.Expression; import fr.inria.corese.core.kgram.api.core.Edge; -import static fr.inria.corese.core.kgram.api.core.ExpType.BIND; -import static fr.inria.corese.core.kgram.api.core.ExpType.EDGE; -import static fr.inria.corese.core.kgram.api.core.ExpType.FILTER; -import static fr.inria.corese.core.kgram.api.core.ExpType.PATH; -import static fr.inria.corese.core.kgram.api.core.ExpType.QUERY; import fr.inria.corese.core.kgram.api.core.Expr; import fr.inria.corese.core.kgram.api.core.ExprType; import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.core.Exp; import fr.inria.corese.core.kgram.core.Query; +import fr.inria.corese.core.sparql.triple.parser.ASTQuery; +import fr.inria.corese.core.sparql.triple.parser.Expression; + import java.util.ArrayList; import java.util.List; +import static fr.inria.corese.core.kgram.api.core.ExpType.*; + /** - * * @author Olivier Corby, Wimmics INRIA I3S, 2014 - * */ public class VisitQuery { @@ -36,13 +32,13 @@ void visit(Query q) { } List visit(Exp exp) { - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList<>(); visit(exp, list); return list; } - + void add(List list, Node p, Edge edge) { - if (! list.contains(p)) { + if (!list.contains(p)) { list.add(p); } query.recordPredicate(p, edge); @@ -57,7 +53,7 @@ void visit(Exp exp, List list) { case EDGE: add(list, exp.getEdge().getEdgeNode(), exp.getEdge()); - if (exp.isPath()){ + if (exp.isPath()) { visit(exp.getPath()); } break; @@ -86,7 +82,6 @@ void visit(Exp exp, List list) { if (q.getHaving() != null) { visit(q.getHaving().getFilter().getExp(), list); } - // continue default: for (Exp ee : exp.getExpList()) { @@ -110,7 +105,6 @@ void visitRegex(Edge edge, Expression exp, List list) { } else if (exp.isTerm() && exp.isNot()) { // ! p is a problem because we do not know the predicate nodes ... // let's return top level property, it subsumes all properties - //list.clear(); Node node = compiler.createNode(ASTQuery.getRootPropertyURI()); add(list, node, edge); } else { diff --git a/src/main/java/fr/inria/corese/core/compiler/result/XMLResult.java b/src/main/java/fr/inria/corese/core/compiler/result/XMLResult.java index 690bf9329..4dc1b43b1 100644 --- a/src/main/java/fr/inria/corese/core/compiler/result/XMLResult.java +++ b/src/main/java/fr/inria/corese/core/compiler/result/XMLResult.java @@ -1,31 +1,5 @@ package fr.inria.corese.core.compiler.result; -import java.io.ByteArrayInputStream; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import org.xml.sax.Attributes; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.helpers.DefaultHandler; - -import fr.inria.corese.core.sparql.api.IDatatype; -import fr.inria.corese.core.sparql.datatype.DatatypeMap; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; -import fr.inria.corese.core.sparql.triple.parser.Variable; import fr.inria.corese.core.compiler.eval.QuerySolver; import fr.inria.corese.core.compiler.parser.CompilerFacKgram; import fr.inria.corese.core.kgram.api.core.Node; @@ -33,32 +7,41 @@ import fr.inria.corese.core.kgram.core.Mapping; import fr.inria.corese.core.kgram.core.Mappings; import fr.inria.corese.core.kgram.core.Query; +import fr.inria.corese.core.sparql.api.IDatatype; +import fr.inria.corese.core.sparql.datatype.DatatypeMap; import fr.inria.corese.core.sparql.exceptions.EngineException; -import java.io.BufferedReader; -import java.io.Reader; -import java.util.Collection; -import java.util.logging.Level; +import fr.inria.corese.core.sparql.triple.parser.ASTQuery; +import fr.inria.corese.core.sparql.triple.parser.BasicGraphPattern; +import fr.inria.corese.core.sparql.triple.parser.Variable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import java.io.*; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; + /** * SPARQL XML Results Format Parser into Mappings * * @author Olivier Corby, Wimmics, INRIA 2012 - * */ @Deprecated public class XMLResult { - private static Logger logger = LoggerFactory.getLogger(XMLResult.class); static final String NL = "\n"; - - // create target Node - Producer producer; - // create query Node - private fr.inria.corese.core.compiler.parser.Compiler compiler; - HashMap table; - ArrayList varList; + private static final Logger logger = LoggerFactory.getLogger(XMLResult.class); private static final int UNKNOWN = -1; private static final int RESULT = 1; private static final int BINDING = 2; @@ -72,9 +55,12 @@ public class XMLResult { private static final int SUBJECT = 10; private static final int PREDICATE = 11; private static final int OBJECT = 12; - - - private boolean debug = false; + // create target Node + Producer producer; + HashMap table; + ArrayList varList; + // create query Node + private fr.inria.corese.core.compiler.parser.Compiler compiler; private boolean trapError = false; private boolean showResult = false; private List link; @@ -96,34 +82,16 @@ public static XMLResult create(Producer p) { return new XMLResult(p); } - public class VTable extends HashMap { - - public Variable get(String name) { - Variable var = super.get(name); - if (var == null) { - var = new Variable("?" + name); - put(name, var); - } - return var; - } - } - /** * parse SPARQL XML Result as Mappings */ - public Mappings parse(InputStream stream) throws ParserConfigurationException, SAXException, IOException - { - + public Mappings parse(InputStream stream) throws ParserConfigurationException, SAXException, IOException { + if (isShowResult()) { String str = read(stream); - System.out.println(str); setShowResult(false); return parseString(str); } - - if (debug) { - System.out.println("start parse XML result"); - } Mappings map = new Mappings(); MyHandler handler = new MyHandler(map); @@ -131,20 +99,18 @@ public Mappings parse(InputStream stream) throws ParserConfigurationException, S factory.setNamespaceAware(true); try { SAXParser parser = factory.newSAXParser(); - InputStreamReader r = new InputStreamReader(stream, "UTF-8"); + InputStreamReader r = new InputStreamReader(stream, StandardCharsets.UTF_8); parser.parse(new InputSource(r), handler); complete(map); map.setLinkList(getLink()); return map; } catch (ParserConfigurationException | SAXException | IOException e) { - if (isTrapError()) { + if (isTrapError()) { logger.error(e.toString()); complete(map); map.setError(true); - System.out.println("Return partial result of size: " + map.size()); return map; - } - else { + } else { throw e; } } @@ -158,7 +124,7 @@ public void complete(Mappings map) { try { ASTQuery ast = ASTQuery.create(); ast.setBody(BasicGraphPattern.create()); - for (Node n : varList) { + for (Node n : varList) { ast.setSelect(new Variable(n.getLabel())); } QuerySolver qs = QuerySolver.create(); @@ -167,7 +133,7 @@ public void complete(Mappings map) { map.setQuery(q); map.init(q); } catch (EngineException ex) { - java.util.logging.Logger.getLogger(XMLResult.class.getName()).log(Level.SEVERE, null, ex); + logger.error("An unexpected error has occurred", ex); } } @@ -176,18 +142,18 @@ public void init() { varList = new ArrayList<>(); setCompiler(new CompilerFacKgram().newInstance()); table = new HashMap<>(); - table.put("result", RESULT); + table.put("result", RESULT); table.put("binding", BINDING); - table.put("uri", URI); - table.put("bnode", BNODE); + table.put("uri", URI); + table.put("bnode", BNODE); table.put("literal", LITERAL); table.put("boolean", BOOLEAN); - table.put("variable",VARIABLE); - table.put("link", LINK); - table.put("triple", TRIPLE); - table.put("subject", SUBJECT); - table.put("predicate", PREDICATE); - table.put("object", OBJECT); + table.put("variable", VARIABLE); + table.put("link", LINK); + table.put("triple", TRIPLE); + table.put("subject", SUBJECT); + table.put("predicate", PREDICATE); + table.put("object", OBJECT); } int type(String name) { @@ -213,46 +179,144 @@ public Mappings parse(String path) throws ParserConfigurationException, SAXExcep public Node getURI(String str) { IDatatype dt = DatatypeMap.createResource(str); - Node n = producer.getNode(dt); - return n; + return producer.getNode(dt); } public Node getBlank(String str) { IDatatype dt = DatatypeMap.createBlank(str); - Node n = producer.getNode(dt); - return n; + return producer.getNode(dt); } public Node getLiteral(String str, String datatype, String lang) { IDatatype dt = DatatypeMap.createLiteral(str, datatype, lang); - Node n = producer.getNode(dt); - return n; + return producer.getNode(dt); + } + + public void defineVariable(Node node) { + varList.add(node); + } + + InputStream getStream(String path) throws FileNotFoundException { + try { + URL uri = new URL(path); + return uri.openStream(); + } catch (IOException ignored) { + } + + FileInputStream stream; + stream = new FileInputStream(path); + return stream; + } + + /** + * @return the trapError + */ + public boolean isTrapError() { + return trapError; + } + + /** + * @param trapError the trapError to set + */ + public void setTrapError(boolean trapError) { + this.trapError = trapError; + } + + public String read(InputStream stream) throws IOException { + return read(new InputStreamReader(stream)); + } + + String read(Reader fr) throws IOException { + BufferedReader fq = new BufferedReader(fr); + StringBuilder sb = new StringBuilder(); + String str; + boolean isnl = false; + while (true) { + str = fq.readLine(); + if (str == null) { + fq.close(); + break; + } + if (isnl) { + sb.append(NL); + } else { + isnl = true; + } + sb.append(str); + } + return sb.toString(); + } + + /** + * @return the showResult + */ + public boolean isShowResult() { + return showResult; + } + + /** + * @param showResult the showResult to set + */ + public void setShowResult(boolean showResult) { + this.showResult = showResult; + } + + /** + * @return the compiler + */ + public fr.inria.corese.core.compiler.parser.Compiler getCompiler() { + return compiler; + } + + /** + * @param compiler the compiler to set + */ + public void setCompiler(fr.inria.corese.core.compiler.parser.Compiler compiler) { + this.compiler = compiler; + } + + public List getLink() { + return link; + } + + public void setLink(List link) { + this.link = link; } - - public void defineVariable(Node var) { - varList.add(var); + + public void addLink(String link) { + getLink().add(link); + } + + public class VTable extends HashMap { + + public Variable get(String name) { + Variable var = super.get(name); + if (var == null) { + var = new Variable("?" + name); + put(name, var); + } + return var; + } } /** - * * SAX Handler */ public class MyHandler extends DefaultHandler { Mappings maps; - //Mapping map; List lvar, lval; String var; VTable vtable; boolean // true for variable binding isContent = false, - // true for ask SPARQL Query - isBoolean = false, + // true for ask SPARQL Query + isBoolean = false, isURI = false, isLiteral = false, isBlank = false, isVariable = false; - int triple = 0; + int triple = 0; String text, datatype, lang; MyHandler(Mappings m) { @@ -264,9 +328,6 @@ public class MyHandler extends DefaultHandler { @Override public void startDocument() { - if (debug) { - System.out.println("start document"); - } } // called for each binding @@ -289,37 +350,32 @@ void add(String var, Node nval) { lvar.add(nvar); lval.add(nval); } - - Node getVariable(String var) { - return getCompiler().createNode(vtable.get(var)); + + Node getVariable(String varString) { + return getCompiler().createNode(vtable.get(varString)); } - + @Override public void startElement(String namespaceURI, String simpleName, - String qualifiedName, Attributes atts) { - if (debug) { - System.out.println("open: " + qualifiedName); - } + String qualifiedName, Attributes atts) { isContent = false; switch (type(simpleName)) { - + case LINK: - addLink(atts.getValue("href")); + addLink(atts.getValue("href")); break; case RESULT: - //map = Mapping.create(); - //maps.add(map); lval.clear(); lvar.clear(); break; - + case VARIABLE: - String name = atts.getValue("name"); - defineVariable(getVariable(name)); - break; + String name = atts.getValue("name"); + defineVariable(getVariable(name)); + break; case BINDING: var = atts.getValue("name"); @@ -346,87 +402,86 @@ public void startElement(String namespaceURI, String simpleName, case BOOLEAN: isBoolean = true; isContent = true; - break; - + break; + case TRIPLE: triple++; - break; + break; } } - + void pushSubject(Node node) { - + } + void pushPredicate(Node node) { - - } + + } + void pushObject(Node node) { - + } + Node getSubject() { return null; - } + } + Node getPredicate() { return null; - } + } + Node getObject() { return null; - } - + } + void edge(Node sub, Node pred, Node obj) { - + } - + // inside triple and possibly inside triple element void triple(String namespaceURI, String simpleName, String qualifiedName) { - + switch (type(simpleName)) { case SUBJECT: pushSubject(getNode()); break; case PREDICATE: pushPredicate(getNode()); - break; + break; case OBJECT: pushObject(getNode()); - break; + break; case TRIPLE: - + } } - + Node getNode() { if (isURI) { - isURI=false; + isURI = false; return getURI(text); } else if (isBlank) { - isBlank=false; + isBlank = false; return getBlank(text); } else if (isLiteral) { - isLiteral=false; + isLiteral = false; return getLiteral(text, datatype, lang); - } - else { + } else { return null; } } - + @Override public void endElement(String namespaceURI, String simpleName, String qualifiedName) { - if (debug) { - System.out.println("close: " + qualifiedName); - } - if (triple > 0) { triple(namespaceURI, simpleName, qualifiedName); triple--; - } - else if (isContent) { + } else if (isContent) { isContent = false; if (text == null) { - // may happen with empty literal + // may happen with empty literal text = ""; } @@ -440,14 +495,9 @@ else if (isContent) { maps.add(Mapping.create()); } } else { - switch (type(simpleName)) { - - case RESULT: - Mapping map = Mapping.create(lvar, lval); - if (debug) { - System.out.println(map); - } - maps.add(map); + if (type(simpleName) == RESULT) { + Mapping map = Mapping.create(lvar, lval); + maps.add(map); } } } @@ -457,7 +507,7 @@ else if (isContent) { * element. */ @Override - public void characters(char buf[], int offset, int len) { + public void characters(char[] buf, int offset, int len) { if (isContent) { String s = new String(buf, offset, len); if (text == null) { @@ -472,98 +522,4 @@ public void characters(char buf[], int offset, int len) { public void endDocument() { } } - - InputStream getStream(String path) throws FileNotFoundException { - try { - URL uri = new URL(path); - return uri.openStream(); - } catch (MalformedURLException e) { - } catch (IOException e) { - } - - FileInputStream stream; - stream = new FileInputStream(path); - return stream; - } - - /** - * @return the trapError - */ - public boolean isTrapError() { - return trapError; - } - - /** - * @param trapError the trapError to set - */ - public void setTrapError(boolean trapError) { - this.trapError = trapError; - } - - public String read(InputStream stream) throws IOException { - return read(new InputStreamReader(stream)); - } - - String read(Reader fr) throws IOException { - BufferedReader fq = new BufferedReader(fr); - StringBuilder sb = new StringBuilder(); - String str; - boolean isnl = false; - while (true) { - str = fq.readLine(); - if (str == null) { - fq.close(); - break; - } - if (isnl){ - sb.append(NL); - } - else { - isnl = true; - } - sb.append(str); - //sb.append(NL); - } - return sb.toString(); - } - - /** - * @return the showResult - */ - public boolean isShowResult() { - return showResult; - } - - /** - * @param showResult the showResult to set - */ - public void setShowResult(boolean showResult) { - this.showResult = showResult; - } - - /** - * @return the compiler - */ - public fr.inria.corese.core.compiler.parser.Compiler getCompiler() { - return compiler; - } - - /** - * @param compiler the compiler to set - */ - public void setCompiler(fr.inria.corese.core.compiler.parser.Compiler compiler) { - this.compiler = compiler; - } - - public List getLink() { - return link; - } - - public void setLink(List link) { - this.link = link; - } - - public void addLink(String link) { - getLink().add(link); - } } diff --git a/src/main/java/fr/inria/corese/core/compiler/visitor/MetadataVisitor.java b/src/main/java/fr/inria/corese/core/compiler/visitor/MetadataVisitor.java index 6538e3c75..719b9f1c0 100644 --- a/src/main/java/fr/inria/corese/core/compiler/visitor/MetadataVisitor.java +++ b/src/main/java/fr/inria/corese/core/compiler/visitor/MetadataVisitor.java @@ -2,36 +2,29 @@ import fr.inria.corese.core.compiler.api.QueryVisitor; import fr.inria.corese.core.kgram.core.Query; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; -import fr.inria.corese.core.sparql.triple.parser.Atom; -import fr.inria.corese.core.sparql.triple.parser.Binding; -import fr.inria.corese.core.sparql.triple.parser.Constant; -import fr.inria.corese.core.sparql.triple.parser.Exp; -import fr.inria.corese.core.sparql.triple.parser.Source; -import fr.inria.corese.core.sparql.triple.parser.Term; -import fr.inria.corese.core.sparql.triple.parser.Triple; -import fr.inria.corese.core.sparql.triple.parser.Variable; +import fr.inria.corese.core.sparql.triple.parser.*; + import java.util.ArrayList; import java.util.List; /** * Metadata Visitor - * - * @author Olivier Corby, Wimmics INRIA I3S, 2018 * + * @author Olivier Corby, Wimmics INRIA I3S, 2018 */ public class MetadataVisitor implements QueryVisitor { - - private static final String META_VARIABLE = "?meta"; - private static final String META_LIST = "munc:metaList"; - private static final String UNCERTAINTY = "munc:hasUncertainty"; - private static final String VALUE = "xt:value"; - private static final String NAME = "xt:name"; - + + private static final String META_VARIABLE = "?meta"; + private static final String META_LIST = "munc:metaList"; + private static final String UNCERTAINTY = "munc:hasUncertainty"; + private static final String VALUE = "xt:value"; + private static final String NAME = "xt:name"; + ASTQuery ast; int count = 0; - - public MetadataVisitor() {} + + public MetadataVisitor() { + } @Override public void visit(ASTQuery ast) { @@ -41,65 +34,63 @@ public void visit(ASTQuery ast) { @Override public void visit(Query query) { - + } - + void init(ASTQuery ast) { - this.ast = ast; - if (ast.getNSM().getNamespace("munc") == null) { - ast.defNSNamespace("munc", "http://ns.inria.fr/metauncertainty/v1/"); - } + this.ast = ast; + if (ast.getNSM().getNamespace("munc") == null) { + ast.defNSNamespace("munc", "http://ns.inria.fr/metauncertainty/v1/"); + } } - + /** * prefix munc: - select ?g ?s ?p ?o ?meta where { - graph ?g {triple(?s ?p ?o ?Tm)} - triple(?g munc:hasUncertainty [] ?Gm) - bind(us:metaList(?Tm,?Gm) as ?meta) - } + select ?g ?s ?p ?o ?meta where { + graph ?g {triple(?s ?p ?o ?Tm)} + triple(?g munc:hasUncertainty [] ?Gm) + bind(us:metaList(?Tm,?Gm) as ?meta) + } - function us:metaList(?Tm,?Gm) { + function us:metaList(?Tm,?Gm) { */ - + /** * name is a named graph */ void process(Atom name, Exp body) { ArrayList list = new ArrayList<>(); - + for (Exp exp : body) { if (exp.isNamedGraph()) { Source g = exp.getNamedGraph(); process(g.getSource(), g.getBodyExp()); - } - else if (exp.isFilter()) {} - else if (exp.isTriple()) { - if (name != null) { + } else if (exp.isFilter()) { + } else if (exp.isTriple()) { + if (name != null) { process(exp.getTriple(), list, name); } - } - else { - for (Exp ee : exp) { - process(name, ee); - } + } else { + for (Exp ee : exp) { + process(name, ee); + } } } - + for (Exp exp : list) { body.add(exp); - } + } } - + /** - graph ?g {triple(?s ?p ?o ?Tm)} - * -> - bind(us:metaList(?Tm, xt:value(xt:name(), munc:hasUncertainty, 2)) as ?meta) - * - * xt:name() -> current named graph, that is ?g - * xt:value get the value of subject property - * 2 is the node index of metadata value (1 is node index of object value) + * graph ?g {triple(?s ?p ?o ?Tm)} + * -> + * bind(us:metaList(?Tm, xt:value(xt:name(), munc:hasUncertainty, 2)) as ?meta) + *

+ * xt:name() -> current named graph, that is ?g + * xt:value get the value of subject property + * 2 is the node index of metadata value (1 is node index of object value) */ void process(Triple t, List list, Atom name) { if (t.getArgs() != null && !t.getArgs().isEmpty()) { @@ -113,7 +104,6 @@ void process(Triple t, List list, Atom name) { list.add(b); } } - - + } diff --git a/src/main/java/fr/inria/corese/core/compiler/visitor/TraceVisitor.java b/src/main/java/fr/inria/corese/core/compiler/visitor/TraceVisitor.java deleted file mode 100644 index 192c0fccf..000000000 --- a/src/main/java/fr/inria/corese/core/compiler/visitor/TraceVisitor.java +++ /dev/null @@ -1,24 +0,0 @@ -package fr.inria.corese.core.compiler.visitor; - -import fr.inria.corese.core.compiler.api.QueryVisitor; -import fr.inria.corese.core.kgram.core.Query; -import fr.inria.corese.core.sparql.triple.parser.ASTQuery; - -/** - * - * @author Olivier Corby, Wimmics INRIA I3S, 2018 - * - */ -public class TraceVisitor implements QueryVisitor { - - @Override - public void visit(ASTQuery ast) { - System.out.println("TraceVisitor:"); - System.out.println(ast); - } - - @Override - public void visit(Query query) { - } - -} diff --git a/src/main/java/fr/inria/corese/core/edge/EdgeBinary.java b/src/main/java/fr/inria/corese/core/edge/EdgeBinary.java index 27334e556..8ecccbe3b 100644 --- a/src/main/java/fr/inria/corese/core/edge/EdgeBinary.java +++ b/src/main/java/fr/inria/corese/core/edge/EdgeBinary.java @@ -8,16 +8,14 @@ * Graph Edge for the defaultGraph * * @author Olivier Corby, Wimmics, INRIA I3S, 2014 - * */ public abstract class EdgeBinary extends EdgeTop implements Edge { - public static boolean displayGraph = true; protected Node subject, object; - public EdgeBinary() { + protected EdgeBinary() { } - public EdgeBinary(Node subject, Node object) { + protected EdgeBinary(Node subject, Node object) { this.subject = subject; this.object = object; } @@ -26,7 +24,7 @@ public EdgeBinary(Node subject, Node object) { public boolean contains(Node node) { return getNode(0).same(node) || getNode(1).same(node); } - + @Override public Node getNode(int n) { switch (n) { diff --git a/src/main/java/fr/inria/corese/core/edge/EdgeDefault.java b/src/main/java/fr/inria/corese/core/edge/EdgeDefault.java index 8baa356ba..e5fef7f17 100644 --- a/src/main/java/fr/inria/corese/core/edge/EdgeDefault.java +++ b/src/main/java/fr/inria/corese/core/edge/EdgeDefault.java @@ -1,26 +1,25 @@ package fr.inria.corese.core.edge; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; +import fr.inria.corese.core.kgram.api.core.Node; /** * Graph Edge for the defaultGraph - * - * @author Olivier Corby, Wimmics INRIA I3S, 2016 * + * @author Olivier Corby, Wimmics INRIA I3S, 2016 */ public class EdgeDefault extends EdgeTriple { - - EdgeDefault(Node predicate, Node subject, Node object){ + + EdgeDefault(Node predicate, Node subject, Node object) { super(predicate, subject, object); } - - public static EdgeDefault create(Node source, Node subject, Node predicate, Node object){ + + public static EdgeDefault create(Node source, Node subject, Node predicate, Node object) { return new EdgeDefault(predicate, subject, object); } - + @Override - public Node getGraph(){ + public Node getGraph() { return subject.getTripleStore().getNode(Graph.DEFAULT_INDEX); } diff --git a/src/main/java/fr/inria/corese/core/edge/EdgeEntail.java b/src/main/java/fr/inria/corese/core/edge/EdgeEntail.java index 63221bd17..fe169eee9 100644 --- a/src/main/java/fr/inria/corese/core/edge/EdgeEntail.java +++ b/src/main/java/fr/inria/corese/core/edge/EdgeEntail.java @@ -1,25 +1,23 @@ package fr.inria.corese.core.edge; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; +import fr.inria.corese.core.kgram.api.core.Node; /** - * * @author Olivier Corby, Wimmics INRIA I3S, 2016 - * */ public class EdgeEntail extends EdgeTriple { - - EdgeEntail(Node predicate, Node subject, Node object){ + + EdgeEntail(Node predicate, Node subject, Node object) { super(predicate, subject, object); } - - public static EdgeEntail create(Node source, Node subject, Node predicate, Node object){ + + public static EdgeEntail create(Node source, Node subject, Node predicate, Node object) { return new EdgeEntail(predicate, subject, object); } - + @Override - public Node getGraph(){ + public Node getGraph() { return subject.getTripleStore().getNode(Graph.ENTAIL_INDEX); } diff --git a/src/main/java/fr/inria/corese/core/edge/EdgeGeneric.java b/src/main/java/fr/inria/corese/core/edge/EdgeGeneric.java index 75e5e4b56..0c8dc30da 100644 --- a/src/main/java/fr/inria/corese/core/edge/EdgeGeneric.java +++ b/src/main/java/fr/inria/corese/core/edge/EdgeGeneric.java @@ -9,13 +9,11 @@ * Buffer Edge as Quad to deliver complete edge for Producer * * @author Olivier Corby, Wimmics, INRIA I3S, 2014 - * */ public class EdgeGeneric extends EdgeTop implements Edge { static int pcount = 0; - public static boolean displayGraph = true; - int index = -1; protected Node graph, predicate, subject, object; + int index = -1; private Object prov; public EdgeGeneric() { @@ -99,6 +97,11 @@ public int getEdgeIndex() { return index; } + @Override + public void setEdgeIndex(int n) { + index = n; + } + @Override public String getEdgeLabel() { return getEdgeNode().getLabel(); @@ -106,26 +109,22 @@ public String getEdgeLabel() { @Override public Node getNode(int n) { - switch (n) { - case Graph.IGRAPH: - return getGraph(); - case 0: - return subject; - case 1: - return object; + if (n == Graph.IGRAPH) { + return getGraph(); + } else if (n == 0) { + return subject; + } else if (n == 1) { + return object; } return null; } @Override public void setNode(int i, Node n) { - switch (i) { - case 0: - subject = n; - break; - case 1: - object = n; - break; + if (i == 0) { + subject = n; + } else if (i == 1) { + object = n; } } @@ -139,11 +138,6 @@ public int nbGraphNode() { return 2; } - @Override - public void setEdgeIndex(int n) { - index = n; - } - @Override public Edge getEdge() { return this; @@ -161,13 +155,11 @@ public void setGraph(Node gNode) { @Override public Node getNode() { - // TODO Auto-generated method stub return DatatypeMap.createObject(this.toString(), this); } @Override public Node getEdgeVariable() { - // TODO Auto-generated method stub return null; } diff --git a/src/main/java/fr/inria/corese/core/edge/EdgeImpl.java b/src/main/java/fr/inria/corese/core/edge/EdgeImpl.java index 7d6fcc59d..1a656f008 100755 --- a/src/main/java/fr/inria/corese/core/edge/EdgeImpl.java +++ b/src/main/java/fr/inria/corese/core/edge/EdgeImpl.java @@ -1,29 +1,29 @@ package fr.inria.corese.core.edge; -import fr.inria.corese.core.sparql.datatype.DatatypeMap; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; -import fr.inria.corese.core.logic.Entailment; -import java.util.Arrays; -import java.util.List; import fr.inria.corese.core.kgram.api.core.Edge; +import fr.inria.corese.core.kgram.api.core.Node; +import fr.inria.corese.core.logic.Entailment; import fr.inria.corese.core.sparql.api.IDatatype; +import fr.inria.corese.core.sparql.datatype.DatatypeMap; + import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** * Graph Edge with n nodes (not only triple) * RDF star triple with reference node t - * g <> + * g <<s p o t>> * * @author Olivier Corby, Edelweiss INRIA 2010 - * */ public class EdgeImpl extends EdgeTop implements Edge { public static boolean displayGraph = true; - int index = -1; protected Node graph, predicate; + int index = -1; Node[] nodes; private boolean metadata; @@ -72,8 +72,7 @@ public static EdgeImpl createMetadata(Node g, Node subject, Node pred, Node obje public static EdgeImpl create(Node g, Node pred, List list) { Node[] nodes = new Node[list.size()]; list.toArray(nodes); - EdgeImpl e = new EdgeImpl(g, pred, nodes); - return e; + return new EdgeImpl(g, pred, nodes); } public static EdgeImpl create(Node g, Node pred, Node[] nodes) { @@ -92,14 +91,14 @@ public EdgeImpl copy() { return ent; } - public void setNodes(Node[] args) { - nodes = args; - } - public Node[] getNodes() { return nodes; } + public void setNodes(Node[] args) { + nodes = args; + } + @Override public void setNode(int i, Node node) { nodes[i] = node; @@ -114,19 +113,18 @@ public void setTag(Node node) { public String toString() { if (isNested()) { return nestedTriple(); - } - else if (nbNode() > 2 && ! DatatypeMap.DISPLAY_AS_TRIPLE) { + } else if (nbNode() > 2 && !DatatypeMap.DISPLAY_AS_TRIPLE) { return tuple(); } return super.toString(); } - + public String nestedTriple() { String str = String.format("<<%s %s %s>>", getNode(0), getEdgeNode(), getNode(1)); if (!DatatypeMap.DISPLAY_AS_TRIPLE && hasReferenceNode()) { str = String.format("%s [%s]", str, getReferenceNode()); } - if (getGraphNode()!=null && !getGraphNode().getLabel().equals(Entailment.DEFAULT)) { + if (getGraphNode() != null && !getGraphNode().getLabel().equals(Entailment.DEFAULT)) { str = String.format("%s %s", getGraphNode(), str); } return str; @@ -142,7 +140,7 @@ public String tuple() { return str; } - String toParse(StringBuilder sb) { + String toParse(StringBuilder sb) { sb.append("tuple("); sb.append(getEdgeNode()); int j = 0; @@ -151,14 +149,13 @@ String toParse(StringBuilder sb) { if (!DatatypeMap.DISPLAY_AS_TRIPLE) { sb.append(" ").append(n); } - } - else { + } else { sb.append(" ").append(n); } } sb.append(")"); - - if (! DatatypeMap.DISPLAY_AS_TRIPLE) { + + if (!DatatypeMap.DISPLAY_AS_TRIPLE) { int i = 0; for (Node n : nodes) { if (i++ < 2) { @@ -169,7 +166,7 @@ String toParse(StringBuilder sb) { } } } - + return sb.toString(); } @@ -198,6 +195,11 @@ public int getEdgeIndex() { return index; } + @Override + public void setEdgeIndex(int n) { + index = n; + } + @Override public String getEdgeLabel() { return getEdgeNode().getLabel(); @@ -226,11 +228,6 @@ public int nbGraphNode() { return nodes.length; } - @Override - public void setEdgeIndex(int n) { - index = n; - } - @Override public Edge getEdge() { return this; @@ -248,13 +245,11 @@ public void setGraph(Node gNode) { @Override public Node getNode() { - // TODO Auto-generated method stub return DatatypeMap.createObject(this.toString(), this); } @Override public Node getEdgeVariable() { - // TODO Auto-generated method stub return null; } @@ -310,7 +305,7 @@ public void setMetadata(boolean metadata) { @Override ArrayList getNodeList() { - ArrayList list = new ArrayList(); + ArrayList list = new ArrayList<>(); for (int i = 0; i <= nodes.length + 1; i++) { list.add(getValue(null, i)); } @@ -321,7 +316,7 @@ ArrayList getNodeList() { * return s p o v1 .. vn g */ @Override - public IDatatype getValue(String var, int n) { + public IDatatype getValue(String varString, int n) { switch (n) { case 0: return nodeValue(getNode(0)); diff --git a/src/main/java/fr/inria/corese/core/edge/EdgeQuad.java b/src/main/java/fr/inria/corese/core/edge/EdgeQuad.java index 232dd99d1..440427cd9 100755 --- a/src/main/java/fr/inria/corese/core/edge/EdgeQuad.java +++ b/src/main/java/fr/inria/corese/core/edge/EdgeQuad.java @@ -6,7 +6,6 @@ * Graph Edge as Quad * * @author Olivier Corby, Wimmics, INRIA I3S, 2014 - * */ public class EdgeQuad extends EdgeTriple { protected Node graph; @@ -14,13 +13,13 @@ public class EdgeQuad extends EdgeTriple { public EdgeQuad() { } - + EdgeQuad(Node g, Node pred, Node subject, Node object) { super(pred, subject, object); this.graph = g; } - - + + public static EdgeQuad create(Node g, Node subject, Node pred, Node object) { return new EdgeQuad(g, pred, subject, object); } diff --git a/src/main/java/fr/inria/corese/core/edge/EdgeTop.java b/src/main/java/fr/inria/corese/core/edge/EdgeTop.java index 8040c47f3..cbf25f11d 100644 --- a/src/main/java/fr/inria/corese/core/edge/EdgeTop.java +++ b/src/main/java/fr/inria/corese/core/edge/EdgeTop.java @@ -1,10 +1,5 @@ package fr.inria.corese.core.edge; -import static fr.inria.corese.core.kgram.api.core.PointerType.TRIPLE; - -import java.util.ArrayList; -import java.util.Objects; - import fr.inria.corese.core.GraphObject; import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.api.core.Node; @@ -14,44 +9,41 @@ import fr.inria.corese.core.sparql.datatype.DatatypeMap; import fr.inria.corese.core.sparql.triple.parser.AccessRight; +import java.util.ArrayList; +import java.util.Objects; + +import static fr.inria.corese.core.kgram.api.core.PointerType.TRIPLE; + /** - * * @author Olivier Corby, Wimmics Inria I3S, 2014 - * */ public abstract class EdgeTop extends GraphObject implements Edge { - private byte level = AccessRight.DEFAULT; public static final String NL = "\n"; + private AccessRight.AccessRights level = AccessRight.DEFAULT; private boolean nested = false; // created by values, bind or triple() private boolean created = false; - public Edge copy() { - return create(getGraph(), getNode(0), getEdgeNode(), getNode(1)); - } - public static Edge create(Node source, Node subject, Node predicate, Node objet) { return null; } + public Edge copy() { + return create(getGraph(), getNode(0), getEdgeNode(), getNode(1)); + } + // manage access right @Override - public byte getLevel() { - // return -1; + public AccessRight.AccessRights getLevel() { return level; } @Override - public Edge setLevel(byte b) { + public Edge setLevel(AccessRight.AccessRights b) { level = b; return this; } - public Edge setLevel(int b) { - level = (byte) b; - return this; - } - @Override public String getDatatypeLabel() { return toString(); @@ -62,14 +54,14 @@ public Node getEdgeNode() { return null; } + public void setEdgeNode(Node pred) { + } + @Override public Node getProperty() { return getEdgeNode(); } - public void setEdgeNode(Node pred) { - } - @Override public void setProperty(Node pred) { setEdgeNode(pred); @@ -111,16 +103,15 @@ ArrayList getNodeList() { } @Override - public IDatatype getValue(String var, int n) { - switch (n) { - case 0: - return nodeValue(getNode(0)); - case 1: - return nodeValue(getEdgeNode()); - case 2: - return nodeValue(getNode(1)); - case 3: - return nodeValue(getGraph()); + public IDatatype getValue(String varString, int n) { + if (n == 0) { + return nodeValue(getNode(0)); + } else if (n == 1) { + return nodeValue(getEdgeNode()); + } else if (n == 2) { + return nodeValue(getNode(1)); + } else if (n == 3) { + return nodeValue(getGraph()); } return null; } diff --git a/src/main/java/fr/inria/corese/core/edge/EdgeTriple.java b/src/main/java/fr/inria/corese/core/edge/EdgeTriple.java index 8477ccebd..1a040f96a 100644 --- a/src/main/java/fr/inria/corese/core/edge/EdgeTriple.java +++ b/src/main/java/fr/inria/corese/core/edge/EdgeTriple.java @@ -1,42 +1,41 @@ package fr.inria.corese.core.edge; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; +import fr.inria.corese.core.kgram.api.core.Node; /** * Graph Edge for the defaultGraph * * @author Olivier Corby, Wimmics, INRIA I3S, 2014 - * */ -public class EdgeTriple extends EdgeBinary { +public class EdgeTriple extends EdgeBinary { protected Node predicate; public EdgeTriple() { } - + public EdgeTriple(Node pred, Node subject, Node object) { this.predicate = pred; this.subject = subject; this.object = object; } - + public static EdgeTriple create(Node source, Node subject, Node pred, Node object) { return new EdgeTriple(pred, subject, object); } - - public String toParse(){ - StringBuilder sb = new StringBuilder(); - sb.append("tuple"); - sb.append("("); - sb.append(getEdgeNode()); - sb.append(subject); - sb.append(" "); - sb.append(object); - sb.append(")"); - return sb.toString(); + + public String toParse() { + StringBuilder sb = new StringBuilder(); + sb.append("tuple"); + sb.append("("); + sb.append(getEdgeNode()); + sb.append(subject); + sb.append(" "); + sb.append(object); + sb.append(")"); + return sb.toString(); } @Override @@ -50,7 +49,7 @@ public void setEdgeNode(Node node) { } @Override - public Node getGraph(){ + public Node getGraph() { return subject.getTripleStore().getNode(Graph.DEFAULT_INDEX); } diff --git a/src/main/java/fr/inria/corese/core/edge/EdgeTripleNode.java b/src/main/java/fr/inria/corese/core/edge/EdgeTripleNode.java index f7fcf76a4..f24d7c7f3 100644 --- a/src/main/java/fr/inria/corese/core/edge/EdgeTripleNode.java +++ b/src/main/java/fr/inria/corese/core/edge/EdgeTripleNode.java @@ -15,51 +15,51 @@ public class EdgeTripleNode extends EdgeTop { private Node graph; private TripleNode triple; - + public EdgeTripleNode(Node g, TripleNode t) { setGraph(g); setTriple(t); } - + public EdgeTripleNode(Node g, Node s, Node p, Node o) { setGraph(g); setTriple(new TripleNode(s, p, o)); } - + public EdgeTripleNode copy(Node graphNode) { return new EdgeTripleNode(graphNode, getTripleNode()); } - + // TripleNode as Triple reference node public IDatatype createTripleReference() { return getTriple().createTripleReference(); } - + public IDatatype createTripleReference(Graph g) { return getTriple().createTripleReference(g); } - + @Override public boolean isTripleNode() { return true; } - + @Override public String toString() { - return String.format(isNested()?"%s <<%s>> [%s]":"%s %s [%s]", + return String.format(isNested() ? "%s <<%s>> [%s]" : "%s %s [%s]", getGraph(), getTriple(), getTriple().getDatatypeValue().getLabel()); - } + } @Override public Node getGraph() { return graph; } - + @Override public void setGraph(Node graph) { this.graph = graph; } - + /** * for sparql query processing there are 3 nodes: s o t */ @@ -67,7 +67,7 @@ public void setGraph(Node graph) { public int nbNode() { return 3; } - + /** * For graph index processing there are 2 nodes: s o */ @@ -75,7 +75,7 @@ public int nbNode() { public int nbNodeIndex() { return 2; } - + @Override public Node getNode(int n) { switch (n) { @@ -90,7 +90,7 @@ public Node getNode(int n) { } return null; } - + @Override public Node getEdgeNode() { return getTriple().getPropertyNode(); @@ -100,20 +100,20 @@ public Node getEdgeNode() { public void setEdgeNode(Node pred) { getTriple().setPropertyNode(pred); } - - + + @Override public TripleNode getTripleNode() { return triple; } - + @Override public void setTripleNode(Node node) { if (node instanceof TripleNode) { setTriple((TripleNode) node); } } - + public TripleNode getTriple() { return triple; } @@ -121,5 +121,5 @@ public TripleNode getTriple() { public void setTriple(TripleNode triple) { this.triple = triple; } - + } diff --git a/src/main/java/fr/inria/corese/core/edge/TripleNode.java b/src/main/java/fr/inria/corese/core/edge/TripleNode.java index b1e36240a..7f14fc480 100644 --- a/src/main/java/fr/inria/corese/core/edge/TripleNode.java +++ b/src/main/java/fr/inria/corese/core/edge/TripleNode.java @@ -7,92 +7,90 @@ import fr.inria.corese.core.sparql.api.IDatatype; /** - * Node that is a Triple + * Node that is a Triple * Can be used as Node in the graph * Can be subject/object of an Edge + * * @todo: function getIndex() is the same here for Node and Edge -> * rename to getEdgeIndex() or getNodeIndex() * It is not a pb because it is mostly used as Node */ -public class TripleNode extends NodeImpl implements Edge -{ +public class TripleNode extends NodeImpl implements Edge { private Node subject; private Node predicate; private Node object; - + public TripleNode(Node s, Node p, Node o) { setSubjectNode(s); setPropertyNode(p); setObjectNode(o); } - + @Override public String toString() { return String.format("%s %s %s", pretty(getSubjectNode()), getPropertyNode(), pretty(getObjectNode())); } - + @Override - public Node getNode(){ + public Node getNode() { return this; } - + @Override public Edge getEdge() { return this; } - + @Override public boolean isTripleNode() { return true; } - + String pretty(Node n) { if (n.isTriple()) { return String.format("<<%s>>", n); } return n.toString(); } - + @Override public String getEdgeLabel() { return getPropertyNode().getLabel(); } - + public IDatatype createTripleReference() { if (getTripleStore() == null) { return null; } - return createTripleReference(getTripleStore()); + return createTripleReference(getTripleStore()); } - + public IDatatype createTripleReference(Graph g) { setDatatypeValue(g.createTripleReference( - getSubjectNode(), getPropertyNode(), getObjectNode())); + getSubjectNode(), getPropertyNode(), getObjectNode())); return getDatatypeValue(); } - + @Override public Graph getTripleStore() { return (Graph) getSubjectNode().getTripleStore(); } - - //@Override + public Node getNode(int n) { - switch (n) { - case 0: - return getSubjectNode(); - case 1: - return getObjectNode(); + if (n == 0) { + return getSubjectNode(); + } else if (n == 1) { + return getObjectNode(); } return null; } - + @Override public Node getGraph() { return null; } - - //@Override + + @Override public Node getSubjectNode() { return subject; } @@ -100,13 +98,12 @@ public Node getSubjectNode() { public void setSubjectNode(Node subject) { this.subject = subject; } - - //@Override + public Node getProperty() { return predicate; } - //@Override + @Override public Node getPropertyNode() { return predicate; } @@ -115,7 +112,7 @@ public void setPropertyNode(Node predicate) { this.predicate = predicate; } - //@Override + @Override public Node getObjectNode() { return object; } diff --git a/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinaryFirst.java b/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinaryFirst.java index aa9183874..b55ea2e11 100644 --- a/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinaryFirst.java +++ b/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinaryFirst.java @@ -1,22 +1,21 @@ package fr.inria.corese.core.edge.binary; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; import fr.inria.corese.core.edge.EdgeBinary; +import fr.inria.corese.core.kgram.api.core.Node; /** * Graph Edge for the defaultGraph - * - * @author Olivier Corby, Wimmics INRIA I3S, 2016 * + * @author Olivier Corby, Wimmics INRIA I3S, 2016 */ public class EdgeBinaryFirst extends EdgeBinary { EdgeBinaryFirst(Node subject, Node object) { super(subject, object); } - - public static EdgeBinaryFirst create(Node source, Node subject, Node predicate, Node object){ + + public static EdgeBinaryFirst create(Node source, Node subject, Node predicate, Node object) { return new EdgeBinaryFirst(subject, object); } diff --git a/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinaryLabel.java b/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinaryLabel.java index 311f0ee9d..a4a551aac 100644 --- a/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinaryLabel.java +++ b/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinaryLabel.java @@ -1,22 +1,21 @@ package fr.inria.corese.core.edge.binary; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; import fr.inria.corese.core.edge.EdgeBinary; +import fr.inria.corese.core.kgram.api.core.Node; /** * Graph Edge for the defaultGraph - * - * @author Olivier Corby, Wimmics INRIA I3S, 2016 * + * @author Olivier Corby, Wimmics INRIA I3S, 2016 */ public class EdgeBinaryLabel extends EdgeBinary { EdgeBinaryLabel(Node subject, Node object) { super(subject, object); } - - public static EdgeBinaryLabel create(Node source, Node subject, Node predicate, Node object){ + + public static EdgeBinaryLabel create(Node source, Node subject, Node predicate, Node object) { return new EdgeBinaryLabel(subject, object); } diff --git a/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinaryRest.java b/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinaryRest.java index 4e1530830..61d9882fb 100644 --- a/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinaryRest.java +++ b/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinaryRest.java @@ -1,22 +1,21 @@ package fr.inria.corese.core.edge.binary; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; import fr.inria.corese.core.edge.EdgeBinary; +import fr.inria.corese.core.kgram.api.core.Node; /** * Graph Edge for the defaultGraph - * - * @author Olivier Corby, Wimmics INRIA I3S, 2016 * + * @author Olivier Corby, Wimmics INRIA I3S, 2016 */ public class EdgeBinaryRest extends EdgeBinary { EdgeBinaryRest(Node subject, Node object) { super(subject, object); } - - public static EdgeBinaryRest create(Node source, Node subject, Node predicate, Node object){ + + public static EdgeBinaryRest create(Node source, Node subject, Node predicate, Node object) { return new EdgeBinaryRest(subject, object); } diff --git a/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinarySubclass.java b/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinarySubclass.java index 0237bff3e..5e3b2c63c 100644 --- a/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinarySubclass.java +++ b/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinarySubclass.java @@ -1,22 +1,21 @@ package fr.inria.corese.core.edge.binary; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; import fr.inria.corese.core.edge.EdgeBinary; +import fr.inria.corese.core.kgram.api.core.Node; /** * Graph Edge for the defaultGraph - * - * @author Olivier Corby, Wimmics INRIA I3S, 2016 * + * @author Olivier Corby, Wimmics INRIA I3S, 2016 */ public class EdgeBinarySubclass extends EdgeBinary { EdgeBinarySubclass(Node subject, Node object) { super(subject, object); } - - public static EdgeBinarySubclass create(Node source, Node subject, Node predicate, Node object){ + + public static EdgeBinarySubclass create(Node source, Node subject, Node predicate, Node object) { return new EdgeBinarySubclass(subject, object); } diff --git a/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinaryType.java b/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinaryType.java index f4af4776f..dc52c12fa 100644 --- a/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinaryType.java +++ b/src/main/java/fr/inria/corese/core/edge/binary/EdgeBinaryType.java @@ -1,22 +1,21 @@ package fr.inria.corese.core.edge.binary; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; import fr.inria.corese.core.edge.EdgeBinary; +import fr.inria.corese.core.kgram.api.core.Node; /** * Graph Edge for the defaultGraph - * - * @author Olivier Corby, Wimmics INRIA I3S, 2016 * + * @author Olivier Corby, Wimmics INRIA I3S, 2016 */ public class EdgeBinaryType extends EdgeBinary { EdgeBinaryType(Node subject, Node object) { super(subject, object); } - - public static EdgeBinaryType create(Node source, Node subject, Node predicate, Node object){ + + public static EdgeBinaryType create(Node source, Node subject, Node predicate, Node object) { return new EdgeBinaryType(subject, object); } diff --git a/src/main/java/fr/inria/corese/core/edge/internal/EdgeInternal.java b/src/main/java/fr/inria/corese/core/edge/internal/EdgeInternal.java index 67648cb1f..33e68be6c 100644 --- a/src/main/java/fr/inria/corese/core/edge/internal/EdgeInternal.java +++ b/src/main/java/fr/inria/corese/core/edge/internal/EdgeInternal.java @@ -8,38 +8,37 @@ * Graph Edge for internal storage * * @author Olivier Corby, Wimmics, INRIA I3S, 2014 - * */ -public class EdgeInternal extends EdgeBinary { +public class EdgeInternal extends EdgeBinary { protected Node graph; public EdgeInternal() { } - + EdgeInternal(Node graph, Node subject, Node object) { this.graph = graph; this.subject = subject; this.object = object; - } - - public static EdgeInternal create(Node graph, Node subject, Node predicate, Node object){ + } + + public static EdgeInternal create(Node graph, Node subject, Node predicate, Node object) { return new EdgeInternal(graph, subject, object); } - - public static EdgeInternal create(Edge edge){ + + public static EdgeInternal create(Edge edge) { return new EdgeInternal(edge.getGraph(), edge.getNode(0), edge.getNode(1)); } - - @Override - public Node getGraph(){ + + @Override + public Node getGraph() { return graph; } - + @Override - public void setGraph(Node g){ - graph = g; - } - + public void setGraph(Node g) { + graph = g; + } + } diff --git a/src/main/java/fr/inria/corese/core/edge/internal/EdgeInternalDefault.java b/src/main/java/fr/inria/corese/core/edge/internal/EdgeInternalDefault.java index 59c2c8b05..258db9768 100644 --- a/src/main/java/fr/inria/corese/core/edge/internal/EdgeInternalDefault.java +++ b/src/main/java/fr/inria/corese/core/edge/internal/EdgeInternalDefault.java @@ -1,38 +1,37 @@ package fr.inria.corese.core.edge.internal; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; import fr.inria.corese.core.edge.EdgeBinary; import fr.inria.corese.core.kgram.api.core.Edge; +import fr.inria.corese.core.kgram.api.core.Node; /** * Graph Edge for internal storage * * @author Olivier Corby, Wimmics, INRIA I3S, 2014 - * */ -public class EdgeInternalDefault extends EdgeBinary { +public class EdgeInternalDefault extends EdgeBinary { public EdgeInternalDefault() { } - + EdgeInternalDefault(Node subject, Node object) { super(subject, object); - } - - public static EdgeInternalDefault create(Node graph, Node subject, Node predicate, Node object){ + } + + public static EdgeInternalDefault create(Node graph, Node subject, Node predicate, Node object) { return new EdgeInternalDefault(subject, object); } - - public static EdgeInternalDefault create(Edge edge){ + + public static EdgeInternalDefault create(Edge edge) { return new EdgeInternalDefault(edge.getNode(0), edge.getNode(1)); } - - @Override - public Node getGraph(){ + + @Override + public Node getGraph() { return subject.getTripleStore().getNode(Graph.DEFAULT_INDEX); } - + } diff --git a/src/main/java/fr/inria/corese/core/edge/internal/EdgeInternalEntail.java b/src/main/java/fr/inria/corese/core/edge/internal/EdgeInternalEntail.java index aa32461e9..06bdab96e 100644 --- a/src/main/java/fr/inria/corese/core/edge/internal/EdgeInternalEntail.java +++ b/src/main/java/fr/inria/corese/core/edge/internal/EdgeInternalEntail.java @@ -1,38 +1,37 @@ package fr.inria.corese.core.edge.internal; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; import fr.inria.corese.core.edge.EdgeBinary; import fr.inria.corese.core.kgram.api.core.Edge; +import fr.inria.corese.core.kgram.api.core.Node; /** * Graph Edge for internal storage * * @author Olivier Corby, Wimmics, INRIA I3S, 2014 - * */ -public class EdgeInternalEntail extends EdgeBinary { +public class EdgeInternalEntail extends EdgeBinary { public EdgeInternalEntail() { } - + EdgeInternalEntail(Node subject, Node object) { super(subject, object); - } - - public static EdgeInternalEntail create(Node graph, Node subject, Node predicate, Node object){ + } + + public static EdgeInternalEntail create(Node graph, Node subject, Node predicate, Node object) { return new EdgeInternalEntail(subject, object); } - - public static EdgeInternalEntail create(Edge edge){ + + public static EdgeInternalEntail create(Edge edge) { return new EdgeInternalEntail(edge.getNode(0), edge.getNode(1)); } - - @Override - public Node getGraph(){ + + @Override + public Node getGraph() { return subject.getTripleStore().getNode(Graph.ENTAIL_INDEX); } - + } diff --git a/src/main/java/fr/inria/corese/core/edge/internal/EdgeInternalRule.java b/src/main/java/fr/inria/corese/core/edge/internal/EdgeInternalRule.java index 1eb8218a9..3fa567ed8 100644 --- a/src/main/java/fr/inria/corese/core/edge/internal/EdgeInternalRule.java +++ b/src/main/java/fr/inria/corese/core/edge/internal/EdgeInternalRule.java @@ -1,33 +1,32 @@ package fr.inria.corese.core.edge.internal; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; import fr.inria.corese.core.edge.EdgeBinary; +import fr.inria.corese.core.kgram.api.core.Node; /** * Graph Edge for internal storage * * @author Olivier Corby, Wimmics, INRIA I3S, 2014 - * */ -public class EdgeInternalRule extends EdgeBinary { +public class EdgeInternalRule extends EdgeBinary { public EdgeInternalRule() { } - + EdgeInternalRule(Node subject, Node object) { super(subject, object); - } - - public static EdgeInternalRule create(Node subject, Node object){ + } + + public static EdgeInternalRule create(Node subject, Node object) { return new EdgeInternalRule(subject, object); } - - @Override - public Node getGraph(){ + + @Override + public Node getGraph() { return subject.getTripleStore().getNode(Graph.RULE_INDEX); } - + } diff --git a/src/main/java/fr/inria/corese/core/edge/rule/EdgeRule.java b/src/main/java/fr/inria/corese/core/edge/rule/EdgeRule.java index 2ff955ebc..1be13066a 100644 --- a/src/main/java/fr/inria/corese/core/edge/rule/EdgeRule.java +++ b/src/main/java/fr/inria/corese/core/edge/rule/EdgeRule.java @@ -1,55 +1,54 @@ package fr.inria.corese.core.edge.rule; -import fr.inria.corese.core.sparql.datatype.DatatypeMap; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; import fr.inria.corese.core.edge.EdgeTriple; +import fr.inria.corese.core.kgram.api.core.Node; +import fr.inria.corese.core.sparql.datatype.DatatypeMap; /** * Edge entailed by a Rule * index and provenance - * - * @author Olivier Corby, Wimmics INRIA I3S, 2016 * + * @author Olivier Corby, Wimmics INRIA I3S, 2016 */ public class EdgeRule extends EdgeTriple { static int pcount = 0; int index = -1; Object prov; - - EdgeRule(Node source, Node pred, Node subject, Node object){ + + EdgeRule(Node source, Node pred, Node subject, Node object) { super(pred, subject, object); } - + public static EdgeRule create(Node source, Node subject, Node pred, Node object) { return new EdgeRule(source, pred, subject, object); } - + @Override - public int getEdgeIndex(){ + public int getEdgeIndex() { return index; } - + @Override - public void setEdgeIndex(int i){ + public void setEdgeIndex(int i) { index = i; } - - @Override + + @Override public Object getProvenance() { - if (prov != null && ! (prov instanceof Node)) { + if (prov != null && !(prov instanceof Node)) { prov = DatatypeMap.createObject("p" + pcount++, prov); } return prov; } - - @Override - public void setProvenance(Object obj) { + + @Override + public void setProvenance(Object obj) { prov = obj; } - + @Override - public Node getGraph(){ + public Node getGraph() { return subject.getTripleStore().getNode(Graph.RULE_INDEX); } diff --git a/src/main/java/fr/inria/corese/core/edge/rule/EdgeRuleGraph.java b/src/main/java/fr/inria/corese/core/edge/rule/EdgeRuleGraph.java index 4b2d1dede..2be228e27 100644 --- a/src/main/java/fr/inria/corese/core/edge/rule/EdgeRuleGraph.java +++ b/src/main/java/fr/inria/corese/core/edge/rule/EdgeRuleGraph.java @@ -1,25 +1,23 @@ package fr.inria.corese.core.edge.rule; -import fr.inria.corese.core.sparql.datatype.DatatypeMap; import fr.inria.corese.core.kgram.api.core.Node; /** * Edge entailed by a Rule * index and provenance - * - * @author Olivier Corby, Wimmics INRIA I3S, 2016 * + * @author Olivier Corby, Wimmics INRIA I3S, 2016 */ public class EdgeRuleGraph extends EdgeRule { private Node graph; - - public EdgeRuleGraph(Node source, Node pred, Node subject, Node object){ - super(source, pred, subject, object); + + public EdgeRuleGraph(Node source, Node pred, Node subject, Node object) { + super(source, pred, subject, object); setGraph(source); } - + @Override - public Node getGraph(){ + public Node getGraph() { return graph; } diff --git a/src/main/java/fr/inria/corese/core/edge/rule/EdgeRuleSubclass.java b/src/main/java/fr/inria/corese/core/edge/rule/EdgeRuleSubclass.java index 36e48fe36..c6fae227d 100644 --- a/src/main/java/fr/inria/corese/core/edge/rule/EdgeRuleSubclass.java +++ b/src/main/java/fr/inria/corese/core/edge/rule/EdgeRuleSubclass.java @@ -1,22 +1,21 @@ package fr.inria.corese.core.edge.rule; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; +import fr.inria.corese.core.kgram.api.core.Node; /** * Edge entailed by a Rule * index and provenance - * - * @author Olivier Corby, Wimmics INRIA I3S, 2016 * + * @author Olivier Corby, Wimmics INRIA I3S, 2016 */ public class EdgeRuleSubclass extends EdgeRuleTop { EdgeRuleSubclass(Node subject, Node object) { super(subject, object); } - - public static EdgeRuleSubclass create(Node source, Node subject, Node predicate, Node object){ + + public static EdgeRuleSubclass create(Node source, Node subject, Node predicate, Node object) { return new EdgeRuleSubclass(subject, object); } diff --git a/src/main/java/fr/inria/corese/core/edge/rule/EdgeRuleTop.java b/src/main/java/fr/inria/corese/core/edge/rule/EdgeRuleTop.java index 2fb2dc47b..bdaf2d3ee 100644 --- a/src/main/java/fr/inria/corese/core/edge/rule/EdgeRuleTop.java +++ b/src/main/java/fr/inria/corese/core/edge/rule/EdgeRuleTop.java @@ -1,51 +1,50 @@ package fr.inria.corese.core.edge.rule; -import fr.inria.corese.core.sparql.datatype.DatatypeMap; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; import fr.inria.corese.core.edge.EdgeBinary; +import fr.inria.corese.core.kgram.api.core.Node; +import fr.inria.corese.core.sparql.datatype.DatatypeMap; /** * Edge entailed by a Rule * index and provenance - * - * @author Olivier Corby, Wimmics INRIA I3S, 2016 * + * @author Olivier Corby, Wimmics INRIA I3S, 2016 */ public abstract class EdgeRuleTop extends EdgeBinary { static int pcount = 0; int index = -1; Object prov; - - EdgeRuleTop (Node subject, Node object){ - super(subject, object); - } - + + EdgeRuleTop(Node subject, Node object) { + super(subject, object); + } + @Override - public int getEdgeIndex(){ + public int getEdgeIndex() { return index; } - + @Override - public void setEdgeIndex(int i){ + public void setEdgeIndex(int i) { index = i; } - - @Override + + @Override public Object getProvenance() { - if (prov != null && ! (prov instanceof Node)) { + if (prov != null && !(prov instanceof Node)) { prov = DatatypeMap.createObject("p" + pcount++, prov); } return prov; } - - @Override - public void setProvenance(Object obj) { + + @Override + public void setProvenance(Object obj) { prov = obj; } - + @Override - public Node getGraph(){ + public Node getGraph() { return subject.getTripleStore().getNode(Graph.RULE_INDEX); } diff --git a/src/main/java/fr/inria/corese/core/edge/rule/EdgeRuleType.java b/src/main/java/fr/inria/corese/core/edge/rule/EdgeRuleType.java index 6ffd28c9d..14ac24f47 100644 --- a/src/main/java/fr/inria/corese/core/edge/rule/EdgeRuleType.java +++ b/src/main/java/fr/inria/corese/core/edge/rule/EdgeRuleType.java @@ -1,22 +1,21 @@ package fr.inria.corese.core.edge.rule; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; +import fr.inria.corese.core.kgram.api.core.Node; /** * Edge entailed by a Rule * index and provenance - * - * @author Olivier Corby, Wimmics INRIA I3S, 2016 * + * @author Olivier Corby, Wimmics INRIA I3S, 2016 */ public class EdgeRuleType extends EdgeRuleTop { EdgeRuleType(Node subject, Node object) { super(subject, object); } - - public static EdgeRuleType create(Node source, Node subject, Node predicate, Node object){ + + public static EdgeRuleType create(Node source, Node subject, Node predicate, Node object) { return new EdgeRuleType(subject, object); } @@ -24,5 +23,5 @@ public static EdgeRuleType create(Node source, Node subject, Node predicate, Nod public Node getEdgeNode() { return subject.getTripleStore().getNode(Graph.TYPE_INDEX); } - + } diff --git a/src/main/java/fr/inria/corese/core/extension/Agent.java b/src/main/java/fr/inria/corese/core/extension/Agent.java index c910f8955..0aa8fee03 100644 --- a/src/main/java/fr/inria/corese/core/extension/Agent.java +++ b/src/main/java/fr/inria/corese/core/extension/Agent.java @@ -1,128 +1,121 @@ package fr.inria.corese.core.extension; import fr.inria.corese.core.Graph; +import fr.inria.corese.core.load.LoadException; import fr.inria.corese.core.rule.RuleEngine; import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.datatype.DatatypeMap; import fr.inria.corese.core.sparql.exceptions.EngineException; import fr.inria.corese.core.sparql.triple.parser.NSManager; -import java.util.logging.Level; -import java.util.logging.Logger; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * * Agent Java object accessible in LDScript with xt:agent() (see function/system.rq) * It has a singleton, hence each ag:fun() function call is performed on the same object * The singleton can be accessed in LDScript using xt:agent() - * - * prefix ag: - * + *

+ * prefix ag: <function://fr.inria.corese.core.extension.Agent> + *

* IDatatype ag:functionName(IDatatype arg) - * + *

* IDatatype java:functionName(xt:agent(), IDatatype arg) * IDatatype java:functionName(xt:agent(), JavaType arg) * . */ -public class Agent { - +public class Agent { + + private static final Logger logger = LoggerFactory.getLogger(Agent.class); + static final String NS = NSManager.USER; - static final String ENTAILMENT = NS+"entailment"; - static final String TEST = NS+"test"; - - private static Agent singleton; - private static IDatatype dt; - private String name; - private Graph graph; - - private IDatatype value, uri; - + static final String ENTAILMENT = NS + "entailment"; + static final String TEST = NS + "test"; + + private static final Agent singleton; + private static final IDatatype dt; + static { singleton = new Agent("main"); dt = DatatypeMap.createObject(singleton()); } - + + private String name; + private Graph graph; + private IDatatype value; + private IDatatype uri; + public Agent() { this("proxy"); } - + public Agent(String n) { setName(n); } - + /** - * Function singleton() enables ag:fun() SPARQL Extension Function (Extern) - * to be called on the same singleton agent + * Function singleton() enables ag:fun() SPARQL Extension Function (Extern) + * to be called on the same singleton agent * otherwise an agent object would be created for each function call. */ public static Agent singleton() { return singleton; } - - - - - - public IDatatype setURI(IDatatype dt) { - uri = dt; - return dt; - } - - public IDatatype getURI() { + + public static IDatatype getDatatypeValue() { + return dt; + } + + public IDatatype setURI(IDatatype dt) { + uri = dt; + return dt; + } + + public IDatatype getURI() { return uri; - } - - public IDatatype message(IDatatype name) { - switch (name.getLabel()) { - case ENTAILMENT: entailment(); break; - case TEST: test(); break; - } - return name; - } - - public IDatatype message(IDatatype name, IDatatype dt) { - switch (name.getLabel()) { - case ENTAILMENT: entailment(); break; - } - return name; - } - - public IDatatype message(IDatatype name, IDatatype... args) { - switch (name.getLabel()) { - case ENTAILMENT: entailment(); break; - } - return name; - } - - - - IDatatype test() { - System.out.println("test"); - return DatatypeMap.TRUE; - } - - + } + + public IDatatype message(IDatatype name) { + String label = name.getLabel(); + if (ENTAILMENT.equals(label)) { + entailment(); + } else if (TEST.equals(label)) { + test(); + } + return name; + } + + public IDatatype message(IDatatype name, IDatatype dt) { + if (ENTAILMENT.equals(name.getLabel())) { + entailment(); + } + return name; + } + + public IDatatype message(IDatatype name, IDatatype... args) { + if (ENTAILMENT.equals(name.getLabel())) { + entailment(); + } + return name; + } + + IDatatype test() { + return DatatypeMap.TRUE; + } + void entailment() { if (getGraph() != null) { RuleEngine re = RuleEngine.create(graph); - re.setProfile(RuleEngine.OWL_RL); try { + re.setProfile(RuleEngine.Profile.OWLRL); re.process(); - } catch (EngineException ex) { - Logger.getLogger(Agent.class.getName()).log(Level.SEVERE, null, ex); + } catch (EngineException | LoadException ex) { + logger.error("An unexpected error has occurred", ex); } } } - - - - - - - public static IDatatype getDatatypeValue() { - return dt; - } - - + /** * @return the name */ @@ -158,10 +151,10 @@ public IDatatype setValue(IDatatype value) { public Graph getGraph() { return graph; } - + public void setGraph(Graph g) { graph = g; } - + } diff --git a/src/main/java/fr/inria/corese/core/extension/Callback.java b/src/main/java/fr/inria/corese/core/extension/Callback.java index 5e131a31a..2700ee88a 100644 --- a/src/main/java/fr/inria/corese/core/extension/Callback.java +++ b/src/main/java/fr/inria/corese/core/extension/Callback.java @@ -4,16 +4,13 @@ import fr.inria.corese.core.sparql.datatype.DatatypeMap; /** - * * @author corby */ public class Callback extends Core { - + public IDatatype report(IDatatype name, IDatatype node) { - System.out.println("report: " + name + " " + node); return DatatypeMap.TRUE; } - - - + + } diff --git a/src/main/java/fr/inria/corese/core/extension/Core.java b/src/main/java/fr/inria/corese/core/extension/Core.java index 68deb8e26..5024bb52b 100644 --- a/src/main/java/fr/inria/corese/core/extension/Core.java +++ b/src/main/java/fr/inria/corese/core/extension/Core.java @@ -1,68 +1,71 @@ package fr.inria.corese.core.extension; import fr.inria.corese.core.Graph; -import fr.inria.corese.core.query.PluginImpl; -import fr.inria.corese.core.transform.Transformer; -import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.api.core.PointerType; import fr.inria.corese.core.kgram.api.query.Environment; import fr.inria.corese.core.kgram.api.query.Producer; import fr.inria.corese.core.kgram.core.Mappings; +import fr.inria.corese.core.query.PluginImpl; import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.datatype.DatatypeMap; import fr.inria.corese.core.sparql.exceptions.EngineException; import fr.inria.corese.core.sparql.exceptions.SafetyException; import fr.inria.corese.core.sparql.triple.function.core.FunctionEvaluator; import fr.inria.corese.core.sparql.triple.function.extension.IOFunction; -import fr.inria.corese.core.sparql.triple.parser.NSManager; import fr.inria.corese.core.sparql.triple.parser.Access.Level; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; +import fr.inria.corese.core.sparql.triple.parser.NSManager; +import fr.inria.corese.core.transform.Transformer; + import java.util.Arrays; import java.util.HashMap; -import java.util.logging.Logger; + +import fr.inria.corese.core.transform.TransformerUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * Super class for Java extension function class - * public class Myclass extends Core + * Super class for Java extension function class + * public class Myclass extends Core * Extension function called with prefix: * function://fr.inria.corese.core.extension.Myclass * See sparql.triple.function.core.Extern - * + *

* Use case: JavaCompiler compiles SHACL Interpreter * * @author Olivier Corby, Wimmics INRIA I3S, 2017-2019 */ public class Core extends PluginImpl implements FunctionEvaluator { + private static final Logger logger = LoggerFactory.getLogger(Core.class); + private static final String MSH = "http://ns.inria.fr/shacl/"; static Class[][] signature; static HashMap prefix; - HashMap functionName; static { init(); } - static void init() { - defSignature(); - defNamespace(); - } - + HashMap functionName; + public Core() { functionName = new HashMap<>(); defFunction(); } - + + static void init() { + defSignature(); + defNamespace(); + } + static HashMap getPrefix() { return prefix; } - + static void define(String pref, String ns) { prefix.put(pref, ns); } - + /** * Define prefix namespace for funcall(sh:fun) * because functions are defined as sh_fun() @@ -72,7 +75,7 @@ static void defNamespace() { define("sh", NSManager.SHAPE); define("msh", MSH); } - + static void defSignature() { signature = new Class[20][]; for (int i = 0; i < signature.length; i++) { @@ -81,26 +84,21 @@ static void defSignature() { signature[i] = sig; } } - + void defFunction() { - functionName.put(NSManager.EXT+"member", "member"); + functionName.put(NSManager.EXT + "member", "member"); } @Override public void setProducer(Producer producer) { super.setProducer(producer); } - + @Override public void setEnvironment(Environment env) { super.setEnvironment(env); } - - - - - - + /** * Mappings map Return value of var in first Mapping Use case: bind (exists @@ -114,21 +112,11 @@ IDatatype mapget(IDatatype m, IDatatype var) { if (map.size() == 0) { return null; } - return map.getValue(var.getLabel()); - } - - IDatatype xt_print(IDatatype... dt) { - for (IDatatype val : dt) { - System.out.print(dt); - System.out.println(" "); - } - System.out.println(); - return TRUE; + return map.getValue(var.getLabel()); } IDatatype xt_load(IDatatype... dt) { try { - //return new GraphSpecificFunction("load").load(this, dt, null, null, Level.DEFAULT); return load(null, dt[0], null, null, null, Level.USER_DEFAULT); } catch (SafetyException ex) { logger.error(ex.getMessage()); @@ -148,23 +136,6 @@ IDatatype xt_value(IDatatype s, IDatatype p) { return value(null, getProducer(), null, s, p, 1); } -// IDatatype xt_objects(IDatatype s, IDatatype p) { -// return enumerate(s, p, null, 1); -// } -// -// IDatatype xt_subjects(IDatatype p, IDatatype o) { -// return enumerate(null, p, o, 0); -// } -// -// IDatatype enumerate(IDatatype s, IDatatype p, IDatatype o, int n) { -// ArrayList list = new ArrayList<>(); -// for (IDatatype dt : edge(null, getProducer(), s, p, o)) { -// Edge edge = dt.getPointerObject().getEdge(); -// list.add( edge.getNode(n).getDatatypeValue()); -// } -// return DatatypeMap.newList(list); -// } - IDatatype xt_insert(IDatatype... ldt) { return insert(null, getProducer(), ldt); } @@ -182,42 +153,32 @@ Graph getGraph(IDatatype dt) { IDatatype xt_turtle(IDatatype x) { if (x.isLiteral() && x.getDatatypeURI().equals(IDatatype.GRAPH_DATATYPE)) { try { - Transformer t = Transformer.create(getGraph(x), Transformer.TURTLE); + Transformer t = Transformer.create(getGraph(x), TransformerUtils.TURTLE); return t.process(); } catch (EngineException ex) { - Logger.getLogger(Core.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + logger.error("An unexpected error has occurred", ex); } } else { - Transformer t = Transformer.create(getGraph(), Transformer.TURTLE); + Transformer t = Transformer.create(getGraph(), TransformerUtils.TURTLE); try { return t.process(x); } catch (EngineException ex) { - Logger.getLogger(Core.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + logger.error("An unexpected error has occurred", ex); } } return x; } IDatatype xt_turtle(IDatatype g, IDatatype x) { - Transformer t = Transformer.create(getGraph(g), Transformer.TURTLE); + Transformer t = Transformer.create(getGraph(g), TransformerUtils.TURTLE); try { return t.process(x); } catch (EngineException ex) { - Logger.getLogger(Core.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); + logger.error("An unexpected error has occurred", ex); } return x; } - - - void trace(Object... lobj) { - for (Object obj : lobj) { - System.out.print(obj); - System.out.print(" "); - } - System.out.println(""); - } - /** * funcall(sh:shacl) * -> @@ -235,38 +196,28 @@ String javaName(IDatatype fun) { return name; } } - } - else { + } else { return name; } - //functionName.put(str, str); return str; } - + public HashMap getFunctionName() { return functionName; } - - public void trace() { - HashMap map = getFunctionName(); - int i = 0; - for (String key : map.keySet()) { - System.out.println(i++ + " " + map.get(key)); + + public IDatatype safe(IDatatype dt) { + return (dt == null) ? DatatypeMap.FALSE : DatatypeMap.TRUE; + } + + // rq:gt -> gt + String datatypeName(String name) { + if (name.startsWith(NSManager.SPARQL)) { + return name.substring(NSManager.SPARQL.length()); } + return null; } - - public IDatatype safe(IDatatype dt) { - return (dt == null) ? FALSE : TRUE; - } - // rq:gt -> gt - String datatypeName(String name) { - if (name.startsWith(NSManager.SPARQL)) { - return name.substring(NSManager.SPARQL.length()); - } - return null; - } - void prepare(IDatatype[] ldt) { for (int i = 1; i < ldt.length; i++) { @@ -277,8 +228,6 @@ void prepare(IDatatype[] ldt) { } } - - IDatatype dt_list(IDatatype dt) { if (dt.isList()) { @@ -302,10 +251,6 @@ IDatatype xt_validURI(IDatatype dt) { return new IOFunction("validURI").validURI(dt); } -// IDatatype xt_sparql(IDatatype q, IDatatype... dt) { -// return kgram(q, dt); -// } - IDatatype xt_replace(IDatatype str, IDatatype x, IDatatype y) { return DatatypeMap.newInstance(str.getLabel().replace(x.getLabel(), y.getLabel())); } @@ -322,6 +267,5 @@ IDatatype st_turtle(IDatatype dt) { return xt_turtle(dt); } - } diff --git a/src/main/java/fr/inria/corese/core/extension/Extension.java b/src/main/java/fr/inria/corese/core/extension/Extension.java index e1dd6181b..eacb780b8 100644 --- a/src/main/java/fr/inria/corese/core/extension/Extension.java +++ b/src/main/java/fr/inria/corese/core/extension/Extension.java @@ -1,7 +1,14 @@ package fr.inria.corese.core.extension; -import fr.inria.corese.core.compiler.eval.QuerySolverVisitor; import fr.inria.corese.core.Graph; +import fr.inria.corese.core.compiler.eval.QuerySolverVisitor; +import fr.inria.corese.core.kgram.api.core.Edge; +import fr.inria.corese.core.kgram.api.core.Node; +import fr.inria.corese.core.kgram.api.query.ProcessVisitor; +import fr.inria.corese.core.kgram.core.Mapping; +import fr.inria.corese.core.kgram.core.Mappings; +import fr.inria.corese.core.kgram.core.ProcessVisitorDefault; +import fr.inria.corese.core.kgram.core.Query; import fr.inria.corese.core.load.LoadException; import fr.inria.corese.core.load.Service; import fr.inria.corese.core.logic.Distance; @@ -11,14 +18,6 @@ import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.rule.Cleaner; import fr.inria.corese.core.rule.RuleEngine; -import fr.inria.corese.core.visitor.solver.QuerySolverVisitorRule; -import fr.inria.corese.core.kgram.api.core.Edge; -import fr.inria.corese.core.kgram.api.core.Node; -import fr.inria.corese.core.kgram.api.query.ProcessVisitor; -import fr.inria.corese.core.kgram.core.Mapping; -import fr.inria.corese.core.kgram.core.Mappings; -import fr.inria.corese.core.kgram.core.ProcessVisitorDefault; -import fr.inria.corese.core.kgram.core.Query; import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.api.IDatatypeList; import fr.inria.corese.core.sparql.datatype.DatatypeMap; @@ -32,42 +31,34 @@ import fr.inria.corese.core.sparql.triple.parser.Access.Level; import fr.inria.corese.core.sparql.triple.parser.Context; import fr.inria.corese.core.sparql.triple.parser.context.ContextLog; +import fr.inria.corese.core.visitor.solver.QuerySolverVisitorRule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Generic Java Extension function public class - * prefix fun: + * prefix fun: <function://fr.inria.corese.core.extension.Extension> * fun:test(xt:graph()) - * + *

* Provide access to query execution environment - * + * * @author Olivier Corby, Wimmics INRIA I3S, 2020 */ public class Extension extends Core { - private static Logger logger = LoggerFactory.getLogger(Extension.class); - - static Extension singleton; - - static { - singleton = new Extension(); - } - -// public static Extension singleton() { -// return singleton; -// } - + private static final Logger logger = LoggerFactory.getLogger(Extension.class); + Binding getBinding() { if (getEnvironment() == null) { return null; } - return getEnvironment().getBind(); + return getEnvironment().getBind(); } - + // inherit access level from Binding Context getCreateContext() { Binding b = getBinding(); @@ -76,18 +67,18 @@ Context getCreateContext() { } return new Context(b.getAccessLevel()); } - + ContextLog getLog() { return getBinding().getLog(); } - + public IDatatype getContextLog() { if (getLog() == null) { return null; } return DatatypeMap.createObject(getLog()); } - + public IDatatype getMessage() { String url = getLog().getMessage(); if (url == null) { @@ -99,29 +90,29 @@ public IDatatype getMessage() { } return DatatypeMap.json(text); } - + public IDatatype parallel(IDatatype name) { return DatatypeMap.newResource(String.format(ProviderService.LOCAL_SERVICE_NS, name.getLabel())); } - + // return list of variables bound in environment public IDatatype variables() { ArrayList list = new ArrayList<>(); - + for (Node node : getEnvironment().getQueryNodes()) { - if (node!=null && node.isVariable() && ! node.isBlank()) { + if (node != null && node.isVariable() && !node.isBlank()) { Node report = getEnvironment().getNode(node); - if (report !=null) { + if (report != null) { list.add(report.getDatatypeValue()); } } } return DatatypeMap.newList(list); } - + /** - * Service evaluation report graph recorded in ContextLog + * Service evaluation report graph recorded in ContextLog */ public IDatatype getLogGraph() { if (getLog() == null) { @@ -136,38 +127,40 @@ public IDatatype getLogGraph() { return null; } } - + public IDatatype getLogURL() { if (getLog() == null || getLog().getLink() == null) { return null; } return DatatypeMap.newResource(getLog().getLink()); - } - + } + public IDatatype parse(IDatatype dt) throws EngineException { Context c = getCreateContext(); if (Access.reject(Feature.LDSCRIPT_SPARQL, c.getLevel())) { throw new SafetyException(TermEval.SPARQL_MESS); } ASTQuery ast = parseQuery(dt.getLabel(), c); - if (ast == null) { + if (ast == null) { return null; } return DatatypeMap.createObject(ast); } - + ASTQuery parseQuery(String str, Context c) throws EngineException { QueryProcess exec = QueryProcess.create(); Query q = exec.compile(str, c); - return q.getAST(); + return q.getAST(); } - - + + public IDatatype list(IDatatype dt) { - if (dt.isExtension()) { - switch (dt.getDatatypeURI()) { - case IDatatype.MAPPINGS_DATATYPE: return list(dt.getPointerObject().getMappings()); - case IDatatype.MAPPING_DATATYPE: return list(dt.getPointerObject().getMapping()); + if (dt.isExtension()) { + String datatypeURI = dt.getDatatypeURI(); + if (IDatatype.MAPPINGS_DATATYPE.equals(datatypeURI)) { + return list(dt.getPointerObject().getMappings()); + } else if (IDatatype.MAPPING_DATATYPE.equals(datatypeURI)) { + return list(dt.getPointerObject().getMapping()); } } if (dt.isTripleWithEdge()) { @@ -181,13 +174,13 @@ public IDatatype list(IDatatype dt) { } return DatatypeMap.list(); } - + IDatatype list(Edge e) { IDatatypeList list = DatatypeMap.newList( e.getSubjectValue(), e.getPredicateValue(), e.getObjectValue()); return DatatypeMap.newList(list); } - + // Mappings as list(list(var, val)) IDatatype list(Mappings map) { IDatatypeList list = DatatypeMap.newList(); @@ -196,24 +189,24 @@ IDatatype list(Mappings map) { } return list; } - + // Mapping as list(list(var, val)) IDatatype list(Mapping m) { return m.getDatatypeList(); } - + public IDatatype allEntailment(IDatatype dt) { Construct.setAllEntailment(dt.booleanValue()); return dt; } - - - public IDatatype distance(IDatatype dt1, IDatatype dt2) { - return distance(dt1, dt2, null); - } - - public IDatatype distance(IDatatype dt1, IDatatype dt2, IDatatype dt) { + + public IDatatype distance(IDatatype dt1, IDatatype dt2) { + return distance(dt1, dt2, null); + } + + + public IDatatype distance(IDatatype dt1, IDatatype dt2, IDatatype dt) { Graph g = getGraph(); Node n1 = g.getNode(dt1); Node n2 = g.getNode(dt2); @@ -222,22 +215,20 @@ public IDatatype distance(IDatatype dt1, IDatatype dt2, IDatatype dt) { } Distance distance = g.getClassDistance(); - if (distance == null || (dt != null && ! distance.getSubClassOf().equals(dt.getLabel()))) { + if (distance == null || (dt != null && !distance.getSubClassOf().equals(dt.getLabel()))) { distance = new Distance(g); distance.setStep(1); if (dt != null) { distance.setSubClassOf(dt.getLabel()); - } + } distance.start(); g.setClassDistance(distance); } double dd = distance.distance(n1, n2); return getValue(dd); } - - - - + + // clean OWL ontology: remove duplicate statements public IDatatype clean() { Cleaner clean = new Cleaner(getGraph()); @@ -246,13 +237,11 @@ public IDatatype clean() { clean.process(); } catch (IOException | LoadException | EngineException ex) { logger.error(ex.getMessage()); - } + } return DatatypeMap.TRUE; } - - - - + + // example IDatatype test(IDatatype dt) { getEnvironment(); @@ -261,23 +250,23 @@ IDatatype test(IDatatype dt) { getEval(); return DatatypeMap.TRUE; } - - ProcessVisitor getVisitor() { - return getEval().getVisitor(); - } - - public IDatatype closeVisitor() { - getEval().setVisitor(new ProcessVisitorDefault()); - getVisitor().setDefaultValue(TRUE); - return visitor(); - } - - public IDatatype openVisitor() { - getEval().setVisitor(new QuerySolverVisitor(getEval())); - getVisitor().init(getEnvironment().getQuery()); - return visitor(); - } - + + ProcessVisitor getVisitor() { + return getEval().getVisitor(); + } + + public IDatatype closeVisitor() { + getEval().setVisitor(new ProcessVisitorDefault()); + getVisitor().setDefaultValue(DatatypeMap.TRUE); + return visitor(); + } + + public IDatatype openVisitor() { + getEval().setVisitor(new QuerySolverVisitor(getEval())); + getVisitor().init(getEnvironment().getQuery()); + return visitor(); + } + /** * Accessor * fun:visitor() @@ -285,15 +274,15 @@ public IDatatype openVisitor() { public IDatatype visitor() { return cast(getVisitor()); } - + public IDatatype query() { return cast(getQuery()); } - + public IDatatype ast() { return cast(getAST()); } - + public IDatatype edge(IDatatype n) { Edge[] edges = getEnvironment().getEdges(); if (edges == null || edges.length < n.intValue()) { @@ -301,42 +290,44 @@ public IDatatype edge(IDatatype n) { } return cast(edges[n.intValue()]); } - + Query getQuery() { return getEnvironment().getQuery(); } - + ASTQuery getAST() { - return getEnvironment().getQuery().getAST(); + return getEnvironment().getQuery().getAST(); } - + IDatatype cast(Object obj) { return DatatypeMap.getValue(obj); } - - - + + public IDatatype fib(IDatatype n) { switch (n.intValue()) { - case 0: - case 1: return n; - default: return fib(n.minus(DatatypeMap.ONE)).plus(fib(n.minus(DatatypeMap.TWO))); + case 0: + case 1: + return n; + default: + return fib(n.minus(DatatypeMap.ONE)).plus(fib(n.minus(DatatypeMap.TWO))); } } - + public IDatatype fibJava(IDatatype n) { return DatatypeMap.newInstance(fib(n.intValue())); } - + int fib(int n) { switch (n) { - case 0: - case 1: return n; - default: return fib(n-1) + fib(n-2); + case 0: + case 1: + return n; + default: + return fib(n - 1) + fib(n - 2); } } - - - + + } diff --git a/src/main/java/fr/inria/corese/core/extension/ExtensionLocal.save b/src/main/java/fr/inria/corese/core/extension/ExtensionLocal.save index 9c35f3427..ca4383001 100644 --- a/src/main/java/fr/inria/corese/core/extension/ExtensionLocal.save +++ b/src/main/java/fr/inria/corese/core/extension/ExtensionLocal.save @@ -313,9 +313,9 @@ public class ExtensionLocal extends Core { IDatatype mytest() { try { QueryProcess exec = QueryProcess.create(getGraph()); - System.out.println("before mytest"); + logger.info("before mytest"); Mappings map = exec.query("insert { graph us:g1 { [] rdf:value ?v } } where { bind (rand() as ?v) }"); - System.out.println("after mytest"); + logger.info("after mytest"); } catch (EngineException ex) { logger.error(ex.getMessage()); } @@ -325,19 +325,20 @@ public class ExtensionLocal extends Core { IDatatype mytest2() { Service s = new Service("http://localhost:8080/sparql"); try { - System.out.println("before mytest"); + logger.info("before mytest"); Mappings map = s.select("insert { graph us:g1 { [] rdf:value ?v } } where { bind (rand() as ?v) }"); - System.out.println("after mytest"); + logger.info("after mytest"); } catch (LoadException ex) { - System.out.println(ex); + logger.error("Error execution: {}", ex.getMessage(), ex); + } catch (EngineException ex) { - System.out.println(ex); + logger.error("Error execution: {}", ex.getMessage(), ex); } return DatatypeMap.TRUE; } public IDatatype mytest1() { - System.out.println("mytest 1"); + logger.info("mytest 1"); return DatatypeMap.TRUE; } diff --git a/src/main/java/fr/inria/corese/core/extension/JavaCompiler.java b/src/main/java/fr/inria/corese/core/extension/JavaCompiler.java index 4e7fefe38..fab923011 100644 --- a/src/main/java/fr/inria/corese/core/extension/JavaCompiler.java +++ b/src/main/java/fr/inria/corese/core/extension/JavaCompiler.java @@ -1,24 +1,23 @@ package fr.inria.corese.core.extension; import fr.inria.corese.core.Graph; -import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.kgram.core.Query; +import fr.inria.corese.core.query.QueryProcess; import fr.inria.corese.core.sparql.exceptions.EngineException; + import java.io.IOException; /** - * * @author Olivier Corby, Wimmics INRIA I3S, 2019 */ public class JavaCompiler extends fr.inria.corese.core.sparql.compiler.java.JavaCompiler { - + public JavaCompiler(String name) { super(name); } - + /** * To recursively import functions, use http://ns.inria.fr/sparql-template/function/name - * */ public void compile(String path) throws EngineException, IOException { String q = String.format("@import <%s> select * where { }", path); @@ -26,5 +25,5 @@ public void compile(String path) throws EngineException, IOException { Query qq = exec.compile(q); compile(qq); } - + } diff --git a/src/main/java/fr/inria/corese/core/extension/Report.java b/src/main/java/fr/inria/corese/core/extension/Report.java index ef1732bfd..63e248cc7 100644 --- a/src/main/java/fr/inria/corese/core/extension/Report.java +++ b/src/main/java/fr/inria/corese/core/extension/Report.java @@ -6,6 +6,7 @@ import fr.inria.corese.core.sparql.datatype.DatatypeMap; import fr.inria.corese.core.sparql.triple.function.term.Binding; import fr.inria.corese.core.sparql.triple.parser.URLParam; + import java.util.ArrayList; /** @@ -13,16 +14,17 @@ * execution Service Report is the value of a variable ?_service_report_n where * n is the number of the service Variable ?_service_report_n is bound in the * environment Variable value is a LDScript JSON object, with dt:json datatype - * prefix js: + * prefix js: <function://fr.inria.corese.core.extension.Report> + * * @report @header [@enum] * values (?akey ?aval) { unnest(js:report()) } * values (?akey ?aval) { unnest(js:header()) } */ public class Report extends Extension implements URLParam { - + // return report number zero if any of first report available if any public IDatatype report() { - IDatatype dt = reportNumber(0); + IDatatype dt = reportNumber(0); if (dt == null) { dt = reports(); if (dt.size() == 0) { @@ -32,15 +34,15 @@ public IDatatype report() { } return dt; } - + public IDatatype myreport() { return getBinding().getReport(); } - + public IDatatype myreport(IDatatype name) { return myreport().get(name); } - + public IDatatype myreport(IDatatype name, IDatatype key) { IDatatype dt = myreport(name); if (dt == null) { @@ -48,7 +50,7 @@ public IDatatype myreport(IDatatype name, IDatatype key) { } return dt.get(key); } - + // key:string -> return value of key in report 0 // key:integer -> return report number key public IDatatype report(IDatatype key) { @@ -58,31 +60,31 @@ public IDatatype report(IDatatype key) { return reportKey(key); } } - + public IDatatype header() { return reportKey(HEADER); - } - + } + public IDatatype header(IDatatype key) { IDatatype dt = header(); if (dt == null) { return null; } return dt.get(key); - } - + } + public IDatatype cookie() { return reportKey(COOKIE); - } - + } + public IDatatype cookie(IDatatype key) { IDatatype dt = cookie(); if (dt == null) { return null; } return dt.get(key); - } - + } + public IDatatype server() { IDatatype server = reportKey(SERVER_NAME); if (server == null) { @@ -90,52 +92,52 @@ public IDatatype server() { } return server(server); } - - public IDatatype server(IDatatype server) { + + public IDatatype server(IDatatype server) { String label = server.getLabel(); if (label.contains("/")) { return DatatypeMap.newInstance(label.substring(0, label.indexOf("/"))); } return server; } - + // return list of reports bound in environment public IDatatype reports() { ArrayList list = new ArrayList<>(); - + for (Node node : getEnvironment().getQueryNodes()) { - if (node!=null && node.getLabel().startsWith(Binding.SERVICE_REPORT)) { + if (node != null && node.getLabel().startsWith(Binding.SERVICE_REPORT)) { Node report = getEnvironment().getNode(node); - if (report !=null) { + if (report != null) { list.add(report.getDatatypeValue()); } } } - + if (list.isEmpty()) { list.add(myreport()); } - + return DatatypeMap.newList(list); } - + // return list of values of name in reports public IDatatype reports(IDatatype name) { return myreports(name); } - + public IDatatype reports(IDatatype n1, IDatatype n2) { return myreports(n1, n2); } - + public IDatatype reports(IDatatype n1, IDatatype n2, IDatatype n3) { return myreports(n1, n2, n3); } - + public IDatatype reports(IDatatype n1, IDatatype n2, IDatatype n3, IDatatype n4) { return myreports(n1, n2, n3, n4); } - + // return list of values of keys in reports // (key1val1 .. key1valn .. keymval1 .. keymvaln) IDatatype myreports(IDatatype... nameList) { @@ -151,27 +153,29 @@ IDatatype myreports(IDatatype... nameList) { } return DatatypeMap.newList(list); } - + // return list(key, (key value list)) // ready for values (?key ?val) {unnest(fun:reportEnum())} public IDatatype reportsEnum() { return iterate(reports()); } - + // focus on key(s) public IDatatype reportsEnum(IDatatype key) { return reports().iterate(DatatypeMap.newList(key)); } + public IDatatype reportsEnum(IDatatype k1, IDatatype k2) { return reports().iterate(DatatypeMap.newList(k1, k2)); } + public IDatatype reportsEnum(IDatatype k1, IDatatype k2, IDatatype k3) { return reports().iterate(DatatypeMap.newList(k1, k2, k3)); } - + /** * @param reports: list of json object - * for all key (of first report) + * for all key (of first report) * @return list of (key_i (val_i1 .. val_in)) */ public IDatatype iterate(IDatatype reports) { @@ -180,30 +184,30 @@ public IDatatype iterate(IDatatype reports) { } return DatatypeMap.newList(); } - + public IDatatype reportKey(String name) { return reportKey(key(name)); } // value of key of first report - public IDatatype reportKey(IDatatype name) { + public IDatatype reportKey(IDatatype name) { Node detail = report(); if (detail == null) { return null; } return detail.getDatatypeValue().get(name); } - + IDatatype key(String key) { return DatatypeMap.key(key); } - - + + // report number n public IDatatype reportNumber(IDatatype dt) { return reportNumber(dt.intValue()); } - + public IDatatype reportNumber(int n) { Node detail = getEnvironment().getNode(String.format(Binding.SERVICE_REPORT_FORMAT, n)); if (detail == null) { @@ -211,7 +215,7 @@ public IDatatype reportNumber(int n) { } return detail.getDatatypeValue(); } - + // value of key of report number n public IDatatype report(IDatatype dt, IDatatype name) { IDatatype detail = reportNumber(dt); @@ -220,16 +224,16 @@ public IDatatype report(IDatatype dt, IDatatype name) { } return detail.getDatatypeValue().get(name); } - + /** - * Return report where result Mappings contains + * Return report where result Mappings contains * Mapping var = value * pragma: @report @detail to get result */ public IDatatype provenance(IDatatype value) { for (IDatatype dt : reports()) { IDatatype result = dt.get(RESULT); - if (result!=null) { + if (result != null) { Mappings map = result.getPointerObject().getMappings(); if (map.contains(value)) { return dt; @@ -238,7 +242,7 @@ public IDatatype provenance(IDatatype value) { } return null; } - + // return slot name of provenance(value) public IDatatype provenance(IDatatype value, IDatatype name) { IDatatype report = provenance(value); @@ -247,14 +251,14 @@ public IDatatype provenance(IDatatype value, IDatatype name) { } return report.get(name); } - + // return other reports of this service report public IDatatype context(IDatatype dt) { - IDatatype num = dt.get(URLParam.CALL); - IDatatype list = dt.get(REPORT); + IDatatype num = dt.get(URLParam.CALL); + IDatatype list = dt.get(REPORT); ArrayList res = new ArrayList<>(); - - if (list != null && num != null) { + + if (list != null && num != null) { for (IDatatype rep : list) { if (num.intValue() != rep.get(URLParam.CALL).intValue()) { res.add(rep); @@ -264,6 +268,5 @@ public IDatatype context(IDatatype dt) { return DatatypeMap.newList(res); } - - + } diff --git a/src/main/java/fr/inria/corese/core/extension/core/Core.java b/src/main/java/fr/inria/corese/core/extension/core/Core.java index b0e01c1b8..e3fadc26d 100644 --- a/src/main/java/fr/inria/corese/core/extension/core/Core.java +++ b/src/main/java/fr/inria/corese/core/extension/core/Core.java @@ -19,6 +19,9 @@ import fr.inria.corese.core.producer.DataProducer; import fr.inria.corese.core.query.PluginTransform; import fr.inria.corese.core.query.QueryProcess; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; @@ -32,6 +35,7 @@ * */ public class Core implements FunctionEvaluator { + private static final Logger logger = LoggerFactory.getLogger(Core.class); private static final String QM = "?"; @@ -71,20 +75,11 @@ public IDatatype funcall(IDatatype fun, IDatatype... ldt) { Method m = this.getClass().getMethod(name, aclasses); return (IDatatype) m.invoke(this, ldt); } catch (SecurityException | NoSuchMethodException | IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { - trace(e, "funcall", name, ldt); + logger.error("", e); } return null; } - void trace(Exception e, String title, String name, IDatatype[] ldt) { - String str = ""; - for (IDatatype dt : ldt) { - str += dt + " "; - } -// logger.warn(e); -// logger.warn(title + " "+ name + " " + str); - } - /** * LDScript Java compiler ldt[0] is a list */ @@ -101,16 +96,8 @@ public IDatatype map(IDatatype fun, IDatatype... ldt) { ldt[0] = dt; m.invoke(this, ldt); } - } catch (SecurityException e) { - trace(e, "map", name, ldt); - } catch (NoSuchMethodException e) { - trace(e, "map", name, ldt); - } catch (IllegalArgumentException e) { - trace(e, "map", name, ldt); - } catch (IllegalAccessException e) { - trace(e, "map", name, ldt); - } catch (InvocationTargetException e) { - trace(e, "map", name, ldt); + } catch (SecurityException | NoSuchMethodException | IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { + logger.error("", e); } return null; } @@ -133,23 +120,15 @@ public IDatatype maplist(IDatatype fun, IDatatype... ldt) { } } return DatatypeMap.newInstance(res); - } catch (SecurityException e) { - trace(e, "maplist", name, ldt); - } catch (NoSuchMethodException e) { - trace(e, "maplist", name, ldt); - } catch (IllegalArgumentException e) { - trace(e, "maplist", name, ldt); - } catch (IllegalAccessException e) { - trace(e, "maplist", name, ldt); - } catch (InvocationTargetException e) { - trace(e, "maplist", name, ldt); + } catch (SecurityException | NoSuchMethodException | IllegalArgumentException | IllegalAccessException | InvocationTargetException e) { + logger.error("", e); } return null; } /** * This PluginImpl was created for executing a Method such as java:report() - * where java: = + * where java: = <function:// ...> * This PluginImpl contains Environment and Producer use case: JavaCompiler * external function */ @@ -178,13 +157,13 @@ public IDatatype kgram(IDatatype query, IDatatype... ldt) { * First param is query other param are variable bindings (variable, value) */ Mapping createMapping(Producer p, IDatatype[] param, int start) { - ArrayList var = new ArrayList(); - ArrayList val = new ArrayList(); + ArrayList variables = new ArrayList<>(); + ArrayList val = new ArrayList<>(); for (int i = start; i < param.length; i += 2) { - var.add(NodeImpl.createVariable(clean(param[i].getLabel()))); + variables.add(NodeImpl.createVariable(clean(param[i].getLabel()))); val.add(p.getNode(param[i + 1])); } - return Mapping.create(var, val); + return Mapping.create(variables, val); } String clean(String name) { @@ -225,13 +204,7 @@ public IDatatype edge(IDatatype subj, IDatatype pred, IDatatype obj) { } Loopable getLoop(final Producer p, final IDatatype subj, final IDatatype pred, final IDatatype obj) { - Loopable loop = new Loopable() { - @Override - public Iterable getLoop() { - return new DataProducer(getGraph(p)).iterate(subj, pred, obj); - } - }; - return loop; + return () -> new DataProducer(getGraph(p)).iterate(subj, pred, obj); } public IDatatype and(IDatatype... ldt) { @@ -292,6 +265,7 @@ private Graph getGraph(Producer producer) { /** * @param environment the environment to set */ + @Override public void setEnvironment(Environment environment) { this.environment = environment; } @@ -299,6 +273,7 @@ public void setEnvironment(Environment environment) { /** * @param producer the producer to set */ + @Override public void setProducer(Producer producer) { this.producer = producer; } diff --git a/src/main/java/fr/inria/corese/core/index/EdgeManager.java b/src/main/java/fr/inria/corese/core/index/EdgeManager.java index 1e90b1a1a..440cde04f 100644 --- a/src/main/java/fr/inria/corese/core/index/EdgeManager.java +++ b/src/main/java/fr/inria/corese/core/index/EdgeManager.java @@ -1,28 +1,25 @@ package fr.inria.corese.core.index; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Graph; +import fr.inria.corese.core.kgram.api.core.Edge; +import fr.inria.corese.core.kgram.api.core.Node; + +import java.util.*; + import static fr.inria.corese.core.index.EdgeManagerIndexer.IGRAPH; import static fr.inria.corese.core.index.EdgeManagerIndexer.ILIST; -import fr.inria.corese.core.util.Tool; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import fr.inria.corese.core.kgram.api.core.Edge; /** * Edge List of a predicate * Edge may be stored without predicate Node to spare memory - * Edges are sorted according to + * Edges are sorted according to * 1- focus node index and then by compareTo when they have same index * 2- other nodes (object, graph) * index 0: - * g1 s1 p o1 ; g2 s1 p o1 ; g1 s1 p o2 ; g2 s2 p o3 ; ... - * + * g1 s1 p o1 ; g2 s1 p o1 ; g1 s1 p o2 ; g2 s2 p o3 ; ... + *

* This version manages XSD datatypes this way: - * integer, long, decimal (and short, byte, int, etc.) + * integer, long, decimal (and short, byte, int, etc.) * - have same node index when values are equal * - different labels are possible for same value: 1 and 01 are kept as is * with same node index @@ -31,40 +28,38 @@ * s p 01, 1, 1.0, '1'^^xsd:long, 1e1 * * @author Olivier Corby, Wimmics INRIA I3S, 2017 - * */ public class EdgeManager implements Iterable { + // Predicate of this EdgeManager: edges in this edge list have this predicate + private final Node predicate; Graph graph; + boolean indexedByNode = false; private EdgeManagerIndexer indexer; - // Predicate of this EdgeManager: edges in this edge list have this predicate - private Node predicate; private ArrayList edgeList; // comparator to sort edge list: g s p o t < g s p o private Comparator comparatorIndex; // comparator to retrieve place of edge: g s p o t = g s p o private Comparator comparator; - // index of first Node to sort + // index of first Node to sort private int index = 0; // index of second Node to sort private int other = 0; // index of third Node to sort private int next = IGRAPH; - boolean indexedByNode = false; EdgeManager(EdgeManagerIndexer indexer, Node p, int i) { graph = indexer.getGraph(); - this.indexer = indexer; + this.indexer = indexer; predicate = p; edgeList = new ArrayList<>(); index = i; if (index == 0) { other = 1; - } - else if (index == IGRAPH){ + } else if (index == IGRAPH) { next = 1; } } - + public Graph getGraph() { return graph; } @@ -84,12 +79,15 @@ void clear() { Edge get(int i) { return getEdgeList().get(i); } - - int getIndex(){ + + int getIndex() { return index; } - - + + public void setIndex(int index) { + this.index = index; + } + /** * input edge are sorted with reference node first: g s p o t g s p o * remove duplicate edges, share reference node if any, share asserted if any @@ -99,22 +97,22 @@ int getIndex(){ * g s p o t - g1 s p o t - g2 s p o t - g3 s p o t * In addition edges may be asserted or not * Remaining edge becomes asserted if one occurrence (with same g s p o) is asserted - * Create NodeManager: node -> (predicate:position) + * Create NodeManager: node -> (predicate:position) */ int reduce(NodeManager nodeManager) { ArrayList reduceNodeList = new ArrayList<>(); Edge pred = null; - int count = 0, ind = 0; - int begin=0, end=0; - //System.out.println("before reduce: " + list); + int count = 0; + int ind = 0; + int begin = 0; + int end = 0; boolean isMetadata = getGraph().isMetadataNode(); - + for (Edge edge : getEdgeList()) { if (pred == null) { pred = edge; reduceNodeList.add(edge); begin = ind; - //nodeManager.add(edge.getNode(getIndex()), getPredicate(), ind); ind++; } else if (equalWithoutConsideringMetadata(pred, edge)) { // g s p o = g s p o -- with or without reference node @@ -129,9 +127,8 @@ int reduce(NodeManager nodeManager) { // no reference node at all for any s p o // skip edge count++; - } - else { - // reference node exist for some s p o, + } else { + // reference node exist for some s p o, // may be on pred g s p o or another following gi s p o if (pred.getReferenceNode() == null) { // pred must share ref node of other s p o @@ -141,8 +138,7 @@ int reduce(NodeManager nodeManager) { pred = predCopy; // skip edge count++; - } - else { + } else { // pred has reference node if (edge.isAsserted()) { // in case pred was not asserted @@ -152,8 +148,7 @@ int reduce(NodeManager nodeManager) { count++; } } - } - else { + } else { // edge = pred, graph not metadata // skip redundant edge count++; @@ -168,40 +163,38 @@ int reduce(NodeManager nodeManager) { ind++; } } - - if (pred!=null) { + + if (pred != null) { nodeManager.add(pred.getNode(getIndex()), getPredicate(), begin, reduceNodeList.size()); } - + reduceNodeList.trimToSize(); setEdgeList(reduceNodeList); if (count > 0) { graph.setSize(graph.size() - count); } - //System.out.println("after reduce: " + list); return count; - } - + } + // when rdf star: equal g s p o without considering reference node t // g s p o = g s p o t = g s p o t2 boolean equalWithoutConsideringMetadata(Edge e1, Edge e2) { return getComparatorEqualWithoutMetadata().compare(e1, e2) == 0; } - + NodeManager getNodeManager() { return getIndexer().getNodeManager(); } - - + // compare subject object graph (not compare reference node if any) int compare3(Edge e1, Edge e2) { - int res = compare2(e1, e2); + int res = compare2(e1, e2); if (res == 0) { res = compareNodeTerm(e1.getNode(IGRAPH), e2.getNode(IGRAPH)); } return res; } - + // compare subject object (not compare graph) int compare2(Edge e1, Edge e2) { for (int i = 0; i < 2; i++) { @@ -212,65 +205,63 @@ int compare2(Edge e1, Edge e2) { } return 0; } - + /** * generate map: node -> (predicate:position) - * with position of node in this edge list of predicate + * with position of node in this edge list of predicate */ void indexNodeManager(NodeManager nodeManager) { Edge pred = null; int begin = 0; int end = 0; - + for (Edge edge : getEdgeList()) { Node focus = edge.getNode(getIndex()); if (pred == null) { // first edge - } - else if (focus != pred.getNode(getIndex())) { + } else if (focus != pred.getNode(getIndex())) { nodeManager.add(pred.getNode(getIndex()), getPredicate(), begin, end); begin = end; } end++; pred = edge; } - if (pred!=null) { + if (pred != null) { nodeManager.add(pred.getNode(getIndex()), getPredicate(), begin, size()); } } - + /** * Replace kg:rule Edge by compact EdgeInternalRule */ - + void compact() { if (graph.isMetadata() || graph.isRDFStar()) { doCompactMetadata(); - } - else { + } else { doCompact(); } } // keep metadata, reset index - void doCompactMetadata(){ + void doCompactMetadata() { for (Edge ent : getEdgeList()) { - ent.setEdgeIndex(-1); + ent.setEdgeIndex(-1); } } - - void doCompact(){ + + void doCompact() { ArrayList l = new ArrayList<>(getEdgeList().size()); for (Edge ent : getEdgeList()) { - Edge ee = getGraph().getEdgeFactory().compact(ent); - l.add(ee); + Edge ee = getGraph().getEdgeFactory().compact(ent); + l.add(ee); } setEdgeList(l); } /** * Main function that sort Index edge list - */ + */ void sort() { Collections.sort(getEdgeList(), getComparatorIndex()); } @@ -300,7 +291,7 @@ void add(Edge ent) { void add(int i, Edge ent) { getEdgeList().add(i, ent); } - + void set(int i, Edge ent) { getEdgeList().set(i, ent); } @@ -319,7 +310,7 @@ void add(List l) { getEdgeList().ensureCapacity(l.size() + getEdgeList().size()); getEdgeList().addAll(l); } - + // pragma: node is bound // pragma: when node2 is bound: node=subject node2=object // use case: DataProducer iterator provides two nodes only for subject/object @@ -327,12 +318,11 @@ void add(List l) { Iterable getEdges(Node node, Node node2) { if (node2 == null) { return getEdgesBasic(node); - } - else { + } else { return getEdgesBasic(node, node2); } } - + // specific iterator when subject/object are both known Iterable getEdgesBasic(Node subject, Node object) { int beginIndex = 0; @@ -345,46 +335,36 @@ Iterable getEdgesBasic(Node subject, Node object) { // index of edge: node predicate node2 beginIndex = findEdgeNodeTerm(subject, object, beginIndex, size()); - + if (beginIndex >= 0 && beginIndex < size()) { // iterate edges with node and node2 - return new EdgeManagerIterate(this, beginIndex, object.getIndex()); + return new EdgeManagerIterate(this, beginIndex, object.getIndex()); } - + return null; } - + // node is bound, enumerate edges where node = edge.getNode(index) Iterable getEdgesBasic(Node node) { int beginIndex = findNodeIndex(node); - + if (beginIndex >= 0 && beginIndex < getEdgeList().size()) { - return new EdgeManagerIterate(this, beginIndex); + return new EdgeManagerIterate(this, beginIndex); } - + return null; } - - void traceEdgeList() { - for (Edge e : getEdgeList()) { - System.out.println(String.format("%s label=%s index=%s", e, - e.getSubjectNode().getLabel(), - e.getSubjectNode().getIndex())); - } - } - + Iterable getEdges(Node node, int beginIndex) { return new EdgeManagerIterate(this, beginIndex); } - - + // use case: rdfs entailment boolean exist(Edge edge) { int i = findEdgeEqualWithoutMetadata(edge); return i != -1; } - /** * Return place where edge should be inserted in this Index return -1 if * already exists @@ -393,10 +373,9 @@ int getPlace(Edge edge) { int i = find(edge); if (i >= getEdgeList().size()) { i = getEdgeList().size(); - } + } return i; } - /** * Place of edge in this Index, e.g. to insert edge @@ -407,6 +386,7 @@ int find(Edge edge) { /** * use case: Construct find occurrence of edge for rdf star + * * @todo: Index is sorted and reduced ? */ Edge findEdge(Edge edge) { @@ -432,7 +412,7 @@ int findEdgeEqualWithoutMetadata(Edge edge) { return -1; } - + /** * There are two comparator * sort Index: g s p o t < g s p o @@ -451,7 +431,7 @@ int basicFind(Comparator comp, Edge edge, int first, int last) { } } } - + /** * Test if an edge (n1 p n2) exist in this Index (in any named graph) * use case: rule engine @@ -460,20 +440,18 @@ boolean exist(Node n1, Node n2) { int n = findEdgeNodeTerm(n1, n2); if (n >= 0 && n < getEdgeList().size()) { Edge ent = getEdgeList().get(n); - if (n1.getIndex() == getNodeIndex(ent, 0) - && n2.getIndex() == getNodeIndex(ent, 1)) { - return true; - } + return n1.getIndex() == getNodeIndex(ent, 0) + && n2.getIndex() == getNodeIndex(ent, 1); } return false; } - + Edge findEdge(Node n1, Node n2) { int n = findEdgeNodeTerm(n1, n2); if (n >= 0 && n < size()) { Edge edge = getEdgeList().get(n); if (compareNodeTerm(n1, edge.getNode(0)) == 0 - && compareNodeTerm(n2, edge.getNode(1)) == 0) { + && compareNodeTerm(n2, edge.getNode(1)) == 0) { return edge; } } @@ -487,7 +465,7 @@ && compareNodeTerm(n2, edge.getNode(1)) == 0) { int findEdgeNodeTerm(Node n1, Node n2) { return findEdgeNodeTerm(n1, n2, 0, size()); } - + int findEdgeNodeTerm(Node n1, Node n2, int first, int last) { if (first >= last) { return first; @@ -499,10 +477,9 @@ int findEdgeNodeTerm(Node n1, Node n2, int first, int last) { return findEdgeNodeTerm(n1, n2, mid + 1, last); } } - } + } - - /** + /** * Find index of node as node(index) -1 if not found * use case: index of graph node n in graph node index */ @@ -531,21 +508,21 @@ int findNodeTerm(Node n, int first, int last) { } } } - + // use case: getEdges(node) int findNodeIndex(Node node) { return getNodeIndex(node); } - + int getNodeIndex(Node n) { - if (getNodeManager().isConsultable() - && ! n.getDatatypeValue().isNumber() - && ! n.getDatatypeValue().isBoolean()){ - return getNodeManager().getPosition(n, getPredicate()); + if (getNodeManager().isConsultable() + && !n.getDatatypeValue().isNumber() + && !n.getDatatypeValue().isBoolean()) { + return getNodeManager().getPosition(n, getPredicate()); } return findNodeIndexBasic(n); } - + int findNodeIndexBasic(Node node) { int n = findNodeIndex(node, 0, getEdgeList().size()); if (n >= 0 && n < getEdgeList().size()) { @@ -557,7 +534,6 @@ int findNodeIndexBasic(Node node) { return -1; } - int findNodeIndex(Node n, int first, int last) { if (first >= last) { return first; @@ -571,8 +547,7 @@ int findNodeIndex(Node n, int first, int last) { } } } - - + int compareNodeTerm(Edge edge, Node n1, Node n2) { int res = compareNodeTerm(edge.getNode(getIndex()), n1); if (res == 0) { @@ -593,47 +568,46 @@ int intCompare(int n1, int n2) { return +1; } } - + /** * Compare nodes with sameTerm semantics * if value, datatype, label are equal : return 0 * return +-1 otherwise */ - int compareNodeTerm(Node n1, Node n2){ + int compareNodeTerm(Node n1, Node n2) { int res = intCompare(n1.getIndex(), n2.getIndex()); - if (res == 0){ + if (res == 0) { // same node index (compatible datatypes) // check datatype and label res = n1.getValue().compareTo(n2.getValue()); } return res; } - + /** * compare named graph nodes * use case: find occurrence of delete edge * for rdf star edge with reference (see Construct find(edge)) * named graph node of delete edge may be null - * context: + * context: * index == 0 (subject index) * edge subject and object are == * if delete graph node is null, edge is found */ int compareNodeTermNull(Node n1, Node n2) { if (n1 == null || n2 == null) { - // occur only for find delete edge + // occur only for find delete edge // Construct getGraphManager().find(edge) return 0; - } - else { + } else { return compareNodeTerm(n1, n2); } } - - int compareNodeIndex(Node n1, Node n2){ - return intCompare(n1.getIndex(), n2.getIndex()); + + int compareNodeIndex(Node n1, Node n2) { + return intCompare(n1.getIndex(), n2.getIndex()); } - + @Override public Iterator iterator() { return getEdgeList().iterator(); @@ -641,7 +615,7 @@ public Iterator iterator() { public Node getPredicate() { return predicate; - } + } // getNode(IGRAPH) must return getGraph() int getNodeIndex(Edge ent, int n) { @@ -653,13 +627,12 @@ int getNodeIndex(int i, int n) { Edge ent = getEdgeList().get(i); return ent.getNode(n).getIndex(); } - + // getNode(IGRAPH) must return getGraph() Node getNode(int i, int n) { Edge ent = getEdgeList().get(i); return ent.getNode(n); } - /** * ************************************************************** @@ -669,98 +642,93 @@ Node getNode(int i, int n) { * after sort Index, reduce() + metadate() remove duplicates * and we keep only g s p o t (g s p o is removed if any) * At the end, the index contains only g s p o t (if any t) - * Then, to retrieve an edge g s p o [t], we can consider edge equality + * Then, to retrieve an edge g s p o [t], we can consider edge equality * without looking at metadata (because they are not both in the Index) */ Comparator createComparatorIndex(int n) { - switch (n) { - case ILIST: - return createListComparator(); + if (n == ILIST) { + return createListComparator(); } return createComparatorIndex(); } - + Comparator createComparator(int n) { - switch (n) { - case ILIST: - return createListComparator(); + if (n == ILIST) { + return createListComparator(); } return createComparator(); } - - // called by EdegeManagerIndexer because every EdgeManager share same comparator object - void setComparatorIndex(Comparator c){ - comparatorIndex = c; - } - + // used to sort edgeList and find edge place in index // g s p o t < g s p o Comparator getComparatorIndex() { return comparatorIndex; - } - - // used to compare and retrieve edge when Index is sorted and reduced + } + + // called by EdegeManagerIndexer because every EdgeManager share same comparator object + void setComparatorIndex(Comparator c) { + comparatorIndex = c; + } + + // used to compare and retrieve edge when Index is sorted and reduced // g s p o t = g s p o Comparator getComparatorEqualWithoutMetadata() { return comparator; } - void setComparator(Comparator c){ + void setComparator(Comparator c) { comparator = c; } - + /** * Compare two edges to sort and retrieve them in Index * rdf star edges are compared on g s p o only, not on ref id - * hence they are considered equal when g s p o are equal + * hence they are considered equal when g s p o are equal * not considering triple ref id * g s p o = g s p o t - * @note: - * sort is not deterministic for rdf star triple with same g s p o + * + * @note: sort is not deterministic for rdf star triple with same g s p o * list will be reduced by metadata() */ - + // compare edges // g s p o t = g s p o Comparator createComparator() { return createComparator(true); } - + // sort edgeList // true: g s p o t = g s p o // false: g s p o t < g s p o Comparator createComparatorIndex() { return createComparator(false); } - + Comparator createComparator(boolean equalWithoutConsideringMetadataNode) { return new Comparator<>() { - boolean equalWithoutConsideringMetadata = equalWithoutConsideringMetadataNode; - + final boolean equalWithoutConsideringMetadata = equalWithoutConsideringMetadataNode; + @Override public int compare(Edge e1, Edge e2) { - + // check the Index Node int res = compareNodeTerm(e1.getNode(getIndex()), e2.getNode(getIndex())); - if (res != 0) { - //System.out.println("subject: " + res); + if (res != 0) { return res; } - + res = compareNodeTerm(e1.getNode(getOther()), e2.getNode(getOther())); if (res != 0) { - //System.out.println("object: " + res); return res; } - - if (e1.nbNodeIndex()== 2 && e2.nbNodeIndex()== 2) { + + if (e1.nbNodeIndex() == 2 && e2.nbNodeIndex() == 2) { // compare third Node (i.e. graph node in the general case) res = compareNodeTermNull(e1.getNode(getNext()), e2.getNode(getNext())); - //System.out.println("graph: " + res); return res; } - + // one of them has metadata, compare third Node if (getGraph().isMetadataNode()) { // rdf star: g s p o = g s p o t = g s p o t2 @@ -768,19 +736,13 @@ public int compare(Edge e1, Edge e2) { res = compareNodeTermNull(e1.getNode(getNext()), e2.getNode(getNext())); if (res == 0) { // equal on g s p o - //System.out.println("equalWithoutConsideringMetadata: " + equalWithoutConsideringMetadata); if (equalWithoutConsideringMetadata) { - //System.out.println("meta1: " + res); return res; - } - else { + } else { res = compareEqualWhenMetadata(e1, e2); - //System.out.println("meta2: " + res); return res; } - } - else { - //System.out.println("meta3: " + res); + } else { return res; } } @@ -803,8 +765,7 @@ public int compare(Edge e1, Edge e2) { // same arity, nodes are equal // check graph node return compareNodeTerm(e1.getNode(IGRAPH), e2.getNode(IGRAPH)); - } - else if (e1.nbNodeIndex() < e2.nbNodeIndex()) { + } else if (e1.nbNodeIndex() < e2.nbNodeIndex()) { // smaller arity edge is before return -1; } else { @@ -814,27 +775,24 @@ else if (e1.nbNodeIndex() < e2.nbNodeIndex()) { } }; } - - /** - * Edges are equal on g s p o - * edge with metadata < edge without metadata - */ - int compareEqualWhenMetadata(Edge e1, Edge e2) { - if (e1.hasReferenceNode()) { - if (e2.hasReferenceNode()) { - return compareNodeTerm(e1.getReferenceNode(), e2.getReferenceNode()); - } - else { - return -1; - } - } - else if (e2.hasReferenceNode()) { - return 1; - } - else { - return 0; - } - } + + /** + * Edges are equal on g s p o + * edge with metadata < edge without metadata + */ + int compareEqualWhenMetadata(Edge e1, Edge e2) { + if (e1.hasReferenceNode()) { + if (e2.hasReferenceNode()) { + return compareNodeTerm(e1.getReferenceNode(), e2.getReferenceNode()); + } else { + return -1; + } + } else if (e2.hasReferenceNode()) { + return 1; + } else { + return 0; + } + } /** * sort in reverse order of edge timestamp @@ -842,19 +800,16 @@ else if (e2.hasReferenceNode()) { */ Comparator createListComparator() { - return new Comparator<>() { - @Override - public int compare(Edge o1, Edge o2) { - int i1 = o1.getEdgeIndex(); - int i2 = o2.getEdgeIndex(); - - if (i1 > i2) { - return -1; - } else if (i1 == i2) { - return 0; - } else { - return 1; - } + return (o1, o2) -> { + int i1 = o1.getEdgeIndex(); + int i2 = o2.getEdgeIndex(); + + if (i1 > i2) { + return -1; + } else if (i1 == i2) { + return 0; + } else { + return 1; } }; @@ -868,10 +823,6 @@ public void setEdgeList(ArrayList edgeList) { this.edgeList = edgeList; } - public void setIndex(int index) { - this.index = index; - } - public int getOther() { return other; } diff --git a/src/main/java/fr/inria/corese/core/index/EdgeManagerIndexer.java b/src/main/java/fr/inria/corese/core/index/EdgeManagerIndexer.java index 24f63ef49..1e0d8467b 100644 --- a/src/main/java/fr/inria/corese/core/index/EdgeManagerIndexer.java +++ b/src/main/java/fr/inria/corese/core/index/EdgeManagerIndexer.java @@ -42,39 +42,35 @@ */ public class EdgeManagerIndexer implements Index { - public static boolean TRACE_REDUCE = false; - public static boolean TRACE_INSERT = false; // draft test to iterate edge list with subList(b, e) with rdf star only (predicate!=null) public static boolean ITERATE_SUBLIST = false; public static boolean RECORD_END = false; // true: store internal Edge without predicate Node - public static boolean test = true; - private static final String NL = "\n"; static final int IGRAPH = Graph.IGRAPH; static final int ILIST = Graph.ILIST; - private static Logger logger = LoggerFactory.getLogger(EdgeManagerIndexer.class); + private static final Logger logger = LoggerFactory.getLogger(EdgeManagerIndexer.class); private boolean byIndex = true; int index = 0, other = 1; int count = 0; - int scoIndex = -1, typeIndex = -1; - boolean isDebug = !true, - isUpdate = true, - isIndexer = false, + int scoIndex = -1; + int typeIndex = -1; + boolean isUpdate = true; + public static boolean test = true; + boolean isIndexer = false; // do not create entailed edge in kg:entailment if it already exist in another graph - isOptim = false; - Comparator comparatorIndex, comparator; + boolean isOptim = false; + Comparator comparatorIndex; + Comparator comparator; private Graph graph; List sortedProperties; PredicateList sortedPredicates; // Property Node -> Edge List HashMap table; private NodeManager nodeManager; - //TransitiveEdgeManager transitiveManager; - private boolean debug = false; public EdgeManagerIndexer(Graph g, boolean bi, int index) { init(g, bi, index); - table = new HashMap(); + table = new HashMap<>(); nodeManager = new NodeManager(g, index); } @@ -82,13 +78,10 @@ void init(Graph g, boolean bi, int n) { setGraph(g); index = n; byIndex = bi; - switch (index) { - case 0: - other = 1; - break; - default: - other = 0; - break; + if (index == 0) { + other = 1; + } else { + other = 0; } } @@ -147,9 +140,6 @@ public boolean same(Node n1, Node n2) { Node getNode(Edge ent, int n) { -// if (n == IGRAPH) { -// return ent.getGraph(); -// } return ent.getNode(n); } @@ -182,12 +172,7 @@ synchronized void sortProperties() { for (Node pred : getProperties()) { sortedProperties.add(pred); } - Collections.sort(sortedProperties, new Comparator() { - @Override - public int compare(Node o1, Node o2) { - return o1.compare(o2); - } - }); + sortedProperties.sort(Node::compare); } @Override @@ -663,17 +648,11 @@ void basicIndex(Node pred) { * index NodeManager */ private void reduce() { - if (TRACE_REDUCE) { - System.out.println("before reduce:\n" + getGraph().display()); - } getNodeManager().start(); for (Node pred : getSortedProperties()) { reduce(pred); } getNodeManager().finish(); - if (TRACE_REDUCE) { - System.out.println("after reduce:\n" + getGraph().display()); - } } private void reduce(Node pred) { @@ -724,7 +703,7 @@ private EdgeManager synCheckGet(Node pred) { synchronized (pred) { EdgeManager list = get(pred); if (list != null && list.size() == 0) { - EdgeManager std = (EdgeManager) getGraph().getIndex().get(pred); + EdgeManager std = getGraph().getIndex().get(pred); list.copy(std); list.sort(); } @@ -817,9 +796,6 @@ public Iterable getEdges(Node pred, Node node, int beginIndex) { return list; } else { - if (debug) { - logger.info("getEdges: " + pred + " " + node + " " + beginIndex); - } return list.getEdges(node, beginIndex); } } @@ -944,16 +920,11 @@ boolean superUser(Edge edge) { * nested delete nested */ boolean accept(Edge edge, Edge target) { - if (edge.isAsserted()) { + // nested delete nested when super user + if (edge.isAsserted()) { return target.isAsserted() || superUser(edge); } - else if (target.isNested() && superUser(edge)) { - // nested delete nested when super user - return true; - } - else { - return false; - } + else return target.isNested() && superUser(edge); } boolean onInsert(Edge ent) { @@ -1049,12 +1020,8 @@ private void update(Node g1, Node g2, Graph.GRAPH_OPERATION mode) { } private void update(Node g1, Node g2, Node pred, EdgeManager list, int n, Graph.GRAPH_OPERATION mode) { - boolean isBefore = false; - - if (g2 != null && nodeCompare(g1, g2) < 0) { - isBefore = true; - } - + boolean isBefore = g2 != null && nodeCompare(g1, g2) < 0; + for (int i = n; i < list.size();) { Edge ent = list.get(i); Edge ee; @@ -1101,10 +1068,7 @@ private Edge copy(Node gNode, Node pred, Edge ent) { private void clear(Node pred, Edge ent) { for (EdgeManagerIndexer ei : getGraph().getIndexList()) { if (ei.getIndex() != IGRAPH) { - Edge rem = ei.delete(pred, ent); - if (isDebug && rem != null) { - logger.debug("** EI clear: " + ei.getIndex() + " " + rem); - } + ei.delete(pred, ent); } } } diff --git a/src/main/java/fr/inria/corese/core/index/EdgeManagerIterate.java b/src/main/java/fr/inria/corese/core/index/EdgeManagerIterate.java index 9416a4a75..ba7318f26 100644 --- a/src/main/java/fr/inria/corese/core/index/EdgeManagerIterate.java +++ b/src/main/java/fr/inria/corese/core/index/EdgeManagerIterate.java @@ -1,18 +1,18 @@ package fr.inria.corese.core.index; import fr.inria.corese.core.edge.EdgeGeneric; -import java.util.Iterator; import fr.inria.corese.core.kgram.api.core.Edge; +import java.util.Iterator; + /** - * Iterate internal Edge Index + * Iterate internal Edge Index * fill buffer Edge with property Node from internal Index * return the buffer * buffer is the same object during iteration * hence if someone need to record edge, it MUST be copied - * - * @author Olivier Corby, Wimmics INRIA I3S, 2017 * + * @author Olivier Corby, Wimmics INRIA I3S, 2017 */ class EdgeManagerIterate implements Iterable, Iterator { @@ -20,8 +20,9 @@ class EdgeManagerIterate implements Iterable, Iterator { int focusNodeIndex; // possibly Edge object Node index // use case: subject and object are known - int objectNodeIndex=-1; - int ind, start = 0; + int objectNodeIndex = -1; + int ind; + int start = 0; boolean isList = true; EdgeGeneric buffer; @@ -31,15 +32,15 @@ class EdgeManagerIterate implements Iterable, Iterator { } EdgeManagerIterate(EdgeManager l, int begin) { - this(l); - start = begin; - focusNodeIndex = getFocusNodeIndex(begin); - isList = false; + this(l); + start = begin; + focusNodeIndex = getFocusNodeIndex(begin); + isList = false; } - + EdgeManagerIterate(EdgeManager l, int begin, int objectNodeIndex) { - this(l, begin); - this.objectNodeIndex = objectNodeIndex; + this(l, begin); + this.objectNodeIndex = objectNodeIndex; } @Override @@ -47,12 +48,12 @@ public Iterator iterator() { ind = start; return this; } - + // return node index of focus node at nth position in edge list int getFocusNodeIndex(int n) { return list.get(n).getNode(list.getIndex()).getIndex(); } - + // return node index of object node at nth position in edge list int getObjectNodeIndex(int n) { return list.get(n).getNode(1).getIndex(); @@ -62,22 +63,22 @@ int getObjectNodeIndex(int n) { public boolean hasNext() { boolean b = ind < list.size() && (isList || getFocusNodeIndex(ind) == focusNodeIndex); - if (b && objectNodeIndex!=-1) { + if (b && objectNodeIndex != -1) { b &= getObjectNodeIndex(ind) == objectNodeIndex; - } + } return b; } @Override public Edge next() { Edge ent = list.get(ind++); - if (ent.isInternal()) { + if (ent.isInternal()) { fill(buffer, ent); return buffer; } return ent; } - + /** * Fill buffer Edge from internal ent */ @@ -91,5 +92,5 @@ void fill(EdgeGeneric buf, Edge ent) { public void remove() { } - + } diff --git a/src/main/java/fr/inria/corese/core/index/NodeManager.java b/src/main/java/fr/inria/corese/core/index/NodeManager.java index cdfeae202..07fa8e62b 100644 --- a/src/main/java/fr/inria/corese/core/index/NodeManager.java +++ b/src/main/java/fr/inria/corese/core/index/NodeManager.java @@ -1,16 +1,19 @@ package fr.inria.corese.core.index; -import fr.inria.corese.core.kgram.api.core.Node; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import fr.inria.corese.core.Event; import fr.inria.corese.core.Graph; +import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.sparql.api.IDatatype.NodeKind; -import java.util.ArrayList; -import java.util.HashMap; /** * Manage a table of list of properties for each node * Node ni -> (p1, .. pn) ; (i1, .. in) - * where ij = position of ni in edge list of property pj + * where ij = position of ni in edge list of property pj * each kind of node has a table (uri, bnode, triple, literal) * * Use case: @@ -26,19 +29,20 @@ public class NodeManager { private Graph graph; - private ArrayList predicateTableList; + private List predicateTableList; // in some case content is obsolete private boolean active = true; // safety to switch off private boolean available = true; private int count = 0; - private int index =0; - private boolean debug = false; + private int index = 0; // record position of node in edge list private boolean position = true; private static final String NL = "\n"; PredicateList emptyPredicateList; - + + private boolean indexing = false; + public class PredicateTable extends HashMap { void trim() { for (PredicateList t : values()) { @@ -46,7 +50,7 @@ void trim() { } } } - + NodeManager(Graph g, int index) { graph = g; predicateTableList = new ArrayList<>(NodeKind.size()); @@ -55,13 +59,13 @@ void trim() { init(); } - void init() { + void init() { // URI, bnode, triple and literal Node have their own map - for (int i = 0; i0; + return active && !indexing && size() > 0; } - public void setActive(boolean active) { this.active = active; } @@ -205,21 +208,10 @@ public boolean isAvailable() { return available; } - public void setAvailable(boolean available) { this.available = available; } - - public boolean isDebug() { - return debug; - } - - - public void setDebug(boolean debug) { - this.debug = debug; - } - public String display() { return display(Integer.MAX_VALUE); } @@ -237,7 +229,7 @@ public String display(int max) { PredicateList plist = getPredicateList(n); int i = 0; for (Node p : plist.getPredicateList()) { - sb.append(String.format(" %s (%s, %s);", p, + sb.append(String.format(" %s (%s, %s);", p, plist.getPosition(i), plist.getEnd(i))); i++; } @@ -248,22 +240,22 @@ public String display(int max) { return sb.toString(); } - + @Override public String toString() { return display(); } - + // one map per kind of Node - public HashMap getPredicateTable(Node node) { + public Map getPredicateTable(Node node) { return getPredicateTableList().get(node.getNodeKind().getIndex()); } - public ArrayList getPredicateTableList() { + public List getPredicateTableList() { return predicateTableList; } - public void setPredicateTableList(ArrayList predicateTableList) { + public void setPredicateTableList(List predicateTableList) { this.predicateTableList = predicateTableList; } diff --git a/src/main/java/fr/inria/corese/core/index/NodeManagerBasic.java b/src/main/java/fr/inria/corese/core/index/NodeManagerBasic.java index 76c0c152a..e96b8b283 100644 --- a/src/main/java/fr/inria/corese/core/index/NodeManagerBasic.java +++ b/src/main/java/fr/inria/corese/core/index/NodeManagerBasic.java @@ -1,42 +1,39 @@ package fr.inria.corese.core.index; -import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.Event; import fr.inria.corese.core.Graph; -import fr.inria.corese.core.sparql.api.IDatatype.NodeKind; -import java.util.ArrayList; +import fr.inria.corese.core.kgram.api.core.Node; + import java.util.HashMap; +import java.util.Map; /** * Manage a table of list of properties for each node * Node ni -> (p1, .. pn) ; (i1, .. in) * where ij = position of ni in edge list of property pj - * + *

* Use case: * ?x rdfs:label "Antibes"@fr . ?x ?q ?v * When we enumerate ?x ?q ?v we can focus on the properties of ?x=xi * instead of enumerating all properties. * DPbedia has more than 10.000 properties ! * - * * @author Olivier Corby, Wimmics INRIA I3S, 2017 - * */ public class NodeManagerBasic { - private Graph graph; - private HashMap nodePredicateTable; + private static final String NL = System.getProperty("line.separator"); + private final Graph graph; + // record position of node in edge list + boolean isPosition = true; + private Map nodePredicateTable; // in some case content is obsolete private boolean active = true; // safety to switch off private boolean available = true; private int count = 0; - private int index =0; - private boolean debug = false; - // record position of node in edge list - boolean isPosition = true; - private static final String NL = "\n"; - + private int index = 0; + NodeManagerBasic(Graph g, int index) { graph = g; nodePredicateTable = new HashMap<>(); @@ -55,7 +52,7 @@ void clear() { getPredicateTable().clear(); count = 0; } - + public int getIndex() { return index; } @@ -69,34 +66,34 @@ public void activate() { clear(); setActive(true); } - + // start indexing public void start() { activate(); graph.getEventManager().start(Event.IndexNodeManager); } - + // finish indexing public void finish() { graph.getEventManager().finish(Event.IndexNodeManager, this); } - + PredicateList get(Node node) { return get1(node); } - + void put(Node node, PredicateList list) { put1(node, list); } - + PredicateList get1(Node node) { return getPredicateTable(node).get(node); } - + void put1(Node node, PredicateList list) { getPredicateTable(node).put(node, list); } - + void add(Node node, Node predicate, int begin, int end) { if (isEffective()) { PredicateList list = get(node); @@ -104,25 +101,20 @@ void add(Node node, Node predicate, int begin, int end) { list = new PredicateList(isPosition); put(node, list); } - list.add(node, predicate, begin,end); + list.add(node, predicate, begin, end); count++; } } - + PredicateList getPredicates(Node node) { if (isEffective()) { - return getPredicateList(node); - } - else if (isAvailable() && ! graph.isIndexable()) { + return getPredicateList(node); + } else if (isAvailable() && !graph.isIndexable()) { synchronized (graph) { graph.getIndex(index).indexNodeManager(); } - if (debug) { - System.out.println("NMP create: " + index + " " + node + " " + getPredicateList(node)); - } return getPredicateList(node); - } - else { + } else { return graph.getIndex().getSortedPredicates(); } } @@ -135,52 +127,41 @@ PredicateList getPredicateList(Node node) { } return list; } - + int getPosition(Node node, Node predicate) { PredicateList list = get(node); if (list == null) { return -2; } return list.getPosition(predicate); - } + } public boolean isEffective() { return active && available; } - + public boolean isActive() { - return active ; - } - - public boolean isConsultable() { - return active && size()>0; + return active; } - public void setActive(boolean active) { this.active = active; } + public boolean isConsultable() { + return active && size() > 0; + } + public boolean isAvailable() { return available; } - + public void setAvailable(boolean available) { this.available = available; } - - public boolean isDebug() { - return debug; - } - - - public void setDebug(boolean debug) { - this.debug = debug; - } - public String display() { StringBuilder sb = new StringBuilder(); int num = 0; @@ -193,35 +174,24 @@ public String display() { } sb.append(NL); } - + return sb.toString(); } - + @Override public String toString() { return getPredicateTable().toString(); } - - public HashMap getPredicateTable(Node node) { - return getPredicateTable(); - } - - // @todo: one map per kind of Node - public HashMap getPredicateTable2(Node node) { - switch (node.getNodeKind()) { - case URI: - case BNODE: - case TRIPLE: - case LITERAL: - } + + public Map getPredicateTable(Node node) { return getPredicateTable(); } - public HashMap getPredicateTable() { + public Map getPredicateTable() { return nodePredicateTable; } - public void setPredicateTable(HashMap ptable) { + public void setPredicateTable(Map ptable) { this.nodePredicateTable = ptable; } diff --git a/src/main/java/fr/inria/corese/core/index/PredicateList.java b/src/main/java/fr/inria/corese/core/index/PredicateList.java index 858abbe76..56f3f4fcc 100644 --- a/src/main/java/fr/inria/corese/core/index/PredicateList.java +++ b/src/main/java/fr/inria/corese/core/index/PredicateList.java @@ -2,23 +2,24 @@ import static fr.inria.corese.core.index.EdgeManagerIndexer.ITERATE_SUBLIST; import static fr.inria.corese.core.index.EdgeManagerIndexer.RECORD_END; -import fr.inria.corese.core.kgram.api.core.Node; + import java.util.ArrayList; import java.util.List; +import fr.inria.corese.core.kgram.api.core.Node; + /** * List of predicates of a given Node in NodeManager * List of positions of node in edge list of each predicate pi * (p1, .. pn) (i1, .. in) * in the edge list of predicate(j) = (t1 .. tn) * index(node) = position(j) - * - * @author Olivier Corby, Wimmics INRIA I3S, 2017 * + * @author Olivier Corby, Wimmics INRIA I3S, 2017 */ public class PredicateList { boolean isPosition = true; - + // list of position(i) of given node in the list of edge of predicate(i) private ArrayList predicateList; private ArrayList positionList; @@ -28,23 +29,20 @@ public class PredicateList { PredicateList() { init(); } - + PredicateList(boolean b) { this(); - //isPosition = b; } - + PredicateList(List l) { this(); getPredicateList().addAll(l); - //isPosition = false; } PredicateList(boolean b, int n) { - this(); - //isPosition = b; + this(b); } - + void init() { setPredicateList(new ArrayList<>()); if (isPosition) { @@ -55,14 +53,14 @@ void init() { } } } - + @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(super.toString()).append(getPositionList()); return sb.toString(); } - + void trim() { getPredicateList().trimToSize(); getPositionList().trimToSize(); @@ -71,58 +69,58 @@ void trim() { getCursorList().trimToSize(); } } - + public int getPosition(Node predicate) { return findPosition(predicate); } - + public int size() { return getPredicateList().size(); } - + Node getPredicate(int i) { return getPredicateList().get(i); } - - int findPosition(Node predicate){ + + int findPosition(Node predicate) { int i = findPosition(predicate, 0, size()); - if (i >= 0 && i < size()){ - if (predicate.getIndex() == getPredicate(i).getIndex()) { - return getPosition(i); - } + if ((i >= 0 && i < size()) && (predicate.getIndex() == getPredicate(i).getIndex())) { + return getPosition(i); } return -1; } - - public Cursor getCursor(Node predicate){ + + public Cursor getCursor(Node predicate) { int i = findPosition(predicate, 0, size()); - if (i >= 0 && i < size()){ + if (i >= 0 && i < size()) { if (predicate.getIndex() == getPredicate(i).getIndex()) { return getCursor(i); } } return null; } - + Cursor getCursor(int n) { - //return new Cursor(getPosition(n), endList.get(n)); return getCursorList().get(n); } - + int getPosition(int n) { - if (isPosition){ + if (isPosition) { + if (getPositionList().isEmpty()) { + return -1; + } return getPositionList().get(n); } return -1; } - + int getEnd(int n) { if (n < getEndList().size()) { return getEndList().get(n); } return -1; } - + int getPositionBasic(Node predicate) { int i = 0; for (Node p : getPredicateList()) { @@ -133,15 +131,13 @@ int getPositionBasic(Node predicate) { } return -3; } - - - + int findPosition(Node predicate, int first, int last) { if (first >= last) { return first; } else { int mid = (first + last) / 2; - int res = getPredicate(mid).compare(predicate); + int res = getPredicate(mid).compare(predicate); if (res >= 0) { return findPosition(predicate, first, mid); } else { @@ -149,8 +145,7 @@ int findPosition(Node predicate, int first, int last) { } } } - - + void add(Node node, Node predicate, int begin, int end) { getPredicateList().add(predicate); if (isPosition) { @@ -210,11 +205,11 @@ public ArrayList getCursorList() { public void setCursorList(ArrayList cursorList) { this.cursorList = cursorList; } - - public class Cursor { + + public static class Cursor { private int begin; private int end; - + Cursor(int b, int e) { begin = b; end = e; diff --git a/src/main/java/fr/inria/corese/core/kgram/api/core/DatatypeValue.java b/src/main/java/fr/inria/corese/core/kgram/api/core/DatatypeValue.java index 87906bf2b..205ff7128 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/core/DatatypeValue.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/core/DatatypeValue.java @@ -1,50 +1,48 @@ - package fr.inria.corese.core.kgram.api.core; import java.math.BigDecimal; import java.util.List; /** - * * Olivier Corby - Wimmics, Inria, I3S, 2015 */ public interface DatatypeValue { - + String stringValue(); boolean booleanValue(); - + int intValue(); - + long longValue(); double doubleValue(); - + float floatValue(); BigDecimal decimalValue(); - + Object objectValue(); - + String getDatatypeURI(); - + String getLang(); - + List getValueList(); - + boolean isURI(); - + boolean isBlank(); - + boolean isLiteral(); - + boolean isNumber(); - + boolean isBoolean(); - + boolean isUndefined(); - + boolean isExtension(); - + Object getNodeObject(); } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/core/DatatypeValueFactory.java b/src/main/java/fr/inria/corese/core/kgram/api/core/DatatypeValueFactory.java index d0f89f7df..81523e844 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/core/DatatypeValueFactory.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/core/DatatypeValueFactory.java @@ -3,13 +3,12 @@ import java.util.List; /** - * * @author Olivier Corby, Wimmics, INRIA 2019 */ public interface DatatypeValueFactory { - + Node nodeList(List list); - + Node nodeValue(int n); - + } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/core/Edge.java b/src/main/java/fr/inria/corese/core/kgram/api/core/Edge.java index f21e6c840..0313cd4c0 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/core/Edge.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/core/Edge.java @@ -2,13 +2,13 @@ import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.exceptions.CoreseDatatypeException; +import fr.inria.corese.core.sparql.triple.parser.AccessRight; /** * Interface for Producer iterator that encapsulate Edge or Node with its Graph * Node * * @author Olivier Corby, Edelweiss, INRIA 2010 - * */ public interface Edge extends Pointerable { @@ -19,7 +19,7 @@ public interface Edge extends Pointerable { default int nbNode() { return 2; } - + // nb nodes to consider in graph index // edge triple node (g, t = (s p o)) has 2 nodes s,o for index and 3 nodes s,o,t for sparql default int nbNodeIndex() { @@ -33,16 +33,17 @@ default int nbNodeIndex() { default int nbGraphNode() { return nbNode(); } - + Node getNode(int i); - default void setNode(int i, Node n) {} + default void setNode(int i, Node n) { + } + - default Node getEdgeNode() { return getProperty(); } - + default Node getEdgeVariable() { return null; } @@ -50,37 +51,44 @@ default Node getEdgeVariable() { // edge variable or edge node Node getProperty(); - default void setProperty(Node node) {} - - + default void setProperty(Node node) { + } + + /** * Is node returned by getNode() * - * @param n + * @param node * @return */ - default boolean contains(Node node) {return false;} + default boolean contains(Node node) { + return false; + } + - String getEdgeLabel(); - - default int getEdgeIndex() { return -1;} - default void setEdgeIndex(int n) {} - // manage access right - default byte getLevel() { + default int getEdgeIndex() { return -1; } - default Edge setLevel(byte b) { + default void setEdgeIndex(int n) { + } + + // manage access right + default AccessRight.AccessRights getLevel() { + return AccessRight.AccessRights.NONE; + } + + default Edge setLevel(AccessRight.AccessRights b) { return this; } - + // use case: internal index edge default boolean isInternal() { - return nbNode() == 2 && ! isTripleNode(); + return nbNode() == 2 && !isTripleNode(); } @Override @@ -94,9 +102,12 @@ default void setGraph(Node n) { @Override Edge getEdge(); - default Object getProvenance() { return null;}; + default Object getProvenance() { + return null; + } - default void setProvenance(Object obj) {} + default void setProvenance(Object obj) { + } default boolean isMatchArity() { return false; @@ -107,24 +118,24 @@ default boolean isNested() { return false; } - default boolean isAsserted() { - return !isNested(); + default void setNested(boolean b) { } - default void setNested(boolean b) { + default boolean isAsserted() { + return !isNested(); } default void setAsserted(boolean b) { setNested(!b); } - + // edge created as nested triple expression // bind (<> as ?t) // values ?t { <> } default boolean isCreated() { return false; } - + default void setCreated(boolean b) { } @@ -175,27 +186,28 @@ default IDatatype getObjectValue() { default boolean hasReferenceNode() { return nbNode() > REF_INDEX && getReferenceNode().getDatatypeValue().isTriple(); } - + default Node getReferenceNode() { if (nbNode() <= REF_INDEX) { return null; } return getNode(REF_INDEX); } - + default void setReferenceNode(Node node) { setNode(REF_INDEX, node); } - + default boolean isTripleNode() { return false; } - + default Node getTripleNode() { return null; } - - default void setTripleNode(Node node) {} + + default void setTripleNode(Node node) { + } default boolean sameTerm(Edge e) { return sameTermWithoutGraph(e) @@ -203,7 +215,7 @@ default boolean sameTerm(Edge e) { ? getGraphValue() == e.getGraphValue() : getGraphValue().sameTerm(e.getGraphValue())); } - + default boolean sameTermWithoutGraph(Edge e) { return getSubjectValue().sameTerm(e.getSubjectValue()) && getPredicateValue().sameTerm(e.getPredicateValue()) @@ -216,13 +228,13 @@ default boolean equals(Edge e) { ? getGraphValue() == e.getGraphValue() : getGraphValue().equals(e.getGraphValue())); } - + default boolean equalsWithoutGraph(Edge e) { return getObjectValue().equals(e.getObjectValue()) && getSubjectValue().equals(e.getSubjectValue()) && getPredicateValue().equals(e.getPredicateValue()); } - + default int compareWithoutGraph(Edge e) throws CoreseDatatypeException { int res = getSubjectValue().compare(e.getSubjectValue()); if (res == 0) { @@ -233,5 +245,5 @@ default int compareWithoutGraph(Edge e) throws CoreseDatatypeException { } return res; } - + } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/core/ExpPattern.java b/src/main/java/fr/inria/corese/core/kgram/api/core/ExpPattern.java index ce9558561..f1a729a58 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/core/ExpPattern.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/core/ExpPattern.java @@ -3,9 +3,9 @@ import java.util.List; public interface ExpPattern { - - void getVariables(List list); - - void getVariables(List list, boolean excludeLocal); + + void getVariables(List list); + + void getVariables(List list, boolean excludeLocal); } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/core/ExpType.java b/src/main/java/fr/inria/corese/core/kgram/api/core/ExpType.java index a98eb4f8f..649b62081 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/core/ExpType.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/core/ExpType.java @@ -2,77 +2,73 @@ /** * Types of expression of KGRAM query language - * - * @author Olivier Corby, Edelweiss, INRIA 2010 * + * @author Olivier Corby, Edelweiss, INRIA 2010 */ public interface ExpType { - - //public static final String KGRAM = "http://ns.inria.fr/edelweiss/2010/kgram/"; - public static final String KGRAM = "http://ns.inria.fr/corese.core.kgram/"; - public static final String DEFAULT_GRAPH = KGRAM + "default"; - public static final String SKOLEM_MARKER = "/.well-known/genid/"; - public static final String SKOLEM = "http://ns.inria.fr" + SKOLEM_MARKER ; - public static final String SPARQL = "http://ns.inria.fr/sparql-function/"; - public static final String STL = "http://ns.inria.fr/sparql-template/"; - public static final String EXT = "http://ns.inria.fr/sparql-extension/"; - public static final String DOM = "http://ns.inria.fr/sparql-extension/dom/"; - public static final String CUSTOM = "http://ns.inria.fr/sparql-custom/"; - public static final String BNODE = EXT + "bnode"; - public static final String UXT = "http://ns.inria.fr/sparql-extension/user/"; - public static final String DT = "http://ns.inria.fr/sparql-datatype/"; - public static final String SWL = "http://ns.inria.fr/sparql-workflow/"; - public static final String TYPE_METADATA = "@type"; + + String KGRAM = "http://ns.inria.fr/corese.core.kgram/"; + String DEFAULT_GRAPH = KGRAM + "default"; + String SKOLEM_MARKER = "/.well-known/genid/"; + String SKOLEM = "http://ns.inria.fr" + SKOLEM_MARKER; + String SPARQL = "http://ns.inria.fr/sparql-function/"; + String STL = "http://ns.inria.fr/sparql-template/"; + String EXT = "http://ns.inria.fr/sparql-extension/"; + String DOM = "http://ns.inria.fr/sparql-extension/dom/"; + String CUSTOM = "http://ns.inria.fr/sparql-custom/"; + String BNODE = EXT + "bnode"; + String UXT = "http://ns.inria.fr/sparql-extension/user/"; + String DT = "http://ns.inria.fr/sparql-datatype/"; + String SWL = "http://ns.inria.fr/sparql-workflow/"; + String TYPE_METADATA = "@type"; - public static final String KPREF = "kg"; + String KPREF = "kg"; - static final int EMPTY = 0; - static final int AND = 1; - static final int UNION = 2; - static final int GRAPH = 3; - static final int OPTION = 4; - static final int EDGE = 5; - static final int FILTER = 6; - static final int NODE = 7; - - static final int BGP = 8; - static final int WATCH = 9; - static final int CONTINUE = 10; - static final int BACKJUMP = 11; - static final int EXTERN = 12; - static final int QUERY = 13; - static final int FORALL = 14; - static final int EXIST = 15; - static final int GRAPHNODE = 16; - static final int OPTIONAL = 17; - static final int SCAN = 18; - static final int IF = 19; - static final int PATH = 20; - static final int XPATH = 21; - static final int ACCEPT = 22; - static final int BIND = 23; - static final int EVAL = 24; - static final int SCOPE = 25; - static final int TEST = 26; - static final int NEXT = 27; - static final int MINUS = 28; - static final int POP = 29; - static final int SERVICE = 30; - static final int RESTORE = 31; - static final int JOIN = 32; - static final int VALUES = 33; - static final int OPT_BIND = 34; - + public enum Type { + EMPTY("EMPTY"), + AND("AND"), + UNION("UNION"), + GRAPH("GRAPH"), + OPTION("OPTION"), + EDGE("EDGE"), + FILTER("FILTER"), + NODE("NODE"), + BGP("BGP"), + WATCH("WATCH"), + CONTINUE("CONTINUE"), + BACKJUMP("BACKJUMP"), + EXTERN("EXTERN"), + QUERY("QUERY"), + FORALL("FORALL"), + EXIST("EXIST"), + GRAPHNODE("GRAPHNODE"), + OPTIONAL("OPTIONAL"), + SCAN("SCAN"), + IF("IF"), + PATH("PATH"), + XPATH("XPATH"), + ACCEPT("ACCEPT"), + BIND("BIND"), + EVAL("EVAL"), + SCOPE("SCOPE"), + TEST("TEST"), + NEXT("NEXT"), + MINUS("MINUS"), + POP("POP"), + SERVICE("POP"), + RESTORE("RESTORE"), + JOIN("JOIN"), + VALUES("VALUES"), + OPT_BIND("OPT_BIND"); + private final String title; + Type(String title) { + this.title = title; + } + public String getTitle() { + return title; + } + } - - static final String[] TITLE = { - "EMPTY", "AND", "UNION", "GRAPH", "OPTION", "EDGE", "FILTER", "NODE", - "BGP", "WATCH", "CONTINUE", "BACKJUMP", "EXTERN", "QUERY", "FORALL", "EXIST", - "GRAPHNODE", "OPTIONAL", "SCAN", "IF", "PATH", "XPATH", "ACCEPT", "BIND", - "EVAL", "SCOPE", "TEST", "NEXT", "MINUS", "POP", "SERVICE", "RESTORE", "JOIN", "VALUES", - "OPT_BIND" - }; - } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/core/Expr.java b/src/main/java/fr/inria/corese/core/kgram/api/core/Expr.java index b26d2e2ed..872d3d164 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/core/Expr.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/core/Expr.java @@ -6,6 +6,7 @@ import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.exceptions.EngineException; import fr.inria.corese.core.sparql.triple.function.term.Binding; + import java.util.Collection; import java.util.List; @@ -13,7 +14,6 @@ * Expr api refer to sparql.triple.parser.Expression * * @author Olivier Corby, Edelweiss, INRIA 2010 - * */ public interface Expr { @@ -26,10 +26,10 @@ public interface Expr { boolean isPublic(); - boolean isDynamic(); - void setPublic(boolean b); + boolean isDynamic(); + boolean isTrace(); boolean isDebug(); @@ -119,7 +119,7 @@ public interface Expr { boolean hasMetadata(String name); IDatatype evalWE(Computer eval, Binding b, Environment env, Producer p) throws EngineException; - + default boolean test(Computer eval, Binding b, Environment env, Producer p) throws EngineException { IDatatype dt = evalWE(eval, b, env, p); if (dt == null) { @@ -127,5 +127,5 @@ default boolean test(Computer eval, Binding b, Environment env, Producer p) thro } return dt.isTrueTest(); } - + } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/core/ExprLabel.java b/src/main/java/fr/inria/corese/core/kgram/api/core/ExprLabel.java index 29c2e2b55..7568bb391 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/core/ExprLabel.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/core/ExprLabel.java @@ -1,25 +1,24 @@ package fr.inria.corese.core.kgram.api.core; /** - * * @author corby */ public interface ExprLabel { - - public static final String SEPARATOR= "#"; - - public static final String EQUAL = "equal"; - public static final String DIFF = "diff"; - public static final String LESS = "less"; - public static final String LESS_EQUAL = "lessEqual"; - public static final String GREATER = "greater"; - public static final String GREATER_EQUAL= "greaterEqual"; - - public static final String PLUS = "plus"; - public static final String MINUS = "minus"; - public static final String MULT = "mult"; - public static final String DIV = "divis"; - - public static final String COMPARE = ExpType.KGRAM + "compare"; - + + String SEPARATOR = "#"; + + String EQUAL = "equal"; + String DIFF = "diff"; + String LESS = "less"; + String LESS_EQUAL = "lessEqual"; + String GREATER = "greater"; + String GREATER_EQUAL = "greaterEqual"; + + String PLUS = "plus"; + String MINUS = "minus"; + String MULT = "mult"; + String DIV = "divis"; + + String COMPARE = ExpType.KGRAM + "compare"; + } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/core/ExprType.java b/src/main/java/fr/inria/corese/core/kgram/api/core/ExprType.java index 4fd73e320..7070d3af6 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/core/ExprType.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/core/ExprType.java @@ -1,461 +1,455 @@ package fr.inria.corese.core.kgram.api.core; public interface ExprType { - - public static int UNDEF = -1; - public static int UNBOUND = -2; - // LDScript variable - public static int LOCAL = -3; - // SPARQL BGP variable - public static int GLOBAL = -4; - - // abstract type - public static int JOKER = 1; - public static int ALTER = 2; - - // type - public static int CONSTANT = 6; - public static int VARIABLE = 7; - public static int BOOLEAN = 8; - public static int TERM = 9; - public static int FUNCTION = 10; - - - - // boolean - public static int AND = 11; - public static int OR = 12; - public static int NOT = 13; - - // function - public static int BOUND = 14; - public static int COUNT = 15; - // ?x in (1, 2) - public static int INLIST = 16; - - public static int SAMETERM = 17; - public static int CUSTOM = 18; - public static int ISNUMERIC = 19; - public static int MIN = 20; - public static int MAX = 21; - public static int AVG = 22; - public static int SUM = 23; - public static int ISURI = 24; - public static int ISBLANK = 25; - public static int ISLITERAL = 26; - public static int LANG = 27; - public static int LANGMATCH = 28; - public static int REGEX = 29; - - public static int DATATYPE = 30; - public static int CAST = 31; - public static int SELF = 32; - public static int DEBUG = 33; - public static int EXTERNAL = 34; - public static int EXTERN = 35; - public static int KGRAM = 36; - public static int SQL = 37; - public static int XPATH = 38; - public static int SKIP = 39; - - public static int LENGTH = 40; - public static int UNNEST = 41; - public static int EXIST = 42; - public static int STRDT = 43; - public static int STRLANG = 44; - public static int BNODE = 45; - public static int COALESCE = 46; - public static int IF = 47; - public static int SYSTEM = 48; - public static int GROUPCONCAT = 49; - public static int SAMPLE = 50; - - public static int STRLEN = 51; - public static int SUBSTR = 52; - public static int UCASE = 53; - public static int LCASE = 54; - public static int ENDS = 55; - public static int STARTS = 56; - public static int CONTAINS = 57; - public static int ENCODE = 58; - public static int CONCAT = 59; - - public static int YEAR = 60; - public static int MONTH = 61; - public static int DAY = 62; - public static int HOURS = 63; - public static int MINUTES = 64; - public static int SECONDS = 65; - public static int TIMEZONE = 66; - public static int NOW = 67; - - public static int ABS = 68; - public static int FLOOR = 69; - public static int ROUND = 70; - public static int CEILING = 71; - public static int RANDOM = 72; - - public static int HASH = 73; - public static int URI = 74; - public static int TZ = 75; - public static int STR = 76; - - public static int STRBEFORE = 77; - public static int STRAFTER = 78; - public static int STRREPLACE = 79; - public static int FUUID = 80; - public static int STRUUID = 81; - public static int XSDSTRING = 82; - public static int APPROXIMATE = 83; - public static int APP_SIM = 84; - public static int ISLIST = 85; - public static int ISUNDEFINED = 86; - public static int ISWELLFORMED = 87; - - public static int TRIPLE = 88; - public static int SUBJECT = 89; - public static int PREDICATE = 90; - public static int OBJECT = 91; - public static int IS_TRIPLE = 92; - public static int SPARQL_COMPARE = 93; - - - - // term - public static int TEQ = 101; - public static int TNEQ = 102; - public static int TLE = 103; - public static int TGE = 104; - public static int TLT = 105; - public static int TGT = 106; - // == where type error return false - public static int EQUAL = 107; - // !== where type error return true - public static int NOT_EQUAL= 108; - - public static int EQNE = 109; - - public static int EQ = 110; - public static int NE = 111; - public static int NEQ = 111; - - public static int GL = 112; - public static int LE = 113; - public static int GE = 114; - public static int LT = 115; - public static int GT = 116; - - public static int PLUS = 117; - public static int MINUS = 118; - public static int MULT = 119; - - public static int DIV = 120; - - public static int CONT = 121; // ~ - public static int START = 122; // ^ - public static int IN = 123; - public static int POWER = 124; - public static int STAR = 125; - - public static int COS = 126; - public static int SIN = 127; - public static int TAN = 128; - public static int ARC_COS = 129; - public static int ARC_SIN = 130; - public static int ARC_TAN = 131; - public static int SQRT = 132; - - - - - // fake for query - public static int TINKERPOP = 150; - public static int TINKERPOP_RESTRICT = 151; - public static int BETWEEN = 152; - public static int MORE = 153; - public static int LESS = 154; - public static int KIND = 155; - public static int BIPREDICATE = 156; - public static int EQ_SAME = 157; - - // extension - - public static int DISPLAY = 200; - public static int NUMBER = 201; - public static int SIM = 202; - public static int EXTEQUAL = 203; - public static int EXTCONT = 204; - public static int PROCESS = 205; - public static int ENV = 206; - public static int DEPTH = 207; - public static int KG_GRAPH = 208; - public static int NODE = 209; - public static int GET_OBJECT = 210; - public static int SET_OBJECT = 211; - public static int LOAD = 212; - public static int PATHNODE = 213; - public static int GROUPBY = 214; - public static int PSIM = 215; - public static int GETP = 216; - public static int SETP = 217; - public static int PWEIGHT = 218; - public static int ANCESTOR = 219; - public static int PROVENANCE = 220; - public static int INDEX = 221; - public static int TIMESTAMP = 222; - public static int ID = 223; - public static int TEST = 224; - public static int DESCRIBE = 225; - public static int STORE = 226; - - - - public static int TURTLE = 227; - public static int LEVEL = 228; - public static int INDENT = 229; - public static int PPURI = 230; - public static int URILITERAL = 231; - public static int VISITED = 232; - public static int AGGAND = 233; - public static int PROLOG = 234; - public static int WRITE = 235; - public static int FOCUS_NODE = 236; - public static int XSDLITERAL = 237; - public static int QNAME = 238; - - public static int STL_DEFAULT = 239; - public static int STL_DEFINE = 240; - public static int STL_NL = 241; - public static int STL_PREFIX = 242; - public static int STL_AGGREGATE = 243; - public static int STL_CONCAT = 244; - public static int STL_GROUPCONCAT=245; - public static int STL_AND = 246; - public static int STL_NUMBER = 247; - public static int STL_LOAD = 248; - public static int STL_IMPORT = 249; - public static int STL_PROCESS = 250; - - - public static int APPLY_TEMPLATES = 251; - public static int APPLY_TEMPLATES_WITH = 252; - public static int APPLY_TEMPLATES_ALL = 253; - public static int APPLY_TEMPLATES_WITH_ALL = 254; - public static int APPLY_TEMPLATES_GRAPH = 255; - public static int APPLY_TEMPLATES_WITH_GRAPH= 256; - public static int APPLY_TEMPLATES_NOGRAPH = 257; - public static int APPLY_TEMPLATES_WITH_NOGRAPH= 258; - public static int CALL_TEMPLATE = 259; - public static int CALL_TEMPLATE_WITH = 260; - public static int STL_TEMPLATE = 261; - - public static int STL_SET = 262; - public static int STL_GET = 263; - public static int STL_BOOLEAN = 264; - public static int STL_VISIT = 265; - public static int STL_VISITED = 266; - public static int STL_FUTURE = 267; - public static int STL_INDEX = 268; - public static int STL_VSET = 269; - public static int STL_VGET = 270; - public static int STL_PROCESS_URI = 271; - public static int STL_EXPORT = 272; - public static int STL_ERRORS = 273; - public static int STL_ISSTART = 274; - public static int AGGLIST = 275; - public static int AGGREGATE = 276; - public static int STL_FORMAT = 277; - public static int STL_VISITED_GRAPH = 278; - public static int STL_CGET = 279; - public static int STL_CSET = 280; - public static int STL_HASGET = 281; - public static int STL_STRIP = 282; - public static int FORMAT = 283; - public static int STL_ERROR_MAP = 284; - public static int STL_DEFINED = 285; - - - public static int ISSKOLEM = 300; - public static int SKOLEM = 301; - - public static int QUERY = 302; - public static int EXTENSION = 303; - public static int EVEN = 304; - public static int ODD = 305; - public static int READ = 306; - public static int PACKAGE = 307; - - public static int IOTA = 308; - public static int LIST = 309; - public static int MAP = 310; - public static int MAPLIST = 311; - public static int APPLY = 312; - public static int LET = 313; - public static int LAMBDA = 314; - public static int ERROR = 315; - public static int MAPEVERY = 316; - public static int MAPANY = 317; - public static int MAPFIND = 318; - public static int MAPFINDLIST = 319; - public static int MAPMERGE = 320; - public static int MAPFUN = 321; - public static int SET = 322; - public static int SEQUENCE = 323; - public static int RETURN = 324; - public static int EVAL = 325; - public static int FUNCALL = 326; - public static int FOR = 327; - public static int MAPAPPEND = 328; - public static int REDUCE = 329; - - public static int XT_SORT = 330; - public static int JAVACALL = 331; - public static int DSCALL = 332; - public static int JAVACAST = 333; - public static int ISEXTENSION = 334; - public static int SAFE = 335; - public static int STATIC = 336; - public static int TRY_CATCH = 337; - public static int THROW = 338; - public static int RESUME = 339; - public static int UNSET = 340; - public static int STATIC_UNSET = 341; - - public static int XT_MAPPING = 400; - public static int XT_ADD = 401; - public static int XT_CONCAT = 402; - public static int XT_COUNT = 403; - public static int XT_CONS = 404; - public static int XT_FIRST = 405; - public static int XT_REST = 406; - public static int XT_GET = 407; - public static int XT_SET = 408; - public static int XT_REVERSE = 409; - public static int XT_APPEND = 410; - - public static int XT_SUBJECT = 411; - public static int XT_OBJECT = 412; - public static int XT_PROPERTY = 413; - public static int XT_VALUE = 414; - public static int XT_INDEX = 415; - public static int XT_GRAPH = 416; - public static int XT_REJECT = 417; - public static int XT_VARIABLES = 418; - public static int XT_VALUES = 419; - public static int XT_EDGES = 420; - public static int XT_TRIPLE = 421; - public static int XT_GEN_GET = 422; - public static int XT_DISPLAY = 423; - public static int XT_PRINT = 424; - - public static int XT_UNION = 425; - public static int XT_MINUS = 426; - public static int XT_OPTIONAL = 427; - public static int XT_JOIN = 428; - public static int XT_QUERY = 429; - public static int XT_AST = 430; - public static int XT_CONTEXT = 431; - public static int XT_METADATA = 432; - public static int XT_FROM = 433; - public static int XT_NAMED = 434; - public static int XT_MEMBER = 435; - public static int XT_MERGE = 436; - public static int XT_TOLIST = 437; - public static int XT_TUNE = 438; - public static int XT_FOCUS = 439; - public static int XT_CONTENT = 440; - public static int XT_ENTAILMENT = 441; - public static int XT_DATATYPE = 442; - public static int XT_KIND = 443; - public static int XT_METHOD = 444; - public static int XT_METHOD_TYPE = 445; - public static int XT_ITERATE = 446; - public static int XT_SWAP = 447; - public static int XT_TRACE = 448; - public static int XT_PRETTY = 449; - public static int XT_EXISTS = 450; - public static int XT_REMOVE_INDEX= 451; - public static int XT_REMOVE = 452; - public static int XT_NAME = 453; - public static int XT_GEN_REST = 454; - public static int XT_LAST = 455; - public static int XT_MAP = 456; - public static int XT_RESULT = 457; - public static int XT_COMPARE = 458; - public static int XT_VISITOR = 459; - public static int XT_REPLACE = 460; - public static int XT_LOWERCASE = 461; - public static int XT_UPPERCASE = 462; - public static int XT_XML = 463; - public static int XT_JSON = 464; - public static int XT_SPIN = 465; - public static int XT_RDF = 466; - public static int XT_SHAPE_GRAPH = 467; - public static int XT_SHAPE_NODE = 468; - public static int XT_TOGRAPH = 469; - public static int XT_EXPAND = 470; - public static int XT_NODE = 471; - public static int XT_VERTEX = 472; - public static int XT_JSON_OBJECT = 473; - public static int XT_HAS = 474; - public static int XT_DEFINE = 475; - public static int XT_DEGREE = 476; - public static int XT_MINDEGREE = 477; - public static int XT_INSERT = 478; - public static int XT_DELETE = 479; - public static int XT_VALID_URI = 480; - public static int XT_STACK = 481; - public static int XT_DATATYPE_VALUE= 482; - public static int XT_CAST = 483; - public static int XT_ISFUNCTION = 484; - public static int XT_EVENT = 485; - public static int XT_SUBJECTS = 486; - public static int XT_OBJECTS = 487; - public static int XT_SYNTAX = 488; - public static int XT_HTTP_GET = 489; - public static int XT_GET_DATATYPE_VALUE = 490; - public static int XT_CREATE = 491; - public static int XT_DOMAIN = 492; - public static int XT_SPLIT = 493; - public static int XT_PATH = 494; - public static int XT_MAPPINGS = 495; - public static int XT_PARSE_MAPPINGS= 496; - public static int XT_LOAD_MAPPINGS= 497; - public static int XT_DISTANCE = 498; - - - - public static int SLICE = 500; - public static int EDGE_LEVEL = 501; - public static int DB = 502; - public static int EDGE_ACCESS = 503; - public static int EDGE_NESTED = 504; - public static int XT_ASSERTED = 505; - public static int XT_EDGE = 506; - public static int XT_REFERENCE= 507; - public static int XT_LABEL = 508; - - - // DOM XML - public static int XT_NODE_PROPERTY = 600; - public static int XT_NODE_TYPE = 601; - public static int XT_ATTRIBUTES = 602; - public static int XT_ELEMENTS = 603; - public static int XT_CHILDREN = 604; - public static int XT_NODE_NAME = 605; - public static int XT_NODE_VALUE = 606; - public static int XT_TEXT_CONTENT= 607; - public static int XT_NODE_PARENT = 608; - public static int XT_NODE_DOCUMENT= 609; - public static int XT_NODE_ELEMENT= 610; - public static int XT_NAMESPACE = 611; - public static int XT_BASE = 612; - public static int XT_ATTRIBUTE = 613; - public static int XT_HAS_ATTRIBUTE=614; - public static int XT_NODE_LOCAL_NAME=615; - public static int XT_NODE_FIRST_CHILD=616; - - public static int XT_XSLT = 650; - + + int UNDEF = -1; + int UNBOUND = -2; + // LDScript variable + int LOCAL = -3; + // SPARQL BGP variable + int GLOBAL = -4; + + // abstract type + int JOKER = 1; + int ALTER = 2; + + // type + int CONSTANT = 6; + int VARIABLE = 7; + int BOOLEAN = 8; + int TERM = 9; + int FUNCTION = 10; + + + // boolean + int AND = 11; + int OR = 12; + int NOT = 13; + + // function + int BOUND = 14; + int COUNT = 15; + // ?x in (1, 2) + int INLIST = 16; + + int SAMETERM = 17; + int CUSTOM = 18; + int ISNUMERIC = 19; + int MIN = 20; + int MAX = 21; + int AVG = 22; + int SUM = 23; + int ISURI = 24; + int ISBLANK = 25; + int ISLITERAL = 26; + int LANG = 27; + int LANGMATCH = 28; + int REGEX = 29; + + int DATATYPE = 30; + int CAST = 31; + int SELF = 32; + int DEBUG = 33; + int EXTERNAL = 34; + int EXTERN = 35; + int KGRAM = 36; + int SQL = 37; + int XPATH = 38; + int SKIP = 39; + + int LENGTH = 40; + int UNNEST = 41; + int EXIST = 42; + int STRDT = 43; + int STRLANG = 44; + int BNODE = 45; + int COALESCE = 46; + int IF = 47; + int SYSTEM = 48; + int GROUPCONCAT = 49; + int SAMPLE = 50; + + int STRLEN = 51; + int SUBSTR = 52; + int UCASE = 53; + int LCASE = 54; + int ENDS = 55; + int STARTS = 56; + int CONTAINS = 57; + int ENCODE = 58; + int CONCAT = 59; + + int YEAR = 60; + int MONTH = 61; + int DAY = 62; + int HOURS = 63; + int MINUTES = 64; + int SECONDS = 65; + int TIMEZONE = 66; + int NOW = 67; + + int ABS = 68; + int FLOOR = 69; + int ROUND = 70; + int CEILING = 71; + int RANDOM = 72; + + int HASH = 73; + int URI = 74; + int TZ = 75; + int STR = 76; + + int STRBEFORE = 77; + int STRAFTER = 78; + int STRREPLACE = 79; + int FUUID = 80; + int STRUUID = 81; + int XSDSTRING = 82; + int APPROXIMATE = 83; + int APP_SIM = 84; + int ISLIST = 85; + int ISUNDEFINED = 86; + int ISWELLFORMED = 87; + + int TRIPLE = 88; + int SUBJECT = 89; + int PREDICATE = 90; + int OBJECT = 91; + int IS_TRIPLE = 92; + int SPARQL_COMPARE = 93; + + + // term + int TEQ = 101; + int TNEQ = 102; + int TLE = 103; + int TGE = 104; + int TLT = 105; + int TGT = 106; + // == where type error return false + int EQUAL = 107; + // !== where type error return true + int NOT_EQUAL = 108; + + int EQNE = 109; + + int EQ = 110; + int NE = 111; + int NEQ = 111; + + int GL = 112; + int LE = 113; + int GE = 114; + int LT = 115; + int GT = 116; + + int PLUS = 117; + int MINUS = 118; + int MULT = 119; + + int DIV = 120; + + int CONT = 121; // ~ + int START = 122; // ^ + int IN = 123; + int POWER = 124; + int STAR = 125; + + int COS = 126; + int SIN = 127; + int TAN = 128; + int ARC_COS = 129; + int ARC_SIN = 130; + int ARC_TAN = 131; + int SQRT = 132; + + + // fake for query + int TINKERPOP = 150; + int TINKERPOP_RESTRICT = 151; + int BETWEEN = 152; + int MORE = 153; + int LESS = 154; + int KIND = 155; + int BIPREDICATE = 156; + int EQ_SAME = 157; + + // extension + + int DISPLAY = 200; + int NUMBER = 201; + int SIM = 202; + int EXTEQUAL = 203; + int EXTCONT = 204; + int PROCESS = 205; + int ENV = 206; + int DEPTH = 207; + int KG_GRAPH = 208; + int NODE = 209; + int GET_OBJECT = 210; + int SET_OBJECT = 211; + int LOAD = 212; + int PATHNODE = 213; + int GROUPBY = 214; + int PSIM = 215; + int GETP = 216; + int SETP = 217; + int PWEIGHT = 218; + int ANCESTOR = 219; + int PROVENANCE = 220; + int INDEX = 221; + int TIMESTAMP = 222; + int ID = 223; + int TEST = 224; + int DESCRIBE = 225; + int STORE = 226; + + + int TURTLE = 227; + int LEVEL = 228; + int INDENT = 229; + int PPURI = 230; + int URILITERAL = 231; + int VISITED = 232; + int AGGAND = 233; + int PROLOG = 234; + int WRITE = 235; + int FOCUS_NODE = 236; + int XSDLITERAL = 237; + int QNAME = 238; + + int STL_DEFAULT = 239; + int STL_DEFINE = 240; + int STL_NL = 241; + int STL_PREFIX = 242; + int STL_AGGREGATE = 243; + int STL_CONCAT = 244; + int STL_GROUPCONCAT = 245; + int STL_AND = 246; + int STL_NUMBER = 247; + int STL_LOAD = 248; + int STL_IMPORT = 249; + int STL_PROCESS = 250; + + + int APPLY_TEMPLATES = 251; + int APPLY_TEMPLATES_WITH = 252; + int APPLY_TEMPLATES_ALL = 253; + int APPLY_TEMPLATES_WITH_ALL = 254; + int APPLY_TEMPLATES_GRAPH = 255; + int APPLY_TEMPLATES_WITH_GRAPH = 256; + int APPLY_TEMPLATES_NOGRAPH = 257; + int APPLY_TEMPLATES_WITH_NOGRAPH = 258; + int CALL_TEMPLATE = 259; + int CALL_TEMPLATE_WITH = 260; + int STL_TEMPLATE = 261; + + int STL_SET = 262; + int STL_GET = 263; + int STL_BOOLEAN = 264; + int STL_VISIT = 265; + int STL_VISITED = 266; + int STL_FUTURE = 267; + int STL_INDEX = 268; + int STL_VSET = 269; + int STL_VGET = 270; + int STL_PROCESS_URI = 271; + int STL_EXPORT = 272; + int STL_ERRORS = 273; + int STL_ISSTART = 274; + int AGGLIST = 275; + int AGGREGATE = 276; + int STL_FORMAT = 277; + int STL_VISITED_GRAPH = 278; + int STL_CGET = 279; + int STL_CSET = 280; + int STL_HASGET = 281; + int STL_STRIP = 282; + int FORMAT = 283; + int STL_ERROR_MAP = 284; + int STL_DEFINED = 285; + + + int ISSKOLEM = 300; + int SKOLEM = 301; + + int QUERY = 302; + int EXTENSION = 303; + int EVEN = 304; + int ODD = 305; + int READ = 306; + int PACKAGE = 307; + + int IOTA = 308; + int LIST = 309; + int MAP = 310; + int MAPLIST = 311; + int APPLY = 312; + int LET = 313; + int LAMBDA = 314; + int ERROR = 315; + int MAPEVERY = 316; + int MAPANY = 317; + int MAPFIND = 318; + int MAPFINDLIST = 319; + int MAPMERGE = 320; + int MAPFUN = 321; + int SET = 322; + int SEQUENCE = 323; + int RETURN = 324; + int EVAL = 325; + int FUNCALL = 326; + int FOR = 327; + int MAPAPPEND = 328; + int REDUCE = 329; + + int XT_SORT = 330; + int JAVACALL = 331; + int DSCALL = 332; + int JAVACAST = 333; + int ISEXTENSION = 334; + int SAFE = 335; + int STATIC = 336; + int TRY_CATCH = 337; + int THROW = 338; + int RESUME = 339; + int UNSET = 340; + int STATIC_UNSET = 341; + + int XT_MAPPING = 400; + int XT_ADD = 401; + int XT_CONCAT = 402; + int XT_COUNT = 403; + int XT_CONS = 404; + int XT_FIRST = 405; + int XT_REST = 406; + int XT_GET = 407; + int XT_SET = 408; + int XT_REVERSE = 409; + int XT_APPEND = 410; + + int XT_SUBJECT = 411; + int XT_OBJECT = 412; + int XT_PROPERTY = 413; + int XT_VALUE = 414; + int XT_INDEX = 415; + int XT_GRAPH = 416; + int XT_REJECT = 417; + int XT_VARIABLES = 418; + int XT_VALUES = 419; + int XT_EDGES = 420; + int XT_TRIPLE = 421; + int XT_GEN_GET = 422; + int XT_DISPLAY = 423; + int XT_PRINT = 424; + + int XT_UNION = 425; + int XT_MINUS = 426; + int XT_OPTIONAL = 427; + int XT_JOIN = 428; + int XT_QUERY = 429; + int XT_AST = 430; + int XT_CONTEXT = 431; + int XT_METADATA = 432; + int XT_FROM = 433; + int XT_NAMED = 434; + int XT_MEMBER = 435; + int XT_MERGE = 436; + int XT_TOLIST = 437; + int XT_TUNE = 438; + int XT_FOCUS = 439; + int XT_CONTENT = 440; + int XT_ENTAILMENT = 441; + int XT_DATATYPE = 442; + int XT_KIND = 443; + int XT_METHOD = 444; + int XT_METHOD_TYPE = 445; + int XT_ITERATE = 446; + int XT_SWAP = 447; + int XT_TRACE = 448; + int XT_PRETTY = 449; + int XT_EXISTS = 450; + int XT_REMOVE_INDEX = 451; + int XT_REMOVE = 452; + int XT_NAME = 453; + int XT_GEN_REST = 454; + int XT_LAST = 455; + int XT_MAP = 456; + int XT_RESULT = 457; + int XT_COMPARE = 458; + int XT_VISITOR = 459; + int XT_REPLACE = 460; + int XT_LOWERCASE = 461; + int XT_UPPERCASE = 462; + int XT_XML = 463; + int XT_JSON = 464; + int XT_SPIN = 465; + int XT_RDF = 466; + int XT_SHAPE_GRAPH = 467; + int XT_SHAPE_NODE = 468; + int XT_TOGRAPH = 469; + int XT_EXPAND = 470; + int XT_NODE = 471; + int XT_VERTEX = 472; + int XT_JSON_OBJECT = 473; + int XT_HAS = 474; + int XT_DEFINE = 475; + int XT_DEGREE = 476; + int XT_MINDEGREE = 477; + int XT_INSERT = 478; + int XT_DELETE = 479; + int XT_VALID_URI = 480; + int XT_STACK = 481; + int XT_DATATYPE_VALUE = 482; + int XT_CAST = 483; + int XT_ISFUNCTION = 484; + int XT_EVENT = 485; + int XT_SUBJECTS = 486; + int XT_OBJECTS = 487; + int XT_SYNTAX = 488; + int XT_HTTP_GET = 489; + int XT_GET_DATATYPE_VALUE = 490; + int XT_CREATE = 491; + int XT_DOMAIN = 492; + int XT_SPLIT = 493; + int XT_PATH = 494; + int XT_MAPPINGS = 495; + int XT_PARSE_MAPPINGS = 496; + int XT_LOAD_MAPPINGS = 497; + int XT_DISTANCE = 498; + + + int SLICE = 500; + int EDGE_LEVEL = 501; + int DB = 502; + int EDGE_ACCESS = 503; + int EDGE_NESTED = 504; + int XT_ASSERTED = 505; + int XT_EDGE = 506; + int XT_REFERENCE = 507; + int XT_LABEL = 508; + + + // DOM XML + int XT_NODE_PROPERTY = 600; + int XT_NODE_TYPE = 601; + int XT_ATTRIBUTES = 602; + int XT_ELEMENTS = 603; + int XT_CHILDREN = 604; + int XT_NODE_NAME = 605; + int XT_NODE_VALUE = 606; + int XT_TEXT_CONTENT = 607; + int XT_NODE_PARENT = 608; + int XT_NODE_DOCUMENT = 609; + int XT_NODE_ELEMENT = 610; + int XT_NAMESPACE = 611; + int XT_BASE = 612; + int XT_ATTRIBUTE = 613; + int XT_HAS_ATTRIBUTE = 614; + int XT_NODE_LOCAL_NAME = 615; + int XT_NODE_FIRST_CHILD = 616; + + int XT_XSLT = 650; + } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/core/Filter.java b/src/main/java/fr/inria/corese/core/kgram/api/core/Filter.java index 80bb93010..032d46d77 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/core/Filter.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/core/Filter.java @@ -1,54 +1,56 @@ package fr.inria.corese.core.kgram.api.core; import fr.inria.corese.core.sparql.triple.parser.Expression; + import java.util.List; /** * Interface of Filter that contains an evaluable expression * Filter (and Expr) api refer to sparql.triple.parser.Expression - * - * @author Olivier Corby, Edelweiss, INRIA 2010 * + * @author Olivier Corby, Edelweiss, INRIA 2010 */ public interface Filter { - /** - * List of variable names contained in the filter - * - * @return - */ - List getVariables(); - List getVariables(boolean excludeLocal); - - /** - * Evaluable expression processed by KGRAM generic Interpreter - * Expr api refer also to sparql.triple.parser.Expression - * - * @return - */ - Expr getExp(); - Expression getFilterExpression(); - - /** - * Does filter contain a bound() function - * - * @return - */ - boolean isBound(); - - /** - * Is it an aggregate function such as count() min() sum() - * - * @return - */ - boolean isAggregate(); - - boolean isRecAggregate(); - - boolean isFunctional(); - - boolean isRecExist(); - - + /** + * List of variable names contained in the filter + * + * @return + */ + List getVariables(); + + List getVariables(boolean excludeLocal); + + /** + * Evaluable expression processed by KGRAM generic Interpreter + * Expr api refer also to sparql.triple.parser.Expression + * + * @return + */ + Expr getExp(); + + Expression getFilterExpression(); + + /** + * Does filter contain a bound() function + * + * @return + */ + boolean isBound(); + + /** + * Is it an aggregate function such as count() min() sum() + * + * @return + */ + boolean isAggregate(); + + boolean isRecAggregate(); + + boolean isFunctional(); + + boolean isRecExist(); + + } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/core/Graph.java b/src/main/java/fr/inria/corese/core/kgram/api/core/Graph.java index 10af828a1..b10007954 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/core/Graph.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/core/Graph.java @@ -4,15 +4,15 @@ * */ public interface Graph { - + Edge getEdge(Node predicate, Node node, int n); - + Node value(Node subject, Node predicate, int n); - + Node getPropertyNode(Node dt); - + Node getNode(Node dt); - + Node getVertex(Node dt); - + } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/core/Loopable.java b/src/main/java/fr/inria/corese/core/kgram/api/core/Loopable.java index 1fef20244..dc1ab7ff9 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/core/Loopable.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/core/Loopable.java @@ -1,13 +1,12 @@ - package fr.inria.corese.core.kgram.api.core; /** - * * Interface for (var in exp) {} + * * @author Olivier Corby 2015 */ public interface Loopable { - + Iterable getLoop(); - + } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/core/Node.java b/src/main/java/fr/inria/corese/core/kgram/api/core/Node.java index 04f07b0c9..97febf9ef 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/core/Node.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/core/Node.java @@ -1,132 +1,135 @@ package fr.inria.corese.core.kgram.api.core; -import static fr.inria.corese.core.kgram.api.core.PointerType.NODE; import fr.inria.corese.core.kgram.path.Path; import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.api.IDatatype.NodeKind; +import static fr.inria.corese.core.kgram.api.core.PointerType.NODE; + /** * Interface of Node provided by graph implementation * and also by KGRAM query Node - * - * @author Olivier Corby, Edelweiss, INRIA 2010 * + * @author Olivier Corby, Edelweiss, INRIA 2010 */ public interface Node extends Pointerable, Comparable { - public static final String INITKEY = ""; + String INITKEY = ""; - public static final int DEPTH = 0; - public static final int LENGTH = 1; - public static final int REGEX = 2; - public static final int OBJECT = 3; + int DEPTH = 0; + int LENGTH = 1; + int REGEX = 2; + int OBJECT = 3; - - public static final int PSIZE = 4; - public static final int STATUS = 4; - - default NodeKind getNodeKind() { - return getValue().getNodeKind(); - } - - @Override - default PointerType pointerType(){ - return NODE; - } + int PSIZE = 4; - /** - * Query nodes have an index computed by KGRAM - * @return - */ - int getIndex(); - - /** - * Query nodes have an index computed by KGRAM - * @return - */ - void setIndex(int n); - - String getKey(); - - void setKey(String str); - - - /** - * sameTerm - * - */ - boolean same(Node n); - - // Node match for Graph match - boolean match(Node n); - - int compare(Node node); - - @Override - default int compareTo(Object node) { - if (node instanceof Node) { - return compareTo((Node)node); - } - return -1; - } - - default int compareTo(Node node) { - return getDatatypeValue().compareTo(node.getDatatypeValue()); - } + int STATUS = 4; - String getLabel(); - - boolean isVariable(); - - boolean isConstant(); - - boolean isBlank(); - - boolean isFuture(); - - default boolean isMatchNodeList() { return false; } - - default boolean isMatchCardinality() { return false; } - - // the target value for Matcher and Evaluator - // for KGRAM query it returns IDatatype - IDatatype getValue(); - - IDatatype getDatatypeValue(); - - default void setDatatypeValue(IDatatype dt) {} - - Node getGraph(); - - @Override - Node getNode(); - - Object getNodeObject(); - void setObject(Object o); - - Path getPath(); - - @Override - TripleStore getTripleStore(); - -// Object getProperty(int p); -// void setProperty(int p, Object o); - - // tagged as triple reference - default boolean isTriple() { - return getDatatypeValue().isTriple(); - } - - // triple reference with edge inside - default boolean isTripleWithEdge() { - return isTriple() && getEdge() != null; - } - - default void setEdge(Edge e) { - getDatatypeValue().setEdge(e); - } - - default boolean isTripleNode() { - return false; + default NodeKind getNodeKind() { + return getValue().getNodeKind(); + } + + @Override + default PointerType pointerType() { + return NODE; + } + + /** + * Query nodes have an index computed by KGRAM + * + * @return + */ + int getIndex(); + + /** + * Query nodes have an index computed by KGRAM + * + */ + void setIndex(int n); + + String getKey(); + + void setKey(String str); + + + /** + * sameTerm + */ + boolean same(Node n); + + // Node match for Graph match + boolean match(Node n); + + int compare(Node node); + + default int compareTo(Node node) { + return getDatatypeValue().compareTo(node.getDatatypeValue()); + } + + @Override + default int compareTo(Object obj) { + if(obj instanceof Node) { + return compareTo((Node) obj); } + return -1; + } + + String getLabel(); + + boolean isVariable(); + + boolean isConstant(); + + boolean isBlank(); + + boolean isFuture(); + + default boolean isMatchNodeList() { + return false; + } + + default boolean isMatchCardinality() { + return false; + } + + // the target value for Matcher and Evaluator + // for KGRAM query it returns IDatatype + IDatatype getValue(); + + IDatatype getDatatypeValue(); + + default void setDatatypeValue(IDatatype dt) { + } + + Node getGraph(); + + @Override + Node getNode(); + + Object getNodeObject(); + + void setObject(Object o); + + Path getPath(); + + @Override + TripleStore getTripleStore(); + + // tagged as triple reference + default boolean isTriple() { + return getDatatypeValue().isTriple(); + } + + // triple reference with edge inside + default boolean isTripleWithEdge() { + return isTriple() && getEdge() != null; + } + + default void setEdge(Edge e) { + getDatatypeValue().setEdge(e); + } + + default boolean isTripleNode() { + return false; + } } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/core/PointerType.java b/src/main/java/fr/inria/corese/core/kgram/api/core/PointerType.java index c959a82aa..8c81365e9 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/core/PointerType.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/core/PointerType.java @@ -4,37 +4,37 @@ /** * Pointer type for object that can be object of CoresePointer - * @author Olivier Corby, Wimmics INRIA I3S, 2019 * + * @author Olivier Corby, Wimmics INRIA I3S, 2019 */ public enum PointerType { - - UNDEF("pointer"), - MAPPINGS("mappings"), - MAPPING("mapping"), - GRAPH("graph"), - NODE("node"), - TRIPLE("triple"), - PATH("path"), - QUERY("query"), - EXPRESSION("expression"), - STATEMENT("statement"), - DATASET("dataset"), - PRODUCER("producer"), - METADATA("metadata"), - CONTEXT("context"), - NSMANAGER("nsmanager"), - VISITOR("visitor"), - ; - - public String name; - - private PointerType(String n) { - name = DT+n; - } - - public String getName() { - return name; - } + + UNDEF("pointer"), + MAPPINGS("mappings"), + MAPPING("mapping"), + GRAPH("graph"), + NODE("node"), + TRIPLE("triple"), + PATH("path"), + QUERY("query"), + EXPRESSION("expression"), + STATEMENT("statement"), + DATASET("dataset"), + PRODUCER("producer"), + METADATA("metadata"), + CONTEXT("context"), + NSMANAGER("nsmanager"), + VISITOR("visitor"), + ; + + protected String name; + + PointerType(String n) { + name = DT + n; + } + + public String getName() { + return name; + } } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/core/Pointerable.java b/src/main/java/fr/inria/corese/core/kgram/api/core/Pointerable.java index 7d03da652..64a66ce3e 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/core/Pointerable.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/core/Pointerable.java @@ -5,76 +5,77 @@ import fr.inria.corese.core.kgram.core.Mappings; import fr.inria.corese.core.kgram.core.Query; import fr.inria.corese.core.kgram.path.Path; + import java.util.ArrayList; /** * Interface for objects that can be object of a CoresePointer + * * @author Olivier Corby - Wimmics Inria I3S - 2015 */ public interface Pointerable extends Loopable { - static final ArrayList empty = new ArrayList(0); - + default PointerType pointerType() { return PointerType.UNDEF; } - + default Object getPointerObject() { return this; } - + default Mappings getMappings() { - return null; + return null; } - + default Mapping getMapping() { return null; } - + default Edge getEdge() { return null; } - + default Node getNode() { return null; } - + default Query getQuery() { return null; } - + default Exp getStatement() { return null; } - + default Path getPathObject() { return null; } - - default TripleStore getTripleStore(){ + + default TripleStore getTripleStore() { return null; } - - default int size(){ + + default int size() { return 0; } - - default Object getValue(String var, int n){ + + default Object getValue(String varString, int n) { return null; } - - + + @Override - default Iterable getLoop(){ - return empty; + default Iterable getLoop() { + return new ArrayList<>(0); } - + default String getDatatypeLabel() { return Integer.toString(hashCode()); } - + default int compare(Pointerable obj) { return Integer.compare(hashCode(), obj.hashCode()); } - + } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/core/Regex.java b/src/main/java/fr/inria/corese/core/kgram/api/core/Regex.java index 0bf66694a..0df0cae70 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/core/Regex.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/core/Regex.java @@ -1,92 +1,92 @@ package fr.inria.corese.core.kgram.api.core; + import fr.inria.corese.core.sparql.api.IDatatype; /** * Interface of Property Path Regex - * - * @author Olivier Corby, Edelweiss, INRIA 2010 * + * @author Olivier Corby, Edelweiss, INRIA 2010 */ public interface Regex { - - public static final int UNDEF = -1; - public static final int LABEL = 0; - public static final int NOT = 1; - public static final int SEQ = 2; - public static final int STAR = 3; - public static final int PLUS = 4; - public static final int OPTION = 5; - public static final int COUNT = 6; - public static final int ALT = 7; - public static final int PARA = 8; - public static final int TEST = 9; - public static final int CHECK = 10; - public static final int REVERSE = 11; - - - String getName(); - - String getLongName(); - - IDatatype getDatatypeValue(); - - String toRegex(); - - int retype(); - - int getArity(); - - boolean isConstant(); - - boolean isAlt(); - - boolean isPara(); - - boolean isSeq(); - - boolean isOpt(); - - boolean isNot(); - - boolean isDistinct(); - - boolean isShort(); - - // @deprecated - boolean isInverse(); - - // @deprecated - void setInverse(boolean b); - - // SPARQL 1.1 reverse ^ - boolean isReverse(); - - void setReverse(boolean b); - - boolean isStar(); - - boolean isPlus(); - - boolean isCounter(); - - int getMin(); - - int getMax(); - - int getWeight(); - - Regex getArg(int n); - - Regex reverse(); - - Regex transform(); - - Regex translate(); - - boolean isNotOrReverse(); - - int regLength(); - - Expr getExpr(); + + int UNDEF = -1; + int LABEL = 0; + int NOT = 1; + int SEQ = 2; + int STAR = 3; + int PLUS = 4; + int OPTION = 5; + int COUNT = 6; + int ALT = 7; + int PARA = 8; + int TEST = 9; + int CHECK = 10; + int REVERSE = 11; + + + String getName(); + + String getLongName(); + + IDatatype getDatatypeValue(); + + String toRegex(); + + int retype(); + + int getArity(); + + boolean isConstant(); + + boolean isAlt(); + + boolean isPara(); + + boolean isSeq(); + + boolean isOpt(); + + boolean isNot(); + + boolean isDistinct(); + + boolean isShort(); + + // @deprecated + boolean isInverse(); + + // @deprecated + void setInverse(boolean b); + + // SPARQL 1.1 reverse ^ + boolean isReverse(); + + void setReverse(boolean b); + + boolean isStar(); + + boolean isPlus(); + + boolean isCounter(); + + int getMin(); + + int getMax(); + + int getWeight(); + + Regex getArg(int n); + + Regex reverse(); + + Regex transform(); + + Regex translate(); + + boolean isNotOrReverse(); + + int regLength(); + + Expr getExpr(); } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/core/TripleStore.java b/src/main/java/fr/inria/corese/core/kgram/api/core/TripleStore.java index 0b4fa0313..a7f5ec686 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/core/TripleStore.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/core/TripleStore.java @@ -3,13 +3,14 @@ import fr.inria.corese.core.sparql.api.IDatatype; /** - * * @author corby */ public interface TripleStore { - + Node getNode(int n); + IDatatype set(IDatatype key, IDatatype value); + int size(); - + } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/query/AST.java b/src/main/java/fr/inria/corese/core/kgram/api/query/AST.java index 4c7bb735d..47ea19376 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/query/AST.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/query/AST.java @@ -1,22 +1,30 @@ package fr.inria.corese.core.kgram.api.query; /** - * * Olivier Corby - Wimmics INRIA I3S - 2020 */ public interface AST { - + boolean isSelect(); + boolean isConstruct(); + boolean isUpdate(); + boolean isInsert(); + boolean isDelete(); + // update query starts with insert/delete boolean isUpdateInsert(); - boolean isUpdateDelete(); + + boolean isUpdateDelete(); + boolean isUpdateInsertData(); - boolean isUpdateDeleteData(); - boolean isUpdateLoad(); - + + boolean isUpdateDeleteData(); + + boolean isUpdateLoad(); + boolean hasMetadata(String name); } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/query/ASTQ.java b/src/main/java/fr/inria/corese/core/kgram/api/query/ASTQ.java index a0736d337..65caa214e 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/query/ASTQ.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/query/ASTQ.java @@ -1,9 +1,8 @@ package fr.inria.corese.core.kgram.api.query; /** - * * Olivier Corby - Wimmics INRIA I3S - 2020 */ public interface ASTQ extends AST, Graphable { - + } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/query/Binder.java b/src/main/java/fr/inria/corese/core/kgram/api/query/Binder.java index 6835649db..224b532de 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/query/Binder.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/query/Binder.java @@ -1,10 +1,10 @@ - package fr.inria.corese.core.kgram.api.query; import fr.inria.corese.core.kgram.api.core.Expr; import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.core.Mappings; import fr.inria.corese.core.sparql.api.IDatatype; + import java.util.List; /** @@ -13,17 +13,28 @@ */ @Deprecated public interface Binder { - + void clear(); + List getVariables(); + boolean hasBind(); + boolean isBound(String label); + Node get(Expr var); + IDatatype getGlobalVariable(String var); + void share(Binder b); - void setVisitor(ProcessVisitor vis); + ProcessVisitor getVisitor(); + + void setVisitor(ProcessVisitor vis); + StringBuilder getTrace(); + Mappings getMappings(); + Binder setMappings(Mappings map); } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/query/DQPFactory.java b/src/main/java/fr/inria/corese/core/kgram/api/query/DQPFactory.java index dfc235e31..1f807f461 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/query/DQPFactory.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/query/DQPFactory.java @@ -3,11 +3,10 @@ import fr.inria.corese.core.kgram.core.BgpGenerator; /** - * * @author corby */ public interface DQPFactory { - + BgpGenerator instance(); - + } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/query/Environment.java b/src/main/java/fr/inria/corese/core/kgram/api/query/Environment.java index b777022ef..af9339207 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/query/Environment.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/query/Environment.java @@ -1,167 +1,161 @@ package fr.inria.corese.core.kgram.api.query; -import java.util.Map; - +import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.api.core.Expr; import fr.inria.corese.core.kgram.api.core.Node; -import fr.inria.corese.core.kgram.core.Exp; -import fr.inria.corese.core.kgram.core.Mapping; -import fr.inria.corese.core.kgram.core.Mappings; -import fr.inria.corese.core.kgram.core.Query; +import fr.inria.corese.core.kgram.core.*; import fr.inria.corese.core.kgram.event.EventManager; import fr.inria.corese.core.kgram.path.Path; import fr.inria.corese.core.kgram.tool.ApproximateSearchEnv; -import fr.inria.corese.core.kgram.api.core.Edge; -import fr.inria.corese.core.kgram.core.Eval; import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.triple.function.term.Binding; import fr.inria.corese.core.sparql.triple.parser.ASTExtension; +import java.util.Map; + /** * Interface of the binding environment provided by KGRAM * e.g. for filter Evaluator - * - * @author Olivier Corby, Edelweiss, INRIA 2010 * + * @author Olivier Corby, Edelweiss, INRIA 2010 */ public interface Environment { - - - /** - * Return current query - * @return - */ - Query getQuery(); - - Binding getBind(); - void setBind(Binding b); - - boolean hasBind(); - - /** - * - * @return current graph node (only for filter interpreter) - */ - Node getGraphNode(); - default void setGraphNode(Node n) { - } - - /** - * Return the target node of variable var - */ - Node getNode(Expr var); - - /** - * Return the target node bound to query node with label - * @param label - * @return - */ - Node getNode(String label); - - /** - * Return the target node bound to query node with label - * @param label - * @return - */ - Node getNode(Node qNode); - - /** - * Return the query node at index n - * @param n - * @return - */ - Node getQueryNode(int n); - - /** - * Return the query node with label - * @param n - * @return - */ - Node getQueryNode(String label); - - /** - * Test whether query node is bound - * @param qNode - * @return - */ - boolean isBound(Node qNode); - - - /** - * Return the path length corresponding to query node - * - * @param qNode - * @return - */ - int pathLength(Node qNode); - - Path getPath(Node qNode); - - int pathWeight(Node qNode); - - - // aggregates - - /** - * Count the number of non null values of query node - * count duplicates - */ - - int count(); - - /** - * Run the eval function of the evaluator with filter f on every Mapping - * use case: select sum(?x) as ?sum - * - * @param eval - * @param f - */ - //void aggregate(Evaluator eval, Producer p, Filter f); - - EventManager getEventManager(); - - boolean hasEventManager(); - - void setObject(Object o); - - Object getObject(); - - void setExp(Exp exp); - - Exp getExp(); - - // id -> bnode - Map getMap(); - - Edge[] getEdges(); - - Node[] getNodes(); - - Node[] getQueryNodes(); - - Mappings getMappings(); - - Mapping getMapping(); - - Iterable getAggregate(); - - void aggregate(Mapping m, int n); - - Node get(Expr var); - - ASTExtension getExtension(); - - ApproximateSearchEnv getAppxSearchEnv(); - - Eval getEval(); - - void setEval(Eval e); - - ProcessVisitor getVisitor(); - - void setReport(IDatatype dt); - IDatatype getReport(); - - int size(); + + + /** + * Return current query + * + * @return + */ + Query getQuery(); + + Binding getBind(); + + void setBind(Binding b); + + boolean hasBind(); + + /** + * @return current graph node (only for filter interpreter) + */ + Node getGraphNode(); + + default void setGraphNode(Node n) { + } + + /** + * Return the target node of variable var + */ + Node getNode(Expr varExpr); + + /** + * Return the target node bound to query node with label + * + * @param label + * @return + */ + Node getNode(String label); + + /** + * Return the target node bound to query node with label + * + * @param qNode + * @return + */ + Node getNode(Node qNode); + + /** + * Return the query node at index n + * + * @param n + * @return + */ + Node getQueryNode(int n); + + /** + * Return the query node with label + * + * @param label + * @return + */ + Node getQueryNode(String label); + + /** + * Test whether query node is bound + * + * @param qNode + * @return + */ + boolean isBound(Node qNode); + + + /** + * Return the path length corresponding to query node + * + * @param qNode + * @return + */ + int pathLength(Node qNode); + + Path getPath(Node qNode); + + int pathWeight(Node qNode); + + + // aggregates + + /** + * Count the number of non null values of query node + * count duplicates + */ + + int count(); + + EventManager getEventManager(); + + boolean hasEventManager(); + + Object getObject(); + + void setObject(Object o); + + Exp getExp(); + + void setExp(Exp exp); + + // id -> bnode + Map getMap(); + + Edge[] getEdges(); + + Node[] getNodes(); + + Node[] getQueryNodes(); + + Mappings getMappings(); + + Mapping getMapping(); + + Iterable getAggregate(); + + void aggregate(Mapping m, int n); + + Node get(Expr varExpr); + + ASTExtension getExtension(); + + ApproximateSearchEnv getAppxSearchEnv(); + + Eval getEval(); + + void setEval(Eval e); + + ProcessVisitor getVisitor(); + + IDatatype getReport(); + + void setReport(IDatatype dt); + + int size(); } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/query/Evaluator.java b/src/main/java/fr/inria/corese/core/kgram/api/query/Evaluator.java index ef95c80f7..cb9d22ac0 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/query/Evaluator.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/query/Evaluator.java @@ -2,75 +2,36 @@ import fr.inria.corese.core.kgram.core.Eval; import fr.inria.corese.core.kgram.event.ResultListener; -import fr.inria.corese.core.sparql.triple.function.term.Binding; import fr.inria.corese.core.sparql.api.Computer; +import fr.inria.corese.core.sparql.triple.function.term.Binding; /** * Interface for the connector that evaluates filters - * -* @author Olivier Corby, Edelweiss, INRIA 2010 -* -*/ + * + * @author Olivier Corby, Edelweiss, INRIA 2010 + */ public interface Evaluator extends Computer { - - static final int KGRAM_MODE = 0; - static final int SPARQL_MODE = 1; - - public static final int CACHE_MODE = 101; - public static final int NO_CACHE_MODE = 102; - - void setMode(int mode); - - int getMode(); - - void setDebug(boolean b); - - /** - * Evaluate a filter - * - * @param f - * @param e - * @return - */ - //boolean test(Filter f, Environment e) throws SparqlException; -// - //boolean test(Filter f, Environment e, Producer p) throws SparqlException ; + Mode getMode(); + + void setMode(Mode mode); + + Binding getBinder(); + + void setProducer(Producer p); + + void setKGRAM(Eval o); + + void addResultListener(ResultListener rl); + + void start(Environment env); - /** - * Evaluate a filter and return a Node - * use case: select fun(?x) as ?y - * - * @param f - * @param e - * @return - */ - //Node eval(Filter f, Environment e, Producer p) throws SparqlException; - - /** - * Evaluate an extension function filter and return Mappings - * use case: select sql('select from where') as (?x ?y) where {} - * TODO: should be an interface instead of Mappings - * - */ -// Mappings eval(Filter f, Environment e, List nodes) throws SparqlException; - + void finish(Environment env); - // cast Java object into IDatatype - //Node cast(Object obj, Environment e, Producer p); + void init(Environment env); - Binding getBinder(); - - void setProducer(Producer p); - - void setKGRAM(Eval o); - - //Eval getEval(); + public enum Mode { + KGRAM_MODE, SPARQL_MODE, CACHE_MODE, NO_CACHE_MODE + } - void addResultListener(ResultListener rl); - - void start(Environment env); - void finish(Environment env); - void init(Environment env); - } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/query/Graphable.java b/src/main/java/fr/inria/corese/core/kgram/api/query/Graphable.java index 44d8c7d2e..a261b4dd2 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/query/Graphable.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/query/Graphable.java @@ -1,18 +1,15 @@ - package fr.inria.corese.core.kgram.api.query; /** - * * Olivier Corby - Wimmics INRIA I3S - 2014 */ public interface Graphable { - + String toGraph(); - - void setGraph(Object obj); - + Object getGraph(); - - - + + void setGraph(Object obj); + + } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/query/Hierarchy.java b/src/main/java/fr/inria/corese/core/kgram/api/query/Hierarchy.java index 33ca30f9e..067a12d56 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/query/Hierarchy.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/query/Hierarchy.java @@ -1,16 +1,16 @@ package fr.inria.corese.core.kgram.api.query; import fr.inria.corese.core.sparql.api.IDatatype; + import java.util.List; /** - * * @author corby */ public interface Hierarchy { - + List getSuperTypes(IDatatype object, IDatatype type); - + void defSuperType(IDatatype type, IDatatype sup); - + } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/query/Matcher.java b/src/main/java/fr/inria/corese/core/kgram/api/query/Matcher.java index ba7f24d47..875d9dad7 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/query/Matcher.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/query/Matcher.java @@ -4,75 +4,74 @@ import fr.inria.corese.core.kgram.api.core.Node; /** - * Interface for the Matcher that checks conformity of candidate edges and nodes - * with respect to their query edge/node for KGRAM - * -* @author Olivier Corby, Edelweiss, INRIA 2010 -* -*/ + * Interface for the Matcher that checks conformity of candidate edges and nodes + * with respect to their query edge/node for KGRAM + * + * @author Olivier Corby, Edelweiss, INRIA 2010 + */ public interface Matcher { - - /** - * Match mode - */ - // equality of types - public static final int UNDEF = -1; - - public static final int STRICT = 0; - // exploit type inference (subsumption) - public static final int SUBSUME = 1; - // type inference and accept generalization of types - public static final int GENERAL = 2; - // subsume + generalize - public static final int MIX = 3; - // accept any types - public static final int RELAX = 4; - // exploit rules - public static final int INFERENCE = 5; + /** + * Match mode + */ + // equality of types + int UNDEF = -1; - /** - * Checks whether a candidate edge matches a query edge. - * May verify that edge labels match (Producer may have done the job properly). - * May verify edges such as rdf:type and check subsumption of type. - * Must verify that each candidate edge node match its query edge node, - * e.g. constant query nodes. - * (KGRAM does not perform the latter test and supposes that matcher does it) - * Matcher is not concerned by bindings that are checked by KGRAM. - * - * @param q The query edge - * @param e The candidate edge - * @param env The binding environment - * @return true if it matches - */ - boolean match(Edge q, Edge e, Environment env); + int STRICT = 0; + // exploit type inference (subsumption) + int SUBSUME = 1; + // type inference and accept generalization of types + int GENERAL = 2; + // subsume + generalize + int MIX = 3; + // accept any types + int RELAX = 4; + // exploit rules + int INFERENCE = 5; + + + /** + * Checks whether a candidate edge matches a query edge. + * May verify that edge labels match (Producer may have done the job properly). + * May verify edges such as rdf:type and check subsumption of type. + * Must verify that each candidate edge node match its query edge node, + * e.g. constant query nodes. + * (KGRAM does not perform the latter test and supposes that matcher does it) + * Matcher is not concerned by bindings that are checked by KGRAM. + * + * @param q The query edge + * @param e The candidate edge + * @param env The binding environment + * @return true if it matches + */ + boolean match(Edge q, Edge e, Environment env); + + /** + * Checks whether a candidate node matches a query node. + * + * @param q The query node + * @param n The candidate node + * @param env The binding environment + * @return true if it matches + */ + boolean match(Node q, Node n, Environment env); + + /** + * Two occurrences of a query node are bound to two candidate nodes. + * Check that the candidate nodes are the same or are equivalent. + * May use owl:sameAs + * + * @param qNode + * @param n1 + * @param n2 + * @param env The binding environment + * @return + */ + boolean same(Node qNode, Node n1, Node n2, Environment env); + + int getMode(); + + void setMode(int mode); - /** - * Checks whether a candidate node matches a query node. - * - * @param q The query node - * @param n The candidate node - * @param env The binding environment - * @return true if it matches - */ - boolean match(Node q, Node n, Environment env); - - /** - * Two occurrences of a query node are bound to two candidate nodes. - * Check that the candidate nodes are the same or are equivalent. - * May use owl:sameAs - * - * @param qNode - * @param n1 - * @param n2 - * @param env The binding environment - * @return - */ - boolean same(Node qNode, Node n1, Node n2, Environment env); - - void setMode(int mode); - - int getMode(); - } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/query/Plugin.java b/src/main/java/fr/inria/corese/core/kgram/api/query/Plugin.java index ab2fd0b61..41fe29d0b 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/query/Plugin.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/query/Plugin.java @@ -5,12 +5,11 @@ /** * Draft KGRAM Plugin for EXTERN expression. * KGRAM exec this function for EXTERN expression. - * - * @author Olivier Corby, Edelweiss, INRIA 2010 * + * @author Olivier Corby, Edelweiss, INRIA 2010 */ public interface Plugin { - void exec(Exp exp, Environment env, int n); - + void exec(Exp exp, Environment env, int n); + } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/query/ProcessVisitor.java b/src/main/java/fr/inria/corese/core/kgram/api/query/ProcessVisitor.java index 97bf86311..e7acb161a 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/query/ProcessVisitor.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/query/ProcessVisitor.java @@ -4,172 +4,299 @@ import fr.inria.corese.core.kgram.api.core.Expr; import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.api.core.Pointerable; -import fr.inria.corese.core.kgram.core.Eval; -import fr.inria.corese.core.kgram.core.Exp; -import fr.inria.corese.core.kgram.core.Mapping; -import fr.inria.corese.core.kgram.core.Mappings; -import fr.inria.corese.core.kgram.core.Query; +import fr.inria.corese.core.kgram.core.*; import fr.inria.corese.core.kgram.path.Path; import fr.inria.corese.core.sparql.api.IDatatype; + import java.util.List; /** - * * @author Olivier Corby, Wimmics INRIA I3S, 2018 - * */ public interface ProcessVisitor extends Pointerable { int SLICE_DEFAULT = 20; - - default void trace(String name) { - System.out.println("Visitor event " + name); - } - - default void setActive(boolean b) {} - - default boolean isActive() {return true;} - - default boolean isShareable() { return false; } - - default void setProcessor(Eval e) {} - - default Eval getProcessor() { return null;} - - default void setDefaultValue(IDatatype val) {} - - default IDatatype defaultValue() {return null;} - - default IDatatype initParam() {return defaultValue();} - + + default boolean isActive() { + return true; + } + + default void setActive(boolean b) { + } + + default boolean isShareable() { + return false; + } + + default Eval getProcessor() { + return null; + } + + default void setProcessor(Eval e) { + } + + default void setDefaultValue(IDatatype val) { + } + + default IDatatype defaultValue() { + return null; + } + + default IDatatype initParam() { + return defaultValue(); + } + // before query and before lock graph - default IDatatype prepare() {return defaultValue();} - - default IDatatype init() {return defaultValue();} - - default IDatatype init(Query q) {return defaultValue();} - - default IDatatype before(Query q) { return defaultValue(); } - - default IDatatype after(Mappings map) { return defaultValue(); } - - default IDatatype construct(Mappings map) { return defaultValue(); } - - default IDatatype beforeUpdate(Query q) { return defaultValue(); } - - default IDatatype afterUpdate(Mappings map) { return defaultValue(); } - - default IDatatype beforeLoad(IDatatype path) { return defaultValue(); } - - default IDatatype afterLoad(IDatatype path) { return defaultValue(); } - - default IDatatype beforeEntailment(IDatatype path) { return defaultValue(); } - - default IDatatype afterEntailment(IDatatype path) { return defaultValue(); } - - default IDatatype loopEntailment(IDatatype path) { return defaultValue(); } - - default IDatatype prepareEntailment(IDatatype path) { return defaultValue(); } - - default boolean entailment() { return false; } - - default IDatatype entailment(Query rule, List construct, List where) { return defaultValue(); } - - default IDatatype beforeRule(Query q) { return defaultValue(); } - - default IDatatype afterRule(Query q, Object res) { return defaultValue(); } - + default IDatatype prepare() { + return defaultValue(); + } + + default IDatatype init() { + return defaultValue(); + } + + default IDatatype init(Query q) { + return defaultValue(); + } + + default IDatatype before(Query q) { + return defaultValue(); + } + + default IDatatype after(Mappings map) { + return defaultValue(); + } + + default IDatatype construct(Mappings map) { + return defaultValue(); + } + + default IDatatype beforeUpdate(Query q) { + return defaultValue(); + } + + default IDatatype afterUpdate(Mappings map) { + return defaultValue(); + } + + default IDatatype beforeLoad(IDatatype path) { + return defaultValue(); + } + + default IDatatype afterLoad(IDatatype path) { + return defaultValue(); + } + + default IDatatype beforeEntailment(IDatatype path) { + return defaultValue(); + } + + default IDatatype afterEntailment(IDatatype path) { + return defaultValue(); + } + + default IDatatype loopEntailment(IDatatype path) { + return defaultValue(); + } + + default IDatatype prepareEntailment(IDatatype path) { + return defaultValue(); + } + + default boolean entailment() { + return false; + } + + default IDatatype entailment(Query rule, List construct, List where) { + return defaultValue(); + } + + default IDatatype beforeRule(Query q) { + return defaultValue(); + } + + default IDatatype afterRule(Query q, Object res) { + return defaultValue(); + } + // success = true when there is no solution // because rule where part test condition where constraint fails // res = Mappings or List - default IDatatype constraintRule(Query q, Object res, IDatatype success) { return success; } - - default IDatatype start(Query q) { return defaultValue(); } - - default IDatatype finish(Mappings map) { return defaultValue(); } - - default IDatatype orderby(Mappings map) { return defaultValue(); } - - default boolean distinct(Eval eval, Query q, Mapping map) { return true; } - - default boolean limit(Mappings map) { return true;} - - default int timeout(Node serv) { return 0; } - - default int slice() { return SLICE_DEFAULT; } + default IDatatype constraintRule(Query q, Object res, IDatatype success) { + return success; + } + + default IDatatype start(Query q) { + return defaultValue(); + } + + default IDatatype finish(Mappings map) { + return defaultValue(); + } + + default IDatatype orderby(Mappings map) { + return defaultValue(); + } + + default boolean distinct(Eval eval, Query q, Mapping map) { + return true; + } + + default boolean limit(Mappings map) { + return true; + } + + default int timeout(Node serv) { + return 0; + } + + default int slice() { + return SLICE_DEFAULT; + } + @Deprecated - default int slice(Node serv, Mappings map) { return SLICE_DEFAULT; } - + default int slice(Node serv, Mappings map) { + return SLICE_DEFAULT; + } + // return result for ldscript call java:setSlice() - default int setSlice(int n) { return SLICE_DEFAULT; } - - default IDatatype produce(Eval eval, Node g, Edge edge) { return defaultValue(); } - - default IDatatype candidate(Eval eval, Node g, Edge q, Edge e) { return defaultValue();} - - default IDatatype path(Eval eval, Node g, Edge q, Path p, Node s, Node o) { return defaultValue();} - - default boolean step(Eval eval, Node g, Edge q, Path p, Node s, Node o) { return true;} - - default boolean result(Eval eval, Mappings map, Mapping m) { return true; } - - default IDatatype statement(Eval eval, Node g, Exp e) { return defaultValue(); } - - - default IDatatype bgp(Eval eval, Node g, Exp e, Mappings m) { return defaultValue(); } - - default IDatatype join(Eval eval, Node g, Exp e, Mappings m1, Mappings m2) { return defaultValue(); } - - default IDatatype optional(Eval eval, Node g, Exp e, Mappings m1, Mappings m2) { return defaultValue(); } - - default IDatatype minus(Eval eval, Node g, Exp e, Mappings m1, Mappings m2) { return defaultValue(); } - - default IDatatype union(Eval eval, Node g, Exp e, Mappings m1, Mappings m2) { return defaultValue(); } - - default IDatatype graph(Eval eval, Node g, Exp e, Mappings m) { return defaultValue(); } - - default IDatatype query(Eval eval, Node g, Exp e, Mappings m) { return defaultValue(); } - - default IDatatype service(Eval eval, Node s, Exp e, Mappings m) { return defaultValue(); } - - default IDatatype values(Eval eval, Node g, Exp e, Mappings m) { return defaultValue(); } - - default boolean filter(Eval eval, Node g, Expr e, boolean b) { return b; } - - default boolean having(Eval eval, Expr e, boolean b) { return b; } - - default IDatatype bind(Eval eval, Node g, Exp e, IDatatype val) { return val; } - - default IDatatype select(Eval eval, Expr e, IDatatype val) { return val; } - - default IDatatype aggregate(Eval eval, Expr e, IDatatype val) { return val; } - - default IDatatype function(Eval eval, Expr funcall, Expr fundef) { return defaultValue(); } - - - default IDatatype error(Eval eval, Expr exp, IDatatype... param) { return null; } - - default IDatatype overload(Eval eval, Expr exp, IDatatype res, IDatatype... param) { return null; } - - default boolean produce() { return false; } - - default boolean statement() { return false; } - - default boolean candidate() { return false; } - - default boolean filter() { return false; } - - default boolean overload(Expr exp, IDatatype res, IDatatype dt1, IDatatype dt2) { return false; } - - default int compare(Eval eval, int res, IDatatype dt1, IDatatype dt2) { return res ;} - - default IDatatype datatype(IDatatype type, IDatatype sup) { return type ;}; - - default IDatatype insert(IDatatype path, Edge edge) { return defaultValue();} - - default IDatatype delete(Edge edge) { return defaultValue();} - - default IDatatype update(Query q, List delete, List insert) { return defaultValue();} + default int setSlice(int n) { + return SLICE_DEFAULT; + } + + default IDatatype produce(Eval eval, Node g, Edge edge) { + return defaultValue(); + } + + default IDatatype candidate(Eval eval, Node g, Edge q, Edge e) { + return defaultValue(); + } + + default IDatatype path(Eval eval, Node g, Edge q, Path p, Node s, Node o) { + return defaultValue(); + } + + default boolean step(Eval eval, Node g, Edge q, Path p, Node s, Node o) { + return true; + } + + default boolean result(Eval eval, Mappings map, Mapping m) { + return true; + } + + default IDatatype statement(Eval eval, Node g, Exp e) { + return defaultValue(); + } + + + default IDatatype bgp(Eval eval, Node g, Exp e, Mappings m) { + return defaultValue(); + } + + default IDatatype join(Eval eval, Node g, Exp e, Mappings m1, Mappings m2) { + return defaultValue(); + } + + default IDatatype optional(Eval eval, Node g, Exp e, Mappings m1, Mappings m2) { + return defaultValue(); + } + + default IDatatype minus(Eval eval, Node g, Exp e, Mappings m1, Mappings m2) { + return defaultValue(); + } + + default IDatatype union(Eval eval, Node g, Exp e, Mappings m1, Mappings m2) { + return defaultValue(); + } + + default IDatatype graph(Eval eval, Node g, Exp e, Mappings m) { + return defaultValue(); + } + + default IDatatype query(Eval eval, Node g, Exp e, Mappings m) { + return defaultValue(); + } + + default IDatatype service(Eval eval, Node s, Exp e, Mappings m) { + return defaultValue(); + } + + default IDatatype values(Eval eval, Node g, Exp e, Mappings m) { + return defaultValue(); + } + + default boolean filter(Eval eval, Node g, Expr e, boolean b) { + return b; + } + + default boolean having(Eval eval, Expr e, boolean b) { + return b; + } + + default IDatatype bind(Eval eval, Node g, Exp e, IDatatype val) { + return val; + } + + default IDatatype select(Eval eval, Expr e, IDatatype val) { + return val; + } + + default IDatatype aggregate(Eval eval, Expr e, IDatatype val) { + return val; + } + + default IDatatype function(Eval eval, Expr funcall, Expr fundef) { + return defaultValue(); + } + + + default IDatatype error(Eval eval, Expr exp, IDatatype... param) { + return null; + } + + default IDatatype overload(Eval eval, Expr exp, IDatatype res, IDatatype... param) { + return null; + } + + default boolean produce() { + return false; + } + + default boolean statement() { + return false; + } + + default boolean candidate() { + return false; + } + + default boolean filter() { + return false; + } + + default boolean overload(Expr exp, IDatatype res, IDatatype dt1, IDatatype dt2) { + return false; + } + + default int compare(Eval eval, int res, IDatatype dt1, IDatatype dt2) { + return res; + } + + default IDatatype datatype(IDatatype type, IDatatype sup) { + return type; + } + + default IDatatype insert(IDatatype path, Edge edge) { + return defaultValue(); + } + + default IDatatype delete(Edge edge) { + return defaultValue(); + } + + default IDatatype update(Query q, List delete, List insert) { + return defaultValue(); + } } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/query/Producer.java b/src/main/java/fr/inria/corese/core/kgram/api/query/Producer.java index 505184b24..a15d0fea7 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/query/Producer.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/query/Producer.java @@ -1,65 +1,55 @@ package fr.inria.corese.core.kgram.api.query; -import fr.inria.corese.core.kgram.api.core.DatatypeValueFactory; -import java.util.List; - -import fr.inria.corese.core.kgram.api.core.Graph; -import fr.inria.corese.core.kgram.api.core.Node; -import fr.inria.corese.core.kgram.api.core.Regex; +import fr.inria.corese.core.kgram.api.core.*; import fr.inria.corese.core.kgram.core.Exp; import fr.inria.corese.core.kgram.core.Mappings; import fr.inria.corese.core.kgram.core.Query; -import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.core.SparqlException; import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.datatype.DatatypeMap; + import java.util.ArrayList; +import java.util.List; /** * Interface for the Connector that produces candidate edges for KGRAM * * @author Olivier Corby, Edelweiss, INRIA 2010 - * */ public interface Producer { - public static final int DEFAULT = 0; - public static final int SKIP_DUPLICATE_TEST = 1; + int DEFAULT = 0; + int SKIP_DUPLICATE_TEST = 1; // Producer delivers from Path of from Provenance Graph - public static final int EXTENSION = 2; + int EXTENSION = 2; /** * KGRAM calls this method before executing a query. It enables to * initialize the Producer - * */ default void init(Query q) { } - ; - default void start(Query q) { + default void start(Query q) { } - ; - default void finish(Query q) { + default void finish(Query q) { } - ; - - /** - * A hook to tune Producer - */ - void setMode(int n); + int getMode(); - public int getMode(); + /** + * A hook to tune Producer + */ + void setMode(int n); /** * Return all graph nodes that are known by the Producer. Should return * graph nodes that are member of from (if any). * * @param gNode The graph query node - * @param from The from named node list (may be empty) - * @param env The binding environment + * @param from The from named node list (may be empty) + * @param env The binding environment * @return graph nodes */ Iterable getGraphNodes(Node gNode, List from, Environment env); @@ -69,8 +59,8 @@ default void finish(Query q) { * from (if any) * * @param gNode The graph query node - * @param from The from named node list (may be empty) - * @param env The binding environment + * @param from The from named node list (may be empty) + * @param env The binding environment * @return true if the node is a graph node */ boolean isGraphNode(Node gNode, List from, Environment env); @@ -85,10 +75,10 @@ default void finish(Query q) { * nevertheless bindings are checked afterwards in KGRAM. * * @param gNode The query graph node if any - * @param from The from named if gNode is not null, otherwise the from (from - * may be empty) + * @param from The from named if gNode is not null, otherwise the from (from + * may be empty) * @param qEdge The query edge - * @param env The current mapping : query node -> target node + * @param env The current mapping : query node -> target node * @return Candidate edge iterator */ Iterable getEdges(Node gNode, List from, Edge qEdge, Environment env); @@ -96,16 +86,18 @@ default void finish(Query q) { default Iterable getEdges(Node s, Node p, Node o, List from) { return new ArrayList<>(0); } - + default Edge insert(Node g, Node s, Node p, Node o) { return null; } - + default Iterable delete(Node g, Node s, Node p, Node o) { return null; } - - default boolean hasDataManager() { return false; } + + default boolean hasDataManager() { + return false; + } //return IDatatype list of IDatatype edge // ldscript iterator @@ -138,26 +130,25 @@ default IDatatype getEdges(Iterable it) { * Return nodes for Zero length path * * @param gNode The graph node where to get nodes (may be null) - * @param from from or from named, may be empty - * @param edge Pseudo query edge for path - * @param env The binding environment - * @param exp either property name or a ! (pname | pname) or null + * @param from from or from named, may be empty + * @param edge Pseudo query edge for path + * @param env The binding environment + * @param exp either property name or a ! (pname | pname) or null * @param index of the node to return * @return Iterable of start nodes for exp - * + *

* SPARQL 1.1 requires: ZeroLengthPath match all nodes of (current) graph, * including Literals If the argument is a constant, it matches even if it * is not a node of the graph - * */ Iterable getNodes(Node gNode, List from, Edge edge, Environment env, - List exp, int index); + List exp, int index); /** * Return candidate edges for a path step for an elementary regex exp. Edge * start at start Node, start is the node at index. Hence start can be * edge.getNode(0) as well as edge.getNode(1) - * + *

* isInverse = true means consider also target edge nodes in reverse order * query: start = Bob ; ?a ^foaf:knows ?b target: Jack foaf:knows Bob return * edge above because we consider also Bob foaf:knows Jack This is @@ -165,23 +156,24 @@ Iterable getNodes(Node gNode, List from, Edge edge, Environment env, * order * * @param gNode The start node of edges - * @param from from or from named, may be empty + * @param from from or from named, may be empty * @param qEdge Pseudo query edge for path - * @param env The binding environment - * @param exp either property name or a ! (pname | pname) - * @param src current source if any + * @param env The binding environment + * @param exp either property name or a ! (pname | pname) + * @param src current source if any * @param start The start node for current edge * @param index of the start node in edge exp.isInverse() authorize to - * consider nodes in reverse order (as if the symmetric relation would - * exist) + * consider nodes in reverse order (as if the symmetric relation would + * exist) * @return Iterable of start nodes for exp */ Iterable getEdges(Node gNode, List from, Edge qEdge, Environment env, - Regex exp, Node src, Node start, int index); + Regex exp, Node src, Node start, int index); - /** + /* * ************** value to node ************* */ + /** * Given a value from the filter language, return a Node that contains this * value use case: select fun(?x) as ?y @@ -220,7 +212,7 @@ Iterable getEdges(Node gNode, List from, Edge qEdge, Environment env * java.sql.ResultSet * * @param qNodes the query nodes to bind with values of object - * @param object + * @param value * @return Mappings */ Mappings map(List qNodes, IDatatype value); @@ -240,14 +232,14 @@ Iterable getEdges(Node gNode, List from, Edge qEdge, Environment env // May return an object that implement the RDF graph Graph getGraph(); - void setGraphNode(Node n); - Node getGraphNode(); + void setGraphNode(Node n); + Edge copy(Edge ent); void close(); - + // generate fresh new blank node ID String blankNode(); } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/query/Provider.java b/src/main/java/fr/inria/corese/core/kgram/api/query/Provider.java index 0ef69c5c4..200f60506 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/query/Provider.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/query/Provider.java @@ -8,34 +8,14 @@ /** * Service Provider - * - * @author Olivier Corby, Edelweiss, INRIA 2011 * + * @author Olivier Corby, Edelweiss, INRIA 2011 */ public interface Provider { - - /** Execute the request in exp on the serv node, with the env environment, - * and returns the mapping obtained. - * @param serv Server on which to execute the query. - * @param exp SPARQL request. - * @param env Environment to use when applying the request. - * @return The mapping of the variables to their values. - */ - //Mappings service(Node serv, Exp exp, Environment env); - - /** - * @param map Pre-existing mappings. - * @return - * @see #service(fr.inria.corese.core.kgram.api.core.Node, fr.inria.corese.core.kgram.core.Exp, fr.inria.corese.core.kgram.api.query.Environment) - */ - //Mappings service(Node serv, Exp exp, Mappings map, Environment env); - - default Mappings service(Node serv, Exp exp, Mappings map, Eval eval) - throws SparqlException { - return null; }; - - void set(String uri, double version); - public boolean isSparql0(Node serv); + default Mappings service(Node serv, Exp exp, Mappings map, Eval eval) + throws SparqlException { + return null; + } } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/query/Result.java b/src/main/java/fr/inria/corese/core/kgram/api/query/Result.java index cd685b646..b05513cb3 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/query/Result.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/query/Result.java @@ -4,14 +4,13 @@ /** * Interface to KGRAM elementary result (a mapping) - * - * @author corby * + * @author corby */ public interface Result { - Node getNode(String name); - - Node getNode(Node node); + Node getNode(String name); + + Node getNode(Node node); } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/query/Results.java b/src/main/java/fr/inria/corese/core/kgram/api/query/Results.java index 6d16f2dda..a4ab26d0f 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/query/Results.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/query/Results.java @@ -1,20 +1,18 @@ package fr.inria.corese.core.kgram.api.query; -import java.util.List; - import fr.inria.corese.core.kgram.api.core.Node; +import java.util.List; + /** * Interface to KGRAM results (mappings) - * - * @author corby * + * @author corby */ -public interface Results extends Iterable -{ - - List getSelect(); - - int size(); - +public interface Results extends Iterable { + + List getSelect(); + + int size(); + } diff --git a/src/main/java/fr/inria/corese/core/kgram/api/query/SPARQLEngine.java b/src/main/java/fr/inria/corese/core/kgram/api/query/SPARQLEngine.java index 2aca41105..e8ab956d6 100644 --- a/src/main/java/fr/inria/corese/core/kgram/api/query/SPARQLEngine.java +++ b/src/main/java/fr/inria/corese/core/kgram/api/query/SPARQLEngine.java @@ -7,20 +7,19 @@ import fr.inria.corese.core.kgram.core.SparqlException; /** - * * @author corby */ public interface SPARQLEngine { - + Mappings eval(Query q, Mapping m, Producer p) throws SparqlException; - + Mappings eval(Node gNode, Query q, Mapping m, Producer p) throws SparqlException; - + void getLinkedFunction(String uri) throws SparqlException; - + // within a lock where query processing has ended and where we can process another query boolean isSynchronized(); - + void setSynchronized(boolean b); - + } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/BgpGenerator.java b/src/main/java/fr/inria/corese/core/kgram/core/BgpGenerator.java index 04455f5b9..cb5b9fb11 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/BgpGenerator.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/BgpGenerator.java @@ -4,25 +4,26 @@ import fr.inria.corese.core.kgram.api.core.Filter; import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.api.query.Producer; + import java.util.ArrayList; import java.util.HashMap; public interface BgpGenerator { - HashMap> getIndexEdgeProducers(); + HashMap> getIndexEdgeProducers(); + + void setIndexEdgeProducers(HashMap> tmpEdgeProducers); + + HashMap> getIndexEdgeVariables(); - HashMap> getIndexEdgeVariables(); + void setIndexEdgeVariables(HashMap> tmpEdgeVariables); - HashMap> getIndexEdgeFilters(); + HashMap> getIndexEdgeFilters(); - void setIndexEdgeProducers(HashMap> tmpEdgeProducers); + void setIndexEdgeFilters(HashMap> tmpEdgeFilters); - void setIndexEdgeVariables(HashMap> tmpEdgeVariables); + Exp process(Exp exp); - void setIndexEdgeFilters(HashMap> tmpEdgeFilters); - - Exp process(Exp exp); + HashMap getEdgeAndContext(); - public HashMap getEdgeAndContext(); - } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/Checker.java b/src/main/java/fr/inria/corese/core/kgram/core/Checker.java index fc0a4db7b..fef82fcdb 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/Checker.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/Checker.java @@ -1,130 +1,120 @@ package fr.inria.corese.core.kgram.core; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.api.query.Environment; import fr.inria.corese.core.kgram.api.query.Matcher; import fr.inria.corese.core.kgram.api.query.Producer; -import fr.inria.corese.core.kgram.api.core.Edge; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Query Type Checker - * + *

* Check occurrence of properties in Producer - * Check if class/property are defined in Producer + * Check if class/property are defined in Producer * - p rdf:type rdf:Property * - c rdf:type rdfs:Class - * - * @author Olivier Corby, Edelweiss, INRIA 2011 * + * @author Olivier Corby, Edelweiss, INRIA 2011 */ public class Checker { - - static Logger logger = LoggerFactory.getLogger(Checker.class); - - Eval eval; - Producer producer; - Matcher matcher; - Query query; - - Checker(Eval e){ - eval = e; - producer = e.getProducer(); - matcher = e.getMatcher(); - } - - public static Checker create(Eval e){ - return new Checker(e); - } - - void check(Query q){ - query = q; - check(null, q.getBody(), eval.getMemory()); - } - - - void check(Node gNode, Exp exp, Environment env){ - - switch (exp.type()){ - - case Exp.EDGE: - edge(gNode, exp, env); - break; - - - case Exp.QUERY: - check(gNode, exp.getQuery().getBody(), env); - break; - - default: - for (Exp ee : exp.getExpList()){ - check(gNode, ee, env); - } - } - - - } - - /** - * Check occurrence of edge - * If edge has an associated query, check class/property definition in ontology - */ - void edge(Node gNode, Exp exp, Environment env){ - Edge edge = exp.getEdge(); - boolean exist = false, match = false, define = false; - - for (Edge ent : producer.getEdges(gNode, query.getFrom(gNode), edge, env)){ - - if (ent != null){ - exist = true; - if (matcher.match(edge, ent, env)){ - match = true; - break; - } - } - } - - Query q = query.get(edge); - if (q != null){ - Eval ee = Eval.create(producer, eval.getEvaluator(), matcher); - Mappings map; - try { - map = ee.query(q); - define = map.size()>0; - report(edge, exist, match, define); - } catch (SparqlException ex) { - ex.printStackTrace(); - } - - } - else { - report(edge, exist, match); - } - } - - - void report(Edge edge, boolean exist, boolean match, boolean define){ - query.addInfo(edge.toString(), - " defined:" + define + " exist: " + exist + " match: " + match ); - logger.info("Edge: " + edge + ": " + exist + " " + match + " " + define); - } - - void report(Edge edge, boolean exist, boolean match){ - query.addInfo(edge.toString(), " exist: " + exist + " match: " + match); - logger.info("Edge: " + edge + ": " + exist + " " + match); - } - - void report(Edge edge, boolean exist){ - logger.info("Defined: " + edge + ": " + exist); - } - - - - - + + static Logger logger = LoggerFactory.getLogger(Checker.class); + + Eval eval; + Producer producer; + Matcher matcher; + Query query; + + Checker(Eval e) { + eval = e; + producer = e.getProducer(); + matcher = e.getMatcher(); + } + + public static Checker create(Eval e) { + return new Checker(e); + } + + void check(Query q) { + query = q; + check(null, q.getBody(), eval.getMemory()); + } + + + void check(Node gNode, Exp exp, Environment env) { + + switch (exp.type()) { + + case EDGE: + edge(gNode, exp, env); + break; + + + case QUERY: + check(gNode, exp.getQuery().getBody(), env); + break; + + default: + for (Exp ee : exp.getExpList()) { + check(gNode, ee, env); + } + } + + + } + + /** + * Check occurrence of edge + * If edge has an associated query, check class/property definition in ontology + */ + void edge(Node gNode, Exp exp, Environment env) { + Edge edge = exp.getEdge(); + boolean exist = false; + boolean match = false; + boolean define = false; + + for (Edge ent : producer.getEdges(gNode, query.getFrom(gNode), edge, env)) { + + if (ent != null) { + exist = true; + if (matcher.match(edge, ent, env)) { + match = true; + break; + } + } + } + + Query q = query.get(edge); + if (q != null) { + Eval ee = Eval.create(producer, eval.getEvaluator(), matcher); + Mappings map; + try { + map = ee.query(q); + define = map.size() > 0; + report(edge, exist, match, define); + } catch (SparqlException ex) { + ex.printStackTrace(); + } + + } else { + report(edge, exist, match); + } + } + + + void report(Edge edge, boolean exist, boolean match, boolean define) { + query.addInfo(edge.toString(), + " defined:" + define + " exist: " + exist + " match: " + match); + logger.info("Edge: " + edge + ": " + exist + " " + match + " " + define); + } + + void report(Edge edge, boolean exist, boolean match) { + query.addInfo(edge.toString(), " exist: " + exist + " match: " + match); + logger.info("Edge: " + edge + ": " + exist + " " + match); + } + } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/CompleteSPARQL.java b/src/main/java/fr/inria/corese/core/kgram/core/CompleteSPARQL.java index 4533d3e7d..428117f03 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/CompleteSPARQL.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/CompleteSPARQL.java @@ -8,89 +8,88 @@ import fr.inria.corese.core.kgram.api.core.Filter; import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.api.query.Producer; +import fr.inria.corese.core.sparql.api.IDatatype; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** - * Compute select expression, - * Compute value of group by, order by - * - * @author Olivier Corby, Wimmics INRIA I3S, 2016 + * Compute select expression, + * Compute value of group by, order by * + * @author Olivier Corby, Wimmics INRIA I3S, 2016 */ public class CompleteSPARQL { - private static Logger logger = LoggerFactory.getLogger(CompleteSPARQL.class); - + private static final Logger logger = LoggerFactory.getLogger(CompleteSPARQL.class); + Eval eval; Query query; - - CompleteSPARQL(Query q, Eval e){ + + CompleteSPARQL(Query q, Eval e) { this.eval = e; this.query = q; } - /** + /** * Complete: * select (exp as var) * group by, order by - * - * @param map + * + * @param map */ - void complete(Producer p, Mappings map) throws SparqlException{ + void complete(Producer p, Mappings map) throws SparqlException { selectExpression(query, p, map); distinct(query, map); orderGroup(query, p, map); } - - void distinct(Query q, Mappings map){ - if (q.isAggregate() || ! map.isDistinct()){ + + void distinct(Query q, Mappings map) { + if (q.isAggregate() || !map.isDistinct()) { // do nothing - } - else { - ArrayList list = new ArrayList(map.size()); + } else { + ArrayList list = new ArrayList<>(map.size()); list.addAll(map.getList()); map.getList().clear(); - for (Mapping m : list){ + for (Mapping m : list) { map.submit(m); } } } - + Mappings selectExpression(Query q, Producer p, Mappings map) throws SparqlException { if (query.isSelectExpression()) { - HashMap bnode = new HashMap(); + HashMap bnode = new HashMap<>(); for (Mapping m : map) { bnode.clear(); m.setMap(bnode); m.setQuery(q); Mapping res = selectExpression(q, p, m); - if (res == null){ + if (res == null) { logger.warn("Select: exp != var value: " + m); } } } return map; } - + Mapping selectExpression(Query q, Producer p, Mapping m) throws SparqlException { - ArrayList ql = new ArrayList(); - ArrayList tl = new ArrayList(); - + ArrayList ql = new ArrayList<>(); + ArrayList tl = new ArrayList<>(); + for (Exp e : q.getSelectFun()) { Filter f = e.getFilter(); if (f != null) { // select (exp as ?y) - if (e.isAggregate()){ + if (e.isAggregate()) { // processed later, need place holder - if (m.getNodeValue(e.getNode()) == null){ + if (m.getNodeValue(e.getNode()) == null) { ql.add(e.getNode()); tl.add(null); } - } - else { + } else { Node qnode = e.getNode(); Node tnode = eval.eval(null, f, m, p); if (tnode != null) { @@ -99,7 +98,7 @@ Mapping selectExpression(Query q, Producer p, Mapping m) throws SparqlException // bind e.getNode() = node ql.add(qnode); tl.add(tnode); - m.setNodeValue(qnode, tnode); + m.setNodeValue(qnode, tnode); } else if (!val.equals(tnode)) { // error: select var != bgp var return null; @@ -108,16 +107,16 @@ Mapping selectExpression(Query q, Producer p, Mapping m) throws SparqlException } } } - - if (ql.size()>0){ + + if (!ql.isEmpty()) { m.complete(ql, tl); } return m; } - - void orderGroup(Query q, Producer p, Mappings map) throws SparqlException{ - for (Mapping m : map){ + + void orderGroup(Query q, Producer p, Mappings map) throws SparqlException { + for (Mapping m : map) { Node[] snode = new Node[q.getOrderBy().size()]; Node[] gnode = new Node[q.getGroupBy().size()]; orderGroup(q.getOrderBy(), snode, p, m); @@ -126,7 +125,7 @@ void orderGroup(Query q, Producer p, Mappings map) throws SparqlException{ m.setGroupBy(gnode); } } - + void orderGroup(List lExp, Node[] nodes, Producer p, Mapping m) throws SparqlException { int n = 0; for (Exp e : lExp) { @@ -144,5 +143,5 @@ void orderGroup(List lExp, Node[] nodes, Producer p, Mapping m) throws Spar n++; } } - + } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/Distinct.java b/src/main/java/fr/inria/corese/core/kgram/core/Distinct.java index 168aa4aaa..51aa7387e 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/Distinct.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/Distinct.java @@ -1,20 +1,30 @@ package fr.inria.corese.core.kgram.core; +import fr.inria.corese.core.kgram.api.core.Node; +import fr.inria.corese.core.kgram.api.query.Environment; + import java.util.Comparator; import java.util.List; import java.util.TreeMap; -import fr.inria.corese.core.kgram.api.core.Node; -import fr.inria.corese.core.kgram.api.query.Environment; - /** * Alternative implementation of select distinct * - * Used by RuleEngine ResultWatcher - * @author Olivier Corby, Wimmics, Inria, I3S, 2014 + * Used by RuleEngine ResultWatcher * + * @author Olivier Corby, Wimmics, Inria, I3S, 2014 */ public class Distinct { - private static boolean byIndex = false; + private static boolean byIndex = false; + TreeMapping table; + List list; + + Distinct() { + table = new TreeMapping(); + } + Distinct(List l) { + this(); + list = l; + } /** * @return the byIndex @@ -29,97 +39,78 @@ public static boolean isByIndex() { public static void setCompareIndex(boolean aByIndex) { byIndex = aByIndex; } - - TreeMapping table; - List list; - - class TreeMapping extends TreeMap { - - TreeMapping(){ - super(new Compare()); - } - } - - - class Compare implements Comparator { - - Compare(){ - } - - @Override - public int compare(Node[] m1, Node[] m2){ - - for (int i = 0; i l) { + return new Distinct(l); + } + + public static Distinct create() { + return new Distinct(); + } + + public boolean isDistinct(Node[] key) { + + if (table.containsKey(key)) { + return false; + } + table.put(key, key); + return true; + } + + public boolean isDistinct(Environment env) { + Node[] key = new Node[list.size()]; + int i = 0; + for (Node node : list) { + key[i++] = env.getNode(node); } - - Distinct(List l){ - this(); - list = l; - } - - public static Distinct create(List l){ - return new Distinct(l); + return isDistinct(key); + } + + public boolean isDistinct(Node n1, Node n2) { + Node[] key = new Node[2]; + key[0] = n1; + key[1] = n2; + return isDistinct(key); + } + + class TreeMapping extends TreeMap { + + TreeMapping() { + super(new Compare()); } - - public static Distinct create(){ - return new Distinct(); + } + + class Compare implements Comparator { + + Compare() { } - - public boolean isDistinct(Node[] key){ - - if (table.containsKey(key)){ - return false; - } - table.put(key, key); - return true; - } - - public boolean isDistinct(Environment env){ - Node [] key = new Node[list.size()]; - int i = 0; - for (Node node : list){ - key[i++] = env.getNode(node); + + @Override + public int compare(Node[] m1, Node[] m2) { + + for (int i = 0; i < m1.length; i++) { + int res = compare(m1[i], m2[i]); + if (res != 0) return res; } - return isDistinct(key); + return 0; } - - public boolean isDistinct(Node n1, Node n2){ - Node [] key = new Node[2]; - key[0] = n1; - key[1] = n2; - return isDistinct(key); + + + int compare(Node n1, Node n2) { + if (n1 == n2) { + return 0; + } else if (n1 == null) { + return -1; + } else if (n2 == null) { + return +1; + } else if (byIndex && n1.getIndex() != -1 && n2.getIndex() != -1) { + return Integer.compare(n1.getIndex(), n2.getIndex()); + } else { + return n1.compare(n2); + } } + } - } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/Eval.java b/src/main/java/fr/inria/corese/core/kgram/core/Eval.java index f8df8774a..1e4b84403 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/Eval.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/Eval.java @@ -1,32 +1,8 @@ package fr.inria.corese.core.kgram.core; -import java.util.ArrayList; -import java.util.List; -import java.util.HashMap; -import java.util.Iterator; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import fr.inria.corese.core.kgram.api.core.Edge; -import fr.inria.corese.core.kgram.api.core.ExpType; -import fr.inria.corese.core.kgram.api.core.Expr; -import static fr.inria.corese.core.kgram.api.core.ExprType.UNNEST; -import fr.inria.corese.core.kgram.api.core.Filter; -import fr.inria.corese.core.kgram.api.core.Loopable; -import fr.inria.corese.core.kgram.api.core.Node; -import fr.inria.corese.core.kgram.api.query.Environment; -import fr.inria.corese.core.kgram.api.query.Evaluator; -import fr.inria.corese.core.kgram.api.query.Matcher; -import fr.inria.corese.core.kgram.api.query.Plugin; -import fr.inria.corese.core.kgram.api.query.ProcessVisitor; -import fr.inria.corese.core.kgram.api.query.Producer; -import fr.inria.corese.core.kgram.api.query.Provider; -import fr.inria.corese.core.kgram.api.query.Results; -import fr.inria.corese.core.kgram.api.query.SPARQLEngine; -import fr.inria.corese.core.kgram.event.Event; -import fr.inria.corese.core.kgram.event.EventImpl; -import fr.inria.corese.core.kgram.event.EventListener; -import fr.inria.corese.core.kgram.event.EventManager; -import fr.inria.corese.core.kgram.event.ResultListener; +import fr.inria.corese.core.kgram.api.core.*; +import fr.inria.corese.core.kgram.api.query.*; +import fr.inria.corese.core.kgram.event.*; import fr.inria.corese.core.kgram.path.PathFinder; import fr.inria.corese.core.kgram.tool.Message; import fr.inria.corese.core.kgram.tool.ResultsImpl; @@ -34,48 +10,53 @@ import fr.inria.corese.core.sparql.datatype.DatatypeMap; import fr.inria.corese.core.sparql.exceptions.EngineException; import fr.inria.corese.core.sparql.triple.function.term.Binding; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import static fr.inria.corese.core.kgram.api.core.ExprType.UNNEST; /** * KGRAM Knowledge Graph Abstract Machine Compute graph homomorphism and * (extended) SPARQL Use: a Stack of expression Exp a Memory for Node/Edge * bindings an abstract Producer of candidate Node/Edge an abstract Evaluator of * Filter an abstract Matcher of Node/Edge - * + *

* - path statement is an EDGE with a boolean isPath this edge needs an Edge * Node (a property variable) - * - * + *

+ *

* TODO: optimize: query ordering, search by dichotomy (in a cache) * * @author Olivier Corby, Edelweiss, INRIA 2010 - * */ public class Eval implements ExpType, Plugin { - // true = new processing of named graph + static final int STOP = -2; + // true = new processing of named graph public static boolean NAMED_GRAPH_DEFAULT = true; - static Logger logger = LoggerFactory.getLogger(Eval.class); public static boolean JOIN_MAPPINGS = true; - + public static int DISPLAY_RESULT_MAX = 10; + public static int count = 0; + static Logger logger = LoggerFactory.getLogger(Eval.class); // draft test: when edge() has Mappings map parameter, push clause values(map) private static boolean pushEdgeMappings = true; // draft test: graph() has Mappings map parameter and eval body with map parameter private static boolean parameterGraphMappings = true; // draft test: union() has Mappings map parameter and eval branch with map parameter private static boolean parameterUnionMappings = true; - public static int DISPLAY_RESULT_MAX = 10; - - static final int STOP = -2; - public static int count = 0; - private ResultListener listener; + + static { + setNewMappingsVersion(true); + } + EventManager manager; - private ProcessVisitor visitor; - private SPARQLEngine sparqlEngine; boolean hasEvent = false; boolean namedGraph = NAMED_GRAPH_DEFAULT; // Edge and Node producer - private Producer producer; - // Edge and Node producer Producer saveProducer; Provider provider; // Filter evaluator @@ -86,62 +67,59 @@ public class Eval implements ExpType, Plugin { Plugin plugin; // Stacks for binding edges and nodes Memory memory; - private Stack current; Query query; Exp maxExp; Node nn; Exp edgeToDiffer; Mapping mapping; Mappings results, - // initial results to be completed - initialResults; + // initial results to be completed + initialResults; EvalSPARQL evalSparql; CompleteSPARQL completeSparql; List empty = new ArrayList<>(0); - //HashMap local; - EvalGraph evalGraphNew; EvalJoin join; EvalOptional optional; - - static { - setNewMappingsVersion(true); - } - int // count number of eval() calls - nbEdge = 0, nbCall = 0, - rcount = 0, - backjump = -1, indexToDiffer = -1, - // max level in stack for debug - level = -1, - maxLevel = -1, - limit = Integer.MAX_VALUE; - private boolean debug = false; + nbEdge = 0; + int nbCall = 0; + int rcount = 0; + int backjump = -1; + int indexToDiffer = -1; + int level = -1; + int maxLevel = -1; + int limit = Integer.MAX_VALUE; // subeval = false: eval query/subquery // subeval = true: eval statement (union, optional, minus, graph, join) - boolean isSubEval = false, - // return only select variables in Mapping - onlySelect = true, - optim = true, - draft = true; - private boolean hasListener = false; + boolean isSubEval = false; + // return only select variables in Mapping + boolean onlySelect = true; + boolean optim = true; + boolean draft = true; boolean storeResult = true; - private int nbResult; boolean hasFilter = false; - private boolean hasCandidate = false, - hasStatement = false, - hasProduce = false; + private ResultListener listener; + private ProcessVisitor visitor; + private SPARQLEngine sparqlEngine; + // Edge and Node producer + private Producer producer; + private Stack current; + private boolean hasListener = false; + private int nbResult; + private boolean hasCandidate = false; + private boolean hasStatement = false; + private boolean hasProduce = false; private boolean stop = false; private boolean joinMappings = JOIN_MAPPINGS; - + public Eval() { } /** - * * @param p edge and node producer * @param e filter evaluator, given an environment (access to variable - * binding) + * binding) */ public Eval(Producer p, Evaluator e, Matcher m) { producer = p; @@ -162,6 +140,36 @@ public static Eval create(Producer p, Evaluator e, Matcher m) { return new Eval(p, e, m); } + public static boolean isPushEdgeMappings() { + return pushEdgeMappings; + } + + public static void setPushEdgeMappings(boolean aPushEdgeMappings) { + pushEdgeMappings = aPushEdgeMappings; + } + + public static boolean isParameterGraphMappings() { + return parameterGraphMappings; + } + + public static void setParameterGraphMappings(boolean aParameterGraphMappings) { + parameterGraphMappings = aParameterGraphMappings; + } + + public static boolean isParameterUnionMappings() { + return parameterUnionMappings; + } + + public static void setParameterUnionMappings(boolean aParameterUnionMappings) { + parameterUnionMappings = aParameterUnionMappings; + } + + public static void setNewMappingsVersion(boolean b) { + setPushEdgeMappings(b); + setParameterGraphMappings(b); + setParameterUnionMappings(b); + } + public void set(Provider p) { provider = p; } @@ -188,17 +196,17 @@ public Results exec(Query q) throws SparqlException { * Main eval function */ public Mappings query(Query q) throws SparqlException { - return query(null, q, (Mapping) null); + return query(null, q, null); } - + public Mappings query(Query q, Mapping m) throws SparqlException { return query(null, q, m); } - + public Mappings query(Node graphNode, Query q, Mapping m) throws SparqlException { return queryBasic(graphNode, q, m); } - + Mappings queryBasic(Node graphNode, Query q, Mapping m) throws SparqlException { if (hasEvent) { send(Event.BEGIN, q); @@ -251,7 +259,7 @@ public void finish(Query q, Mappings map) { public Mappings eval(Node gNode, Query q, Mapping map) throws SparqlException { return eval(gNode, q, map, null); } - + /** * Mapping m is binding parameter, possibly null * a) from template call with parameter: st:call-template(st:name, ?x, ?y) @@ -271,8 +279,8 @@ Mappings eval(Node gNode, Query q, Mapping m, Mappings map) throws SparqlExcepti Checker check = Checker.create(this); check.check(q); } - - if (!q.isFail()) { + + if (!q.isFail()) { queryWE(gNode, q, m, map); if (q.getQueryProfile() == Query.COUNT_PROFILE) { @@ -289,13 +297,10 @@ Mappings eval(Node gNode, Query q, Mapping m, Mappings map) throws SparqlExcepti } } - if (isDebug() && !isSubEval && !q.isSubQuery()) { - debug(); - } getEvaluator().finish(getMemory()); return getResults(); } - + int queryWE(Node gNode, Query q, Mapping m, Mappings map) throws SparqlException { try { return query(gNode, q, m, map); @@ -324,17 +329,9 @@ int query(Node gNode, Query q, Mapping m, Mappings map) throws SparqlException { if (q.getValues() == null) { // no external values return eval(gNode, q, map); - } - // external values clause - // select * where {} values var {} -// else if (map == null && m == null) { -// // there is no binding parameter -// // external values evaluated as join(values, body) -// return queryWithJoinValues(gNode, q, map); -// } - else { + } else { // there is binding parameter (m and/or map) - // Mapping m is bound in memory, keep it, mappings map is passed as eval parameter + // Mapping m is bound in memory, keep it, mappings map is passed as eval parameter // bind external values one by one in memory and eval one by one return queryWithValues(gNode, q, map); } @@ -345,12 +342,11 @@ int query(Node gNode, Query q, Mapping m, Mappings map) throws SparqlException { */ int queryWithJoinValues(Node gNode, Query q, Mappings map) throws SparqlException { - Exp values = Exp.create(AND, q.getValues()); - return evalExp(gNode, q, Exp.create(JOIN, values, q.getBody()), map); + Exp values = Exp.create(Type.AND, q.getValues()); + return evalExp(gNode, q, Exp.create(Type.JOIN, values, q.getBody()), map); } - + /** - * * Bind external values one by one in memory and eval one by one */ int queryWithValues(Node gNode, Query q, Mappings map) @@ -371,39 +367,26 @@ int queryWithValues(Node gNode, Query q, Mappings map) } return eval(gNode, q, map); } - + int eval(Node gNode, Query q, Mappings map) throws SparqlException { return evalExp(gNode, q, q.getBody(), map); } - int evalExp(Node gNode, Query q, Exp exp, Mappings map) throws SparqlException { Stack stack = Stack.create(exp); set(stack); return eval(getProducer(), gNode, stack, map, 0); } - + /** * We just counted number of results: nbResult Just build a Mapping */ void countProfile() { - // Node n = getEvaluator().cast(nbResult, getMemory(), getProducer()); Node n = DatatypeMap.newInstance(nbResult); Mapping m = Mapping.create(getQuery().getSelectFun().get(0).getNode(), n); getResults().add(m); - } - -// public Mappings filter(Mappings map, Query q) throws SparqlException { -// Query qq = map.getQuery(); -// init(qq); -// qq.compile(q.getHaving().getFilter()); -// qq.index(qq, q.getHaving().getFilter()); -// map.filter(getEvaluator(), q.getHaving().getFilter(), getMemory()); -// return map; -// } - - + } /** * Subquery processed by a function call that return Mappings Producer may @@ -440,7 +423,7 @@ private Mapping complete(Mapping map, Producer p) throws SparqlException { } } - if (query.getOrderBy().size() > 0 || query.getGroupBy().size() > 0) { + if (!query.getOrderBy().isEmpty() || !query.getGroupBy().isEmpty()) { memory.push(map, -1); Mapping m = memory.store(query, p, true, true); memory.pop(map); @@ -448,77 +431,65 @@ private Mapping complete(Mapping map, Producer p) throws SparqlException { } return map; } - + // draft for processing EXTERN expression public void add(Plugin p) { plugin = p; } - public void setMatcher(Matcher m) { - match = m; - } - public void setMappings(Mappings lMap) { initialResults = lMap; } void debug() { - Message.log(Message.LOOP, nbCall + " " + nbEdge); + logger.warn(Message.Prefix.LOOP.getString(), nbCall + " " + nbEdge); if (results.size() == 0) { if (query.isFail()) { - Message.log(Message.FAIL); - System.out.println("eval: " + query); + logger.warn(Message.Prefix.FAIL.getString()); for (Filter filter : query.getFailures()) { - Message.log(filter + " "); + logger.warn(filter + " "); } - Message.log(); } else { if (maxExp == null) { - Message.log(Message.FAIL_AT, "init phase, e.g. parameter binding"); + logger.warn(Message.Prefix.FAIL_AT.getString(), "init phase, e.g. parameter binding"); } else { - Message.log(Message.FAIL_AT); - Message.log(maxExp); - getTrace().append(String.format("SPARQL fail at: %s", maxExp)).append(Message.NL); + logger.warn(Message.Prefix.FAIL_AT.getString(), maxExp); + getTrace().append(String.format("SPARQL fail at: %s", maxExp)).append(System.getProperty("line.separator")); } } } } - + StringBuilder getTrace() { return getBind().getTrace(); } - + /** * this eval is a fresh copy * use by compiler interpreter for exists {} - */ + */ public Mappings subEval(Query q, Node gNode, Stack stack, int n) throws SparqlException { return subEval(q, gNode, stack, null, n); } - + /** * main subEval function * evaluates exp in new Eval with new Memory * for optional, minus, union, join, graph * not for subquery which has its own processing - * */ Mappings subEval(Query q, Node gNode, Stack stack, Mappings map, int n) throws SparqlException { setSubEval(true); starter(q); - if (q.isDebug()) { - setDebug(true); - } eval(getProducer(), gNode, stack, map, n); return getResults(); } - /** * Eval exp in a fresh new Memory where exp is part of main expression * use case: main = optional, minus, union, join - * Node gNode : actual graph node + * Node gNode : actual graph node * Node queryNode : exp query graph node * use case: union */ @@ -527,10 +498,10 @@ Mappings subEval(Query q, Node gNode, Stack stack, Mappings map, int n) throws S public Mappings subEval(Producer p, Node gNode, Node queryNode, Exp exp, Exp main, Mappings map) throws SparqlException { return subEval(p, gNode, queryNode, exp, main, map, null, false, false); } - + /** * external = false : graphNode is named graph URI or null, queryGraphNode is meaningless - * external = true : graphNode is external graph, + * external = true : graphNode is external graph, * queryGraphNode: named graph variable if any or null * graphNode: if ext=true & queryNode=null -> graphNode can be null * external graph: external graph in GraphStore, PPath or Node graph pointer @@ -538,10 +509,9 @@ public Mappings subEval(Producer p, Node gNode, Node queryNode, Exp exp, Exp mai * exp is current exp to evaluate in new Eval with new Memory * main is embedding statement of exp (main = A optional B, exp = A | exp = B) * map and m are possible bindings stemming from previous statement evaluation - * */ - Mappings subEval(Producer p, Node graphNode, Node queryGraphNode, Exp exp, Exp main, - Mappings map, Mapping m, boolean bind, boolean external) throws SparqlException { + Mappings subEval(Producer p, Node graphNode, Node queryGraphNode, Exp exp, Exp main, + Mappings map, Mapping m, boolean bind, boolean external) throws SparqlException { Memory mem = new Memory(match, getEvaluator()); getEvaluator().init(mem); // share Binding (global variable, context, etc.) @@ -552,36 +522,33 @@ Mappings subEval(Producer p, Node graphNode, Node queryGraphNode, Exp exp, Exp m if (external) { if (queryGraphNode != null) { // graph ?queryNode { } -> bind ?queryNode = graphNode for further use - // usually we do not bind named graph variable before + // usually we do not bind named graph variable before // statement evaluation to preserve sparql semantics // external graph is an extension to sparql mem.push(queryGraphNode, graphNode, -1); } - // named graph is external graph, not URI -> + // named graph is external graph, not URI -> // do not pass graphNode as named graph URI // Producer p is bound to external named graph graphNode = null; } bind(mem, exp, main, map, m, bind); - Mappings lMap = eval.subEval(getQuery(), graphNode, Stack.create(exp), map, 0); - return lMap; - } - - + return eval.subEval(getQuery(), graphNode, Stack.create(exp), map, 0); + } + /** * subEval with bind parameters - * freshMemory inherits data to evaluate exp - * + * freshMemory inherits data to evaluate exp */ void bind(Memory freshMemory, Exp exp, Exp main, Mappings map, Mapping m, boolean bind) { if (m != null) { freshMemory.push(m, -1); } - + // QuerySorter may have computed exp node list candidate for binding if (main.isGraph() && main.getNodeList() != null) { bindExpNodeList(freshMemory, main, main.getGraphName()); - } else if ((bind || main.isBinary()) && exp.getNodeList() != null) { + } else if ((bind || main.isBinary()) && exp.getNodeList() != null) { // A optional B // bind variables of A from environment bindExpNodeList(freshMemory, exp, null); @@ -590,21 +557,18 @@ void bind(Memory freshMemory, Exp exp, Exp main, Mappings map, Mapping m, boolea bindService(freshMemory, exp, main); } - - /** * Bind relevant nodes of exp from memory to fresh memory - * except may be a graphNode: do not bind it here + * except may be a graphNode: do not bind it here * because it is bound somewhere else by subEval * getNodeList() is computer by QuerySorter - * */ void bindExpNodeList(Memory freshMemory, Exp exp, Node except) { for (Node qnode : exp.getNodeList()) { // getOuterNodeSelf use case: join(subquery, exp) -- federated query use case if (except == null || qnode != except) { - Node myqnode = getMemory().getQuery().getOuterNodeSelf(qnode); - Node node = getMemory().getNode(myqnode); + Node myqnode = getMemory().getQuery().getOuterNodeSelf(qnode); + Node node = getMemory().getNode(myqnode); if (node != null) { freshMemory.push(qnode, node, -1); } @@ -616,31 +580,26 @@ void bindExpNodeList(Memory freshMemory, Exp exp, Node except) { * Bind service variable if any */ void bindService(Memory freshMemory, Exp exp, Exp main) { - switch (main.type()) { - case Exp.JOIN: - service(exp, freshMemory); + if (main.type() == Type.JOIN) { + service(exp, freshMemory); } } - + /** * special case for service variable - * JOIN(service ?s {}, exp) if ?s is bound in main memory, + * JOIN(service ?s {}, exp) if ?s is bound in main memory, * bind it in subeval memory */ void service(Exp exp, Memory freshMemory) { - if (exp.type() == SERVICE) { + if (exp.type() == Type.SERVICE) { bindService(exp, freshMemory); } else { for (Exp ee : exp.getExpList()) { - switch (ee.type()) { - case SERVICE: - bindService(ee, freshMemory); - break; - case AND: - case BGP: - case JOIN: - service(ee, freshMemory); - break; + Type type = ee.type(); + if (type == Type.SERVICE) { + bindService(ee, freshMemory); + } else if (type == Type.AND || type == Type.BGP || type == Type.JOIN) { + service(ee, freshMemory); } } } @@ -655,7 +614,6 @@ void bindService(Exp exp, Memory freshMemory) { } /** - * * Copy current evaluator to eval subquery same memory (share bindings) new * exp stack */ @@ -687,7 +645,7 @@ Eval copy(Memory m, Producer p, Evaluator e, Query q, boolean extern) { } return ev; } - + public Memory createMemory(Environment env, Exp exp) { if (env instanceof Memory) { return getMemory((Memory) env, exp); @@ -723,8 +681,6 @@ public Memory getMemory(Memory memory, Exp exp) { * use case: exists {} in aggregate select (count(if (exists { BGP }, ?x, * ?y)) as ?c) Env is a Mapping Copy Mapping into fresh Memory in order to * evaluate exists {} in Memory TODO: optimize by storing mem - * - * */ public Memory getMemory(Mapping map, Exp exp) { Memory mem = new Memory(match, evaluator); @@ -757,10 +713,6 @@ void setLevel(int n) { level = n; } - public void setDebug(boolean b) { - debug = b; - } - public void setSubEval(boolean b) { isSubEval = b; } @@ -768,15 +720,19 @@ public void setSubEval(boolean b) { public Memory getMemory() { return memory; } - + + public void setMemory(Memory mem) { + memory = mem; + } + public Binding getBinding() { return getEnvironment().getBind(); } - + public Binding getBind() { return getEnvironment().getBind(); } - + Query getQuery() { return query; } @@ -789,10 +745,18 @@ public Matcher getMatcher() { return match; } + public void setMatcher(Matcher m) { + match = m; + } + public Producer getProducer() { return producer; } + public void setProducer(Producer producer) { + this.producer = producer; + } + public Provider getProvider() { return provider; } @@ -809,10 +773,6 @@ void setResult(Mappings r) { results = r; } - public void setMemory(Memory mem) { - memory = mem; - } - // total init (for global query) public void init(Query q) { initMemory(q); @@ -835,13 +795,9 @@ void initMemory(Query q) { } getProducer().init(q); evaluator.start(memory); - setDebug(q.isDebug()); if (q.isAlgebra()) { complete(q); } - if (isDebug()) { - System.out.println(q); - } } } @@ -906,46 +862,30 @@ private void aggregate() throws SparqlException { private void template() throws SparqlException { results.template(evaluator, memory, getProducer()); } - + /** * Process map with new query modifier * Use case: user edit query modifier and click Modifier button in GUI - * select distinct select exp + * select distinct select exp * select aggregate group by having * order by limit offset */ public Mappings modifier(Query q, Mappings map) throws SparqlException { - if (q.isDebug()) { - System.out.println("modifier"); - } - q.complete(getProducer()); + q.complete(getProducer()); Memory env = new Memory(getMatcher(), getEvaluator()); env.init(q).setBinding(getMemory().getBind()).setResults(map); env.setEval(this); - - if (q.isDebug()) { - System.out.println("prepare modifier"); - } + map.modify(q); - - if (q.isDebug()) { - System.out.println("select expression"); - } - map.modifySelect(this, q); - - if (q.isDebug()) { - System.out.println("aggregate"); - } - map.modifyAggregate(q, getEvaluator(), env, getProducer()); - - if (q.isDebug()) { - System.out.println("order by"); - } + + map.modifySelect(this, q); + + map.modifyAggregate(q, getEvaluator(), env, getProducer()); + map.modifyDistinct(); map.modifyOrderBy(this, q); map.modifyLimitOffset(); - Mappings res = map.modifyValues(q); - return res; + return map.modifyValues(q); } /** @@ -965,9 +905,6 @@ void bind(Mapping map) { Node node = map.getNode(qNode); if (node != null) { bind(qqNode, node); - if (isDebug()) { - logger.debug("Bind: " + qqNode + " = " + node); - } } } } @@ -981,7 +918,7 @@ private PathFinder getPathFinder(Exp exp, Producer p) { } } PathFinder pathFinder = PathFinder.create(this, p, query); - //pathFinder.setDefaultBreadth(false); + if (hasEvent) { pathFinder.set(manager); } @@ -991,7 +928,7 @@ private PathFinder getPathFinder(Exp exp, Producer p) { // to be optimized pathFinder.setStorePath(query.getGlobalQuery().isStorePath() && !exp.isSystem()); pathFinder.setCache(query.getGlobalQuery().isCachePath()); - // TODO: subQuery + // TODO: subQuery pathFinder.setCheckLoop(query.isCheckLoop()); pathFinder.setCountPath(query.isCountPath()); pathFinder.init(exp.getRegex(), exp.getObject(), exp.getMin(), exp.getMax()); @@ -1037,12 +974,10 @@ private int solution(Producer p, Mapping m, int n) throws SparqlException { backtrack = backjump; backjump = -1; } - } else if (query.isDistinct()) { - if (!isSubEval && optim) { - int index = memory.getIndex(query.getSelect()); - if (index != -1) { - backtrack = index; - } + } else if ((query.isDistinct()) && (!isSubEval && optim)) { + int index = memory.getIndex(query.getSelect()); + if (index != -1) { + backtrack = index; } } return backtrack; @@ -1054,7 +989,7 @@ private int solution(Producer p, Mapping m, int n) throws SparqlException { int eval(Producer p, Node gNode, Stack stack, int n) throws SparqlException { return eval(p, gNode, stack, null, n); } - + /** * Mappings map, possibly null, is result of previous expression that may be used to evaluate current exp * optional(s p o, o q r) @@ -1080,26 +1015,6 @@ int eval(Producer p, Node graphNode, Stack stack, Mappings map, int n) throws Sp return backtrack; } - if (isDebug()) { - - if (n > level - || (maxExp.type() == UNION)) { - Exp ee = stack.get(n); - if (true){//(ee.type() != AND) { - level = n; - maxExp = stack.get(n); - String s = String.format("%02d", n); - Message.log(Message.EVAL, s + " " + maxExp); - if (map!=null) { - logger.warn(String.format("With mappings:\nvalues %s\n%s", - map.getNodeList(), map.toString(false, false, DISPLAY_RESULT_MAX))); - } - getTrace().append(String.format("Eval: %02d %s", n, maxExp)) - .append(Message.NL).append(Message.NL); - } - } - } - if (n > maxLevel) { maxLevel = n; } @@ -1109,7 +1024,7 @@ int eval(Producer p, Node graphNode, Stack stack, Mappings map, int n) throws Sp // rule engine may have a ResultWatcher listener exp = getListener().listen(exp, n); } - + if (isEvent) { send(Event.START, exp, graphNode, stack); } @@ -1123,29 +1038,24 @@ int eval(Producer p, Node graphNode, Stack stack, Mappings map, int n) throws Sp if (exp.isBGPAble()) { // @deprecated // evaluate and record result for next time - // template optimization + // template optimization exp.setBGPAble(false); backtrack = bgpAble(p, graphNode, exp, stack, n); exp.setBGPAble(true); } else { // draft test not used if (query.getGlobalQuery().isAlgebra()) { - switch (exp.type()) { - case BGP: - case JOIN: - case MINUS: - case OPTIONAL: - case GRAPH: - case UNION: - process(graphNode, p, exp); - return backtrack; + Type type = exp.type(); + if (type == Type.BGP || type == Type.JOIN || type == Type.MINUS || type == Type.OPTIONAL || type == Type.GRAPH || type == Type.UNION) { + process(graphNode, p, exp); + return backtrack; } - }; + } if (hasStatement) { getVisitor().statement(this, getGraphNode(graphNode), exp); } - + if (!isJoinMappings()) { // for testing and debug map = null; @@ -1158,7 +1068,7 @@ int eval(Producer p, Node graphNode, Stack stack, Mappings map, int n) throws Sp eval(p, graphNode, stack, n + 1); break; - case AND: + case AND: backtrack = and(p, graphNode, exp, stack, map, n); break; @@ -1168,21 +1078,21 @@ int eval(Producer p, Node graphNode, Stack stack, Mappings map, int n) throws Sp case SERVICE: // @note: map processing is not optimal for service with union - // we pass mappings only for variables that are in-scope in + // we pass mappings only for variables that are in-scope in // both branches of the union // it can be bypassed with values var {undef} backtrack = service(p, graphNode, exp, map, stack, n); break; case GRAPH: - backtrack = + backtrack = evalGraphNew.eval(p, graphNode, exp, map, stack, n); break; case UNION: backtrack = union(p, graphNode, exp, map, stack, n); break; - + case OPTIONAL: backtrack = optional.eval(p, graphNode, exp, map, stack, n); break; @@ -1193,8 +1103,8 @@ int eval(Producer p, Node graphNode, Stack stack, Mappings map, int n) throws Sp backtrack = join.eval(p, graphNode, exp, map, stack, n); break; case QUERY: - backtrack = query(p, graphNode, exp, map, stack, n); - break; + backtrack = query(p, graphNode, exp, map, stack, n); + break; case FILTER: backtrack = filter(p, graphNode, exp, stack, n); break; @@ -1214,14 +1124,14 @@ int eval(Producer p, Node graphNode, Stack stack, Mappings map, int n) throws Sp backtrack = values(p, graphNode, exp, stack, n); break; - /** + /* * ******************************** * * Draft extensions * */ case OPT_BIND: - // use case: ?x p ?y FILTER ?t = ?y BIND(?t, ?y) ?z q ?t + // use case: ?x p ?y FILTER ?t = ?y BIND(?t, ?y) ?z q ?t // not effective backtrack = optBind(p, graphNode, exp, stack, n); break; @@ -1239,7 +1149,7 @@ int eval(Producer p, Node graphNode, Stack stack, Mappings map, int n) throws Sp } else { backtrack = eval(p, graphNode, stack, n + 1); } - break; + break; } } } @@ -1250,21 +1160,12 @@ int eval(Producer p, Node graphNode, Stack stack, Mappings map, int n) throws Sp return backtrack; } - - - private int minus(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) throws SparqlException { int backtrack = n - 1; - //boolean hasGraph = gNode != null; Memory env = getMemory(); - Node queryGraphNode = null; //getQuery().getGraphNode(); + Node queryGraphNode = null; -// Node node1 = null, node2 = null; -// if (hasGraph) { -// node1 = queryGraphNode; -// node2 = exp.getGraphNode(); -// } Mappings map1 = subEval(p, graphNode, queryGraphNode, exp.first(), exp, data); if (stop) { return STOP; @@ -1274,43 +1175,38 @@ private int minus(Producer p, Node graphNode, Exp exp, Mappings data, Stack stac } MappingSet set1 = new MappingSet(env.getQuery(), map1); - Exp rest = exp.rest(); + Exp rest = exp.rest(); Mappings minusMappings = set1.prepareMappingsRest(rest); - - Mappings map2 = subEval(p, graphNode, queryGraphNode, rest, exp, minusMappings); + + Mappings map2 = subEval(p, graphNode, queryGraphNode, rest, exp, minusMappings); getVisitor().minus(this, getGraphNode(graphNode), exp, map1, map2); MappingSet set = new MappingSet(env.getQuery(), exp, set1, new MappingSet(memory.getQuery(), map2)); - set.setDebug(getQuery().isDebug()); set.start(); - + for (Mapping map : map1) { if (stop) { return STOP; } boolean ok = !set.minusCompatible(map); - if (ok) { - if (env.push(map, n)) { - backtrack = eval(p, graphNode, stack, n + 1); - env.pop(map); - if (backtrack < n) { - return backtrack; - } + if ((ok) && (env.push(map, n))) { + backtrack = eval(p, graphNode, stack, n + 1); + env.pop(map); + if (backtrack < n) { + return backtrack; } } } return backtrack; } - boolean isFederate(Exp exp) { if (getQuery().getGlobalQuery().isFederate()) { return true; } return exp.isRecFederate(); } - private int union(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) throws SparqlException { int backtrack = n - 1; @@ -1323,7 +1219,7 @@ private int union(Producer p, Node graphNode, Exp exp, Mappings data, Stack stac Mappings map2 = unionBranch(p, graphNode, exp.rest(), exp, data); getVisitor().union(this, getGraphNode(graphNode), exp, map1, map2); - + int b1 = unionPush(p, graphNode, exp, stack, n, map1); int b2 = unionPush(p, graphNode, exp, stack, n, map2); @@ -1339,23 +1235,21 @@ private int union(Producer p, Node graphNode, Exp exp, Mappings data, Stack stac * clause */ Mappings unionBranch(Producer p, Node graphNode, Exp exp, Exp main, Mappings data) throws SparqlException { - Node queryNode = null; //(graphNode == null) ? null : query.getGraphNode(); - - if (exp.isFirstWith(UNION)) { + Node queryNode = null; + + if (exp.isFirstWith(Type.UNION)) { // union in union: eval inner union with parameter data as is return subEval(p, graphNode, queryNode, exp, main, data); - } - else if (isFederate(exp) || exp.isUnion() || isParameterUnionMappings()) { - Mappings unionData = unionData(exp, data); + } else if (isFederate(exp) || exp.isUnion() || isParameterUnionMappings()) { + Mappings unionData = unionData(exp, data); return subEval(p, graphNode, queryNode, exp, main, unionData); - } - else { + } else { // exp += values(var, map) Exp ee = exp.complete(data); return subEval(p, graphNode, queryNode, ee, main, null); } } - + /** * exp is a branch of union * extract from data relevant mappings for exp in-scope variables @@ -1364,14 +1258,12 @@ Mappings unionData(Exp exp, Mappings data) { if (data != null) { if (data.getNodeList() == null) { MappingSet ms = new MappingSet(getQuery(), data); - Mappings map = ms.prepareMappingsRest(exp); - return map; - } - else if (data.getJoinMappings()!=null) { - // select relevant variables from original join Mappings + return ms.prepareMappingsRest(exp); + } else if (data.getJoinMappings() != null) { + // select relevant variables from original join Mappings return unionData(exp, data.getJoinMappings()); } - } + } return data; } @@ -1395,25 +1287,23 @@ int unionPush(Producer p, Node graphNode, Exp exp, Stack stack, int n, Mappings } return backtrack; } - + private int and(Producer p, Node graphNode, Exp exp, Stack stack, Mappings data, int n) throws SparqlException { getVisitor().bgp(this, getGraphNode(graphNode), exp, null); if (data != null && exp.size() > 0 && exp.get(0).isEdgePath()) { // pass Mappings data as values clause exp = exp.complete(data); - //System.out.println(exp); stack = stack.and(exp, n); // Mappings data is in stack, not in parameter return eval(p, graphNode, stack, n); - } - else { + } else { stack = stack.and(exp, n); // pass Mappings data as parameter return eval(p, graphNode, stack, data, n); } } - + private int bgp(Producer p, Node graphNode, Exp exp, Stack stack, int n) throws SparqlException { int backtrack = n - 1; List from = getQuery().getFrom(graphNode); @@ -1436,7 +1326,6 @@ private int bgp(Producer p, Node graphNode, Exp exp, Stack stack, int n) throws return backtrack; } - private int service(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) throws SparqlException { int backtrack = n - 1; Memory env = getMemory(); @@ -1451,17 +1340,13 @@ private int service(Producer p, Node graphNode, Exp exp, Mappings data, Stack st // service delegated to provider Mappings map = getProvider().service(node, exp, selectQueryMappings(data), this); -// if (stack.isCompleted()) { -// return result(p, lMap, n); -// } - for (Mapping m : map) { if (stop) { return STOP; } // push each Mapping in memory and continue complete(getQuery(), m, false); - + if (env.push(m, n, false, false)) { backtrack = eval(p, graphNode, stack, n + 1); env.pop(m, false); @@ -1477,7 +1362,7 @@ private int service(Producer p, Node graphNode, Exp exp, Mappings data, Stack st return backtrack; } - + // stack = just one service: store and return result directly int result(Producer p, Mappings lMap, int n) throws SparqlException { for (Mapping map : lMap) { @@ -1496,7 +1381,7 @@ void complete(Query q, Mapping map, boolean addNode) { // draft: use case ?_server_0 if (out == null) { out = node; - if (addNode && ! q.getSelect().contains(node)) { + if (addNode && !q.getSelect().contains(node)) { q.getSelect().add(node); } } @@ -1504,21 +1389,18 @@ void complete(Query q, Mapping map, boolean addNode) { i++; } } - + Node getNode(Producer p, Node gNode) { if (gNode.isConstant()) { return p.getNode(gNode); - } - return getMemory().getNode(gNode); - } - -// Node getGraphNode(Node node) { -// return (node == null) ? null : node.isConstant() ? node : getMemory().getNode(node); -// } - + } + return getMemory().getNode(gNode); + } + Node getGraphNode(Node node) { return node; } + /** * bind(exp as var) */ @@ -1547,17 +1429,16 @@ private int bind(Producer p, Node graphNode, Exp exp, Mappings map, Stack stack, /** * values (?x ?y) { unnest(exp) } - * compiled as extended bind + * compiled as extended bind */ private int extBind(Producer p, Node graphNode, Exp exp, Stack stack, int n) throws SparqlException { int backtrack = n - 1; Memory env = getMemory(); env.setGraphNode(graphNode); - //Mappings map = getEvaluator().eval(exp.getFilter(), env, exp.getNodeList()); Mappings map = eval(exp.getFilter(), env, exp.getNodeList()); env.setGraphNode(null); getVisitor().values(this, getGraphNode(graphNode), exp, map); - + if (map != null) { HashMap tab = toMap(exp.getNodeList()); for (Mapping m : map) { @@ -1613,15 +1494,7 @@ private int filter(Producer p, Node graphNode, Exp exp, Stack stack, int n) thro return backtrack; } - -// boolean test2(Node graphNode, Filter f, Environment env, Producer p) throws SparqlException { -// env.setGraphNode(graphNode); -// boolean b = getEvaluator().test(f, env, p); -// env.setGraphNode(null); -// return b; -// } - - + boolean test(Node graphNode, Filter f, Environment env, Producer p) throws SparqlException { try { env.setGraphNode(graphNode); @@ -1631,40 +1504,31 @@ boolean test(Node graphNode, Filter f, Environment env, Producer p) throws Sparq env.setGraphNode(null); } } - + boolean isTrue(IDatatype dt) { if (dt == null) { return false; } return dt.isTrueTest(); } - + Node eval(Node graphNode, Filter f, Environment env, Producer p) throws SparqlException { try { env.setGraphNode(graphNode); - return eval(f.getExp(), env, p); + return eval(f.getExp(), env, p); } finally { env.setGraphNode(null); } } - // evalWE clean the binding stack if an EngineException is thrown IDatatype eval(Filter f, Environment env, Producer p) throws EngineException { - return f.getExp().evalWE(getEvaluator(), env.getBind(), env, p); + return f.getExp().evalWE(getEvaluator(), env.getBind(), env, p); } - + IDatatype eval(Expr e, Environment env, Producer p) throws EngineException { - return e.evalWE(getEvaluator(), env.getBind(), env, p); + return e.evalWE(getEvaluator(), env.getBind(), env, p); } - -// if (dt == null) { -// // Evaluation error, may be overloaded by visitor event @error function -// DatatypeValue res = env.getVisitor().error(env.getEval(), exp, EMPTY); -// if (res != null) { -// return (IDatatype) res; -// } -// } // values var { unnext(exp) } // @todo Producer is not current producer but global producer @@ -1672,49 +1536,44 @@ Mappings eval(Filter f, Environment env, List nodes) throws EngineException { return eval(f, env, getProducer(), nodes); } - + Mappings eval(Filter f, Environment env, Producer p, List nodes) throws EngineException { int n = 1; Expr exp = f.getExp(); - switch (exp.oper()) { - - case UNNEST: - if (hasListener) { - listener.listen(exp); - } - if (exp.arity() == 2) { - // unnest(exp, 2) - IDatatype dt = eval(exp.getExp(1), env, p); - if (dt == null) { - return new Mappings(); - } - n = dt.intValue(); - } - exp = exp.getExp(0); - - default: - IDatatype res = eval(exp, env, p); - if (res == null) { + if (exp.oper() == UNNEST) { + if (hasListener) { + listener.listen(exp); + } + if (exp.arity() == 2) { + // unnest(exp, 2) + IDatatype dt = eval(exp.getExp(1), env, p); + if (dt == null) { return new Mappings(); } - // use std producer to map in case local p cannot map - return getProducer().map(nodes, res, n); + n = dt.intValue(); + } + exp = exp.getExp(0); + } + IDatatype res = eval(exp, env, p); + if (res == null) { + return new Mappings(); } + // use std producer to map in case local p cannot map + return getProducer().map(nodes, res, n); } - + /** * Enumerate candidate edges * exp = query edge - * graphNode = null for default graph triple pattern + * graphNode = null for default graph triple pattern * graphNode = URI of named graph for named graph triple pattern * graph ?g { exp } evaluates exp for each value of ?g = g_i - * in this case graphNode = g_i and from is useless here + * in this case graphNode = g_i and from is useless here * from named has been used in named graph pattern evaluator * data is possible relevant bindings coming from preceding statement evaluation * data may be null - * */ private int path(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) throws SparqlException { int backtrack = n - 1, evENUM = Event.ENUM; @@ -1723,11 +1582,11 @@ private int path(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack Memory env = getMemory(); Query qq = getQuery(); boolean isEvent = hasEvent; - - if (data!=null && data.getNodeList()!=null && isPushEdgeMappings()) { + + if (data != null && data.getNodeList() != null && isPushEdgeMappings()) { // push values(data) before edge in stack - logger.info(String.format("Push path mappings:\nvalue %s\n%s", - data.getNodeList(), data.toString(false, false, DISPLAY_RESULT_MAX))); + logger.info(String.format("Push path mappings:\nvalue %s\n%s", + data.getNodeList(), data.toString(false, false, DISPLAY_RESULT_MAX))); return eval(p, graphNode, stack.addCopy(n, exp.getValues(data)), n); } @@ -1790,7 +1649,7 @@ private int path(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack private int values(Producer p, Node graphNode, Exp exp, Stack stack, int n) throws SparqlException { int backtrack = n - 1; getVisitor().values(this, getGraphNode(graphNode), exp, exp.getMappings()); - + for (Mapping map : exp.getMappings()) { if (stop) { return STOP; @@ -1811,7 +1670,7 @@ private int values(Producer p, Node graphNode, Exp exp, Stack stack, int n) thro boolean valuesBinding(List varList, Mapping map, int n) { int i = 0; - for (Node qNode : varList) { + for (Node qNode : varList) { Node node = map.getNode(qNode); if (node != null) { Node value = getProducer().getNode(node.getValue()); @@ -1828,9 +1687,9 @@ boolean valuesBinding(List varList, Mapping map, int n) { boolean popBinding(List varList, Mapping map, int i) { int j = 0; - for (Node qq : varList) { - Node nn = map.getNode(qq); - if (nn != null) { + for (Node qq : varList) { + Node mapNode = map.getNode(qq); + if (mapNode != null) { if (j >= i) { return false; } else { @@ -1847,30 +1706,24 @@ void free(List varList, Mapping map) { getMemory().pop(qNode); } } - - void trace(String mes, Object... obj) { - if (getQuery().isDebug()) { - System.out.println(String.format(mes, obj)); - } - } /** * Enumerate candidate edges * exp = query edge - * graphNode = null for default graph triple pattern + * graphNode = null for default graph triple pattern * graphNode = URI of named graph for named graph triple pattern * graph ?g { exp } evaluates exp for each value of ?g = g_i - * in this case graphNode = g_i and from is useless here + * in this case graphNode = g_i and from is useless here * from named has been used in named graph pattern evaluator * data is possible relevant bindings coming from preceding statement evaluation * data may be null - * */ private int edge(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) throws SparqlException { - int backtrack = n - 1, evENUM = Event.ENUM; - boolean isSuccess = false, - hasGraphNode = graphNode != null, - isEvent = hasEvent; + int backtrack = n - 1; + int evENUM = Event.ENUM; + boolean isSuccess = false; + boolean hasGraphNode = graphNode != null; + boolean isEvent = hasEvent; Edge qEdge = exp.getEdge(); Node graph = null; Memory env = getMemory(); @@ -1883,18 +1736,11 @@ private int edge(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack // the backtrack graphNode (deprecated) Node backtrackGraphNode = graphNode; boolean matchNBNode = qEdge.isMatchArity(); - + if (data != null && data.getNodeList() != null) { if (isPushEdgeMappings()) { // push values(data) before edge in stack - if (isDebug()) { - logger.warn(String.format("Push edge mappings:\nvalues %s\n%s", - data.getNodeList(), data.toString(false, false, DISPLAY_RESULT_MAX))); - } return eval(p, graphNode, stack.addCopy(n, exp.getValues(data)), n); - } else if (isDebug()) { - logger.warn(String.format("Eval edge skip mappings:\nvalues %s\n%s", - data.getNodeList(), data.toString(false, false, DISPLAY_RESULT_MAX))); } } @@ -1922,24 +1768,21 @@ private int edge(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack entities = p.getEdges(graphNode, graphNodeList, qEdge, env); } - Iterator it = entities.iterator(); - - while (it.hasNext()) { + for (Edge entity : entities) { if (stop) { return STOP; } - Edge edge = it.next(); + Edge edge = entity; if (edge != null) { - nbEdge++; + nbEdge++; if (hasListener && !listener.listen(exp, qEdge, edge)) { continue; } graph = edge.getGraph(); boolean bmatch = match(qEdge, edge, graphNode, graph, env); - //trace ("I: %s Q: %s E: %s match: %s", qEdge.getEdgeIndex(), qEdge, edge, bmatch); if (matchNBNode) { bmatch &= (qEdge.nbNode() == edge.nbNode()); @@ -1954,7 +1797,6 @@ private int edge(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack } bmatch &= push(p, qEdge, edge, graphNode, graph, n); - if (!bmatch) trace("push success: %s", bmatch); } if (isEvent) { @@ -1987,16 +1829,14 @@ private int edge(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack return backtrack; } - - /** * subquery - * select * where {{select * where {?x p ?y}} . ?y q ?z} + * select * where {{select * where {?x p ?y}} . ?y q ?z} * new eval, new memory, share only sub query select variables - * */ private int query(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) throws SparqlException { - int backtrack = n - 1, evENUM = Event.ENUM; + int backtrack = n - 1; + int evENUM = Event.ENUM; boolean isEvent = hasEvent; Query subQuery = exp.getQuery(); Memory env = getMemory(); @@ -2004,13 +1844,8 @@ private int query(Producer p, Node graphNode, Exp exp, Mappings data, Stack stac // copy current Eval, new stack // bind sub query select nodes in new memory - Eval ev = copy(copyMemory(env, getQuery(), subQuery, null), p, getEvaluator(), subQuery, false); - ev.setDebug(isDebug()); + Eval ev = copy(copyMemory(env, getQuery(), subQuery, null), p, getEvaluator(), subQuery, false); Mappings lMap = ev.eval(graphNode, subQuery, null, selectQueryMappings(data)); - - if (isDebug()) { - logger.info("subquery results size:\n"+ lMap.size()); - } getVisitor().query(this, getGraphNode(graphNode), exp, lMap); getVisitor().finish(lMap); @@ -2038,7 +1873,7 @@ private int query(Producer p, Node graphNode, Exp exp, Mappings data, Stack stac return backtrack; } - + /** * Skip Mappings with null nodeList for subquery and service */ @@ -2055,12 +1890,10 @@ Mappings selectQueryMappings(Mappings data) { } return data; } - - + /** * res is a result of sub query bind the select nodes of sub query into * current memory retrieve outer node that correspond to sub node - * */ private boolean push(Query subQuery, Mapping res, int n) { int k = 0; @@ -2071,10 +1904,10 @@ private boolean push(Query subQuery, Mapping res, int n) { for (Exp exp : subQuery.getSelectFun()) { Node subNode = exp.getNode(); Node node = res.getNode(subNode); - Node outNode; //= query.getNode(subNode); + Node outNode; if (exp.size() == 0) { // store outer node for next time - outNode = qq.getOuterNodeSelf(subNode); //ici + outNode = qq.getOuterNodeSelf(subNode); //ici exp.add(outNode); } else { outNode = exp.get(0).getNode(); @@ -2121,7 +1954,6 @@ private void pop(Query subQuery, Mapping ans) { } } - /** * Store a new result */ @@ -2136,16 +1968,15 @@ private int store(Producer p, Mapping m) throws SparqlException { if (storeResult && store) { Mapping ans = m; if (m == null) { - ans = getMemory().store(getQuery(), p, isSubEval); + ans = getMemory().store(getQuery(), p, isSubEval); } store(ans); } return -1; } - + void store(Mapping ans) { if (ans != null && acceptable(ans)) { - //submit(ans); if (hasEvent) { send(Event.RESULT, ans); } @@ -2195,14 +2026,7 @@ private boolean match(Edge qEdge, Edge edge, Node gNode, Node graphNode, Memory private boolean push(Producer p, Edge qEdge, Edge ent, Node gNode, Node node, int n) { Memory env = getMemory(); - if (!env.push(p, qEdge, ent, n)) { - return false; - } -// if (gNode != null && !env.push(gNode, node, n)) { -// env.pop(qEdge, ent); -// return false; -// } - return true; + return env.push(p, qEdge, ent, n); } private boolean match(Node qNode, Node node, Node gNode, Node graphNode) { @@ -2228,7 +2052,7 @@ private boolean push(Node qNode, Node node, Node gNode, Node graphNode, int n) { return true; } - // for path + // for path private boolean match(Mapping map) { int i = 0; Memory env = getMemory(); @@ -2243,8 +2067,6 @@ private boolean match(Mapping map) { } /** - * ******************************************************** - * * @param el */ public void addResultListener(ResultListener el) { @@ -2273,15 +2095,15 @@ void createManager() { } } + public EventManager getEventManager() { + return manager; + } + public void setEventManager(EventManager man) { manager = man; hasEvent = true; } - public EventManager getEventManager() { - return manager; - } - boolean send(int type, Object obj) { Event e = EventImpl.create(type, obj); return manager.send(e); @@ -2304,36 +2126,41 @@ void set(Stack current) { public Stack getStack() { return current; } - + public SPARQLEngine getSPARQLEngine() { return sparqlEngine; } - public void setSPARQLEngine(SPARQLEngine sparqlEngine) { this.sparqlEngine = sparqlEngine; } - public ProcessVisitor getVisitor() { return visitor; } - public void setVisitor(ProcessVisitor visitor) { this.visitor = visitor; } - public boolean isStop() { return stop; } - public void setStop(boolean stop) { this.stop = stop; } + + + + /* + * ************************************************************************* + * + * Alternative interpreter + * + */ + public void finish() { setStop(true); join.setStop(true); @@ -2341,71 +2168,14 @@ public void finish() { optional.setStop(true); } - public static boolean isPushEdgeMappings() { - return pushEdgeMappings; - } - - public static void setPushEdgeMappings(boolean aPushEdgeMappings) { - pushEdgeMappings = aPushEdgeMappings; - } - - public static boolean isParameterGraphMappings() { - return parameterGraphMappings; - } - - public static void setParameterGraphMappings(boolean aParameterGraphMappings) { - parameterGraphMappings = aParameterGraphMappings; - } - - public static boolean isParameterUnionMappings() { - return parameterUnionMappings; - } - - public static void setParameterUnionMappings(boolean aParameterUnionMappings) { - parameterUnionMappings = aParameterUnionMappings; - } - - public static void setNewMappingsVersion(boolean b) { - setPushEdgeMappings(b); - setParameterGraphMappings(b); - setParameterUnionMappings(b); - } - - public boolean isDebug() { - return debug; - } - - - - - /*************************************************************************** - * - * Alternative interpreter - * - */ - - /** + /** * SPARQL algebra requires kgram to compute BGP exp and return Mappings * List from = query.getFrom(gNode); Mappings map = * p.getMappings(gNode, from, exp, memory); */ Mappings exec(Node gNode, Producer p, Exp exp, Mapping m) throws SparqlException { - if (true) { - List from = query.getFrom(gNode); - Mappings map = p.getMappings(gNode, from, exp, memory); - return map; - } - Stack stack = Stack.create(exp); - set(stack); - if (m != null) { - process(exp, m); - } - eval(p, gNode, stack, 0); - Mappings map = Mappings.create(query); - map.add(results); - memory.start(); - results.clear(); - return map; + List from = query.getFrom(gNode); + return p.getMappings(gNode, from, exp, memory); } void process(Exp exp, Mapping m) { @@ -2423,37 +2193,22 @@ void process(Exp exp, Mapping m) { /** * Evaluate exp with SPARQL Algebra on Mappings, not with Memory stack - * - * */ void process(Node gNode, Producer p, Exp exp) { results = evalSparql.eval(gNode, p, exp); } - - // int eval(Node gNode, Query q, Mappings map) throws SparqlException { -// if (q.isFunctional()) { -// // select xpath() as ?val -// // select unnest(fun()) as ?x -// function(); -// return 0; -// } else { -// return evalExp(gNode, q, q.getBody(), map); -// } -// } - - - + /** * use case: - * + *

* (n) EDGE{?x ?q ?z} (n+1) FILTER{?x = ?y} with BIND {?x := ?y} compiled * as: - * + *

* (n) BIND {?x := ?y} (n+1) EDGE{?x ?q ?z} (n+2) FILTER{?x = ?y} */ private int optBind(Producer p, Node gNode, Exp exp, Stack stack, int n) throws SparqlException { Memory env = getMemory(); - int backtrack = n - 1; + int backtrack; if (exp.isBindCst()) { backtrack = cbind(p, gNode, exp, stack, n); return backtrack; @@ -2511,7 +2266,7 @@ private int cbind(Producer p, Node gNode, Exp exp, Stack stack, int n) throws Sp Node node = prod.getNode(cst.getValue()); if (node != null && prod.isBindable(node)) { // store constant Node into Bind expression - // TODO: + // TODO: // if there are several producers, it is considered // bindable for all producers. This may be a problem. exp.addNode(node); @@ -2545,9 +2300,9 @@ private int cbind(Producer p, Node gNode, Exp exp, Stack stack, int n) throws Sp } /** - * * Exp evaluated as a BGP, get result Mappings, push Mappings and continue * Use case: cache the Mappings + * * @deprecated */ private int bgpAble(Producer p, Node graphNode, Exp exp, Stack stack, int n) throws SparqlException { @@ -2575,6 +2330,7 @@ private int bgpAble(Producer p, Node graphNode, Exp exp, Stack stack, int n) thr * template exp = graph ?shape {?sh sh:path ?p} exp is evaluated once for * each value of ?sh and Mappings are cached successive evaluations of exp * on ?sh get Mappings from cache + * * @deprecated */ Mappings getMappings(Producer p, Node graphNode, Exp exp) throws SparqlException { @@ -2592,7 +2348,7 @@ Mappings getMappings(Producer p, Node graphNode, Exp exp) throws SparqlException } return subEval(p, graphNode, null, exp, exp, null, null, true, false); } - + /** * Draf extension where a Visitor provides Edge iterator */ @@ -2611,9 +2367,7 @@ Iterable produce(Producer p, Node gNode, List from, Edge edge) { } return null; } - - - + @Override @Deprecated public void exec(Exp exp, Environment env, int n) { @@ -2641,8 +2395,4 @@ public void setListener(ResultListener listener) { this.listener = listener; } - public void setProducer(Producer producer) { - this.producer = producer; - } - } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/EvalGraph.java b/src/main/java/fr/inria/corese/core/kgram/core/EvalGraph.java index 34351a20a..80414cc68 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/EvalGraph.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/EvalGraph.java @@ -3,25 +3,25 @@ import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.api.query.Matcher; import fr.inria.corese.core.kgram.api.query.Producer; + import java.util.List; /** - * * @author corby */ public class EvalGraph { - + Eval eval; boolean stop = false; - + EvalGraph(Eval e) { eval = e; } - + void setStop(boolean b) { stop = b; } - + /** * gNode is possible named graphURI stemming from evaluation context * It is not the named graph at stake here @@ -31,7 +31,7 @@ int eval(Producer p, Node gNode, Exp exp, Mappings data, Stack stack, int n) thr // current named graph URI/VAR Node graphNode = exp.getGraphName(); // URI or value of VAR or null if unbound - Node graph = eval.getNode(p, graphNode); + Node graph = eval.getNode(p, graphNode); Mappings res; if (graph == null) { @@ -49,21 +49,21 @@ int eval(Producer p, Node gNode, Exp exp, Mappings data, Stack stack, int n) thr for (Mapping m : res) { if (stop) { - return eval.STOP; - } - + return Eval.STOP; + } + Node namedGraph = null; if (graphNode.isVariable()) { namedGraph = m.getNode(graphNode); - if (namedGraph != null && ! namedGraph.equals(m.getNamedGraph())) { + if (namedGraph != null && !namedGraph.equals(m.getNamedGraph())) { // graph ?g { s p o optional { o q ?g }} // variable ?g bound by exp not equal to named graph variable ?g continue; } } - + if (env.push(m, n)) { - boolean pop = false; + boolean pop = false; if (env.push(graphNode, m.getNamedGraph())) { pop = true; } else { @@ -86,7 +86,7 @@ int eval(Producer p, Node gNode, Exp exp, Mappings data, Stack stack, int n) thr } /** - * Iterate named graph pattern evaluation on named graph list + * Iterate named graph pattern evaluation on named graph list * named graph list may come from Mappings map from previous statement * OR from the "from named" clause OR from dataset named graph list */ @@ -94,11 +94,10 @@ private Mappings graphNodes(Producer p, Exp exp, Mappings map, int n) throws Spa Memory env = eval.getMemory(); Query qq = eval.getQuery(); Matcher mm = eval.getMatcher(); - int backtrack = n - 1; Node name = exp.getGraphName(); Mappings res = null; Iterable graphNodes = null; - + if (map != null && map.inScope(name)) { // named graph list may come from evaluation context List list = map.aggregate(name); @@ -130,12 +129,11 @@ private Mappings graphNodes(Producer p, Exp exp, Mappings map, int n) throws Spa * Exp exp: graph name { BGP } */ private Mappings graph(Producer p, Node graph, Exp exp, Mappings map, int n) throws SparqlException { - int backtrack = n - 1; boolean external = false; Node graphNode = exp.getGraphName(); Producer np = p; if (graph != null && p.isProducer(graph)) { - // graph ?g { } + // graph ? g { } // named graph in GraphStore np = p.getProducer(graph, eval.getMemory()); np.setGraphNode(graph); // the new gNode @@ -145,39 +143,37 @@ private Mappings graph(Producer p, Node graph, Exp exp, Mappings map, int n) thr Exp main = exp; Exp body = exp.rest(); Mappings res; - Node var = null, target = null; - + Node varNode = null; + Node target = null; + if (external) { if (graphNode.isVariable() && graph.getDatatypeValue().isExtension()) { - var = graphNode; + varNode = graphNode; target = graph; } - } - else { + } else { target = graph; } - + if (eval.isFederate(exp)) { - res = eval.subEval(np, target, var, body, main, map, null, false, external); - } - else { + res = eval.subEval(np, target, varNode, body, main, map, null, false, external); + } else { Exp ee = body; - Mappings data = null; - - if (graph.getPath() == null) { + Mappings data = null; + + if (graph != null && graph.getPath() == null) { // not a path pointer if (Eval.isParameterGraphMappings()) { // eval graph body with parameter map // pro: if body is optional, eval it with parameter map data = map; - } - else { + } else { // eval graph body with values(map) ee = body.complete(map); } } - - res = eval.subEval(np, target, var, ee, main, data, null, false, external); + + res = eval.subEval(np, target, varNode, ee, main, data, null, false, external); } res.setNamedGraph(graph); @@ -185,5 +181,5 @@ private Mappings graph(Producer p, Node graph, Exp exp, Mappings map, int n) thr return res; } - + } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/EvalJoin.java b/src/main/java/fr/inria/corese/core/kgram/core/EvalJoin.java index a0e1a8d95..a7c91fded 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/EvalJoin.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/EvalJoin.java @@ -2,44 +2,35 @@ import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.api.query.Producer; + import static fr.inria.corese.core.kgram.core.Eval.STOP; -import java.util.Date; -import static fr.inria.corese.core.kgram.core.Eval.DISPLAY_RESULT_MAX; /** - * * @author corby */ public class EvalJoin { public static boolean SORT_OVERLOAD = true; - public static boolean DEBUG_JOIN = false; Eval eval; boolean stop = false; - boolean debug = DEBUG_JOIN; - + EvalJoin(Eval eval) { this.eval = eval; } - + void setStop(boolean b) { stop = b; } - + Query getQuery() { return eval.getMemory().getQuery(); } - - /** + + /** * JOIN(e1, e2) Eval e1, eval e2, generate all joins that are compatible in * cartesian product */ int eval(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) throws SparqlException { - if (debug) { - if (data!=null) { - System.out.println("join 1st with data:\n" + data); - } - } int backtrack = n - 1; Memory env = eval.getMemory(); Mappings map1 = eval.subEval(p, graphNode, graphNode, exp.first(), exp, data); @@ -47,8 +38,7 @@ int eval(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) eval.getVisitor().join(eval, eval.getGraphNode(graphNode), exp, map1, map1); return backtrack; } - Date d1 = new Date(); - Mappings map1Extended = map1; + Mappings map1Extended = map1; if (data != null && isFirstWithValuesOnly(exp)) { // use case: join(values ?s { }, service ?s { }) // where values specify endpoint URL for service and @@ -58,18 +48,14 @@ int eval(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) map1Extended = map1.join(data); } - Date d2 = new Date(); if (stop) { return STOP; } - + MappingSet set1 = new MappingSet(getQuery(), map1Extended); Mappings joinMappings = null; if (eval.isJoinMappings()) { joinMappings = set1.prepareMappingsRest(exp.rest()); - if (debug) { - System.out.println("join 2nd with data:\n" + joinMappings); - } } Mappings map2 = eval.subEval(p, graphNode, graphNode, exp.rest(), exp, joinMappings); @@ -78,16 +64,9 @@ int eval(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) if (map2.size() == 0) { return backtrack; } - if (eval.isDebug()) { - System.out.println("join map1:\n" + - map1.toString(false, false, DISPLAY_RESULT_MAX)); - System.out.println("join map2:\n" + - map2.toString(false, false, DISPLAY_RESULT_MAX)); - } - + return join(p, graphNode, stack, env, map1, map2, n); } - int join(Producer p, Node graphNode, Stack stack, Memory env, Mappings map1, Mappings map2, int n) throws SparqlException { @@ -98,16 +77,15 @@ int join(Producer p, Node graphNode, Stack stack, Memory env, Mappings map1, Map return joinWithCommonVariable(commonVariable, p, graphNode, stack, env, map1, map2, n); } } - + /** * Try to find common variable var in both mappings * if any: sort second map wrt var - * iterate first map, find occurrence of same value of var by dichotomy in second map + * iterate first map, find occurrence of same value of var by dichotomy in second map * map1 and map2 share commonVariable * sort map2 on commonVariable * enumerate map1 * retrieve the index of value of commonVariable in map2 by dichotomy - * */ int joinWithCommonVariable(Node commonVariable, Producer p, Node graphNode, Stack stack, Memory env, Mappings map1, Mappings map2, int n) throws SparqlException { int backtrack = n - 1; @@ -116,17 +94,12 @@ int joinWithCommonVariable(Node commonVariable, Producer p, Node graphNode, Stac map1 = map2; map2 = tmp; } - if (debug) { - System.out.println("join:"); - System.out.println(map1); - System.out.println(map2); - } if (SORT_OVERLOAD) { // setEval enable node comparison overload by Visitor compare() for extended datatypes map2.setEval(eval); } map2.sort(commonVariable); - + for (Mapping m1 : map1) { if (stop) { return STOP; @@ -142,9 +115,6 @@ int joinWithCommonVariable(Node commonVariable, Producer p, Node graphNode, Stac return STOP; } if (env.push(m2, n)) { - if (debug) { - System.out.println("join 1:\n" + m1 + "\n" + m2); - } backtrack = eval.eval(p, graphNode, stack, n + 1); env.pop(m2); if (backtrack < n) { @@ -179,14 +149,11 @@ int joinWithCommonVariable(Node commonVariable, Producer p, Node graphNode, Stac // get value of var in map2 Mapping m2 = map2.get(i); Node n2 = m2.getNode(commonVariable); - - if (n2 == null || !n1.match(n2)) { + + if (n2 == null || !n1.match(n2)) { // map2 is sorted, if n1 != n2 we can exit the loop break; } else if (env.push(m2, n)) { - if (debug) { - System.out.println("join 2:\n" + m1 + "\n" + m2); - } backtrack = eval.eval(p, graphNode, stack, n + 1); env.pop(m2); if (backtrack < n) { @@ -231,142 +198,12 @@ int joinWithoutCommonVariable(Producer p, Node graphNode, Stack stack, Memory en } return backtrack; } - - - + + // use case: join(and(values ?s { }), service ?s { }) boolean isFirstWithValuesOnly(Exp exp) { Exp fst = exp.first(); - return fst.isBGPAnd() && fst.size() == 1 && fst.get(0).isValues() ; - } - - // int eval2(Producer p, Node gNode, Exp exp, Mappings data, Stack stack, int n) throws SparqlException { -// int backtrack = n - 1; -// Memory env = eval.getMemory(); -// Mappings map1 = eval.subEval(p, gNode, gNode, exp.first(), exp, data); -// if (map1.size() == 0) { -// eval.getVisitor().join(eval, eval.getGraphNode(gNode), exp, map1, map1); -// return backtrack; -// } -// Date d1 = new Date(); -// Mappings map1Extended = map1; -// if (data != null && isFirstWithValuesOnly(exp)) { -// // use case: join(values ?s { }, service ?s { }) -// // where values specify endpoint URL for service and -// // previous data contains relevant bindings for service in rest -// // let's give a chance to pass relevant data to rest (service) -// // although there is values in between -// map1Extended = map1.join(data); -// } -// -// Date d2 = new Date(); -// if (stop) { -// return STOP; -// } -// -// MappingSet set1 = new MappingSet(getQuery(), map1Extended); -// Exp rest = set1.prepareRest(exp); -// Mappings map2 = eval.subEval(p, gNode, gNode, rest, exp, set1.getJoinMappings()); -// -// eval.getVisitor().join(eval, eval.getGraphNode(gNode), exp, map1, map2); -// -// if (map2.size() == 0) { -// return backtrack; -// } -// -// return join(p, gNode, stack, env, map1, map2, n); -// } - - @Deprecated - private int join(Producer p, Node graphNode, Exp exp, Mappings map1, Mappings map2, Stack stack, int n) throws SparqlException { - int backtrack = n - 1; - Memory env = eval.getMemory(); - Node qn1 = null, qn2 = null; - - for (int j = n + 1; j < stack.size(); j++) { - // check if next exp is filter (?x = ?y) - // where ?x in map1 and ?y in map2 - Exp e = stack.get(j); - - if (!e.isFilter()) { - break; - } else if (e.size() == 1 && e.get(0).isBindVar()) { - // b = BIND(?x, ?y) - Exp b = e.get(0); - qn1 = b.get(0).getNode(); - qn2 = b.get(1).getNode(); - - // Do the mappings bind variables ?x and ?y respectively ? - if ((map1.get(0).getNode(qn1) != null && map2.get(0).getNode(qn2) != null)) { - // ok do nothing - break; - } else if ((map1.get(0).getNode(qn2) != null && map2.get(0).getNode(qn1) != null)) { - // ok switch variables: qn1 for map1 etc. - Node tmp = qn2; - qn2 = qn1; - qn1 = tmp; - break; - } else { - // Mappings do not bind variables - qn2 = null; - } - } - } - - if (qn1 != null && qn2 != null) { - // sort map2 Mappings according to value of ?y - // in order to perform dichotomy with ?x = ?y - // ?x in map1, ?y in map2 - map2.sort(eval, qn2); - - // exploit dichotomy for ?x = ?y - for (Mapping m1 : map1) { - if (stop) { - return STOP; - } - Node n1 = m1.getNode(qn1); - if (n1 != null) { - - if (env.push(m1, n)) { - - // index of ?y in map2 - int nn = map2.find(n1, qn2); - - if (nn >= 0 && nn < map2.size()) { - - for (int i = nn; i < map2.size(); i++) { - if (stop) { - return STOP; - } - // enumerate occurrences of ?y in map2 - Mapping m2 = map2.get(i); - Node n2 = m2.getNode(qn2); - if (n2 == null || !n1.match(n2)) { - // as map2 is sorted, if ?x != ?y we can exit the loop - break; - } else if (env.push(m2, n)) { - backtrack = eval.eval(p, graphNode, stack, n + 1); - env.pop(m2); - if (backtrack < n) { - return backtrack; - } - } - } - - } - - env.pop(m1); - } else { - } - } - } - } -// else { -// backtrack = joinWithCommonVariable(p, graphNode, stack, env, map1, map2, n); -// } - return backtrack; + return fst.isBGPAnd() && fst.size() == 1 && fst.get(0).isValues(); } - - } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/EvalOptional.java b/src/main/java/fr/inria/corese/core/kgram/core/EvalOptional.java index aa42fb636..8ecd88a1d 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/EvalOptional.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/EvalOptional.java @@ -3,14 +3,21 @@ import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.api.query.Environment; import fr.inria.corese.core.kgram.api.query.Producer; + import static fr.inria.corese.core.kgram.core.Eval.STOP; /** - * * @author corby */ public class EvalOptional { + Eval eval; + private boolean stop = false; + + EvalOptional(Eval e) { + eval = e; + } + /** * @return the stop */ @@ -25,15 +32,7 @@ public void setStop(boolean stop) { this.stop = stop; } - private boolean stop = false; - Eval eval; - - EvalOptional(Eval e) { - eval = e; - } - /** - * * A optional B Filter F map1 = eval(A) ; map2 = eval(values Vb { * distinct(map1/Vb) } B) Vb = variables in-subscope in B, ie in-scope * except in right arg of an optional in B for m1 in map1: for m2 in map2: @@ -42,7 +41,6 @@ public void setStop(boolean stop) { */ int eval(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) throws SparqlException { int backtrack = n - 1; - boolean hasGraph = graphNode != null; Memory env = eval.getMemory(); Node queryNode = null; @@ -60,7 +58,7 @@ int eval(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) Mappings map = set1.prepareMappingsRest(rest); if (map != null && exp.getInscopeFilter() != null) { - /** + /* * Use case: BGP1 optional { filter(exp) BGP2} all var in * exp.getVariables() are inscope(BGP1, BGP2) and are bound in * Mappings map => select Mapping m in map where filter (exp) @@ -72,7 +70,7 @@ int eval(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) map = nmap; } - /** + /* * Push bindings from map1 into rest when there is at least one variable * in-subscope of rest that is always bound in map1 ?x p ?y optional { * ?y q ?z } -> values ?y { y1 yn } {?x p ?y optional { ?y q ?z }} @@ -85,20 +83,15 @@ int eval(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) */ if (map != null && map.isEmpty()) { // Every Mapping fail filter, rest() will always fail: skip optional rest() - if (env.getQuery().isDebug()) { - trace(exp); - } map2 = Mappings.create(env.getQuery()); } else { - //rest = set1.getRest(exp, map); - map2 = eval.subEval(p, graphNode, queryNode, rest, exp, map); //set1.getJoinMappings()); + map2 = eval.subEval(p, graphNode, queryNode, rest, exp, map); } eval.getVisitor().optional(eval, eval.getGraphNode(graphNode), exp, map1, map2); MappingSet set = new MappingSet(getQuery(), exp, set1, new MappingSet(getQuery(), map2)); - set.setDebug(env.getQuery().isDebug()); set.start(); for (Mapping m1 : map1) { @@ -128,13 +121,11 @@ int eval(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) } } - if (nbsuc == 0) { - if (env.push(m1, n)) { - backtrack = eval.eval(p, graphNode, stack, n + 1); - env.pop(m1); - if (backtrack < n) { - return backtrack; - } + if ((nbsuc == 0) && (env.push(m1, n))) { + backtrack = eval.eval(p, graphNode, stack, n + 1); + env.pop(m1); + if (backtrack < n) { + return backtrack; } } } @@ -142,13 +133,6 @@ int eval(Producer p, Node graphNode, Exp exp, Mappings data, Stack stack, int n) return backtrack; } - void trace(Exp exp) { - Eval.logger.info("Optional: candidate Mappings fail filter:"); - Eval.logger.info(exp.getInscopeFilter().toString()); - Eval.logger.info("Skip optional part:"); - Eval.logger.info(exp.toString()); - } - /** * Remove Mapping that fail in-scope filter Use case: BGP1 optional { * filter(var) BGP2 } var memberOf in-scope(BGP1, BGP2) Mappings map = eval @@ -156,21 +140,16 @@ void trace(Exp exp) { * Mapping m from map before binding BGP2 with map */ Mappings filter(Node gNode, Exp exp, Environment memory, Producer p, Mappings map) throws SparqlException { - if (memory.getQuery().isDebug()) { - System.out.println("filter inscope: " + exp.getInscopeFilter()); - } - for (int i = 0; i < map.size();) { + for (int i = 0; i < map.size(); ) { Mapping m = map.get(i); m.setQuery(memory.getQuery()); m.setMap(memory.getMap()); m.setBind(memory.getBind()); - //m.setGraphNode(gNode); m.setEval(eval); boolean suc = true; for (Exp ft : exp.getInscopeFilter()) { boolean b = eval.test(gNode, ft.getFilter(), m, p); - //m.setGraphNode(null); if (!b) { suc = false; break; @@ -183,13 +162,11 @@ Mappings filter(Node gNode, Exp exp, Environment memory, Producer p, Mappings ma map.remove(i); } } - if (memory.getQuery().isDebug()) { - System.out.println("filter mappings:\n" + map); - } return map; } /** + * */ boolean filter(Environment memory, Producer p, Node queryNode, Node gNode, Mapping map, Exp exp) throws SparqlException { if (exp.isPostpone()) { @@ -199,10 +176,8 @@ boolean filter(Environment memory, Producer p, Node queryNode, Node gNode, Mappi map.setQuery(memory.getQuery()); map.setMap(memory.getMap()); map.setBind(memory.getBind()); - //map.setGraphNode(gNode); map.setEval(eval); boolean b = eval.test(gNode, f.getFilter(), map, p); - //map.setGraphNode(null); if (eval.hasFilter) { b = eval.getVisitor().filter(eval, gNode, f.getFilter().getExp(), b); } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/EvalSPARQL.java b/src/main/java/fr/inria/corese/core/kgram/core/EvalSPARQL.java index 59c7ad390..50852cdf1 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/EvalSPARQL.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/EvalSPARQL.java @@ -2,67 +2,68 @@ import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.api.query.Producer; +import fr.inria.corese.core.sparql.api.IDatatype; + import java.util.HashMap; /** * SPARQL Statements implemented as SPARQL Algebra on Mappings * Alternative interpreter not used - * - * @author Olivier Corby, Wimmics INRIA I3S, 2016 * + * @author Olivier Corby, Wimmics INRIA I3S, 2016 */ public class EvalSPARQL { - + Eval eval; Query query; - private boolean debug = false; - - EvalSPARQL(Query q, Eval e){ + + EvalSPARQL(Query q, Eval e) { eval = e; query = q; - debug = q.isDebug(); } - - Mappings eval(Node graph, Producer p, Exp exp){ + + Mappings eval(Node graph, Producer p, Exp exp) { return eval(graph, p, exp, null); } - - Mappings eval(Node graph, Producer p, Exp exp, Mapping m){ + + Mappings eval(Node graph, Producer p, Exp exp, Mapping m) { Mappings map; - if (debug){ - System.out.println("SPARQL: " + exp); - System.out.println(m); - System.out.println(); - } - switch (exp.type()){ - - case Exp.BGP: map = bgp(graph, p, exp, m); break; - - case Exp.JOIN: map = join(graph, p, exp, m); break; - - case Exp.UNION: map = union(graph, p, exp, m); break; - - case Exp.MINUS: map = minus(graph, p, exp, m); break; - - case Exp.OPTIONAL: map = optional(graph, p, exp, m); break; - - case Exp.GRAPH: map = graph(graph, p, exp, m); break; - - default: map = Mappings.create(query); - - } - - if (debug){ - System.out.println("Result: " + map.size()); - System.out.println(map); + switch (exp.type()) { + + case BGP: + map = bgp(graph, p, exp, m); + break; + + case JOIN: + map = join(graph, p, exp, m); + break; + + case UNION: + map = union(graph, p, exp, m); + break; + + case MINUS: + map = minus(graph, p, exp, m); + break; + + case OPTIONAL: + map = optional(graph, p, exp, m); + break; + + case GRAPH: + map = graph(graph, p, exp, m); + break; + + default: + map = Mappings.create(query); + } - + return map; } - - + Mappings join(Node graph, Producer p, Exp exp, Mapping m) { Mappings m1 = eval(graph, p, exp.first(), m); if (exp.rest().isBGPFilter()) { @@ -72,187 +73,169 @@ Mappings join(Node graph, Producer p, Exp exp, Mapping m) { return join(m1, m2); } } - - Mappings join(Mappings map1, Mappings map2){ - if (map1.size() == 0){ + + Mappings join(Mappings map1, Mappings map2) { + if (map1.size() == 0) { return map1; } - if (map2.size() == 0){ + if (map2.size() == 0) { return map2; } - + Mapping m1 = map1.get(0); Mapping m2 = map2.get(0); - + // common variable Node cmn = m1.getCommonNode(m2); - - if (cmn == null){ + + if (cmn == null) { return map1.joiner(map2); } - + // sort map2 according to common variable, null value first map2.sort(eval, cmn); - return map1.joiner(map2, cmn); + return map1.joiner(map2, cmn); } - - - - Mappings graph(Node graph, Producer p, Exp exp, Mapping m){ - return bgp(exp.getGraphName(), p, exp.rest(), m); + + Mappings graph(Node graph, Producer p, Exp exp, Mapping m) { + return bgp(exp.getGraphName(), p, exp.rest(), m); } - - Mappings optional(Node graph, Producer p, Exp exp, Mapping mm){ - Mappings m1 = bgp(graph, p, exp.first(), mm); - Mappings m2 = bgp(graph, p, exp.rest()); - Mappings res = Mappings.create(query); - HashMap hm = new HashMap(); - - for (Mapping ma : m1){ - int nbsuc = 0; - for (Mapping mb : m2){ - boolean success = false; - Mapping m = ma.merge(mb); - if (m != null){ - success = true; - if (exp.isPostpone()){ - m.setQuery(query); - m.setMap(hm); - hm.clear(); - if (! postpone(graph, exp, m, p)){ - success = false; - } - } - if (success){ - res.add(m); - nbsuc++; - } - } - } - - if (nbsuc == 0){ - res.add(ma); - } - } - return res; + + Mappings optional(Node graph, Producer p, Exp exp, Mapping mm) { + Mappings m1 = bgp(graph, p, exp.first(), mm); + Mappings m2 = bgp(graph, p, exp.rest()); + Mappings res = Mappings.create(query); + HashMap hm = new HashMap<>(); + + for (Mapping ma : m1) { + int nbsuc = 0; + for (Mapping mb : m2) { + boolean success = false; + Mapping m = ma.merge(mb); + if (m != null) { + success = true; + if (exp.isPostpone()) { + m.setQuery(query); + m.setMap(hm); + hm.clear(); + if (!postpone(graph, exp, m, p)) { + success = false; + } + } + if (success) { + res.add(m); + nbsuc++; + } + } + } + + if (nbsuc == 0) { + res.add(ma); + } + } + return res; } - - boolean postpone(Node gNode, Exp exp, Mapping m, Producer p){ - for (Exp e : exp.getPostpone()){ + + boolean postpone(Node gNode, Exp exp, Mapping m, Producer p) { + for (Exp e : exp.getPostpone()) { try { - if (! eval.test(gNode, e.getFilter(), m, p)){ + if (!eval.test(gNode, e.getFilter(), m, p)) { return false; } } catch (SparqlException ex) { - return false; + return false; } } return true; } - - - Mappings optional2(Node graph, Producer p, Exp exp, Mapping mm){ - Mappings m1 = bgp(graph, p, exp.first(), mm); - Mappings res = Mappings.create(query); - for (Mapping m : m1){ - Mappings m2 = bgp(graph, p, exp.rest(), m); - if (m2.size() == 0){ - res.add(m); - } - else { - res.add(m2); - } - } - return res; - } - - Mappings minus(Node graph, Producer p, Exp exp, Mapping mm){ + + + Mappings minus(Node graph, Producer p, Exp exp, Mapping mm) { Mappings m1 = bgp(graph, p, exp.first(), mm); Mappings m2 = bgp(graph, p, exp.rest()); Mappings res = Mappings.create(m1.getQuery()); - + for (Mapping m : m1) { boolean ok = true; - - for (Mapping minus : m2) { + + for (Mapping minus : m2) { if (m.compatible(minus)) { ok = false; break; } } - + if (ok) { res.add(m); } } return res; } - - - Mappings union(Node graph, Producer p, Exp exp, Mapping m){ + + + Mappings union(Node graph, Producer p, Exp exp, Mapping m) { Mappings m1 = bgp(graph, p, exp.first(), m); Mappings m2 = bgp(graph, p, exp.rest(), m); Mappings res = m1.union(m2); res.setQuery(m1.getQuery()); return res; } - - Mappings bgp(Node graph, Producer p, Exp exp){ + + Mappings bgp(Node graph, Producer p, Exp exp) { return bgp(graph, p, exp, null); } - + Mappings bgp(Node graph, Producer p, Exp exp, Mapping m) { - if (exp.size() == 1){ + if (exp.size() == 1) { Exp body = exp.get(0); if (body.isBGP()) { return bgp(graph, p, body, m); - } - else if (body.isStatement() && ! body.isQuery()){ + } else if (body.isStatement() && !body.isQuery()) { return eval(graph, p, body, m); } - } + } return basic(graph, p, exp, m); } - + Mappings basic(Node graph, Producer p, Exp exp, Mapping m) { - exp.setType(Exp.AND); - Mappings map =null; + exp.setType(Exp.Type.AND); + Mappings map = null; try { map = eval.exec(graph, p, exp, m); } catch (SparqlException ex) { ex.printStackTrace(); } - exp.setType(Exp.BGP); + exp.setType(Exp.Type.BGP); return map; } private Mappings filter(Producer p, Exp exp, Mappings map) { Mappings res = Mappings.create(map.getQuery()); - HashMap bnode = new HashMap(); - for (Mapping m : map){ + HashMap bnode = new HashMap<>(); + for (Mapping m : map) { m.setMap(bnode); bnode.clear(); m.setQuery(map.getQuery()); - if (test(p, exp, m)){ + if (test(p, exp, m)) { res.add(m); } } return res; } - - private boolean test(Producer p, Exp exp, Mapping m){ - for (Exp f : exp){ + + private boolean test(Producer p, Exp exp, Mapping m) { + for (Exp f : exp) { try { - if (! eval.test(null, f.getFilter(), m, p)){ + if (!eval.test(null, f.getFilter(), m, p)) { return false; } } catch (SparqlException ex) { - return false; + return false; } } return true; } - + } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/Exp.java b/src/main/java/fr/inria/corese/core/kgram/core/Exp.java index 3aae71544..2d44374a1 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/Exp.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/Exp.java @@ -1,71 +1,52 @@ package fr.inria.corese.core.kgram.core; +import fr.inria.corese.core.kgram.api.core.*; +import fr.inria.corese.core.kgram.api.query.Producer; +import fr.inria.corese.core.sparql.triple.parser.Expression; + import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; -import fr.inria.corese.core.kgram.api.core.Edge; -import fr.inria.corese.core.kgram.api.core.ExpPattern; -import fr.inria.corese.core.kgram.api.core.ExpType; -import fr.inria.corese.core.kgram.api.core.Expr; -import fr.inria.corese.core.kgram.api.core.ExprType; -import fr.inria.corese.core.kgram.api.core.Filter; -import fr.inria.corese.core.kgram.api.core.Node; -import fr.inria.corese.core.kgram.api.core.PointerType; import static fr.inria.corese.core.kgram.api.core.PointerType.STATEMENT; -import fr.inria.corese.core.kgram.api.core.Regex; -import fr.inria.corese.core.kgram.api.query.Producer; -import fr.inria.corese.core.sparql.triple.parser.Expression; -import java.util.HashMap; /** * KGRAM/SPARQL expressions: bgp, union, optional, etc. * * @author Olivier Corby, Edelweiss, INRIA 2010 - * */ public class Exp extends PointerObject implements ExpType, ExpPattern, Iterable { - - public static final int ANY = -1; - public static final int SUBJECT = 0; - public static final int OBJECT = 1; - public static final int PREDICATE = 2; + + public static final int ANY = -1; + public static final int SUBJECT = 0; + public static final int OBJECT = 1; + public static final int PREDICATE = 2; public static final int GRAPH_NAME = 3; - public static boolean DEBUG_DEFAULT = false; - + static final String NL = "\n"; static final String SP = " "; - static Exp empty = new Exp(EMPTY); // group edge even if there is a disconnected filter public static boolean groupEdge = true; - int type, index = -1; + static Exp empty = new Exp(Type.EMPTY); + Type type; + int index = -1; // optional success boolean // default status must be false (for order by desc()) - status = false, - // for WATCH: skip exp if reach CONTINUE/BACKJUMP - skip, - isFail = false, - isPath = false, - isFree = false, - isAggregate = false, - isBGP = false, - isSilent = false; - boolean isDebug = DEBUG_DEFAULT; - private boolean isPostpone = false; - private boolean BGPAble = false; - private boolean isFunctional = false; - private boolean generated = false; + status = false; + boolean skip; + boolean isFail = false; + boolean isPath = false; + boolean isFree = false; + boolean isAggregate = false; + boolean isBGP = false; + boolean isSilent = false; VExp args; Edge edge; Node node; - private Node arg; List lNodes; - // service with several URI: - private List nodeSet, - // in-scope variables except those that are only in right arg of optional - simpleNodeList; // Filter api refer to sparql.triple.parser.Expression Filter filter; List lFilter; @@ -73,20 +54,30 @@ public class Exp extends PointerObject List expGroupBy; // for UNION Stack stack; - // for EXTERN + // for EXTERN Object object; Producer producer; Regex regex; Exp next; + Mappings map; + Mappings templateMap; + HashMap cache; + int min = -1; + int max = -1; + private boolean isPostpone = false; + private boolean BGPAble = false; + private boolean isFunctional = false; + private boolean generated = false; + private Node arg; + // service with several URI: + private List nodeSet; + private List simpleNodeList; private Exp postpone; private List inscopeFilter; private Exp path; private Exp bind; private Exp values; private Query externQuery; - Mappings map, templateMap; - HashMap cache; - int min = -1, max = -1; private int level = -1; // service number private int number = -1; @@ -94,27 +85,78 @@ public class Exp extends PointerObject private boolean isSystem = false; private boolean mappings = false; - - public Exp getBind() { - return bind; + + Exp(Type t) { + type = t; + args = new VExp(); + lFilter = new ArrayList<>(); } - - public void setBind(Exp bind) { - this.bind = bind; + public static Exp create(Type t) { + if (t == Type.PATH || t == Type.EDGE) { + return new ExpEdge(t); + } + return new Exp(t); + } + + public static Exp create(Type t, Exp e1, Exp e2) { + Exp e = create(t); + e.add(e1); + e.add(e2); + return e; + } + + public static Exp create(Type t, Exp e1, Exp e2, Exp e3) { + Exp e = create(t); + e.add(e1); + e.add(e2); + e.add(e3); + return e; + } + + public static Exp create(Type t, Exp e1) { + Exp e = create(t); + e.add(e1); + return e; + } + + public static Exp create(Type t, Node n) { + Exp exp = create(t); + exp.setNode(n); + return exp; + } + + public static Exp create(Type t, Edge e) { + Exp exp = create(t); + exp.setEdge(e); + return exp; + } + + public static Exp create(Type t, Filter e) { + Exp exp = create(t); + exp.setFilter(e); + return exp; + } + + public static Exp createValues(List list, Mappings map) { + Exp exp = create(Type.VALUES); + exp.setNodeList(list); + exp.setMappings(map); + return exp; + } + + public Exp getBind() { + return bind; } - public boolean isFunctional() { return isFunctional; } - public void setFunctional(boolean isFunctional) { this.isFunctional = isFunctional; } - public Exp getPath() { return path; } @@ -123,43 +165,34 @@ public boolean hasPath() { return path != null; } - - public void setPath(Exp path) { - this.path = path; + public boolean isSystem() { + return isSystem; } public void setSystem(boolean b) { isSystem = b; } - public boolean isSystem() { - return isSystem; - } - - public int getLevel() { return level; } - public void setLevel(int level) { this.level = level; } public boolean isBGP() { - return type == BGP; + return type == Type.BGP; } public boolean isBGPAnd() { - return type == AND || type == BGP; + return type == Type.AND || type == Type.BGP; } - public boolean isBGPAble() { return BGPAble; } - public void setBGPAble(boolean BGPAble) { this.BGPAble = BGPAble; } @@ -168,105 +201,26 @@ public Node getCacheNode() { return arg; } - public void setCacheNode(Node arg) { this.arg = arg; } - public Exp getValues() { return values; } - - public void setValues(Exp values) { - this.values = values; - } - - public boolean isPostpone() { return isPostpone; } - - public void setPostpone(boolean postpone) { - this.isPostpone = postpone; - } - - - public void setPostpone(Exp postpone) { - this.postpone = postpone; - } - - public List getNodeSet() { return nodeSet; } - public void setNodeSet(List nodeSet) { this.nodeSet = nodeSet; } - class VExp extends ArrayList { - } - - Exp() { - } - - Exp(int t) { - type = t; - args = new VExp(); - lFilter = new ArrayList(); - } - - public static Exp create(int t) { - switch (t){ - case PATH: - case EDGE: return new ExpEdge(t); - } - return new Exp(t); - } - - public static Exp create(int t, Exp e1, Exp e2) { - Exp e = create(t); - e.add(e1); - e.add(e2); - return e; - } - - public static Exp create(int t, Exp e1, Exp e2, Exp e3) { - Exp e = create(t); - e.add(e1); - e.add(e2); - e.add(e3); - return e; - } - - public static Exp create(int t, Exp e1) { - Exp e = create(t); - e.add(e1); - return e; - } - - public static Exp create(int t, Node n) { - Exp exp = create(t); - exp.setNode(n); - return exp; - } - - public static Exp create(int t, Edge e) { - Exp exp = create(t); - exp.setEdge(e); - return exp; - } - - public static Exp create(int t, Filter e) { - Exp exp = create(t); - exp.setFilter(e); - return exp; - } - // draft for BGP public Exp duplicate() { Exp exp = Exp.create(type()); @@ -275,16 +229,9 @@ public Exp duplicate() { } return exp; } - - public static Exp createValues(List list, Mappings map){ - Exp exp = create(VALUES); - exp.setNodeList(list); - exp.setMappings(map); - return exp; - } public boolean hasArg() { - return args.size() > 0; + return !args.isEmpty(); } @Override @@ -297,15 +244,15 @@ public void add(Exp e) { } public void add(Edge e) { - args.add(create(EDGE, e)); + args.add(create(Type.EDGE, e)); } public void add(Node n) { - args.add(create(NODE, n)); + args.add(create(Type.NODE, n)); } public void add(Filter f) { - args.add(create(FILTER, f)); + args.add(create(Type.FILTER, f)); } public void set(int n, Exp e) { @@ -318,7 +265,7 @@ public Query getQuery() { } public void insert(Exp e) { - if (type() == AND && e.type() == AND) { + if (type() == Type.AND && e.type() == Type.AND) { for (Exp ee : e) { insert(ee); } @@ -327,8 +274,6 @@ public void insert(Exp e) { } } - - public void add(int n, Exp e) { args.add(n, e); } @@ -340,28 +285,28 @@ public boolean remove(Exp e) { public Exp remove(int n) { return args.remove(n); } - + @Override - public String toString() { + public String toString() { StringBuilder sb = new StringBuilder(); toString(sb); return sb.toString(); } - + public StringBuilder toString(StringBuilder sb) { return toString(sb, 0); } - + StringBuilder toString(StringBuilder sb, int n) { sb.append(title()).append(SP); - if (type() == VALUES) { + if (type() == Type.VALUES) { sb.append(getNodeList()); sb.append(SP); } - + sb.append("{"); - + if (edge != null) { sb.append(edge); if (size() > 0) { @@ -384,13 +329,13 @@ StringBuilder toString(StringBuilder sb, int n) { } } - if (type() == VALUES) { + if (type() == Type.VALUES) { nl(sb, 0); sb.append(getMappings().toString(true)); - } else if (type() == WATCH || type() == CONTINUE || type() == BACKJUMP) { + } else if (type() == Type.WATCH || type() == Type.CONTINUE || type() == Type.BACKJUMP) { // skip because loop } else { - if (isOptional() && isPostpone()){ + if (isOptional() && isPostpone()) { sb.append("POSTPONE "); getPostpone().toString(sb); nl(sb, n); @@ -398,32 +343,32 @@ StringBuilder toString(StringBuilder sb, int n) { int i = 0; for (Exp e : this) { nl(sb, n); - e.toString(sb, n+1).append(SP); + e.toString(sb, n + 1).append(SP); i++; } } - - if (type() == VALUES){ + + if (type() == Type.VALUES) { indent(sb, n); } sb.append("}"); return sb; } - - StringBuilder nl(StringBuilder sb, int n) { - sb.append(NL); - indent(sb, n); - return sb; - } - + + StringBuilder nl(StringBuilder sb, int n) { + sb.append(NL); + indent(sb, n); + return sb; + } + void indent(StringBuilder sb, int n) { for (int i = 0; i < n; i++) { sb.append(SP).append(SP); } } - + String title() { - return TITLE[type]; + return this.type.getTitle(); } public void skip(boolean b) { @@ -442,10 +387,10 @@ public boolean status() { return status; } - public int type() { + public Type type() { return type; } - + public boolean isStatement() { switch (type()) { case BGP: @@ -469,14 +414,14 @@ public int getIndex() { public void setIndex(int n) { index = n; } - - public boolean isBGPFilter(){ - return isBGP() && isOnly(FILTER); + + public boolean isBGPFilter() { + return isBGP() && isOnly(Type.FILTER); } - - boolean isOnly(int type){ - for (Exp exp : this){ - if (exp.type() != type){ + + boolean isOnly(Type type) { + for (Exp exp : this) { + if (exp.type() != type) { return false; } } @@ -484,7 +429,7 @@ boolean isOnly(int type){ } public boolean isFilter() { - return type == FILTER; + return type == Type.FILTER; } public boolean isAggregate() { @@ -504,67 +449,67 @@ public void setSilent(boolean b) { } public boolean isNode() { - return type == NODE; + return type == Type.NODE; } public boolean isEdge() { - return type == EDGE; + return type == Type.EDGE; } - + public boolean isEdgePath() { return isEdge() || isPath(); } public boolean isOption() { - return type == OPTION; + return type == Type.OPTION; } public boolean isOptional() { - return type == OPTIONAL; + return type == Type.OPTIONAL; } public boolean isJoin() { - return type == JOIN; + return type == Type.JOIN; } - + public boolean isAndJoin() { return isJoin() || (isBGPAnd() && size() == 1 && get(0).isJoin()); } - + public boolean isAnd() { - return type == AND; + return type == Type.AND; } - + public boolean isBinary() { return isUnion() || isOptional() || isMinus() || isJoin(); } public boolean isGraph() { - return type == GRAPH; + return type == Type.GRAPH; } public boolean isUnion() { - return type == UNION; + return type == Type.UNION; } - + public boolean isMinus() { - return type == MINUS; + return type == Type.MINUS; } public boolean isQuery() { - return type == QUERY; + return type == Type.QUERY; } - + public boolean isService() { - return type == SERVICE; + return type == Type.SERVICE; } public boolean isAtomic() { - return type == FILTER || type == EDGE || type == NODE - || type == ACCEPT; + return type == Type.FILTER || type == Type.EDGE || type == Type.NODE + || type == Type.ACCEPT; } - public void setType(int n) { + public void setType(Type n) { type = n; } @@ -591,7 +536,7 @@ void getEdgeList(List list) { } public Exp first() { - if (args.size() > 0) { + if (!args.isEmpty()) { return args.get(0); } else { return empty; @@ -607,8 +552,8 @@ public Exp rest() { } public Exp last() { - if (args.size() > 0) { - return args.get(args.size() -1); + if (!args.isEmpty()) { + return args.get(args.size() - 1); } else { return null; } @@ -645,25 +590,17 @@ public Mappings getMappings() { return map; } - public void setMappings(Mappings m) { - map = m; - } - public Mappings getActualMappings() { - if (getValues() == null){ + if (getValues() == null) { return null; } return getValues().getMappings(); } - + public Filter getFilter() { return filter; } - - public Expression getFilterExpression() { - return getFilter().getFilterExpression(); - } - + public void setFilter(Filter f) { filter = f; if (f.isRecAggregate()) { @@ -671,6 +608,10 @@ public void setFilter(Filter f) { } } + public Expression getFilterExpression() { + return getFilter().getFilterExpression(); + } + public void addFilter(Filter f) { lFilter.add(f); } @@ -678,11 +619,11 @@ public void addFilter(Filter f) { public List getFilters() { return lFilter; } - + public List getFilters(int n, int t) { return new ArrayList<>(0); } - + public boolean isHaving() { return getHavingFilter() != null; } @@ -699,14 +640,14 @@ public boolean isExpGroupBy() { return expGroupBy != null; } - public void setExpGroupBy(List l) { - expGroupBy = l; - } - public List getExpGroupBy() { return expGroupBy; } + public void setExpGroupBy(List l) { + expGroupBy = l; + } + public boolean isFail() { return isFail; } @@ -716,25 +657,37 @@ public void setFail(boolean b) { } public boolean isPath() { - return type == PATH; - } - - public boolean isValues() { - return type == VALUES; + return type == Type.PATH; } - - public boolean isBind() { - return type == BIND; + + public void setPath(Exp path) { + this.path = path; } public void setPath(boolean b) { isPath = b; } + public boolean isValues() { + return type == Type.VALUES; + } + + public void setValues(Exp values) { + this.values = values; + } + + public boolean isBind() { + return type == Type.BIND; + } + + public void setBind(Exp bind) { + this.bind = bind; + } + public Node getGraphName() { return first().first().getNode(); } - + public Node getServiceNode() { return first().getNode(); } @@ -771,22 +724,22 @@ public void addNode(Node n) { lNodes.add(n); } + public Object getObject() { + return object; + } + public void setObject(Object o) { object = o; } - public Object getObject() { - return object; + public Producer getProducer() { + return producer; } public void setProducer(Producer p) { producer = p; } - - public Producer getProducer() { - return producer; - } - + public List getObjectValues() { if (object instanceof List) { return (List) object; @@ -795,22 +748,22 @@ public List getObjectValues() { } } - public void setMin(int i) { - min = i; - } - public int getMin() { return min; } - public void setMax(int i) { - max = i; + public void setMin(int i) { + min = i; } public int getMax() { return max; } + public void setMax(int i) { + max = i; + } + public Stack getStack() { return stack; } @@ -826,37 +779,35 @@ public void setStack(Stack st) { * in other words, this is only for main body BGP */ boolean distinct(Node qNode) { - switch (type()) { - case AND: - case BGP: + Type title = type(); + if (title == Type.AND || title == Type.BGP) { + for (int i = 0; i < size(); i++) { + Exp exp = get(i); + switch (exp.type()) { + case EDGE: + case PATH: + case XPATH: + case EVAL: + if (exp.contains(qNode)) { + add(i + 1, Exp.create(Type.ACCEPT, qNode)); + return true; + } + break; - for (int i = 0; i < size(); i++) { - Exp exp = get(i); - switch (exp.type()) { - case EDGE: - case PATH: - case XPATH: - case EVAL: - if (exp.contains(qNode)) { - add(i + 1, Exp.create(ACCEPT, qNode)); - return true; - } - break; - - case AND: - if (exp.distinct(qNode)) { - return true; - } - break; - } + case AND: + if (exp.distinct(qNode)) { + return true; + } + break; } + } } return false; } boolean isSortable() { - return isEdge() || isPath() || isGraph() || type == OPT_BIND; + return isEdge() || isPath() || isGraph() || type == Type.OPT_BIND; } boolean isSimple() { @@ -880,8 +831,8 @@ boolean bind(Mapping map) { } for (int i = 0; i < nbNode(); i++) { - Node node = getNode(i); - if (node.isVariable() && map.getNode(node) != null) { + Node bindNode = getNode(i); + if (bindNode.isVariable() && map.getNode(bindNode) != null) { return true; } } @@ -897,9 +848,7 @@ boolean isGraphPath(Exp e1, Exp e2) { if (e1.isPath() && e2.isGraph()) { Node var1 = e1.getEdge().getEdgeVariable(); Node var2 = e2.getGraphName(); - if (var1 != null && var2.isVariable() && var1.same(var2)) { - return true; - } + return var1 != null && var2.isVariable() && var1.same(var2); } return false; } @@ -915,8 +864,8 @@ public int nBind(List lNode, List lVar, List lBind) { int gCount(List lNode, List lVar, List lBind) { int n = 0; List list = getNodes(); - for (Node node : list) { - n += member(node, lNode, lVar, lBind); + for (Node listNode : list) { + n += member(listNode, lNode, lVar, lBind); } return n; } @@ -959,15 +908,15 @@ boolean member(Node node, List lBind) { void bind(List lNode) { if (isSimple()) { for (int i = 0; i < nbNode(); i++) { - Node node = getNode(i); - if (node != null) { - bind(node, lNode); + Node bindNode = getNode(i); + if (bindNode != null) { + bind(bindNode, lNode); } } } else { List list = getNodes(); - for (Node node : list) { - bind(node, lNode); + for (Node bindNode : list) { + bind(bindNode, lNode); } } } @@ -979,18 +928,17 @@ void bind(Node node, List lNode) { } void addBind(List lVar) { - switch (type()) { - case EDGE: - case PATH: - for (int i = 0; i < nbNode(); i++) { - Node node = getNode(i); - addBind(node, lVar); - } + Type title = type(); + if (title == Type.EDGE || title == Type.PATH) { + for (int i = 0; i < nbNode(); i++) { + Node bindNode = getNode(i); + addBind(bindNode, lVar); + } } } void addBind(Node node, List lVar) { - if (node.isVariable() && ! lVar.contains(node.getLabel())) { + if (node.isVariable() && !lVar.contains(node.getLabel())) { lVar.add(node.getLabel()); } } @@ -1054,11 +1002,10 @@ public boolean contains(Node node) { } /** - * * @param filterVar: variables of a filter - * @param expVar: list of variables bound by expressions Add in expVar the - * variables bound by this expression that are in filterVar bound means no - * optional, no union + * @param expVar: list of variables bound by expressions Add in expVar the + * variables bound by this expression that are in filterVar bound means no + * optional, no union */ public void share(List filterVar, List expVar) { switch (type()) { @@ -1071,18 +1018,19 @@ public void share(List filterVar, List expVar) { break; case OPTIONAL: + case MINUS: first().share(filterVar, expVar); break; case UNION: - // must be bound in both branches + // must be bound in both branches ArrayList lVar1 = new ArrayList<>(); ArrayList lVar2 = new ArrayList<>(); first().share(filterVar, lVar1); rest().share(filterVar, lVar2); - for (String var : lVar1) { - if (lVar2.contains(var) && !expVar.contains(var)) { - expVar.add(var); + for (String varString : lVar1) { + if (lVar2.contains(varString) && !expVar.contains(varString)) { + expVar.add(varString); } } @@ -1101,15 +1049,15 @@ public void share(List filterVar, List expVar) { break; case BIND: - // bind may not bind the variable (in case of error) + // bind may not bind the variable (in case of error) // hence variable cannot be considered as bound for filter break; case EDGE: case PATH: for (int i = 0; i < nbNode(); i++) { - Node node = getNode(i); - share(node, filterVar, expVar); + Node nodePath = getNode(i); + share(nodePath, filterVar, expVar); } break; @@ -1117,10 +1065,6 @@ public void share(List filterVar, List expVar) { share(getNode(), filterVar, expVar); break; - case MINUS: - first().share(filterVar, expVar); - break; - default: for (Exp exp : this) { exp.share(filterVar, expVar); @@ -1139,8 +1083,8 @@ void share(Node node, List fVar, List eVar) { } public boolean bound(List fvec, List evec) { - for (String var : fvec) { - if (!evec.contains(var)) { + for (String varString : fvec) { + if (!evec.contains(varString)) { return false; } } @@ -1173,39 +1117,37 @@ void getNodes(ExpHandler h) { break; case NODE: + //use case: join() check connection, need all variables + case ACCEPT: h.add(getNode()); break; case EDGE: case PATH: - Edge edge = getEdge(); - h.add(edge.getNode(0)); - if (edge.getEdgeVariable() != null) { - h.add(edge.getEdgeVariable()); + Edge pathEdge = getEdge(); + h.add(pathEdge.getNode(0)); + if (pathEdge.getEdgeVariable() != null) { + h.add(pathEdge.getEdgeVariable()); } - h.add(edge.getNode(1)); - - for (int i = 2; i < edge.nbNode(); i++) { - h.add(edge.getNode(i)); + h.add(pathEdge.getNode(1)); + + for (int i = 2; i < pathEdge.nbNode(); i++) { + h.add(pathEdge.getNode(i)); } break; - + case XPATH: case EVAL: for (int i = 0; i < nbNode(); i++) { - Node node = getNode(i); - h.add(node); + Node nodeEval = getNode(i); + h.add(nodeEval); } break; - case ACCEPT: - //use case: join() check connection, need all variables - h.add(getNode()); - break; case VALUES: - for (Node var : getNodeList()) { - h.add(var); + for (Node varNode : getNodeList()) { + h.add(varNode); } break; @@ -1215,58 +1157,57 @@ void getNodes(ExpHandler h) { first().getNodes(h); } break; - + case OPTIONAL: boolean b = h.isOptional(); first().getNodes(h.setOptional(true)); - if (! h.isInSubScope()){ - rest().getNodes(h); + if (!h.isInSubScope()) { + rest().getNodes(h); } h.setOptional(b); break; - - case GRAPH: + + case GRAPH: h.add(getGraphName()); if (size() > 1) { rest().getNodes(h); } break; - + case UNION: if (h.isInSubScope()) { // in-subscope record nodes that are bound in both branches of union - List left = first().getTheNodes(h.copy()); + List left = first().getTheNodes(h.copy()); List right = rest().getTheNodes(h.copy()); - for (Node node : left) { - if (right.contains(node)) { - h.add(node); + for (Node nodeLeft : left) { + if (right.contains(nodeLeft)) { + h.add(nodeLeft); } } - } - else { - for (Exp ee : this) { - ee.getNodes(h); - } + } else { + for (Exp ee : this) { + ee.getNodes(h); + } } break; - + case BIND: if (h.isBind()) { if (getNodeList() == null) { h.add(getNode()); } else { - for (Node node : getNodeList()) { - h.add(node); + for (Node nodeBind : getNodeList()) { + h.add(nodeBind); } } } - + break; - - case QUERY: + + case QUERY: queryNodeList(h); break; - + default: // BGP, service, union, named graph pattern for (Exp ee : this) { @@ -1274,12 +1215,12 @@ void getNodes(ExpHandler h) { if (h.isInSubScopeSample() && ee.isSkipStatement()) { // skip statements after optional/minus/union/.. for in-subscope nodes break; - } + } } } } - + boolean isSkipStatement() { switch (type()) { case JOIN: @@ -1296,27 +1237,26 @@ boolean isSkipStatement() { } } - /** - * complete handler selectList with this query selectList - */ + /** + * complete handler selectList with this query selectList + */ void queryNodeList(ExpHandler h) { - List selectList = h.getSelectNodeList(); - List subSelectList = getQuery().getSelect(); //getSelectNodeList(); - + List selectList = h.getSelectNodeList(); + List subSelectList = getQuery().getSelect(); + if (h.isInSubScope()) { - // focus on left optional etc. in query body + // focus on left optional etc. in query body // because select * includes right optional etc. - //List scopeList = getQuery().getBody().getInScopeNodes(h.isBind()); List scopeList = getQuery().getBody().getTheNodes(h.copy()); - - for (Node node : scopeList) { - if (subSelectList.contains(node)) { - add(selectList, node); + + for (Node nodeScope : scopeList) { + if (subSelectList.contains(nodeScope)) { + add(selectList, nodeScope); } } } else { - for (Node node : subSelectList) { - add(selectList, node); + for (Node nodeSubSelect : subSelectList) { + add(selectList, nodeSubSelect); } } } @@ -1332,29 +1272,24 @@ public Exp getPattern(Expr exp) { * This is a filter get exists{} nodes if any */ void getExistNodes(Expr exp, ExpHandler h, List lExistNode) { - switch (exp.oper()) { - - case ExprType.EXIST: - Exp pat = getPattern(exp); - // @todo: subscope = false|true ? - //List lNode = pat.getTheNodes(new ExpHandler(true, false, h.isBind()).all()); - List lNode = pat.getTheNodes(h.copy()); - for (Node node : lNode) { - add(lExistNode, node); - } - break; - - default: - for (Expr ee : exp.getExpList()) { - getExistNodes(ee, h, lExistNode); - } + if (exp.oper() == ExprType.EXIST) { + Exp pat = getPattern(exp); + // @todo: subscope = false|true ? + List lNode = pat.getTheNodes(h.copy()); + for (Node exprNode : lNode) { + add(lExistNode, exprNode); + } + } else { + for (Expr ee : exp.getExpList()) { + getExistNodes(ee, h, lExistNode); + } } } - + /** * Compute inscope variables for variable binding for MappingSet */ - + public List getRecordInScopeNodes(boolean bind) { if (getInScopeNodeList() == null) { setInScopeNodeList(getInScopeNodes(bind)); @@ -1373,30 +1308,29 @@ public List getRecordInScopeNodesWithoutBind() { public List getRecordInScopeNodesForService() { return getRecordInScopeNodesWithoutBind(); } - - + /** * in subscope + bind - * setAll(true) ::= for all exp in this exp + * setAll(true) ::= for all exp in this exp */ public List getAllInScopeNodes() { return getTheNodes(handler(true, true).all()); } - + /** * in scope + bind */ public List getNodes() { return getTheNodes(handler(false, true).sample()); } - + /** * in subscope + bind */ public List getInScopeNodes() { return getTheNodes(handler(true, true).sample()); } - + // in subscope with/without bind List getInScopeNodes(boolean bind) { return getTheNodes(handler(true, bind).sample()); @@ -1405,8 +1339,8 @@ List getInScopeNodes(boolean bind) { public List getAllNodes() { return getTheNodes(handler(false, true).setBlank(true).sample()); } - - public List getTheNodes(ExpHandler h){ + + public List getTheNodes(ExpHandler h) { getNodes(h); return h.getNodes(); } @@ -1414,7 +1348,7 @@ public List getTheNodes(ExpHandler h){ ExpHandler handler(boolean inSubScope, boolean bind) { return new ExpHandler(inSubScope, bind); } - + void add(List lNode, Node node) { add(lNode, node, false); } @@ -1447,8 +1381,8 @@ public void getVariables(List list) { @Override public void getVariables(List list, boolean excludeLocal) { List lNode = getNodes(); - for (Node node : lNode) { - String name = node.getLabel(); + for (Node varNode : lNode) { + String name = varNode.getLabel(); if (!list.contains(name)) { list.add(name); } @@ -1458,31 +1392,26 @@ public void getVariables(List list, boolean excludeLocal) { } public void getFilterVar(List list, boolean excludeLocal) { - switch (type) { - - case FILTER: - List lVar = getFilter().getVariables(excludeLocal); - for (String var : lVar) { - if (!list.contains(var)) { - list.add(var); - } - } - break; - - default: - for (Exp exp : getExpList()) { - exp.getFilterVar(list, excludeLocal); + if (type == Type.FILTER) { + List lVar = getFilter().getVariables(excludeLocal); + for (String varString : lVar) { + if (!list.contains(varString)) { + list.add(varString); } - + } + } else { + for (Exp exp : getExpList()) { + exp.getFilterVar(list, excludeLocal); + } } } boolean isBindCst() { - return type() == OPT_BIND && size() == 1; + return type() == Type.OPT_BIND && size() == 1; } boolean isBindVar() { - return type() == OPT_BIND && size() == 2; + return type() == Type.OPT_BIND && size() == 2; } /** @@ -1492,13 +1421,11 @@ List varBind() { List lBind = new ArrayList<>(); for (int i = 0; i < size(); i++) { Exp f = get(i); - if ((f.type() == VALUES) || (f.isFilter() && f.size() > 0)) { - Exp bind = f.first(); - if (bind.type() == OPT_BIND) { - if (bind.isBindCst()) { - // ?x = cst - lBind.add(bind); - } + if ((f.type() == Type.VALUES) || (f.isFilter() && f.size() > 0)) { + Exp bindExp = f.first(); + if ((bindExp.type() == Type.OPT_BIND) && (bindExp.isBindCst())) { + // ?x = cst + lBind.add(bindExp); } } } @@ -1512,10 +1439,10 @@ void setBind() { for (int i = 1; i < size(); i++) { Exp f = get(i); if (f.isFilter() && f.size() > 0) { - Exp bind = f.first(); - if (bind.type() == OPT_BIND + Exp bindExp = f.first(); + if (bindExp.type() == Type.OPT_BIND // no bind (?x = ?y) in case of JOIN - && (!Query.testJoin || bind.isBindCst())) { + && (!Query.testJoin || bindExp.isBindCst())) { int j = i - 1; while (j > 0 && get(j).isFilter()) { j--; @@ -1523,9 +1450,9 @@ void setBind() { if (j >= 0) { Exp g = get(j); if ((g.isEdge() || g.isPath()) - && (bind.isBindCst() ? g.bind(bind.first().getNode()) : true)) { - bind.status(true); - g.setBind(bind); + && (!bindExp.isBindCst() || g.bind(bindExp.first().getNode()))) { + bindExp.status(true); + g.setBind(bindExp); } } } @@ -1557,11 +1484,10 @@ boolean match(Node node, Filter f) { } /** - * this is FILTER with TEST ?x < ?y + * this is FILTER with TEST ?x < ?y */ public int oper() { - int ope = getFilter().getExp().oper(); - return ope; + return getFilter().getExp().oper(); } boolean check(Exp filter, int index) { @@ -1600,7 +1526,7 @@ public int indexNode(Node node) { } /** - * index of node in FILTER ?x < ?y + * index of node in FILTER ?x < ?y */ public int indexVar(Node node) { Expr ee = getFilter().getExp(); @@ -1614,19 +1540,18 @@ public int indexVar(Node node) { return -1; } - boolean isBound(List lvar, List lnode) { - for (String var : lvar) { - if (!isBound(var, lnode)) { + for (String varString : lvar) { + if (!isBound(varString, lnode)) { return false; } } return true; } - boolean isBound(String var, List lnode) { - for (Node node : lnode) { - if (node.isVariable() && node.getLabel().equals(var)) { + boolean isBound(String variableString, List lnode) { + for (Node boundNode : lnode) { + if (boundNode.isVariable() && boundNode.getLabel().equals(variableString)) { return true; } } @@ -1634,8 +1559,8 @@ boolean isBound(String var, List lnode) { } private boolean intersect(List nodes, List list) { - for (Node node : nodes) { - if (list.contains(node)) { + for (Node intersectNode : nodes) { + if (list.contains(intersectNode)) { return true; } } @@ -1644,7 +1569,7 @@ private boolean intersect(List nodes, List list) { public void cache(Node n) { setCacheNode(n); - cache = new HashMap(); + cache = new HashMap<>(); } boolean hasCache() { @@ -1656,27 +1581,25 @@ void cache(Node n, Mappings m) { } Mappings getMappings(Node n) { - Mappings m = cache.get(n); - return m; + return cache.get(n); } - + /** * {?x ex:p ?y} optional {?y ex:q ?z filter(?z != ?x) optional {?z ?p ?x}} * filter ?x is not bound in optional ... * this postponed filter must be processed at the end of optional after join occurred */ public void optional() { - Exp p = Exp.create(BGP); + Exp p = Exp.create(Type.BGP); Exp rest = rest(); - for (Exp exp : rest) { - if (exp.isFilter() && ! rest.simpleBind(exp.getFilter())) { + for (Exp exp : rest) { + if (exp.isFilter() && !rest.simpleBind(exp.getFilter())) { p.add(exp); exp.setPostpone(true); - } - else if (exp.isOptional() || exp.isMinus()) { - Exp first = exp.first(); - for (Exp e : first) { - if (e.isFilter() && ! first.simpleBind(e.getFilter())) { + } else if (exp.isOptional() || exp.isMinus()) { + Exp first = exp.first(); + for (Exp e : first) { + if (e.isFilter() && !first.simpleBind(e.getFilter())) { p.add(e); e.setPostpone(true); } @@ -1686,15 +1609,15 @@ else if (exp.isOptional() || exp.isMinus()) { if (p.size() > 0) { setPostpone(p); setPostpone(true); - } - inscopeFilter(); + } + inscopeFilter(); } - + /** * BGP1 optional { filter(exp) BGP2 } * var(exp) memberOf inscope(BGP1, BGP2) - * TODO: - * for safety we skip bind because bind may fail + * TODO: + * for safety we skip bind because bind may fail * and variable may not be bound whereas we need them to be bound * to test in-scope filter * FIX: we could check at runtime whether variables are bound in Mapping @@ -1703,9 +1626,9 @@ else if (exp.isOptional() || exp.isMinus()) { void inscopeFilter() { List l1 = first().getRecordInScopeNodesWithoutBind(); List l2 = rest().getRecordInScopeNodesWithoutBind(); - - for (Exp exp : rest()) { - if (exp.isFilter() && ! exp.getFilter().isRecExist()) { + + for (Exp exp : rest()) { + if (exp.isFilter() && !exp.getFilter().isRecExist()) { List lvar = exp.getFilter().getVariables(); if (bind(l1, lvar) && bind(l2, lvar)) { getCreateInscopeFilter().add(exp); @@ -1713,39 +1636,39 @@ void inscopeFilter() { } } } - + boolean bind(List lnode, List lvar) { - for (String var : lvar) { + for (String variable : lvar) { boolean suc = false; - for (Node node : lnode) { - if (node.getLabel().equals(var)) { + for (Node bindNode : lnode) { + if (bindNode.getLabel().equals(variable)) { suc = true; break; } } - if (! suc) { + if (!suc) { return false; } } return true; } - + /** * Filter variables of f are bound by triple, path, values or bind, locally in this Exp */ - boolean simpleBind(Filter f){ + boolean simpleBind(Filter f) { List varList = f.getVariables(); List nodeList = getNodeVariables(); - - for (String var : varList) { - if (! nodeList.contains(var)){ + + for (String variable : varList) { + if (!nodeList.contains(variable)) { return false; } } - + return true; } - + /** * Node variables of edge, path, bind, values */ @@ -1757,7 +1680,7 @@ List getNodeVariables() { case PATH: exp.getEdgeVariables(list); break; - case BIND: + case BIND: exp.getBindVariables(list); break; case VALUES: @@ -1771,85 +1694,82 @@ List getNodeVariables() { void getBindVariables(List list) { if (getNodeList() == null) { addVariable(list, getNode()); - } - else { + } else { getValuesVariables(list); } } - + void getValuesVariables(List list) { - for (Node node : getNodeList()) { - addVariable(list, node); + for (Node valuesNode : getNodeList()) { + addVariable(list, valuesNode); } } void getEdgeVariables(List list) { addVariable(list, getEdge().getNode(0)); addVariable(list, getEdge().getNode(1)); - if (! isPath()) { + if (!isPath()) { addVariable(list, getEdge().getProperty()); } } - + void addVariable(List list, Node node) { - if (node.isVariable() && ! list.contains(node.getLabel())) { + if (node.isVariable() && !list.contains(node.getLabel())) { list.add(node.getLabel()); } } - + // optional postponed filters - public Exp getPostpone(){ + public Exp getPostpone() { return postpone; } - - public boolean isDebug() { - return isDebug; + + public void setPostpone(boolean postpone) { + this.isPostpone = postpone; } - public void setDebug(boolean b) { - isDebug = b; + public void setPostpone(Exp postpone) { + this.postpone = postpone; } - + @Override - public PointerType pointerType(){ + public PointerType pointerType() { return STATEMENT; } - - @Override + + @Override public String getDatatypeLabel() { - return String.format("[Statement]"); + return "[Statement]"; } - + @Override public Exp getStatement() { return this; } - + @Override - public Object getValue(String var, int n) { + public Object getValue(String variable, int n) { if (n < size()) { return get(n); } return null; } - public List getInscopeFilter() { return inscopeFilter; } - public void setInscopeFilter(List inscopeFilter) { this.inscopeFilter = inscopeFilter; } - + public List getCreateInscopeFilter() { if (getInscopeFilter() == null) { setInscopeFilter(new ArrayList<>()); } return getInscopeFilter(); } - + public int getNumber() { return number; } @@ -1857,72 +1777,67 @@ public int getNumber() { public void setNumber(int number) { this.number = number; } - + boolean isEvaluableWithMappings() { return isAndJoinRec() || isRecFederate(); } - + /** * if exp = and(join(and(edge) service())) * then pass Mappings map as parameter */ - boolean isAndJoinRec(){ + boolean isAndJoinRec() { if (isAnd()) { if (size() != 1) { return false; } return get(0).isAndJoinRec(); - } - else if (isJoin()) { + } else if (isJoin()) { Exp fst = get(0); - if (fst.isAnd() && fst.size() > 0 && fst.get(0).isEdgePath()) { - return true; - } + return fst.isAnd() && fst.size() > 0 && fst.get(0).isEdgePath(); } return false; } - - /** + + /** * exp is rest of minus, optional: exp is AND * exp is rest of join: AND is not mandatory, it may be a service - * if exp is, or starts with, a service, - * pass Mappings map as parameter - */ - boolean isRecFederate(){ + * if exp is, or starts with, a service, + * pass Mappings map as parameter + */ + boolean isRecFederate() { if (isService()) { return true; } if (size() == 1) { return get(0).isRecService(); - } - else if (isBGPAnd() && size() > 0) { + } else if (isBGPAnd() && size() > 0) { return get(0).isRecService(); - } - else { + } else { return false; } } - + boolean isRecService() { - return isService() || (isBinary() && isFederate2()); + return isService() || (isBinary() && isFederate2()); } - + // binary such as union boolean isFederate2() { - return size() == 2 && - get(0).isRecFederate() && + return size() == 2 && + get(0).isRecFederate() && get(1).isRecFederate(); } - - boolean isFirstWith(int type) { - return type() == type || (isBGPAnd() && size()>0 && get(0).type() == type); + + boolean isFirstWith(Type type) { + return type() == type || (isBGPAnd() && size() > 0 && get(0).type() == type); } - - boolean isGraphFirstWith(int type) { - return type()==GRAPH && size()>1 && get(1).isFirstWith(type); + + boolean isGraphFirstWith(Type type) { + return type() == Type.GRAPH && size() > 1 && get(1).isFirstWith(type); } - - boolean isJoinFirstWith(int type) { + + boolean isJoinFirstWith(Type type) { return isFirstWith(type) || isGraphFirstWith(type); } @@ -1934,47 +1849,43 @@ Exp complete(Mappings map) { res.getExpList().add(0, getValues(map)); return res; } - + Exp getValues(Mappings map) { return createValues(map.getNodeList(), map); } - - + public boolean isMappings() { return mappings; } - + public void setMappings(Mappings m) { + map = m; + } + public void setMappings(boolean mappings) { this.mappings = mappings; } - public boolean isGenerated() { return generated; } - public void setGenerated(boolean generated) { this.generated = generated; } - public List getInScopeNodeList() { return simpleNodeList; } - public void setInScopeNodeList(List simpleNodeList) { this.simpleNodeList = simpleNodeList; } - public Query getExternQuery() { return externQuery; } - public void setExternQuery(Query externQuery) { this.externQuery = externQuery; } @@ -1986,141 +1897,133 @@ public int getNum() { public void setNum(int num) { this.num = num; } - - - - - /******************************************************************** - * - * Alternative interpreter not used - * - */ - - + /** * isAlgebra() only, not used * This is a BGP * if it contains several statements (union, minus, optional, graph, query, bgp), JOIN them - * if it contains statement and basic (eg triple/path/filter/values/bind) + * if it contains statement and basic (eg triple/path/filter/values/bind) * crate BGP for basics and JOIN them * otherwise leave as is * called by compiler transformer when algebra = true (default is false) */ - public void dispatch(){ - if (size() == 0){ + public void dispatch() { + if (size() == 0) { return; } - int nb = 0, ns = 0; - for (Exp exp : this){ - if (exp.isStatement()){ + int nb = 0; + int ns = 0; + for (Exp exp : this) { + if (exp.isStatement()) { ns++; - } - else { + } else { nb++; } } - if (ns == 0 || (ns == 1 && nb == 0)){ + if (ns == 0 || (ns == 1 && nb == 0)) { return; } doDispatch(); } - - void doDispatch(){ - Exp join = Exp.create(JOIN); - Exp basic = Exp.create(BGP); - for (Exp exp : this){ - if (exp.isStatement()){ - if (basic.size() > 0){ + + + + + /* + * + * Alternative interpreter not used + * + */ + + void doDispatch() { + Exp join = Exp.create(Type.JOIN); + Exp basic = Exp.create(Type.BGP); + for (Exp exp : this) { + if (exp.isStatement()) { + if (basic.size() > 0) { join.add(basic); - basic = Exp.create(BGP); + basic = Exp.create(Type.BGP); } join.add(exp); - } - else { + } else { basic.add(exp); } } - if (basic.size() > 0){ + if (basic.size() > 0) { join.add(basic); } Exp body = join.dispatch(0); getExpList().clear(); add(body); } - + /** * create binary JOIN from nary */ - Exp dispatch(int i){ - if (i == size() - 1){ + Exp dispatch(int i) { + if (i == size() - 1) { return last(); - } - else { - return Exp.create(JOIN, get(i), dispatch(i+1)); + } else { + return Exp.create(Type.JOIN, get(i), dispatch(i + 1)); } } - - - /** + + /** * If content is disconnected, generate join(e1, e2) * called by QuerySorter when testJoin=true (default is false) * not used. */ Exp join() { List connectedNode = null; - Exp connectedExp = Exp.create(AND); + Exp connectedExp = Exp.create(Type.AND); List disconnectedExp = new ArrayList<>(); boolean disconnectedFilter = false; for (int i = 0; i < size(); i++) { Exp e = get(i); - switch (e.type()) { + if (e.type() == Type.FILTER) { + Filter f = e.getFilter(); + List lvar = f.getVariables(); - case FILTER: - Filter f = e.getFilter(); - List lvar = f.getVariables(); - - if (connectedNode == null || isBound(lvar, connectedNode)) { - // filter is first - // or filter is bound by current exp : add it to exp - connectedExp.add(e); - } else { - // filter not bound by current exp - if (!disconnectedFilter) { - add(disconnectedExp, connectedExp); - disconnectedFilter = true; - } - add(disconnectedExp, e); + if (connectedNode == null || isBound(lvar, connectedNode)) { + // filter is first + // or filter is bound by current exp : add it to exp + connectedExp.add(e); + } else { + // filter not bound by current exp + if (!disconnectedFilter) { + add(disconnectedExp, connectedExp); + disconnectedFilter = true; } - continue; + add(disconnectedExp, e); + } + continue; + } else {// TODO: UNION + List nodes; + if (type() == Type.MINUS || type() == Type.OPTIONAL) { + nodes = e.first().getAllNodes(); + } else { + nodes = e.getAllNodes(); + } - default: - // TODO: UNION - List nodes = null; - if (type() == MINUS || type() == OPTIONAL) { - nodes = e.first().getAllNodes(); - } else { - nodes = e.getAllNodes(); - } - - if (disconnectedFilter) { - if (!groupEdge) { - connectedExp = Exp.create(AND); - connectedNode = null; - } - disconnectedFilter = false; + if (disconnectedFilter) { + if (!groupEdge) { + connectedExp = Exp.create(Type.AND); + connectedNode = null; } + disconnectedFilter = false; + } - if (connectedNode == null) { - connectedNode = nodes; - } else if (intersect(nodes, connectedNode)) { - connectedNode.addAll(nodes); - } else { - add(disconnectedExp, connectedExp); - connectedExp = Exp.create(AND); - connectedNode = nodes; - } + if (connectedNode == null) { + connectedNode = nodes; + } else if (intersect(nodes, connectedNode)) { + connectedNode.addAll(nodes); + } else { + add(disconnectedExp, connectedExp); + connectedExp = Exp.create(Type.AND); + connectedNode = nodes; + } } connectedExp.add(e); @@ -2133,8 +2036,7 @@ Exp join() { if (disconnectedExp.size() <= 1) { return this; } else { - Exp res = join(disconnectedExp); - return res; + return join(disconnectedExp); } } @@ -2155,16 +2057,16 @@ Exp join(List list) { Exp cur = list.get(i); - if (cur.type() == FILTER || exp.type() == FILTER) { + if (cur.type() == Type.FILTER || exp.type() == Type.FILTER) { // and - if (exp.type() == AND) { + if (exp.type() == Type.AND) { exp.add(cur); } else { - exp = Exp.create(AND, exp, cur); + exp = Exp.create(Type.AND, exp, cur); } } else { // variables that may be bound from environment (e.g. values) - exp = Exp.create(JOIN, exp, cur); + exp = Exp.create(Type.JOIN, exp, cur); exp.bindNodes(); } } @@ -2172,8 +2074,6 @@ Exp join(List list) { return exp; } - - /** * Nodes that may be bound by previous clause or by environment except * minus, etc. @@ -2185,5 +2085,8 @@ void bindNodes() { } } - + class VExp extends ArrayList { + } + + } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/ExpEdge.java b/src/main/java/fr/inria/corese/core/kgram/core/ExpEdge.java index 143f71b10..3a09a5342 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/ExpEdge.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/ExpEdge.java @@ -13,16 +13,12 @@ * */ public class ExpEdge extends Exp { - - static final ArrayList EMPTY = new ArrayList<>(0); - - ExpEdge(int t){ + ExpEdge(Type t){ super(t); } - - - /** + + /* ?s ope cst | cst ope ?s ope ::= = < <= > >= fun(?s, cst) fun ::= contains, strstarts, strends, regex @@ -66,7 +62,7 @@ public List getFilters(int node) { public List getFilters(int node, int type){ Node n = getNode(node); if (n == null || ! n.isVariable()){ - return EMPTY; + return new ArrayList<>(0); } ArrayList list = new ArrayList<>(); for (Filter f : getFilters()){ @@ -122,9 +118,7 @@ boolean match(Expr e, Node n, int node, int type) { */ boolean compatible(Expr e, int node){ if (node == PREDICATE){ - if (e.match(ExprType.LANG) || e.match(ExprType.DATATYPE)){ - return false; - } + return !e.match(ExprType.LANG) && !e.match(ExprType.DATATYPE); } return true; } @@ -143,8 +137,8 @@ boolean match(Expr exp, Node n, int node) { } else if (compatible(fst, node) && (fst.match(ExprType.DATATYPE) || fst.match(ExprType.LANG)) && fst.arity() == 1) { // datatype(var) == cst - Expr var = fst.getExp(0); - return var.isVariable() && var.getLabel().equals(n.getLabel()); + Expr varEpr = fst.getExp(0); + return varEpr.isVariable() && varEpr.getLabel().equals(n.getLabel()); } } return false; diff --git a/src/main/java/fr/inria/corese/core/kgram/core/ExpHandler.java b/src/main/java/fr/inria/corese/core/kgram/core/ExpHandler.java index 1f62d0ea4..e7c551a0a 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/ExpHandler.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/ExpHandler.java @@ -1,6 +1,7 @@ package fr.inria.corese.core.kgram.core; import fr.inria.corese.core.kgram.api.core.Node; + import java.util.ArrayList; import java.util.List; @@ -31,12 +32,12 @@ public ExpHandler(boolean exist, boolean inSubScope, boolean bind, boolean blank this(); setExist(exist).setInSubScope(inSubScope).setBind(bind).setBlank(blank); } - + public ExpHandler(boolean exist, boolean inSubScope, boolean bind) { this(); setExist(exist).setInSubScope(inSubScope).setBind(bind); } - + public ExpHandler(boolean inSubScope, boolean bind) { this(); setInSubScope(inSubScope).setBind(bind); @@ -55,17 +56,17 @@ void add(Node node) { addDistinct(node); } } - + void addDistinct(Node node) { - if (! getNodeList().contains(node)) { + if (!getNodeList().contains(node)) { getNodeList().add(node); } } - + // add select nodes that are not already in node list - public List getNodes(){ + public List getNodes() { for (Node selectNode : getSelectNodeList()) { - if (!getNodeList().contains(selectNode)) { + if (!getNodeList().contains(selectNode)) { getNodeList().add(overloadSelectNodeByExistNode(selectNode)); } } @@ -76,29 +77,30 @@ public List getNodes(){ addDistinct(existNode); } } - + return getNodeList(); } - - /** - * use case: - * select * where { - * {select * where {?x foaf:knows ?y}} - * filter exists {?x foaf:knows ?y} } - * - * lNode = {} lSelNode = {?x, ?y} lExistNode = {?x, ?y} - * overload select nodes of subquery by exists nodes - * @hint: this code would be useful if nodes ?y and ?y were different - * currently they are the same, hence it is useless - */ + + /** + * use case: + * select * where { + * {select * where {?x foaf:knows ?y}} + * filter exists {?x foaf:knows ?y} } + *

+ * lNode = {} lSelNode = {?x, ?y} lExistNode = {?x, ?y} + * overload select nodes of subquery by exists nodes + * + * @hint: this code would be useful if nodes ?y and ?y were different + * currently they are the same, hence it is useless + */ Node overloadSelectNodeByExistNode(Node node) { - if (getExistNodeList().contains(node)) { + if (getExistNodeList().contains(node)) { return get(getExistNodeList(), node); } else { return node; } } - + Node get(List lNode, Node node) { for (Node qNode : lNode) { if (qNode.equals(node)) { @@ -136,15 +138,15 @@ public boolean isInSubScope() { return inSubScope; } - boolean isInSubScopeSample() { - return isInSubScope() && !isAll(); - } - public ExpHandler setInSubScope(boolean inSubScope) { this.inSubScope = inSubScope; return this; } + boolean isInSubScopeSample() { + return isInSubScope() && !isAll(); + } + public boolean isBind() { return bind; } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/Group.java b/src/main/java/fr/inria/corese/core/kgram/core/Group.java index 4b91567d3..207c7e2a1 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/Group.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/Group.java @@ -1,145 +1,51 @@ package fr.inria.corese.core.kgram.core; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.TreeMap; - import fr.inria.corese.core.kgram.api.core.Node; -import java.util.Map; + +import java.util.*; /** * select distinct ?x ?y select (count(distinct *) as ?c) - * + *

* group by ?x ?y min(?l, groupBy(?x, ?y)) - * + *

* Compare Mapping using a TreeMap * * @author Olivier Corby, Edelweiss, INRIA 2011 - * */ public class Group implements Comparator { + private static boolean compareIndex = false; TreeMapping table; + Node fake; + boolean isDistinct = false; + // min(?l, groupBy(?x, ?y)) + boolean isExtend = false; private List nodes; + private boolean isFake = false; - Node fake; - boolean isDistinct = false, - // min(?l, groupBy(?x, ?y)) - isExtend = false; - private boolean isFake = false; - private static boolean compareIndex = false; + Group() { - - public boolean isFake() { - return isFake; } - - public void setFake(boolean afake) { - this.isFake = afake; + + Group(List list) { + setNodeList(list); + table = new TreeMapping(list); } - public static boolean isCompareIndex() { return compareIndex; } - + public static void setCompareIndex(boolean b) { compareIndex = b; } - class TreeMapping extends TreeMap { - - TreeMapping(List ln) { - super(new Compare(ln)); - } - } - - public void dispose() { - table.clear(); - } - - class Compare implements Comparator { - - List list; - int size; - - Compare(List ln) { - list = ln; - size = list.size(); - } - - @Override - public int compare(Mapping m1, Mapping m2) { - if (isExtend) { - return compareExtend(m1, m2); - } - - if (isDistinct) { - return compareDistinct(m1, m2); - } - - return compareGroup(m1, m2); - } - - int compareExtend(Mapping m1, Mapping m2) { - Node[] g1 = m1.getGroupNodes(); - Node[] g2 = m2.getGroupNodes(); - - for (int i = 0; i < size; i++) { - int res = compare(g1[i], g2[i]); - if (res != 0) { - return res; - } - } - return 0; - } - - int compareDistinct(Mapping m1, Mapping m2) { - for (int i = 0; i < size; i++) { - int res = compare(m1.getDistinctNode(i), m2.getDistinctNode(i)); - if (res != 0) { - return res; - } - } - return 0; - } - - int compareGroup(Mapping m1, Mapping m2) { - for (int i = 0; i < size; i++) { - Node qNode = list.get(i); - int res = compare(m1.getGroupBy(qNode, i), m2.getGroupBy(qNode, i)); - if (res != 0) { - return res; - } - } - return 0; - } - - int compare(Node n1, Node n2) { - if (n1 == n2) { - return 0; - } else if (n1 == null) { - return -1; - } else if (n2 == null) { - return +1; - } else if (isCompareIndex() && n1.getIndex() != -1 && n2.getIndex() != -1) { - return Integer.compare(n1.getIndex(), n2.getIndex()); - } else { - return n1.compare(n2); - } - } - } - - Group() { - - } - - public static Group create(List lNode) { + public static Group create(List lNode) { return new Group(lNode); } @@ -150,16 +56,27 @@ public static Group createFromExp(List list) { } return new Group(nodes); } - - Group(List list) { - setNodeList(list); - table = new TreeMapping(list); + + public boolean isFake() { + return isFake; + } + + public void setFake(boolean afake) { + this.isFake = afake; + } + + public void dispose() { + table.clear(); } public List getNodeList() { return nodes; } + public void setNodeList(List nodes) { + this.nodes = nodes; + } + public void setDistinct(boolean b) { isDistinct = b; } @@ -186,8 +103,7 @@ public int compare(Mappings lm1, Mappings lm2) { Node getGroupBy(Mapping map, Node qNode, int n) { if (isDistinct) { return map.getDistinctNode(n); - } - else { + } else { return map.getGroupBy(qNode, n); } } @@ -221,20 +137,95 @@ public boolean isDistinct(Mapping map) { if (table.containsKey(map)) { return false; } - table.put(map, null); + table.put(map, null); return true; } Iterable getValues() { return table.values(); } - - public Map getTable() { + + public Map getTable() { return table; } - public void setNodeList(List nodes) { - this.nodes = nodes; + class TreeMapping extends TreeMap { + + TreeMapping(List ln) { + super(new Compare(ln)); + } + } + + class Compare implements Comparator { + + List list; + int size; + + Compare(List ln) { + list = ln; + size = list.size(); + } + + @Override + public int compare(Mapping m1, Mapping m2) { + if (isExtend) { + return compareExtend(m1, m2); + } + + if (isDistinct) { + return compareDistinct(m1, m2); + } + + return compareGroup(m1, m2); + } + + int compareExtend(Mapping m1, Mapping m2) { + Node[] g1 = m1.getGroupNodes(); + Node[] g2 = m2.getGroupNodes(); + + for (int i = 0; i < size; i++) { + int res = compare(g1[i], g2[i]); + if (res != 0) { + return res; + } + } + return 0; + } + + int compareDistinct(Mapping m1, Mapping m2) { + for (int i = 0; i < size; i++) { + int res = compare(m1.getDistinctNode(i), m2.getDistinctNode(i)); + if (res != 0) { + return res; + } + } + return 0; + } + + int compareGroup(Mapping m1, Mapping m2) { + for (int i = 0; i < size; i++) { + Node qNode = list.get(i); + int res = compare(m1.getGroupBy(qNode, i), m2.getGroupBy(qNode, i)); + if (res != 0) { + return res; + } + } + return 0; + } + + int compare(Node n1, Node n2) { + if (n1 == n2) { + return 0; + } else if (n1 == null) { + return -1; + } else if (n2 == null) { + return +1; + } else if (isCompareIndex() && n1.getIndex() != -1 && n2.getIndex() != -1) { + return Integer.compare(n1.getIndex(), n2.getIndex()); + } else { + return n1.compare(n2); + } + } } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/IterableEntity.java b/src/main/java/fr/inria/corese/core/kgram/core/IterableEntity.java index 50d9f498b..1e7b1e7b9 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/IterableEntity.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/IterableEntity.java @@ -1,49 +1,48 @@ package fr.inria.corese.core.kgram.core; +import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.api.core.Node; + import java.util.Iterator; -import fr.inria.corese.core.kgram.api.core.Edge; /** - * * @author Olivier Corby, Wimmics INRIA I3S, 2015 - * */ - class IterableEntity implements Iterable, Iterator { - - Iterable loop; - Iterator it; - - IterableEntity(Iterable loop){ - this.loop = loop; - it = loop.iterator(); - } +class IterableEntity implements Iterable, Iterator { - @Override - public Iterator iterator() { - return this; - } - - @Override - public boolean hasNext() { - return it.hasNext(); - } + Iterable loop; + Iterator it; - @Override - public Edge next() { - Object obj = it.next(); - if (obj instanceof Node) { - Node n = (Node) obj; - return (Edge) n.getNodeObject(); - } + IterableEntity(Iterable loop) { + this.loop = loop; + it = loop.iterator(); + } - return (Edge) obj; + @Override + public Iterator iterator() { + return this; + } + @Override + public boolean hasNext() { + return it.hasNext(); + } + @Override + public Edge next() { + Edge obj = it.next(); + if (obj instanceof Node) { + Node n = (Node) obj; + return (Edge) n.getNodeObject(); } - @Override - public void remove() { - } - + return obj; + + + } + + @Override + public void remove() { } + +} diff --git a/src/main/java/fr/inria/corese/core/kgram/core/Mapping.java b/src/main/java/fr/inria/corese/core/kgram/core/Mapping.java index 47fcd70a8..c74f477f9 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/Mapping.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/Mapping.java @@ -1,19 +1,7 @@ package fr.inria.corese.core.kgram.core; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import fr.inria.corese.core.kgram.api.core.Edge; -import fr.inria.corese.core.kgram.api.core.Expr; -import fr.inria.corese.core.kgram.api.core.ExprType; -import fr.inria.corese.core.kgram.api.core.Filter; -import fr.inria.corese.core.kgram.api.core.Node; -import fr.inria.corese.core.kgram.api.core.PointerType; -import static fr.inria.corese.core.kgram.api.core.PointerType.MAPPING; +import fr.inria.corese.core.kgram.api.core.*; import fr.inria.corese.core.kgram.api.query.Environment; -import fr.inria.corese.core.kgram.api.core.Pointerable; -import fr.inria.corese.core.kgram.api.core.TripleStore; import fr.inria.corese.core.kgram.api.query.ProcessVisitor; import fr.inria.corese.core.kgram.api.query.Result; import fr.inria.corese.core.kgram.path.Path; @@ -24,19 +12,20 @@ import fr.inria.corese.core.sparql.datatype.DatatypeMap; import fr.inria.corese.core.sparql.triple.function.term.Binding; import fr.inria.corese.core.sparql.triple.parser.ASTExtension; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Set; -/* +import java.util.*; + +import static fr.inria.corese.core.kgram.api.core.PointerType.MAPPING; + +/** * An elementary result of a query or a subquery - * Store query/target nodes and edges + * Store query/target nodes and edges * Store path edges in case of path node * Store order by nodes * Store nodes for select fun() as ?var - * + *

* Implements Environment to enable evaluate having (?count>50) - * + * * @author Olivier Corby, Edelweiss, INRIA 2009 */ public class Mapping @@ -44,9 +33,14 @@ public class Mapping implements Result, Environment, Pointerable { - public static boolean DEBUG_DEFAULT = false; static final Edge[] emptyEdge = new Edge[0]; static final Node[] emptyNode = new Node[0]; + // record group Mappings when group by + Mappings lMap; + // var -> Node + HashMap values; + // aggregate may need to share bnode map + Map bnode; private Edge[] queryEdges; private Edge[] targetEdges; private Node[] queryNodes; @@ -56,14 +50,6 @@ public class Mapping private Node[] groupByNodes; private Node[] distinctNodes; private Node[] groupAlterNodes; - // record group Mappings when group by - Mappings lMap; - // var -> Node - HashMap values; - // aggregate may need to share bnode map - Map bnode; - // Mapping as Environment - Query query; // current named graph URI for eval filter private Node graphNode; // value of graph ?g variable when eval named graph pattern @@ -71,8 +57,7 @@ public class Mapping private Binding bind; private Eval eval; private IDatatype report; - boolean debug = DEBUG_DEFAULT; - + public Mapping() { init(emptyEdge, emptyEdge); init(emptyNode, emptyNode); @@ -107,13 +92,13 @@ public static Mapping create(List q, List t) { public static Mapping create() { return new Mapping(); } - + public static Mapping create(Binding b) { Mapping m = new Mapping(); m.setBind(b); return m; } - + public static Mapping create(Node[] qnodes, Node[] nodes) { return simpleCreate(qnodes, nodes); } @@ -146,67 +131,33 @@ static Mapping cleanCreate(Node[] qnodes, Node[] nodes) { } public static Mapping create(Node qnode, Node node) { - Node[] qnodes = new Node[1], - nodes = new Node[1]; + Node[] qnodes = new Node[1]; + Node[] nodes = new Node[1]; qnodes[0] = qnode; nodes[0] = node; return new Mapping(qnodes, nodes); } -// public static Mapping create(Node q1, Node n1, Node q2, Node n2) { -// Node[] qnodes = new Node[2], -// nodes = new Node[2]; -// qnodes[0] = q1; -// nodes[0] = n1; -// qnodes[1] = q2; -// nodes[1] = n2; -// return new Mapping(qnodes, nodes); -// } - -// public static Mapping create(Edge query, Edge result) { -// ArrayList qNodes = new ArrayList<>(), -// tNodes = new ArrayList<>(); -// for (int i = 0; i < query.nbNode(); i++) { -// Node node = query.getNode(i); -// if (node.isVariable()) { -// qNodes.add(node); -// tNodes.add(result.getNode(i)); -// } -// } -// if (query.getEdgeVariable() != null) { -// qNodes.add(query.getEdgeVariable()); -// tNodes.add(result.getEdgeNode()); -// } -// return new Mapping(qNodes, tNodes); -// } - -// public static Mapping create(Edge[] query, Edge[] result, -// Node[] qnodes, Node[] nodes) { -// return new Mapping(query, result, qnodes, nodes); -// } - - - /** + + /** * TODO: remove duplicates in getVariables() * use case: * function us:fun(?x){let (select ?x where {}) {}} * variable ?x appears twice in the stack because it is redefined in the let clause */ public static Mapping create(Query q, Binding b) { - ArrayList lvar = new ArrayList(); - ArrayList lval = new ArrayList(); - for (Expr var : b.getVariables()) { - Node node = q.getProperAndSubSelectNode(var.getLabel()); + ArrayList lvar = new ArrayList<>(); + ArrayList lval = new ArrayList<>(); + for (Expr varExpr : b.getVariables()) { + Node node = q.getProperAndSubSelectNode(varExpr.getLabel()); if (node != null && !lvar.contains(node)) { lvar.add(node); - lval.add(b.get(var)); + lval.add(b.get(varExpr)); } } - Mapping m = Mapping.create(lvar, lval); - return m; + return Mapping.create(lvar, lval); } - - + void init(List q, List t) { Node[] qn = new Node[q.size()]; @@ -219,8 +170,6 @@ void init(List q, List t) { /** * Complete Mapping with select (exp as var) pragma: setNodeValue already * done - * - * */ void complete(List q, List t) { Node[] qn = new Node[getQueryNodes().length + q.size()]; @@ -241,7 +190,7 @@ void init(Node[] qnodes, Node[] nodes) { this.setTargetNodes(nodes); initValues(); } - + void init(Edge[] query, Edge[] result) { setQueryEdges(query); setTargetEdges(result); @@ -254,10 +203,8 @@ public void initValues() { } int i = 0; for (Node q : getQueryNodes()) { - if (i < getTargetNodes().length) { - if (q != null && q.isVariable() && getTargetNodes()[i] != null) { - setNodeValue(q, getTargetNodes()[i]); - } + if ((i < getTargetNodes().length) && (q != null && q.isVariable() && getTargetNodes()[i] != null)) { + setNodeValue(q, getTargetNodes()[i]); } i++; } @@ -309,19 +256,6 @@ public void project(Query q) { init(lqNodes, ltNodes); } - void setOrderBy(Node[] nodes) { - setOrderByNodes(nodes); - } - - void setOrderBy(Node node) { - setOrderByNodes(new Node[1]); - getOrderByNodes()[0] = node; - } - - void setGroupBy(Node[] nodes) { - setGroupByNodes(nodes); - } - public void dispose() { setMappings(null); } @@ -335,17 +269,13 @@ void setMappings(Mappings l) { lMap = l; } - void setQuery(Query q) { - query = q; - } - @Override public Query getQuery() { return query; } - void setMap(Map m) { - bnode = m; + void setQuery(Query q) { + query = q; } @Override @@ -353,22 +283,39 @@ public Map getMap() { return bnode; } + void setMap(Map m) { + bnode = m; + } + public Node[] getOrderBy() { return getOrderByNodes(); } + void setOrderBy(Node[] nodes) { + setOrderByNodes(nodes); + } + + void setOrderBy(Node node) { + setOrderByNodes(new Node[1]); + getOrderByNodes()[0] = node; + } + public Node[] getGroupBy() { return getGroupByNodes(); } - public void setSelect(Node[] nodes) { - setSelectNodes(nodes); + void setGroupBy(Node[] nodes) { + setGroupByNodes(nodes); } public Node[] getSelect() { return getSelectNodes(); } + public void setSelect(Node[] nodes) { + setSelectNodes(nodes); + } + @Deprecated public void rename(Node oName, Node nName) { int i = 0; @@ -415,7 +362,7 @@ int getIndex(Node qNode) { @Override public int pathLength(Node qNode) { Path path = getPath(qNode); - if (path == null){ + if (path == null) { return -1; } return path.length(); @@ -424,14 +371,14 @@ public int pathLength(Node qNode) { @Override public int pathWeight(Node qNode) { Path path = getPath(qNode); - if (path == null){ + if (path == null) { return -1; } return path.weight(); } boolean isPath(int n) { - return getPath(n) != null; + return getPath(n) != null; } public Path getPath(int n) { @@ -442,9 +389,9 @@ public Path getPath(int n) { } boolean isPath(Node qNode) { - return isPath(getIndex(qNode)); + return isPath(getIndex(qNode)); } - + @Override public String getDatatypeLabel() { return toString(" "); @@ -454,49 +401,48 @@ public String getDatatypeLabel() { public String toString() { return toString("\n"); } - + @Override public Object getObject() { return this; } - + @Override public Object getPointerObject() { return this; } - - String toString(String sep) { + + String toString(String sep) { StringBuilder sb = new StringBuilder(); int i = 0; for (Node e : getTargetNodes()) { - sb.append(getQueryNodes()[i]); //.append("[").append(qNodes[i].getIndex()).append("]"); + sb.append(getQueryNodes()[i]); sb.append(" = ").append(e).append(sep); if (e != null && e.getNodeObject() != null && e.getNodeObject() != this) { - if ((e.getNodeObject() instanceof TripleStore)) { - } - else { + if ((e.getNodeObject() instanceof TripleStore)) { + } else { sb.append(sep).append(e.getNodeObject()).append(sep); } - } + } i++; } return sb.toString(); } - public List getNodes(Node var) { - return getNodes(var.getLabel()); + public List getNodes(Node varNode) { + return getNodes(varNode.getLabel()); } - public List getNodes(String var) { - return getNodes(var, false); + public List getNodes(String varString) { + return getNodes(varString, false); } - public List getNodes(String var, boolean distinct) { + public List getNodes(String varString, boolean distinct) { List list = new ArrayList<>(); if (getMappings() != null) { for (Mapping map : getMappings()) { - Node n = map.getNode(var); + Node n = map.getNode(varString); if (n != null) { if (distinct && list.contains(n)) { } else { @@ -523,7 +469,7 @@ void computeDistinct(List list) { setDistinctNodes(new Node[list.size()]); set(list, getDistinctNodes()); } - + void prepareModify(Query q) { if (!q.getOrderBy().isEmpty()) { setOrderBy(new Node[q.getOrderBy().size()]); @@ -539,7 +485,7 @@ void set(List list, Node[] array) { for (Node qNode : list) { Node node = getNode(qNode); array[i++] = node; - } + } } /** @@ -588,16 +534,16 @@ public void setNode(Node qNode, Node node) { } addNode(qNode, node); } - + void setNode(Node qNode, Node node, int n) { getTargetNodes()[n] = node; if (qNode.isVariable()) { setNodeValue(qNode, node); } } - + public void setNode(Node node, int n) { - setNode(getQueryNode(n), node, n); + setNode(getQueryNode(n), node, n); } public Mapping project(Node q) { @@ -608,22 +554,9 @@ public Mapping project(Node q) { return create(q, value); } - /** - * rename query nodes Used by Producer.map() to return Mappings - */ - public void setNodes(List lNodes) { - int n = 0; - for (Node qNode : lNodes) { - if (n < getQueryNodes().length) { - getQueryNodes()[n++] = qNode; - } - } - } - /** * use case: bind(sparql('select ?x ?y where { ... }') as (?z, ?t)) rename * ?x as ?z and ?y as ?t in all Mapping as well as in Mappings select - * */ public void rename(List oselect, List nselect) { int size = Math.min(oselect.size(), nselect.size()); @@ -671,14 +604,13 @@ public void setGroupBy(int n, Node node) { public Node getNode(int n) { return getTargetNodes()[n]; } - + public Node getNodeProtect(int n) { if (n < getTargetNodes().length) { return getTargetNodes()[n]; } return null; } - @Override public Node getQueryNode(int n) { @@ -693,7 +625,7 @@ public Object getNodeObject(String name) { return node.getNodeObject(); } - public HashMap getNodeValues() { + public Map getNodeValues() { return values; } @@ -718,8 +650,7 @@ public void setNodeValue(Node q, Node t) { public void setNodeValue(String q, Node t) { if (t == null) { values.remove(q); - } - else { + } else { values.put(q, t); } } @@ -743,7 +674,7 @@ public IDatatype getValue(Node qn) { } return n.getDatatypeValue(); } - + @Override public Node getNode(Node node) { if (node.isVariable()) { @@ -751,12 +682,12 @@ public Node getNode(Node node) { } return getNodeBasic(node); } - + @Override public Node getNode(String label) { return getNodeValue(label); } - + Node getNodeBasic(Node node) { int n = 0; for (Node qnode : getQueryNodes()) { @@ -778,15 +709,15 @@ Node getNodeBasic(String label) { } return null; } - + /** * Use case: * let (((?var, ?val)) = ?m) - * let ((?x, ?y) = ?m) + * let ((?x, ?y) = ?m) */ @Override - public Object getValue(String var, int n) { - if (var == null){ + public Object getValue(String varString, int n) { + if (varString == null) { // let (((?var, ?val)) = ?m) -- ?m : Mapping // compiled as: let (?vv = xt:get(?m, 0), (?var, ?val) = ?vv) // xt:get(?m, 0) evaluated as xt:gget(?m, null, 0) @@ -794,12 +725,12 @@ public Object getValue(String var, int n) { return getBinding(n); } // let ((?x, ?y) = ?m) -- ?m : Mapping - return getValue(var); + return getValue(varString); } - List getBinding(int n){ + List getBinding(int n) { List> l = getList(); - if (n < l.size()){ + if (n < l.size()) { return l.get(n); } return null; @@ -807,19 +738,20 @@ List getBinding(int n){ /** * List of variable binding - * @return + * + * @return */ @Override - public Iterable getLoop() { + public Iterable> getLoop() { return getList(); } - - public List> getList() { + + public List> getList() { ArrayList> list = new ArrayList<>(); int i = 0; for (Node n : getQueryNodes()) { Node val = getNode(i++); - if (val != null){ + if (val != null) { ArrayList l = new ArrayList<>(2); l.add(n.getDatatypeValue()); l.add(val.getDatatypeValue()); @@ -828,7 +760,7 @@ public List> getList() { } return list; } - + public IDatatype getDatatypeList() { IDatatypeList dt = DatatypeMap.newList(); for (List list : getList()) { @@ -837,12 +769,15 @@ public IDatatype getDatatypeList() { return dt; } - @Override public Node[] getQueryNodes() { return queryNodes; } + public void setQueryNodes(Node[] qNodes) { + this.queryNodes = qNodes; + } + public List getQueryNodeList() { return Arrays.asList(getQueryNodes()); } @@ -851,11 +786,27 @@ public List getQueryNodeList() { public Node[] getNodes() { return getTargetNodes(); } - + + /** + * rename query nodes Used by Producer.map() to return Mappings + */ + public void setNodes(List lNodes) { + int n = 0; + for (Node qNode : lNodes) { + if (n < getQueryNodes().length) { + getQueryNodes()[n++] = qNode; + } + } + } + public Edge[] getQueryEdges() { return queryEdges; } + public void setQueryEdges(Edge[] qEdges) { + this.queryEdges = qEdges; + } + @Override public Edge[] getEdges() { return getTargetEdges(); @@ -868,34 +819,34 @@ Edge getEdge(int n) { Edge getQueryEdge(int n) { return getQueryEdges()[n]; } - - /** + + /** * minus compatible * varList is the list of common variables between Mappings map1 and map2 * Focus on varList but we are not sure that they are bound in these particular Mapping * If no common variable : compatible = false * If all common variables have same values : compatible = true * else compatible = false - * */ + */ boolean minusCompatible(Mapping map, List varList) { return compatible(map, varList, false); } - + boolean optionalCompatible(Mapping map, List varList) { return compatible(map, varList, true); } - + boolean compatible(Mapping map, List varList, boolean compatibleWithoutCommonVariable) { boolean success = compatibleWithoutCommonVariable; - for (String var : varList) { - Node val1 = getNodeValue(var); - Node val2 = map.getNodeValue(var); + for (String varString : varList) { + Node val1 = getNodeValue(varString); + Node val2 = map.getNodeValue(varString); if (val1 == null || val2 == null) { // do nothing as if variable were not in Mapping // use case: select count(*) as ?c // ?c is in QueryNodes but has no value // use case: minus {option{}} - } else if (val1.match(val2)) { + } else if (val1.match(val2)) { success = true; } else { return false; @@ -911,29 +862,31 @@ boolean compatible(Mapping map, List varList, boolean compatibleWithoutC public boolean compatible(Mapping minus) { return compatible(minus, false); } - + boolean compatible(Mapping map, boolean defaultValue) { - if (map.getSelect() == null){ + if (map.getSelect() == null) { return compatible1(map, defaultValue); - } - else { - return compatible2(map, defaultValue); + } else { + return compatible2(map, defaultValue); } } - - // common variables have compatible values + + // common variables have compatible values boolean isMergeAble(Mapping m) { - for (String var : getVariableNames()) { - Node v1 = getNodeValue(var); - Node v2 = m.getNodeValue(var); + for (String varString : getVariableNames()) { + Node v1 = getNodeValue(varString); + Node v2 = m.getNodeValue(varString); if (v2 != null && !v2.match(v1)) { // was equal return false; } } return true; } - - + + /* + * Environment + */ + boolean compatible1(Mapping map, boolean defaultValue) { boolean sameVarValue = defaultValue; for (Node node : getSelectQueryNodes()) { @@ -954,7 +907,7 @@ boolean compatible1(Mapping map, boolean defaultValue) { } return sameVarValue; } - + boolean compatible2(Mapping map, boolean defaultValue) { boolean sameVarValue = defaultValue; for (Node node1 : getSelectQueryNodes()) { @@ -978,41 +931,11 @@ boolean compatible2(Mapping map, boolean defaultValue) { } return sameVarValue; } - - - -// boolean compatible2(Mapping map, boolean defaultValue) { -// boolean sameVarValue = defaultValue; -// for (Node node2 : map.getSelectQueryNodes()) { -// if (node2.isVariable()) { -// Node node1 = getSelectQueryNode(node2.getLabel()); -// if (node1 != null) { -// Node val1 = getNodeValue(node1); -// Node val2 = map.getNodeValue(node2); -// if (val1 == null || val2 == null) { -// // do nothing as if variable were not in Mapping -// // use case: select count(*) as ?c -// // ?c is in QueryNodes but has no value -// // use case: minus {option{}} -// } else if (!val1.match(val2)) { // was same -// return false; -// } else { -// sameVarValue = true; -// } -// } -// } -// } -// return sameVarValue; -// } - /** - * Environment - */ /** * Warning: do not cache this index because index may vary between mappings */ int getIndex(String label) { - // TODO Auto-generated method stub int n = 0; for (Node qNode : getQueryNodes()) { if (qNode.isVariable() && qNode.getLabel().equals(label)) { @@ -1024,26 +947,11 @@ int getIndex(String label) { } @Override - public Node getNode(Expr var) { - switch (var.subtype()) { - case ExprType.LOCAL: { - Node node = get(var); - if (debug && node == null) { - System.out.println("Mapping: Unbound variable: " + var); - } - return node; - } + public Node getNode(Expr varExpr) { + if (varExpr.subtype() == ExprType.LOCAL) { + return get(varExpr); } - Node node = getNodeValue(var.getLabel()); - if (debug && node == null) { - System.out.println("Mapping: Unbound variable: " + var); - } - return node; -// int i = getIndex(var.getLabel()); -// if (i == -1){ -// return null; -// } -// return nodes[i]; + return getNodeValue(varExpr.getLabel()); } @Override @@ -1055,12 +963,12 @@ public Node getQueryNode(String label) { } return null; } - + Node getQueryNode(Node node) { return getQueryNode(node.getLabel()); } - - Node getCommonNode(Mapping m) { + + Node getCommonNode(Mapping m) { for (Node q1 : getQueryNodes()) { if (q1.isVariable()) { Node q2 = m.getQueryNode(q1); @@ -1099,7 +1007,7 @@ public boolean isBound(Node qNode) { return n != -1 && getTargetNodes()[n] != null; } - /** + /* * ******************************************************************* * * Pipeline Solutions implementation @@ -1114,7 +1022,7 @@ Node[] getSelectQueryNodes() { return getQueryNodes(); } } - + Mapping join(Mapping m) { List qNodes = new ArrayList<>(); List tNodes = new ArrayList<>(); @@ -1124,7 +1032,7 @@ Mapping join(Mapping m) { Node q2 = m.getSelectQueryNode(q1.getLabel()); if (q2 != null) { Node n2 = m.getNodeValue(q2); - if (! n1.match(n2)) { // was same + if (!n1.match(n2)) { // was same return null; } } @@ -1142,66 +1050,38 @@ Mapping join(Mapping m) { } } - Mapping map = new Mapping(qNodes, tNodes); - return map; + return new Mapping(qNodes, tNodes); } - Mapping merge(Mapping m) { - if (!isMergeAble(m)) { // ! compatible(m, true); + if (!isMergeAble(m)) { return null; } - List q = new ArrayList(); - List t = new ArrayList(); + List q = new ArrayList<>(); + List t = new ArrayList<>(); - List p = null; -// boolean isPath = isPath() || m.isPath(); -// if (isPath) { -// p = new ArrayList(); -// } - - int n = 0; for (Node qn : getQueryNodes()) { if (qn.isVariable()) { Node tn = getNodeValue(qn.getLabel()); if (tn != null) { q.add(qn); t.add(tn); -// if (isPath) { -// p.add(getPath(n)); -// } } } - n++; } - n = 0; for (Node qn : m.getQueryNodes()) { if (qn.isVariable()) { Node tn = m.getNodeValue(qn.getLabel()); if (tn != null && getNodeValue(qn.getLabel()) == null) { q.add(qn); t.add(tn); -// if (isPath) { -// p.add(m.getPath(n)); -// } } } - n++; } - Mapping map = new Mapping(q, t); -// if (isPath) { -// map.init(p); -// } - return map; - } - - - Mapping project(List lExp) { - - return this; + return new Mapping(q, t); } Mapping rename(List lExp) { @@ -1259,22 +1139,9 @@ boolean contains(Node node) { return false; } - /** - * Mapping as Environment may compute aggregates see same function in Memory - */ -// @Override -// public void aggregate(Evaluator eval, Producer p, Filter f) { -// if (!getMappings().isFake()) { -// for (Mapping map : getMappings()) { -// // in case there is a nested aggregate -// eval.eval(f, map, p); -// } -// } -// } - @Override - public Iterable getAggregate(){ - if (getMappings()==null) { + public Iterable getAggregate() { + if (getMappings() == null) { return List.of(this); } if (getMappings().isFake()) { @@ -1282,19 +1149,19 @@ public Iterable getAggregate(){ } return getMappings(); } - + @Override - public void aggregate(Mapping map, int n){ + public void aggregate(Mapping map, int n) { getAggregateMappings().prepareAggregate(map, getQuery(), getMap(), n); - } - + } + Mappings getAggregateMappings() { if (getMappings() == null) { return new Mappings().add(this); } return getMappings(); } - + @Override public ASTExtension getExtension() { return query.getActualExtension(); @@ -1304,7 +1171,7 @@ public ASTExtension getExtension() { public Binding getBind() { return bind; } - + @Override public void setBind(Binding b) { bind = b; @@ -1314,19 +1181,18 @@ public void setBind(Binding b) { public boolean hasBind() { return bind != null && bind.hasBind(); } - - Binding getCreateBind(){ + + Binding getCreateBind() { return bind; } @Override - public Node get(Expr var) { - // return getCreateBind().get(var); + public Node get(Expr varExpr) { if (getBind() == null) { - Eval.logger.error("Mapping unbound ldscript variable: " + var); + Eval.logger.error("Mapping unbound ldscript variable: " + varExpr); return null; } - return getBind().get(var); + return getBind().get(varExpr); } @Override @@ -1352,40 +1218,42 @@ public ApproximateSearchEnv getAppxSearchEnv() { @Override public TripleStore getTripleStore() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - + } + @Override public Node getGraphNode() { return graphNode; } - + + @Override public void setGraphNode(Node graphNode) { this.graphNode = graphNode; } - + public Node getNamedGraph() { return targetGraphNode; } - + public void setNamedGraph(Node targetGraphNode) { this.targetGraphNode = targetGraphNode; - } - + } + @Override public Eval getEval() { return eval; } - + + @Override + public void setEval(Eval eval) { + this.eval = eval; + } + @Override public ProcessVisitor getVisitor() { if (getEval() == null) { return null; } return getEval().getVisitor(); - } - @Override - public void setEval(Eval eval) { - this.eval = eval; } @Override @@ -1398,10 +1266,6 @@ public void setReport(IDatatype report) { this.report = report; } - public void setQueryNodes(Node[] qNodes) { - this.queryNodes = qNodes; - } - public Node[] getTargetNodes() { return targetNodes; } @@ -1409,7 +1273,7 @@ public Node[] getTargetNodes() { public void setTargetNodes(Node[] nodes) { this.targetNodes = nodes; } - + public Node[] getSelectNodes() { return selectNodes; } @@ -1450,10 +1314,6 @@ public void setGroupAlter(Node[] group) { this.groupAlterNodes = group; } - public void setQueryEdges(Edge[] qEdges) { - this.queryEdges = qEdges; - } - public Edge[] getTargetEdges() { return targetEdges; } @@ -1462,6 +1322,5 @@ public void setTargetEdges(Edge[] edges) { this.targetEdges = edges; } - - + } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/MappingSet.java b/src/main/java/fr/inria/corese/core/kgram/core/MappingSet.java index 8978a94e7..e12018fbb 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/MappingSet.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/MappingSet.java @@ -1,71 +1,75 @@ package fr.inria.corese.core.kgram.core; import fr.inria.corese.core.kgram.api.core.Node; -import static fr.inria.corese.core.kgram.tool.Message.NL; + import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; /** - * * Utilitary class for Join Minus Optional - * Compute common variables in left and right expression + * Compute common variables in left and right expression * and whether common variables are always bound * Select subset of Mappings from left exp relevant for right expression - * optional(s p o, minus(o q t, t r s)) - * variable o can be used in minus expression, variable s cannot + * optional(s p o, minus(o q t, t r s)) + * variable o can be used in minus expression, variable s cannot * special case for union: * join(s p o, union(s q t, o q t)) * there is no common variable bound in branches of union * return complete Mappings, then union() will process it in the branches: left s and right o - * In addition, in case of successful subset of Mappings, return also the original Mappings in case there is + * In addition, in case of successful subset of Mappings, return also the original Mappings in case there is * an union in right expression * If union is in subquery, the subquery may skip the original Mappings depending on its select - * - * @author Olivier Corby, Wimmics INRIA I3S, 2018 * + * @author Olivier Corby, Wimmics INRIA I3S, 2018 */ public class MappingSet { - private Query query; Mappings map; - private Mappings targetMapping; Exp exp; - MappingSet set1, set2; - HashMap - union, // union of variables - intersection; // intersection of variables + MappingSet set1; + MappingSet set2; + HashMap union; // union of variables + HashMap intersection; // intersection of variables List varList; boolean isBound = false; - private boolean debug= false; - - + private Query query; + private Mappings targetMapping; + + MappingSet(Query q, Mappings map1, Mappings map2) { set1 = new MappingSet(q, map1); set2 = new MappingSet(q, map2); setQuery(q); } - - + + MappingSet(Query q, Exp exp, MappingSet s1, MappingSet s2) { this.exp = exp; this.set1 = s1; this.set2 = s2; setQuery(q); } - + + MappingSet(Query q, Mappings map) { + this.map = map; + union = new HashMap<>(); + intersection = new HashMap<>(); + setQuery(q); + process(); + } + Mappings getMappings() { return map; } - + List getVarList() { return varList; } - + boolean isBound() { return isBound; } - /** * Variables in common in map1 and map2 @@ -73,14 +77,14 @@ boolean isBound() { List computeVarList() { return set1.intersectionOfUnion(set2); } - + /** * Common variables bound in every Mapping in map1 and map2 ? */ boolean isBound(List varList) { return set1.inIntersection(varList) && set2.inIntersection(varList); } - + boolean hasIntersection(List nodeList) { for (Node node : nodeList) { if (getIntersection().containsKey(node.getLabel())) { @@ -89,39 +93,37 @@ boolean hasIntersection(List nodeList) { } return false; } - + MappingSet start() { varList = computeVarList(); isBound = isBound(varList); - if (isDebug()) { - System.out.println(this); - } + if (isBound) { set2.getMappings().sort(varList); } return this; } - + @Override public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("inter: ").append(getIntersection()).append(NL); - sb.append("union: ").append(getUnion()).append(NL); + sb.append("inter: ").append(getIntersection()).append(System.lineSeparator()); + sb.append("union: ").append(getUnion()).append(System.lineSeparator()); if (set1 != null) { - sb.append("first var: ").append(set1.getUnion()).append(NL); + sb.append("first var: ").append(set1.getUnion()).append(System.lineSeparator()); } if (set2 != null) { - sb.append("rest var: ").append(set2.getUnion()).append(NL); + sb.append("rest var: ").append(set2.getUnion()).append(System.lineSeparator()); } - if (varList!=null) { + if (varList != null) { sb.append("common var: ").append(varList).append(" always bound: ").append(isBound); } return sb.toString(); } - + /** * return Mapping in map2 potential compatible with m in map1 for optional - * If common variables are bound in every Mapping, + * If common variables are bound in every Mapping, * find potential compatible Mapping by dichotomy and iterate * else return all Mappings * PRAGMA: if isBound, map2 has been sorted by start() above @@ -132,36 +134,7 @@ Iterable getCandidateMappings(Mapping m) { } return set2.getMappings(); } - - - class Iterate implements Iterable, Iterator { - - int n; - Mapping m; - Mappings map; - - Iterate(Mapping m){ - map = set2.getMappings(); - this.n = map.find(m, varList); - this.m = m; - } - @Override - public boolean hasNext() { - return n >= 0 && n < map.size() && map.get(n).optionalCompatible(m, varList); - } - - @Override - public Mapping next() { - return map.get(n++); - } - - @Override - public Iterator iterator() { - return this; - } - } - /** * Is there one Mapping in map2 minus compatible with map in map1 */ @@ -185,19 +158,6 @@ boolean minusCompatible(Mapping map) { return false; } - - - //------------------------------------------------------ - - MappingSet(Query q, Mappings map) { - this.map = map; - union = new HashMap<>(); - intersection = new HashMap<>(); - setQuery(q); - process(); - } - - List intersectionOfUnion(MappingSet model) { ArrayList varList = new ArrayList<>(); for (String var : getUnion().keySet()) { @@ -207,73 +167,56 @@ List intersectionOfUnion(MappingSet model) { } return varList; } - + boolean inIntersection(List varList) { return inSet(varList, getIntersection()); } - + boolean inSet(List varList, HashMap table) { for (String var : varList) { - if (! table.containsKey(var)) { + if (!table.containsKey(var)) { return false; } } return true; } - - - + HashMap getUnion() { return union; } - + HashMap getIntersection() { return intersection; } - + /** * compute union and intersection of variables in Mappings map */ void process() { - if ( ! map.isEmpty()) { + if (!map.isEmpty()) { Mapping m = map.get(0); - for (String var : m.getVariableNames()) { - intersection.put(var, var); + for (String varString : m.getVariableNames()) { + intersection.put(varString, varString); } } List remove = new ArrayList<>(); for (Mapping m : map) { - for (String var : m.getVariableNames()) { - union.put(var, var); + for (String varString : m.getVariableNames()) { + union.put(varString, varString); } remove.clear(); - for (String var : intersection.keySet()) { - if (m.getNodeValue(var) == null) { - remove.add(var); + for (String varString : intersection.keySet()) { + if (m.getNodeValue(varString) == null) { + remove.add(varString); } } - for (String var : remove) { - intersection.remove(var); + for (String varString : remove) { + intersection.remove(varString); } } } - - - /** - * @return the debug - */ - public boolean isDebug() { - return debug; - } /** - * @param debug the debug to set - */ - public void setDebug(boolean debug) { - this.debug = debug; - } - - /** * @return the targetMapping */ public Mappings getJoinMappings() { @@ -286,20 +229,19 @@ public Mappings getJoinMappings() { public void setJoinMappings(Mappings targetMapping) { this.targetMapping = targetMapping; } - - - /** + + /** * exp a Join, Minus, Optional, Union */ Exp prepareRest(Exp exp) { Mappings map = prepareMappings(exp); return getRest(exp, map); } - + Exp getRest(Exp exp, Mappings map) { - return (map == null) ? exp.rest(): setMappings(exp, map); + return (map == null) ? exp.rest() : setMappings(exp, map); } - + /** * Process intermediate Mappings * either as parameter of eval(rest, map) @@ -310,7 +252,7 @@ Exp setMappings(Exp exp, Mappings map) { setJoinMappings(map); return exp.rest(); } - + /** * Process intermediate Mappings * either as parameter of eval(rest, map) @@ -319,23 +261,21 @@ Exp setMappings(Exp exp, Mappings map) { */ Exp setMappings2(Exp exp, Mappings map) { Exp rest = exp.rest(); - if (exp.isJoin()){ - // join is generated to enable us to pass + if (exp.isJoin()) { + // join is generated to enable us to pass // Mappings map as parameter to right argument // join (A, bgp(B)) // join (A, union(B, C)) // join (A, graph(B)) // join (A, service) setJoinMappings(map); - } - else if (isFederate() || rest.isEvaluableWithMappings()) { - // user case: + } else if (isFederate() || rest.isEvaluableWithMappings()) { + // user case: // A optional rest | A minus rest - // and 1) rest recursively starts with service clause - // or 2) rest recursively starts with edge/path + // and 1) rest recursively starts with service clause + // or 2) rest recursively starts with edge/path // --2) special case taken into account in eval and() // eval(rest, map) may take Mappings map argument into account - //System.out.println("parameter"); setJoinMappings(map); } else { // inject Mappings map in copy of rest as a values clause @@ -345,29 +285,27 @@ else if (isFederate() || rest.isEvaluableWithMappings()) { } return rest; } - + boolean isFederate() { - return getQuery().getGlobalQuery().isFederate(); + return getQuery().getGlobalQuery().isFederate(); } - + Mappings prepareMappings(Exp exp) { return prepareMappingsRest(exp.rest()); } - + /** - * * in-scope variables in exp except bind except those that are only in * right arg of an optional in exp and skip statements after first * union/minus/optional/graph in exp - * */ Mappings prepareMappingsRest(Exp exp) { List nodeListInScope = exp.getRecordInScopeNodesWithoutBind(); if (!nodeListInScope.isEmpty() && hasIntersection(nodeListInScope)) { - // generate values when at least one variable in-subscope is always + // generate values when at least one variable in-subscope is always // bound in map1, otherwise it would generate duplicates in map2 - // or impose irrelevant bindings - // map = select distinct map1 wrt exp inscope nodes + // or impose irrelevant bindings + // map = select distinct map1 wrt exp inscope nodes Mappings map = getMappings().distinct(nodeListInScope); map.setNodeList(nodeListInScope); // record original Mappings because union in exp may process it @@ -375,15 +313,15 @@ Mappings prepareMappingsRest(Exp exp) { // s p o {s q r} union {o q r} // map node list = {r} // whereas we can get s for first branch and o for second branch - // this is why we record original Mappings for union in exp if any + // this is why we record original Mappings for union in exp if any map.setJoinMappings(getMappings()); - return map; + return map; } // there is no in-scope variable. // return original Mappings in case of union in exp (see comment above) return getMappings(); // return null } - + public Query getQuery() { return query; } @@ -391,6 +329,34 @@ public Query getQuery() { public void setQuery(Query query) { this.query = query; } - + + class Iterate implements Iterable, Iterator { + + int n; + Mapping m; + Mappings map; + + Iterate(Mapping m) { + map = set2.getMappings(); + this.n = map.find(m, varList); + this.m = m; + } + + @Override + public boolean hasNext() { + return n >= 0 && n < map.size() && map.get(n).optionalCompatible(m, varList); + } + + @Override + public Mapping next() { + return map.get(n++); + } + + @Override + public Iterator iterator() { + return this; + } + } + } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/Mappings.java b/src/main/java/fr/inria/corese/core/kgram/core/Mappings.java index 4261a44b1..dd5dcb79c 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/Mappings.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/Mappings.java @@ -1,74 +1,65 @@ package fr.inria.corese.core.kgram.core; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; - -import fr.inria.corese.core.kgram.api.core.Filter; -import fr.inria.corese.core.kgram.api.core.Node; -import fr.inria.corese.core.kgram.api.core.TripleStore; +import fr.inria.corese.core.kgram.api.core.*; +import fr.inria.corese.core.kgram.api.query.Environment; import fr.inria.corese.core.kgram.api.query.Evaluator; import fr.inria.corese.core.kgram.api.query.Producer; import fr.inria.corese.core.kgram.event.Event; import fr.inria.corese.core.kgram.event.EventImpl; import fr.inria.corese.core.kgram.event.EventManager; -import java.util.HashMap; -import fr.inria.corese.core.kgram.api.core.Edge; -import fr.inria.corese.core.kgram.api.core.Expr; -import fr.inria.corese.core.kgram.api.core.PointerType; -import static fr.inria.corese.core.kgram.api.core.PointerType.MAPPINGS; -import fr.inria.corese.core.kgram.api.query.Environment; import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.datatype.DatatypeMap; -import fr.inria.corese.core.sparql.exceptions.EngineException; import fr.inria.corese.core.sparql.triple.function.term.Binding; import fr.inria.corese.core.sparql.triple.parser.ASTQuery; import fr.inria.corese.core.sparql.triple.parser.Context; import fr.inria.corese.core.sparql.triple.parser.Metadata; -import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.*; + +import static fr.inria.corese.core.kgram.api.core.PointerType.MAPPINGS; + /* * Manage list of Mapping, result of a query - * + * * process select distinct * process group by, order by, limit offset, aggregates, having(?count>50) - * + * * @author Olivier Corby, Edelweiss, INRIA 2009 */ public class Mappings extends PointerObject implements Comparator, Iterable { - private static Logger logger = LoggerFactory.getLogger(Mappings.class); + private static final Logger logger = LoggerFactory.getLogger(Mappings.class); private static final String NL = "\n"; private static final String AGGREGATE_LOCAL = "@local"; private static final long serialVersionUID = 1L; - private static int SELECT = -1; - private static int HAVING = -2; + private static final int SELECT = -1; + private static final int HAVING = -2; // SPARQL: -1 (unbound first) // Corese order: 1 (unbound last) public static int unbound = -1; List select; - boolean isDistinct = false, - // statisfy having(test) - isValid = true, - hasEvent = false, - // if true, store all Mapping of the group - isListGroup = false; + boolean isDistinct = false; + // statisfy having(test) + boolean isValid = true; + boolean hasEvent = false; + // if true, store all Mapping of the group + boolean isListGroup = false; boolean sortWithDesc = true; + List reject; + EventManager manager; + int count = 0; private Query query; private List list; - List reject; // Original join Mappings // use case: union manage its own way private Mappings joinMappings; // Update result private List insert; private List delete; - // in-scope node list + // in-scope node list private List nodeList; private Group group; private Group distinct; @@ -79,8 +70,6 @@ public class Mappings extends PointerObject // construct where result graph private TripleStore graph; private int nbsolutions = 0; - EventManager manager; - int count = 0; private int nbDelete = 0; private int nbInsert = 0; // result of query as a template @@ -89,7 +78,6 @@ public class Mappings extends PointerObject private boolean isFake = false; // parse error in service result private boolean error = false; - //private Node result; // return Binding stack as part of result to share it private Binding binding; // Federate Service manage provenance @@ -117,11 +105,6 @@ public Mappings() { query = q; } - void setEventManager(EventManager man) { - manager = man; - hasEvent = true; - } - public static Mappings create(Query q) { return create(q, false); } @@ -132,8 +115,17 @@ public static Mappings create(Query q, boolean subEval) { return lMap; } + public static void setOrderUnboundFirst(boolean b) { + unbound = (b) ? -1 : 1; + } + + void setEventManager(EventManager man) { + manager = man; + hasEvent = true; + } + @Override - public Iterable getLoop() { + public Iterable getLoop() { return this; } @@ -159,7 +151,7 @@ void initiate(Query q, boolean b, boolean all) { isDistinct = b; isListGroup = q.isListGroup(); setSelect(q.getSelect()); - + if (isDistinct) { if (all) { setDistinct(group(getAllExpList(q))); @@ -170,16 +162,16 @@ void initiate(Query q, boolean b, boolean all) { getDistinct().setDuplicate(q.isDistribute()); } } - + // use case: service require distinct mappings for bindings // for variables in body of q, not for select (exp as var) List getAllExpList(Query q) { // variables in body of q - List list = q.selectNodesFromPattern(); - if (list.isEmpty()) { + List nodesFromPattern = q.selectNodesFromPattern(); + if (nodesFromPattern.isEmpty()) { return q.getSelectFun(); } else { - return q.toExp(list); + return q.toExp(nodesFromPattern); } } @@ -193,17 +185,16 @@ public Mappings distinct() { } public Mappings distinct(List list) { - Mappings map = distinct(getQuery().getSelect(), list); - return map; + return distinct(getQuery().getSelect(), list); } public Mappings distinct(List selectList, List distinctList) { Mappings map = new Mappings(getQuery()); map.setSelect(selectList); - Group group = Group.create(distinctList); - group.setDistinct(true); + Group distinctListGroup = Group.create(distinctList); + distinctListGroup.setDistinct(true); for (Mapping m : this) { - if (group.isDistinct(m)) { + if (distinctListGroup.isDistinct(m)) { map.add(m); } } @@ -283,7 +274,7 @@ void remove(int n) { public void clear() { getMappingList().clear(); } - + public void cleanIndex() { for (Node node : getSelect()) { if (node != null) { @@ -297,6 +288,11 @@ public Query getQuery() { return query; } + public Mappings setQuery(Query q) { + query = q; + return this; + } + public ASTQuery getAST() { if (getQuery() == null) { return null; @@ -311,11 +307,6 @@ public Context getContext() { return getQuery().getContext(); } - public Mappings setQuery(Query q) { - query = q; - return this; - } - public Mappings initQuery(Query q) { setQuery(q); init(q); @@ -332,11 +323,11 @@ public String toString(boolean all) { } public String toString(boolean all, boolean ptr, int max) { - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); int i = 1; boolean isSelect = select != null && !all; ArrayList alist = new ArrayList<>(); - + for (Mapping map : this) { if (i > max) { sb.append(String.format("# size = %s, stop after: %s", size(), (i - 1))); @@ -349,7 +340,7 @@ public String toString(boolean all, boolean ptr, int max) { if (isSelect) { for (Node qNode : select) { print(map, qNode, sb, alist, ptr); - + } } else { for (Node qNode : map.getQueryNodes()) { @@ -359,27 +350,20 @@ public String toString(boolean all, boolean ptr, int max) { i++; sb.append(NL); -// for (Node n : alist) { -// sb.append(n).append(" : ").append(n.getEdge()).append(NL); -// } -// alist.clear(); } return sb.toString(); } - void print(Mapping map, Node qNode, StringBuffer sb, List list, boolean ptr) { + void print(Mapping map, Node qNode, StringBuilder sb, List list, boolean ptr) { Node node = map.getNode(qNode); if (node != null) { sb.append(qNode).append(" = ").append(node); -// if (node.isTripleWithEdge()) { -// list.add(node); -// } Object obj = node.getNodeObject(); if (ptr && obj != null && obj != this && obj instanceof PointerObject) { sb.append(" : \n"); - sb.append(obj.toString()); + sb.append(obj); } sb.append("; "); } @@ -389,6 +373,15 @@ public List getSelect() { return select; } + void setSelect(List nodes) { + select = nodes; + } + + public void setSelect(Node node) { + select = new ArrayList<>(1); + select.add(node); + } + public IDatatype getValue(Node qNode) { if (size() == 0) { return null; @@ -396,22 +389,22 @@ public IDatatype getValue(Node qNode) { Mapping map = get(0); return map.getValue(qNode); } - - public List getNodeValueList(String var) { + + public List getNodeValueList(String varString) { List alist = new ArrayList<>(); for (Mapping m : this) { - Node n = m.getNode(var); + Node n = m.getNode(varString); if (n != null) { alist.add(n); } } return alist; } - - public List getStringValueList(String var) { + + public List getStringValueList(String varString) { List alist = new ArrayList<>(); for (Mapping m : this) { - IDatatype dt = m.getValue(var); + IDatatype dt = m.getValue(varString); if (dt != null) { alist.add(dt.getLabel()); } @@ -419,39 +412,39 @@ public List getStringValueList(String var) { return alist; } - public Node getNode(String var) { + public Node getNode(String varString) { if (size() == 0) { return null; } Mapping map = get(0); - return map.getNode(var); + return map.getNode(varString); } - public Object getNodeObject(String var) { + public Object getNodeObject(String varString) { if (size() == 0) { return null; } - return get(0).getNodeObject(var); + return get(0).getNodeObject(varString); } - public Node getNode(Node var) { + public Node getNode(Node varString) { if (size() == 0) { return null; } Mapping map = get(0); - return map.getNode(var); + return map.getNode(varString); } - public Node getQueryNode(String var) { + public Node getQueryNode(String varString) { if (size() == 0) { return null; } Mapping map = get(0); - return map.getQueryNode(var); + return map.getQueryNode(varString); } - public IDatatype getValue(String var) { - Node node = getNode(var); + public IDatatype getValue(String varString) { + Node node = getNode(varString); if (node == null) { return null; } @@ -460,30 +453,20 @@ public IDatatype getValue(String var) { @Override // PRAGMA: Do **not** take var into account - public Object getValue(String var, int n) { + public Object getValue(String varString, int n) { if (n >= size()) { return null; } return get(n); } - public Object getValue2(String var, int n) { - return getValue(var); - } - - void setSelect(List nodes) { - select = nodes; - } - - public void setSelect(Node node) { - select = new ArrayList<>(1); - select.add(node); + public Object getValue2(String varString, int n) { + return getValue(varString); } /** * use case: bind(sparql('select ?x ?y where { ... }') as (?z, ?t)) rename * ?x as ?z and ?y as ?t in all Mapping as well as in Mappings select - * */ public void setNodes(List nodes) { if (getSelect() != null) { @@ -533,7 +516,7 @@ void submit2(Mapping a) { add(a); } } - + public void modifyDistinct() { // select distinct + group by is already done by submit2 if (isDistinct() && getQuery().getGroupBy().isEmpty()) { @@ -548,7 +531,7 @@ public void modifyDistinct() { } boolean accept(Node node) { - return (getDistinct() == null) ? true : getDistinct().accept(node); + return getDistinct() == null || getDistinct().accept(node); } // TODO: check select == null @@ -562,14 +545,14 @@ public boolean accept(Mapping r) { return true; } - void setValid(boolean b) { - isValid = b; - } - boolean isValid() { return isValid; } + void setValid(boolean b) { + isValid = b; + } + @Deprecated boolean same(Node n1, Node n2) { if (n1 == null) { @@ -581,24 +564,23 @@ boolean same(Node n1, Node n2) { } } - /** * Query with new modifier * Prepare Mappings: * Mapping orderBy groupBy */ public void modify(Query q) { - setGroup(null); + setGroup(null); setDistinct(null); init(q); - - if (! q.getOrderBy().isEmpty() || !q.getGroupBy().isEmpty()) { + + if (!q.getOrderBy().isEmpty() || !q.getGroupBy().isEmpty()) { for (Mapping m : this) { m.prepareModify(q); } } } - + /** * New select (exp as var) */ @@ -608,7 +590,6 @@ public void modifySelect(Eval eval, Query q) { Node node = exp.getNode(); for (Mapping m : this) { - //if (m.getNode(node) == null) { // @todo: bnode ? m.setBind(eval.getEnvironment().getBind()); m.setEval(eval); @@ -622,14 +603,13 @@ public void modifySelect(Eval eval, Query q) { } catch (SparqlException ex) { logger.error(ex.getMessage()); } - //} } } } } - + void addSelectVariable(Node node) { - if (! getSelect().contains(node)) { + if (!getSelect().contains(node)) { getSelect().add(node); } } @@ -642,9 +622,9 @@ public void modifyOrderBy() { modifyOrderBy(getEval(), getQuery()); } } - + public void modifyOrderBy(Eval eval, Query q) { - if (! q.getOrderBy().isEmpty()) { + if (!q.getOrderBy().isEmpty()) { setOrderBy(eval, q); sort(); } @@ -654,12 +634,9 @@ public void modifyOrderBy(Eval eval, Query q) { * Compute order by array again and set it in every Mapping */ void setOrderBy(Eval eval, Query q) { - if (q.isDebug()) { - System.out.println("Order By: " + this.toString(true)); - } for (Mapping m : this) { int i = 0; - + for (Exp exp : q.getOrderBy()) { Node node = null; if (exp.getFilter() == null) { @@ -669,48 +646,33 @@ void setOrderBy(Eval eval, Query q) { // @todo: complete Mapping m with Binding, etc. m.setBind(eval.getEnvironment().getBind()); node = eval.eval(null, exp.getFilter(), m, eval.getProducer()); - if (q.isDebug()) { - System.out.println("Order By eval: " + exp); - System.out.println(m); - } } catch (SparqlException ex) { Eval.logger.error("Order By error: " + ex); } } - if (q.isDebug()) { - System.out.println("Order By Result: " + exp + " " + node); - System.out.println("__"); - } // order by array was reset by prepareModify() m.getOrderBy()[i++] = node; } } } - - - public static void setOrderUnboundFirst(boolean b) { - unbound = (b) ? -1 : 1; - } - - - - - - /********************************* - * + + + + + + /* + * * MappingSet sort - * + * ********************************/ - public void sort(List varList) { Collections.sort(getMappingList(), new VariableSorter(varList)); } - - - /** + + + /** * Is there a Mapping compatible with m - * */ int find(Mapping m, List list) { return find(m, getVariableSorter(list), 0, size() - 1); @@ -721,26 +683,6 @@ VariableSorter getVariableSorter(List varList) { return new VariableSorter(varList); } - class VariableSorter implements Comparator { - - List varList; - - VariableSorter(List list) { - this.varList = list; - } - - @Override - public int compare(Mapping m1, Mapping m2) { - int res = 0; - for (int i = 0; i < varList.size() && res == 0; i++) { - Node n1 = m1.getNodeValue(varList.get(i)); - Node n2 = m2.getNodeValue(varList.get(i)); - res = genCompare(n1, n2); - } - return res; - } - } - int find(Mapping m, VariableSorter vs, int first, int last) { if (first >= last) { return first; @@ -755,7 +697,7 @@ int find(Mapping m, VariableSorter vs, int first, int last) { } } } - + boolean minusCompatible(Mapping m, List list) { int n = find(m, getVariableSorter(list), 0, size() - 1); if (n >= 0 && n < size()) { @@ -763,29 +705,28 @@ boolean minusCompatible(Mapping m, List list) { return m.minusCompatible(mm, list); } return false; - } + } - - /***************************************** - * - * Standard sort - * order by - * join() - * - *****************************************/ - void sort(Eval eval) { this.setEval(eval); sort(); this.setEval(null); } + + /* + * + * Standard sort + * order by + * join() + * + *****************************************/ + void sort() { Collections.sort(getMappingList(), this); } - + /** - * * Sort according to node * use case: join(exp, exp) */ @@ -793,41 +734,38 @@ void sort(Eval eval, Node node) { prepare(node); sort(eval); } - + void sort(Node node) { prepare(node); sort(); } - + void prepare(Node node) { sortWithDesc = false; for (Mapping m : this) { m.setOrderBy(m.getNode(node)); } } - - + // find index of node where qnode=node // with standard sort int find(Node node, Node qnode) { return find(node, qnode, 0, size() - 1); } - /** * comparator of Node for standard sort * use IDatatype compareTo() * compare with sameTerm semantics: order 1 and 01 in deterministic way * authorize overload of comparator for specific datatypes using a Visitor - */ + */ int comparator(Node n1, Node n2) { if (getEval() != null) { return getEval().getVisitor().compare(getEval(), n1.compare(n2), n1.getDatatypeValue(), n2.getDatatypeValue()); } return n1.compare(n2); } - - + // comparator of Mapping for standard sort @Override public int compare(Mapping m1, Mapping m2) { @@ -835,11 +773,11 @@ public int compare(Mapping m1, Mapping m2) { Node[] order2 = m2.getOrderBy(); List orderBy = getQuery().getOrderBy(); int res = 0; - + for (int i = 0; i < order1.length && i < order2.length && res == 0; i++) { if (order1[i] != null && order2[i] != null) { // sort ?x res = comparator(order1[i], order2[i]); - } // unbound + } // unbound else if (order1[i] == null) { // unbound var if (order2[i] == null) { res = 0; @@ -851,11 +789,11 @@ else if (order1[i] == null) { // unbound var } else { res = 0; } - if (sortWithDesc && !orderBy.isEmpty() && orderBy.get(i).status() ) { + if (sortWithDesc && !orderBy.isEmpty() && orderBy.get(i).status()) { res = desc(res); } } - + return res; } @@ -868,7 +806,6 @@ int desc(int i) { return -1; } } - // find index of node where qnode=node int find(Node node, Node qnode, int first, int last) { @@ -890,81 +827,46 @@ int find(Node node, Node qnode, int first, int last) { int compare(Node n1, Node n2) { int res = 0; if (n1 != null && n2 != null) { // sort ?x - res = comparator(n1, n2); //n1.compare(n2); - } // unbound + res = comparator(n1, n2); + } // unbound else if (n1 == null) { // unbound var if (n2 == null) { res = 0; } else { res = unbound; } - } else if (n2 == null) { + } else { res = -unbound; - } -// else { -// res = 0; -// } + } return res; } - int genCompare(Node n1, Node n2) { + int genCompare(Node n1, Node n2) { return compare(n1, n2); - } - - - - /************************** - * Alternative sorter - * use case: gui - * - **************************/ - + } public void genericSort() { - Collections.sort(getMappingList(), new MappingSorter()); + getMappingList().sort(new MappingSorter()); } - - class MappingSorter implements Comparator { - @Override - public int compare(Mapping m1, Mapping m2) { - int res = 0; - for (int i = 0; i < getSelect().size() && res == 0; i++) { - Node n = getSelect().get(i); - Node n1 = m1.getNodeValue(n); - Node n2 = m2.getNodeValue(n); - res = genCompare(n1, n2); - } - return res; - } - } - - - - /** - * ********************************************************* - * - * Aggregates - * - * 1. select [distinct] var where 2. group by 3. count/min/max as var 4. - * order by 5. limit offset - * - * group by with aggregate return one Mapping per group where the mapping - * hold the result of the aggregate + /* + * Alternative sorter + * use case: gui * - */ + **************************/ + /** * order by limit offset */ public void complete(Eval eval) { - if (getQuery().getOrderBy().size() > 0) { + if (!getQuery().getOrderBy().isEmpty()) { sort(eval); - } + } limitOffset(); } - + void limitOffset() { if (getQuery().getOffset() > 0) { // skip offset @@ -978,6 +880,20 @@ void limitOffset() { } } + + /** + * ********************************************************* + * + * Aggregates + * + * 1. select [distinct] var where 2. group by 3. count/min/max as var 4. + * order by 5. limit offset + * + * group by with aggregate return one Mapping per group where the mapping + * hold the result of the aggregate + * + */ + /** * select count(?doc) as ?count group by ?person ?date order by ?count * having(?count > 100) TODO: optimize this because we enumerate all @@ -986,30 +902,30 @@ void limitOffset() { */ public void aggregate(Query q, Evaluator evaluator, Environment env, Producer p) throws SparqlException { if (env instanceof Memory) { - aggregate(q, evaluator, (Memory)env, p); + aggregate(q, evaluator, (Memory) env, p); } } - + public void aggregate(Evaluator evaluator, Memory memory, Producer p) throws SparqlException { aggregate(getQuery(), evaluator, memory, p); } - + // new aggregate on former Mappings public void modifyAggregate(Query q, Evaluator evaluator, Memory memory, Producer p) throws SparqlException { aggregate(q, evaluator, memory, p); } - + public void modifyLimitOffset() { limitOffset(); } - + public Mappings modifyValues(Query q) { if (q.getValues() != null) { return join(q.getValues().getMappings()); } return this; } - + public void aggregate(Query q, Evaluator evaluator, Memory memory, Producer p) throws SparqlException { if (size() == 0) { if (q.isAggregate()) { @@ -1037,10 +953,10 @@ public void aggregate(Query q, Evaluator evaluator, Memory memory, Producer p) t finish(q); } - + /** - * list = list of select | order by - * select (aggregate() as ?c) + * list = list of select | order by + * select (aggregate() as ?c) * order by aggregate() */ void aggregateExpList(Query q, Evaluator evaluator, Memory memory, Producer p, List list, boolean isSelect) throws SparqlException { @@ -1073,11 +989,10 @@ private void aggregateSwitch(Query q, Evaluator eval, Exp exp, Memory mem, Produ aggregate(q, eval, exp, mem, p, n); } } - /** * Compute select aggregate, order by aggregate and having on one group or on - * whole result (in both case: this Mappings) + * whole result (in both case: this Mappings) */ private boolean aggregate(Query q, Evaluator eval, Exp exp, Memory memory, Producer p, int n) throws SparqlException { int iselect = SELECT; @@ -1087,9 +1002,8 @@ private boolean aggregate(Query q, Evaluator eval, Exp exp, Memory memory, Produ memory.aggregate(firstMap); boolean res = true; Eval ev = memory.getEval(); - + if (n == HAVING) { - //res = eval.test(exp.getFilter(), memory, p); res = exp.getFilter().getExp().test(eval, memory.getBind(), memory, p); if (ev != null) { ev.getVisitor().having(ev, exp.getFilter().getExp(), res); @@ -1104,15 +1018,14 @@ private boolean aggregate(Query q, Evaluator eval, Exp exp, Memory memory, Produ // use case: order by var aggregateValue = memory.getNode(exp.getNode()); } else { - // exp = aggregate(term) // call fr.inria.corese.core.sparql.triple.function.aggregate.${AggregateFunction} aggregateValue = eval(exp.getFilter(), eval, memory, p); if (ev != null) { ev.getVisitor().aggregate(ev, exp.getFilter().getExp(), - (aggregateValue == null) ? null : aggregateValue.getDatatypeValue()); + (aggregateValue == null) ? null : aggregateValue.getDatatypeValue()); } } - + if (hasEvent) { manager.send(EventImpl.create(Event.FILTER, exp, aggregateValue)); } @@ -1132,9 +1045,8 @@ private boolean aggregate(Query q, Evaluator eval, Exp exp, Memory memory, Produ memory.pop(firstMap); return res; } - + Node eval(Filter f, Evaluator eval, Environment env, Producer p) throws SparqlException { - //return eval.eval(f, env, p); return f.getExp().evalWE(eval, env.getBind(), env, p); } @@ -1142,19 +1054,18 @@ Node eval(Filter f, Evaluator eval, Environment env, Producer p) throws SparqlEx * Process aggregate for each group select, order by, having */ private void aggregateGroupMembers(Query q, Group group, Evaluator eval, Exp exp, Memory mem, Producer p, int n) throws SparqlException { - int count = 0; - for (Mappings map : group.getValues()) { + int mappingCount = 0; + for (Mappings map : group.getValues()) { if (hasEvent) { map.setEventManager(manager); } - map.setCount(count++); + map.setCount(mappingCount++); mem.setGroup(map); map.aggregate(q, eval, exp, mem, p, n); mem.setGroup(null); } } - void finish(Query qq) { setNbsolutions(size()); if (qq.getAST().hasMetadata(AGGREGATE_LOCAL)) { @@ -1188,19 +1099,19 @@ void clean() { add(map); } } - + public void dispose() { for (Mapping m : this) { m.dispose(); } - if (getGroup()!=null) { + if (getGroup() != null) { getGroup().dispose(); } - if (getDistinct() !=null) { + if (getDistinct() != null) { getDistinct().dispose(); } } - + public void prepareAggregate(Mapping map, Query q, Map bn, int n) { setCount(n); // in case there is a nested aggregate, map will be an Environment @@ -1210,20 +1121,20 @@ public void prepareAggregate(Mapping map, Query q, Map bn, in // share same bnode table in all Mapping of current group solution map.setMap(bn); } - - // min(?l, groupBy(?x, ?y)) as ?min + + // min(?l, groupBy(?x, ?y)) as ?min void evalGroupByExp(Query q, Evaluator eval, Exp exp, Memory mem, Producer p, int n) throws SparqlException { Group g = createGroup(exp); aggregateGroupMembers(q, g, eval, exp, mem, p, n); if (exp.isHaving()) { // min(?l, groupBy(?x, ?y), (?l = ?min)) as ?min having(eval, exp, mem, p, g); - // remove global group if any + // remove global group if any // may be recomputed with new Mapping list setGroup(null); } } - + /** * exp : min(?l, groupBy(?x, ?y), (?l = ?min)) as ?min) test the filter, * remove Mappping that fail @@ -1234,7 +1145,6 @@ void having(Evaluator eval, Exp exp, Memory mem, Producer p, Group g) throws Spa for (Mappings lm : g.getValues()) { for (Mapping map : lm) { mem.push(map, -1); - //if (eval.test(f, mem, p)) { if (f.getExp().test(eval, mem.getBind(), mem, p)) { add(map); } @@ -1242,22 +1152,6 @@ void having(Evaluator eval, Exp exp, Memory mem, Producer p, Group g) throws Spa } } } - - - /** - * Eliminate all Mapping that do not match filter - */ -// void filter(Evaluator eval, Filter f, Memory mem) throws SparqlException { -// ArrayList l = new ArrayList<>(); -// for (Mapping map : this) { -// mem.push(map, -1); -// if (eval.test(f, mem)) { -// l.add(map); -// } -// mem.pop(map); -// } -// setList(l); -// } /** * Template perform additionnal group_concat(?out) @@ -1273,8 +1167,8 @@ void template(Evaluator eval, Query q, Memory mem, Producer p) throws SparqlExce setTemplateResult(apply(eval, q.getTemplateGroup(), mem, p)); } } - - /** + + /** * Template perform additionnal group_concat(?out) */ public Node apply(Evaluator eval, Exp exp, Memory memory, Producer p) throws SparqlException { @@ -1361,12 +1255,11 @@ public Mappings project(Node q) { private Group createGroup() { if (getQuery().isConnect()) { // group by any - Merge group = new Merge(this); - group.merge(); - return group; + Merge newGroup = new Merge(this); + newGroup.merge(); + return newGroup; } else { - Group group = createGroup(getQuery().getGroupBy()); - return group; + return createGroup(getQuery().getGroupBy()); } } @@ -1389,7 +1282,7 @@ public void setGroup(Group g) { * Generate a group by list of variables */ public Group defineGroup(List list) { - ArrayList el = new ArrayList(); + ArrayList el = new ArrayList<>(); for (String name : list) { el.add(getQuery().getSelectExp(name)); } @@ -1413,7 +1306,7 @@ Group createGroup(List list, boolean extend) { gp.setExtend(extend); gp.setFake(isFake()); - for (Mapping map : this) { + for (Mapping map : this) { gp.add(map); } return gp; @@ -1423,13 +1316,11 @@ Group createGroup(List list, boolean extend) { * for select distinct */ Group group(List list) { - Group group = Group.createFromExp(list); - return group; + return Group.createFromExp(list); } public Node max(Node qNode) { - Node node = minmax(qNode, true); - return node; + return minmax(qNode, true); } public Node min(Node qNode) { @@ -1456,8 +1347,7 @@ private Node minmax(Node qNode, boolean isMax) { return res; } - /** - * ******************************************************************* + /* * * Pipeline Solutions implementation These operations use the select nodes * if any and otherwise the query nodes @@ -1480,9 +1370,9 @@ List getCommonVariables(Mappings map) { List intersectionVariable(HashMap t1, HashMap t2) { ArrayList varList = new ArrayList<>(); - for (String var : t1.keySet()) { - if (t2.containsKey(var)) { - varList.add(var); + for (String varString : t1.keySet()) { + if (t2.containsKey(varString)) { + varList.add(varString); } } return varList; @@ -1491,8 +1381,8 @@ List intersectionVariable(HashMap t1, HashMap unionVariable() { HashMap union = new HashMap<>(); for (Mapping m : this) { - for (String var : m.getVariableNames()) { - union.put(var, var); + for (String varString : m.getVariableNames()) { + union.put(varString, varString); } } return union; @@ -1635,9 +1525,7 @@ public Mappings option(Mappings lm) { } public Mappings project(List lExp) { - Mappings res = new Mappings(); - - return res; + return new Mappings(); } public Mappings rename(List lExp) { @@ -1653,15 +1541,15 @@ public Mappings rename(List lExp) { * Join (var = val) to each Mapping, remove those where var = something else * Use case: service ?s { BGP } */ - public void join(Node var, Node val) { - if (!getSelect().contains(var)) { - getSelect().add(var); + public void join(Node varNode, Node val) { + if (!getSelect().contains(varNode)) { + getSelect().add(varNode); } - for (int i = 0; i < size();) { + for (int i = 0; i < size(); ) { Mapping m = getMappingList().get(i); - Node node = m.getNodeValue(var); + Node node = m.getNodeValue(varNode); if (node == null) { - m.addNode(var, val); + m.addNode(varNode, val); i++; } else if (node.equals(val)) { i++; @@ -1671,36 +1559,36 @@ public void join(Node var, Node val) { } } - public boolean inScope(Node var) { + public boolean inScope(Node varNode) { if (getNodeList() != null) { - return getNodeList().contains(var); + return getNodeList().contains(varNode); } if (getSelect() != null) { - return getSelect().contains(var); + return getSelect().contains(varNode); } return true; } - public List aggregate(Node var) { - List list = new ArrayList<>(); + public List aggregate(Node varNode) { + List aggregateNodeList = new ArrayList<>(); for (Mapping m : this) { - Node val = m.getNodeValue(var); - if (val != null && !list.contains(val)) { - list.add(val); + Node val = m.getNodeValue(varNode); + if (val != null && !aggregateNodeList.contains(val)) { + aggregateNodeList.add(val); } } - return list; + return aggregateNodeList; } /** * Analyse results of source selection query For each boolean variable, * count number of true */ - public HashMap countBooleanValue() { + public Map countBooleanValue() { HashMap cmap = new HashMap<>(); for (Node node : getSelect()) { - int count = 0; + int valueCount = 0; boolean bool = true; for (Mapping m : this) { @@ -1711,7 +1599,7 @@ public HashMap countBooleanValue() { if (value.isBoolean() || value.isNumber()) { if (value.booleanValue()) { - count++; + valueCount++; } } else { bool = false; @@ -1721,7 +1609,7 @@ public HashMap countBooleanValue() { } if (bool) { - cmap.put(node.getLabel(), count); + cmap.put(node.getLabel(), valueCount); } } @@ -1735,16 +1623,15 @@ public Mappings limit(int n) { return this; } - public Mappings getMappings(Query q, Node var, Node val) { + public Mappings getMappings(Query q, Node varNode, Node val) { Mappings map = create(q); for (Mapping m : this) { - Node node = m.getNodeValue(var); + Node node = m.getNodeValue(varNode); if (node != null && node.equals(val)) { map.add(m); } } - Mappings res = map.distinct(); - return res; + return map.distinct(); } public Mappings getMappings(Query q) { @@ -1752,8 +1639,7 @@ public Mappings getMappings(Query q) { for (Mapping m : this) { map.add(m); } - Mappings res = map.distinct(); - return res; + return map.distinct(); } /** @@ -1763,16 +1649,16 @@ void select() { if (size() > 0) { Mapping m = get(0); if (m.size() > 0) { - Node var = m.getQueryNode(0); - if (var.isVariable()) { - IDatatype value = m.getValue(var); + Node varNode = m.getQueryNode(0); + if (varNode.isVariable()) { + IDatatype value = m.getValue(varNode); if (value.isURI()) { String ns = value.stringValue(); - boolean check = check(var, ns); + boolean check = check(varNode, ns); if (check) { - ArrayList list = new ArrayList<>(); - list.add(var); - list.add(ns); + ArrayList objectArrayList = new ArrayList<>(); + objectArrayList.add(varNode); + objectArrayList.add(ns); } } } @@ -1780,10 +1666,10 @@ void select() { } } - boolean check(Node var, String ns) { + boolean check(Node varNode, String ns) { for (Mapping m : this) { if (m.size() > 0) { - IDatatype value = m.getValue(var); + IDatatype value = m.getValue(varNode); if (!(value != null && value.isURI() && value.stringValue().startsWith(ns))) { return false; } @@ -1811,10 +1697,6 @@ public void finish() { } } - public void setGraph(TripleStore graph) { - this.graph = graph; - } - @Override public TripleStore getTripleStore() { return graph; @@ -1824,6 +1706,10 @@ public TripleStore getGraph() { return graph; } + public void setGraph(TripleStore graph) { + this.graph = graph; + } + public int nbUpdate() { return nbDelete + nbInsert; } @@ -1872,6 +1758,10 @@ public Node getTemplateResult() { return templateResult; } + private void setTemplateResult(Node templateResult) { + this.templateResult = templateResult; + } + public String getTemplateStringResult() { if (templateResult == null) { return null; @@ -1879,10 +1769,6 @@ public String getTemplateStringResult() { return templateResult.getLabel(); } - private void setTemplateResult(Node templateResult) { - this.templateResult = templateResult; - } - @Override public PointerType pointerType() { return MAPPINGS; @@ -1893,22 +1779,18 @@ public Mappings getMappings() { return this; } - public Eval getEval() { return eval; } - public void setEval(Eval eval) { this.eval = eval; } - public boolean isFake() { return isFake; } - public Mappings setFake(boolean isFake) { this.isFake = isFake; return this; @@ -1918,11 +1800,17 @@ boolean isNodeList() { return size() != 0 && getNodeList() != null && !getNodeList().isEmpty(); } - public List getNodeList() { return nodeList; } + /** + * @param nodeList the nodeList to set + */ + public void setNodeList(List nodeList) { + this.nodeList = nodeList; + } + /** * Generate nodeList for values clause for this Mappings */ @@ -1937,21 +1825,6 @@ public List getQueryNodeList() { return getNodeListValues(); } - /** - * @param nodeList the nodeList to set - */ - public void setNodeList(List nodeList) { - this.nodeList = nodeList; - } - -// public Node getResult() { -// return result; -// } -// -// -// public void setResult(Node result) { -// this.result = result; -// } public Binding getBinding() { return binding; } @@ -2087,18 +1960,18 @@ public void setReport(IDatatype detail) { public Mappings recordReport(Node node, IDatatype report) { setReport(report); if (isEmpty()) { - // when detail is required, we generate a fake result + // when detail is required, we generate a fake result // to record var=detail add(Mapping.create()); } for (Mapping m : this) { // augment each result with var=detail - m.addNode(node, report); + m.addNode(node, report); m.setReport(report); } return this; } - + public Mappings completeReport(String key, IDatatype value) { if (getReport() != null) { getReport().complete(key, value); @@ -2107,7 +1980,7 @@ public Mappings completeReport(String key, IDatatype value) { } return this; } - + public Mappings basicCompleteReport(String key, IDatatype value) { for (Mapping m : this) { if (m.getReport() == null) { @@ -2118,19 +1991,19 @@ public Mappings basicCompleteReport(String key, IDatatype value) { } return this; } - + public Mappings completeReport(String key, String value) { return completeReport(key, DatatypeMap.newInstance(value)); } - + public Mappings completeReport(String key, int value) { return completeReport(key, DatatypeMap.newInstance(value)); } - + public Mappings completeReport(String key, double value) { return completeReport(key, DatatypeMap.newInstance(value)); } - + public boolean contains(IDatatype value) { for (Mapping m : this) { for (Node node : m.getNodes()) { @@ -2141,17 +2014,53 @@ public boolean contains(IDatatype value) { } return false; } - + public Mappings getResult() { Query q = getQuery(); ASTQuery ast = getAST(); - if (ast.hasMetadata(Metadata.SELECTION) && q.getSelection()!=null) { + if (ast.hasMetadata(Metadata.SELECTION) && q.getSelection() != null) { return q.getSelection(); } - if (ast.hasMetadata(Metadata.DISCOVERY) && q.getDiscorevy()!=null) { + if (ast.hasMetadata(Metadata.DISCOVERY) && q.getDiscorevy() != null) { return q.getDiscorevy(); } return this; } - + + class VariableSorter implements Comparator { + + List varList; + + VariableSorter(List list) { + this.varList = list; + } + + @Override + public int compare(Mapping m1, Mapping m2) { + int res = 0; + for (int i = 0; i < varList.size() && res == 0; i++) { + Node n1 = m1.getNodeValue(varList.get(i)); + Node n2 = m2.getNodeValue(varList.get(i)); + res = genCompare(n1, n2); + } + return res; + } + } + + class MappingSorter implements Comparator { + + @Override + public int compare(Mapping m1, Mapping m2) { + int res = 0; + for (int i = 0; i < getSelect().size() && res == 0; i++) { + Node n = getSelect().get(i); + Node n1 = m1.getNodeValue(n); + Node n2 = m2.getNodeValue(n); + res = genCompare(n1, n2); + } + return res; + } + + } + } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/Memory.java b/src/main/java/fr/inria/corese/core/kgram/core/Memory.java index d56f934c7..da8e1f764 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/Memory.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/Memory.java @@ -1,19 +1,7 @@ package fr.inria.corese.core.kgram.core; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import fr.inria.corese.core.kgram.api.core.Edge; -import fr.inria.corese.core.kgram.api.core.Expr; -import fr.inria.corese.core.kgram.api.core.ExprType; -import fr.inria.corese.core.kgram.api.core.Filter; -import fr.inria.corese.core.kgram.api.core.Node; -import fr.inria.corese.core.kgram.api.query.Environment; -import fr.inria.corese.core.kgram.api.query.Evaluator; -import fr.inria.corese.core.kgram.api.query.Matcher; -import fr.inria.corese.core.kgram.api.query.ProcessVisitor; -import fr.inria.corese.core.kgram.api.query.Producer; +import fr.inria.corese.core.kgram.api.core.*; +import fr.inria.corese.core.kgram.api.query.*; import fr.inria.corese.core.kgram.event.Event; import fr.inria.corese.core.kgram.event.EventImpl; import fr.inria.corese.core.kgram.event.EventManager; @@ -22,29 +10,32 @@ import fr.inria.corese.core.sparql.api.IDatatype; import fr.inria.corese.core.sparql.triple.function.term.Binding; import fr.inria.corese.core.sparql.triple.parser.ASTExtension; + import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * Node and Edge binding stacks for KGRAM evaluator * * @author Olivier Corby, Edelweiss, INRIA 2009 - * */ public class Memory extends PointerObject implements Environment { - public static boolean DEBUG_DEFAULT = false; - public static boolean IS_EDGE = !true; static final Edge[] emptyEdges = new Edge[0]; static final Edge[] emptyEntities = new Edge[0]; + public static boolean IS_EDGE = !true; // number of times nodes are bound by Stack // decrease with backtrack int[] nbNodes, nbEdges, - // stackIndex[n] = index in Eval Exp stack where nth node is bound first - // enable to compute where to backjump - stackIndex; + // stackIndex[n] = index in Eval Exp stack where nth node is bound first + // enable to compute where to backjump + stackIndex; Edge[] qEdges; Edge[] result; - Node[] qNodes, nodes; + Node[] qNodes; + Node[] nodes; Evaluator eval; Matcher match; Eval kgram; @@ -58,38 +49,34 @@ public class Memory extends PointerObject implements Environment { Query query; Node gNode; // to evaluate aggregates such as count(?x) - Mappings results, group; //, join; + Mappings results; + Mappings group; Mapping mapping; - // service evaluation detail report - private IDatatype detail; - // true when processing aggregate at the end + // true when processing aggregate at the end boolean isAggregate = false; - private boolean isFake = false, - isEdge = IS_EDGE; EventManager manager; boolean hasEvent = false; - int nbEdge = 0, nbNode = 0; + int nbEdge = 0; + int nbNode = 0; + // service evaluation detail report + private IDatatype detail; + private boolean isFake = false; + private boolean isEdge = IS_EDGE; private Binding bind; private ApproximateSearchEnv appxSearchEnv; - boolean debug = DEBUG_DEFAULT; - public Memory() {} - + public Memory() { + } + public Memory(Matcher m, Evaluator e) { match = m; eval = e; - bnode = new HashMap(); + bnode = new HashMap<>(); this.appxSearchEnv = new ApproximateSearchEnv(); } - public Memory setResults(Mappings r) { - results = r; - return this; - } - - void setEventManager(EventManager man) { - manager = man; - hasEvent = true; + public static void recordEdge(boolean b) { + IS_EDGE = b; } @Override @@ -100,21 +87,26 @@ public EventManager getEventManager() { return manager; } + void setEventManager(EventManager man) { + manager = man; + hasEvent = true; + } + @Override public boolean hasEventManager() { return (manager != null); } @Override - public void setEval(Eval e) { - kgram = e; + public Eval getEval() { + return kgram; } @Override - public Eval getEval() { - return kgram; + public void setEval(Eval e) { + kgram = e; } - + @Override public ProcessVisitor getVisitor() { return getEval().getVisitor(); @@ -128,6 +120,11 @@ Mappings getResults() { return results; } + public Memory setResults(Mappings r) { + results = r; + return this; + } + @Override public Query getQuery() { return query; @@ -137,26 +134,22 @@ public Matcher getMatcher() { return match; } - public void setGraphNode(Node g) { - gNode = g; - } - @Override public Node getGraphNode() { return gNode; } - void setStack(Stack s) { - stack = s; + @Override + public void setGraphNode(Node g) { + gNode = g; } public Stack getStack() { return stack; } - @Override - public void setExp(Exp ee) { - exp = ee; + void setStack(Stack s) { + stack = s; } @Override @@ -164,8 +157,9 @@ public Exp getExp() { return exp; } - void setAggregate(boolean b) { - isAggregate = b; + @Override + public void setExp(Exp ee) { + exp = ee; } public boolean isAggregate() { @@ -226,7 +220,7 @@ void start() { } @Override - public String toString() { + public String toString() { StringBuilder sb = new StringBuilder(); int n = 0; for (Node qNode : qNodes) { @@ -235,7 +229,7 @@ public String toString() { sb.append("\n"); } sb.append("(").append(qNode.getIndex()).append(") "); - //sb.append(nbNodes[qNode.getIndex()]).append(" "); + sb.append(qNode).append(" = ").append(getNode(qNode)); } } @@ -244,10 +238,10 @@ public String toString() { } return sb.toString(); } - - Node getNode(String name, List list){ - for (Node node : list){ - if (node.getLabel().equals(name)){ + + Node getNode(String name, List list) { + for (Node node : list) { + if (node.getLabel().equals(name)) { return node; } } @@ -257,18 +251,17 @@ Node getNode(String name, List list){ /** * mem is a fresh new Memory, init() has been done Copy this memory into mem * Use case: exists {} , sub query Can bind all Memory nodes or bind only - * subquery select nodes (2 different semantics) + * subquery select nodes (2 different semantics) * TODO: let ( .., exists {}), * MUST push BGP solution and then push Bind - * */ Memory copyInto(Query sub, Memory mem, Exp exp) { int n = 0; if (sub == null) { // exists {} - copyInto(mem, exp); + copyInto(mem, exp); } // subquery - else if (eval.getMode() == Evaluator.SPARQL_MODE){ + else if (eval.getMode() == Evaluator.Mode.SPARQL_MODE) { // SPARQL does not bind args } else { // bind subquery select nodes @@ -287,21 +280,21 @@ else if (eval.getMode() == Evaluator.SPARQL_MODE){ } return mem; } - - /** + + /** * Use case: exists {} in aggregate Copy Mapping into this fresh Memory - * similar to copyInto + * similar to copyInto */ void copy(Mapping map, Exp exp) { if (map.hasBind()) { copy(map.getBind(), exp); - } + } share(getBind(), map.getBind()); push(map, -1); } - + /** - * exists { } + * exists { } * PRAGMA: when exists is in function, this memory is empty */ void copyInto(Memory mem, Exp exp) { @@ -309,11 +302,11 @@ void copyInto(Memory mem, Exp exp) { // bind ldscript variables as sparql // pattern matching variables mem.copy(getBind(), exp); - } + } mem.share(this); copyInto(mem); } - + /** * Share global variable, context, etc. */ @@ -322,13 +315,13 @@ public void share(Binding target, Binding source) { target.share(source); } } - + void share(Memory source) { share(getBind(), source.getBind()); } - + /** - * Copy this Bind local variable stack into this memory + * Copy this Bind local variable stack into this memory * Use case: function xt:foo(?x) { exists { ?x ex:pp ?y } } */ void copy(Binding bind, Exp exp) { @@ -341,7 +334,7 @@ void copy(Binding bind, Exp exp) { } } } - + void copyInto(Memory mem) { int n = 0; // bind all nodes @@ -351,7 +344,7 @@ void copyInto(Memory mem) { n++; } } - + void copyInto(Node qNode, Memory mem, int n) { if (qNode != null) { Node tNode = getNode(qNode); @@ -360,7 +353,7 @@ void copyInto(Node qNode, Memory mem, int n) { } } } - + /** * Store a new result: take a picture of the stack as a Mapping */ @@ -378,8 +371,8 @@ Mapping store(Query q, Producer p, boolean subEval) throws SparqlException { * subEval = false: main or nested select query. */ Mapping store(Query q, Producer p, boolean subEval, boolean func) throws SparqlException { - boolean complete = ! q.getGlobalQuery().isAlgebra(); - + boolean complete = !q.getGlobalQuery().isAlgebra(); + Node detailNode = null; if (getReport() != null) { // draft: set service report as variable value @@ -391,24 +384,25 @@ Mapping store(Query q, Producer p, boolean subEval, boolean func) throws SparqlE push(detailNode, getReport()); } } - + int nb = nbNode; - if (!subEval && complete) { - // select (exp as var) it may happen that var is already bound in - // memory (bindings, subquery), so we should not allocate a - // supplementary cell for var in Mapping node array - for (Exp exp : q.getSelectFun()) { //q.getSelectWithExp()) { - if (exp.getFilter() != null && !isBound(exp.getNode())) { + if (!subEval && complete) { + // select (exp as var) it may happen that var is already bound in + // memory (bindings, subquery), so we should not allocate a + // supplementary cell for var in Mapping node array + for (Exp selectFunExp : q.getSelectFun()) { + if (selectFunExp.getFilter() != null && !isBound(selectFunExp.getNode())) { nb++; } } } Edge[] qedge = emptyEdges; Edge[] tedge = emptyEntities; - Node[] qnode = new Node[nb], tnode = new Node[nb]; + Node[] qnode = new Node[nb]; + Node[] tnode = new Node[nb]; // order by - Node[] snode = new Node[q.getOrderBy().size()], - gnode = new Node[q.getGroupBy().size()]; + Node[] snode = new Node[q.getOrderBy().size()]; + Node[] gnode = new Node[q.getGroupBy().size()]; int n = 0, i = 0; if (isEdge) { @@ -417,14 +411,14 @@ Mapping store(Query q, Producer p, boolean subEval, boolean func) throws SparqlE for (Edge edge : qEdges) { if (edge != null) { qedge[n] = edge; - //tedge[n] = result[i]; + tedge[n] = p.copy(result[i]); n++; } i++; } } - + n = 0; i = 0; for (Node node : qNodes) { @@ -435,13 +429,13 @@ Mapping store(Query q, Producer p, boolean subEval, boolean func) throws SparqlE } i++; } - + Mapping map = null; - - if (complete) { + + if (complete) { if (subEval) { // statement e.g. minus/optional/union - if (func) { + if (func) { orderGroup(q.getOrderBy(), snode, p); orderGroup(q.getGroupBy(), gnode, p); } @@ -459,11 +453,10 @@ Mapping store(Query q, Producer p, boolean subEval, boolean func) throws SparqlE if (e.isAggregate()) { // do nothing - } - else { - //node = eval.eval(f, this, p); + } else { + node = kgram.eval(f, this, p); - kgram.getVisitor().select(kgram, f.getExp(), node==null?null:node.getDatatypeValue()); + kgram.getVisitor().select(kgram, f.getExp(), node == null ? null : node.getDatatypeValue()); // bind fun(?x) as ?y boolean success = push(e.getNode(), node); if (success) { @@ -500,7 +493,7 @@ Mapping store(Query q, Producer p, boolean subEval, boolean func) throws SparqlE map = new Mapping(qedge, tedge, qnode, tnode); mapping = map; - map.init(); + map.init(); // order/group by may access mapping with xt:result() orderGroup(q.getOrderBy(), snode, p); orderGroup(q.getGroupBy(), gnode, p); @@ -512,14 +505,14 @@ Mapping store(Query q, Producer p, boolean subEval, boolean func) throws SparqlE pop(e.getNode()); } } - } + } } - + if (map == null) { map = new Mapping(qedge, tedge, qnode, tnode); mapping = map; } - + if (detailNode != null) { pop(detailNode); setReport(null); @@ -532,12 +525,12 @@ Mapping store(Query q, Producer p, boolean subEval, boolean func) throws SparqlE return map; } - + @Override public Mapping getMapping() { return mapping; } - + @Override public int size() { return nbNode; @@ -576,7 +569,6 @@ void orderGroup(List lExp, Node[] nodes, Producer p) throws SparqlException if (nodes[n] == null) { Filter f = e.getFilter(); if (f != null && !e.isAggregate()) { - //nodes[n] = eval.eval(f, this, p); nodes[n] = kgram.eval(f, this, p); } @@ -584,26 +576,26 @@ void orderGroup(List lExp, Node[] nodes, Producer p) throws SparqlException n++; } } - + boolean pushNodeList(Producer p, Node node, Edge edge, int i) { if (node.isMatchCardinality()) { return pushCardinality(p, node, edge, i); } return pushList(p, node, edge, i); } - + boolean pushList(Producer p, Node node, Edge edge, int i) { ArrayList list = new ArrayList<>(); - for (int j = i; j 0){ + if (nodes[index] == null) { nodes[index] = target; qNodes[index] = node; @@ -752,29 +735,28 @@ public void pop(Node node) { * hence where to backjump when edge fails */ int getIndex(Node gNode, Edge edge) { - int[] stack = stackIndex; int max = -1; int length = edge.nbNode(); for (int i = 0; i < length; i++) { Node qNode = edge.getNode(i); if (qNode != null) { int n = qNode.getIndex(); - if (stack[n] > max) { - max = stack[n]; + if (stackIndex[n] > max) { + max = stackIndex[n]; } } } Node pNode = edge.getEdgeVariable(); if (pNode != null) { int n = pNode.getIndex(); - if (stack[n] > max) { - max = stack[n]; + if (stackIndex[n] > max) { + max = stackIndex[n]; } } if (gNode != null && gNode.isVariable()) { int n = gNode.getIndex(); - if (stack[n] > max) { - max = stack[n]; + if (stackIndex[n] > max) { + max = stackIndex[n]; } } return max; @@ -846,22 +828,21 @@ boolean push(Mapping res, int n) { * Bind Mapping in order to compute aggregate on one group Create a fresh * new bnode table for the solution of this group use case: select * (count(?x) as ?c) (bnode(?c) as ?bn) - * */ void aggregate(Mapping map) { push(map, -1); - Map bnode = map.getMap(); - if (bnode == null) { - bnode = new HashMap(); - map.setMap(bnode); + Map bnodeMap = map.getMap(); + if (bnodeMap == null) { + bnodeMap = new HashMap<>(); + map.setMap(bnodeMap); } - setMap(bnode); + setMap(bnodeMap); } boolean push(Mapping res, int n, boolean isEdge) { return push(res, n, isEdge, true); } - + boolean push(Mapping res, int n, boolean isEdge, boolean isBlank) { int k = 0; for (Node qNode : res.getQueryNodes()) { @@ -892,12 +873,11 @@ boolean push(Mapping res, int n, boolean isEdge, boolean isBlank) { pop(res.getQueryEdge(i), res.getEdge(i)); } // TODO: pop the nodes - System.out.println("**** MEMORY: push mapping fail on edges"); return false; } k++; } - } + } return true; } @@ -911,7 +891,7 @@ boolean push(HashMap list, Mapping map, int n) { Node tNode = list.get(qNode.getLabel()); if (tNode != null) { Node node = map.getNodeProtect(k); - if (push(tNode, node, n)) { + if (push(tNode, node, n)) { } else { // pop for (int i = 0; i < k; i++) { @@ -919,7 +899,7 @@ boolean push(HashMap list, Mapping map, int n) { if (qq != null) { Node tt = list.get(qq.getLabel()); if (tt != null) { - pop(tt); + pop(tt); } } } @@ -938,7 +918,7 @@ void pop(HashMap list, Mapping map) { if (qNode != null) { Node tNode = list.get(qNode.getLabel()); if (tNode != null) { - pop(tNode); + pop(tNode); } } n++; @@ -1021,10 +1001,10 @@ public Edge getEdge(Node qnode) { return null; } - public Edge getEdge(String var) { + public Edge getEdge(String varString) { for (Edge e : getQueryEdges()) { if (e != null && e.getEdgeVariable() != null - && e.getEdgeVariable().getLabel().equals(var)) { + && e.getEdgeVariable().getLabel().equals(varString)) { return getEdge(e); } } @@ -1047,7 +1027,7 @@ public Node getNode(Node node) { int n = node.getIndex(); if (n == -1) { return null; - } + } return nodes[n]; } @@ -1068,8 +1048,7 @@ public Node getNode(String name) { */ @Override public Node getQueryNode(String name) { - Node node = query.getProperAndSubSelectNode(name); - return node; + return query.getProperAndSubSelectNode(name); } /** @@ -1087,44 +1066,30 @@ int getIndex(String name) { } return ExprType.UNBOUND; } - + @Override - public Node getNode(Expr var) { - int index = var.getIndex(); - switch (var.subtype()) { + public Node getNode(Expr varExpr) { + int index = varExpr.getIndex(); + switch (varExpr.subtype()) { // ldscript variable // normally we do not get here because ldscript variable is // instance of VariableLocal and eval() call Binding directly // however, it is not a bug, it is just less efficient to be here - case ExprType.LOCAL: - return get(var); + case ExprType.LOCAL: + return get(varExpr); case ExprType.UNDEF: - if (debug) { - System.out.println("Memory UNDEF: Unbound variable: " + var); - } return null; // sparql bgp case ExprType.GLOBAL: - index = getIndex(var.getLabel()); - var.setIndex(index); + index = getIndex(varExpr.getLabel()); + varExpr.setIndex(index); if (index == ExprType.UNBOUND) { - if (debug) { - System.out.println("Memory GLOBAL: Unbound variable: " + var); - } return null; } } - Node node = getNode(index); - if (node == null && debug) { - System.out.println("Memory DEFAULT: Unbound variable: " + var); - if (var.getLabel().equals("?value")) { - System.out.println(query.getAST()); - System.out.println(this); - } - } - return node; + return getNode(index); } // Filter evaluator @@ -1132,7 +1097,7 @@ public Evaluator getEvaluator() { return eval; } - /** + /* * ************************************* * * Aggregates and system functions @@ -1146,12 +1111,6 @@ public int sum(Node qNode) { return -1; } - // sum(?x) -// @Override -// public void aggregate(Evaluator eval, Producer p, Filter f) { -// current().aggregate(eval, f, this, p); -// } - public Node max(Node qNode) { return current().max(qNode); } @@ -1175,24 +1134,11 @@ public Mappings current() { public Mappings getMappings() { return current(); } - -// Mappings getJoinMappings() { -// return join; -// } -// -// Mappings getResetJoinMappings() { -// Mappings map = getJoinMappings(); -// setJoinMappings(null); -// return map; -// } -// -// void setJoinMappings(Mappings m) { -// join = m; -// } - + /** * Iterate Mappings for aggregate - * @return + * + * @return */ @Override public Iterable getAggregate() { @@ -1201,17 +1147,22 @@ public Iterable getAggregate() { } return current(); } - + + void setAggregate(boolean b) { + isAggregate = b; + } + /** * Prepare Mapping for aggregate + * * @param map - * @param n + * @param n */ @Override public void aggregate(Mapping map, int n) { current().prepareAggregate(map, getQuery(), getMap(), n); } - + @Override public int pathLength(Node qNode) { Path path = getPath(qNode); @@ -1232,7 +1183,7 @@ public int pathWeight(Node qNode) { @Override public Path getPath(Node qNode) { - Node node = getNode(qNode); + Node node = getNode(qNode); if (node == null) { return null; } @@ -1253,30 +1204,24 @@ public void setObject(Object o) { object = o; } - public void setFake(boolean isFake) { - this.isFake = isFake; - } - boolean isFake() { return isFake; } + public void setFake(boolean isFake) { + this.isFake = isFake; + } + @Override public ASTExtension getExtension() { return query.getActualExtension(); } @Override - public Node get(Expr var) { - return bind.get(var); + public Node get(Expr varExpr) { + return bind.get(varExpr); } - - @Override - public void setBind(Binding b) { - bind = b; - } - public Memory setBinding(Binding b) { setBind(b); return this; @@ -1287,11 +1232,16 @@ public Binding getBind() { return bind; } + @Override + public void setBind(Binding b) { + bind = b; + } + @Override public boolean hasBind() { return bind != null && bind.hasBind(); } - + @Override public ApproximateSearchEnv getAppxSearchEnv() { return this.appxSearchEnv; @@ -1300,24 +1250,23 @@ public ApproximateSearchEnv getAppxSearchEnv() { public void setAppxSearchEnv(ApproximateSearchEnv appxEnv) { this.appxSearchEnv = appxEnv; } - - - - /** + + /** * List of variable binding - * @return + * + * @return */ @Override public Iterable> getLoop() { return getList(); } - - List> getList() { + + List> getList() { ArrayList> list = new ArrayList<>(); int i = 0; for (Node n : getQueryNodes()) { Node val = getNode(i++); - if (n!= null && val != null){ + if (n != null && val != null) { ArrayList l = new ArrayList<>(2); l.add(n.getDatatypeValue()); l.add(val.getDatatypeValue()); @@ -1326,15 +1275,15 @@ List> getList() { } return list; } - - /** + + /** * Use case: * let (((?var, ?val)) = ?m) - * let ((?x, ?y) = ?m) + * let ((?x, ?y) = ?m) */ @Override - public Object getValue(String var, int n) { - if (var == null){ + public Object getValue(String varString, int n) { + if (varString == null) { // let (((?var, ?val)) = ?m) -- ?m : Mapping // compiled as: let (?vv = xt:get(?m, 0), (?var, ?val) = ?vv) // xt:get(?m, 0) evaluated as xt:gget(?m, null, 0) @@ -1342,24 +1291,20 @@ public Object getValue(String var, int n) { return getBinding(n); } // let ((?x, ?y) = ?m) -- ?m : Mapping - Node node = getNode(var); + Node node = getNode(varString); if (node == null) { return null; } return node.getDatatypeValue(); } - List getBinding(int n){ + List getBinding(int n) { List> l = getList(); - if (n < l.size()){ + if (n < l.size()) { return l.get(n); } return null; } - - public static void recordEdge(boolean b) { - IS_EDGE = b; - } public IDatatype getReport() { return detail; @@ -1369,5 +1314,5 @@ public IDatatype getReport() { public void setReport(IDatatype detail) { this.detail = detail; } - + } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/ProcessVisitorDefault.java b/src/main/java/fr/inria/corese/core/kgram/core/ProcessVisitorDefault.java index fd7c79428..2a4605181 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/ProcessVisitorDefault.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/ProcessVisitorDefault.java @@ -45,7 +45,7 @@ public IDatatype defaultValue() { void visit(Eval eval, Node g, Exp e, Mappings m1, Mappings m2) { - if (eval.getQuery().getGlobalAST().hasMetadata(Metadata.REPORT)) { + if (eval.getQuery().getGlobalAST().hasMetadata(Metadata.Type.REPORT)) { eval.getBind().visit(e, g, m1, m2); } } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/Query.java b/src/main/java/fr/inria/corese/core/kgram/core/Query.java index 21b4c4e73..8151a5e9e 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/Query.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/Query.java @@ -4,12 +4,7 @@ import java.util.HashMap; import java.util.List; -import fr.inria.corese.core.kgram.api.core.Edge; -import fr.inria.corese.core.kgram.api.core.Expr; -import fr.inria.corese.core.kgram.api.core.ExprType; -import fr.inria.corese.core.kgram.api.core.Filter; -import fr.inria.corese.core.kgram.api.core.Node; -import fr.inria.corese.core.kgram.api.core.PointerType; +import fr.inria.corese.core.kgram.api.core.*; import fr.inria.corese.core.kgram.api.query.DQPFactory; import fr.inria.corese.core.kgram.api.query.Graphable; import fr.inria.corese.core.kgram.api.query.Matcher; @@ -47,7 +42,7 @@ public class Query extends Exp implements Graphable { public static final int DEFAULT_SLICE = 20; - private static Logger logger = LoggerFactory.getLogger(Query.class); + private static final Logger logger = LoggerFactory.getLogger(Query.class); public static final String PATHNODE = "pathNode"; public static final String BPATH = "_:_path_"; @@ -125,7 +120,7 @@ public static void setFactory(DQPFactory aFactory) { HashMap tprinter; Compile compiler; - private QuerySorter querySorter; + private final QuerySorter querySorter; HashMap pragma; // Extended filters: pathNode() @@ -142,19 +137,20 @@ public static void setFactory(DQPFactory aFactory) { private ASTExtension extension; private boolean isCompiled = false; - //private boolean hasFunctional = false; boolean isCheck = false; private boolean isUseBind = true; boolean - isAggregate = false, isFunctional = false, isRelax = false, - isDistribute = false, - isOptimize = false, - isTest = false, - isNew = true, - // sort edges to be connected - isSort = true, isConstruct = false; + isAggregate = false; + boolean isFunctional = false; + boolean isRelax = false; + boolean isDistribute = false; + boolean isOptimize = false; + boolean isTest = false; + boolean isNew = true; + boolean isSort = true; + boolean isConstruct = false; private boolean isInsert = false; boolean isDelete = false; boolean isUpdate = false; @@ -176,11 +172,11 @@ public static void setFactory(DQPFactory aFactory) { private boolean importFailure = false; boolean - isCorrect = true, isConnect = false, - // join service send Mappings from first pattern to service - isMap = true, - // construct where as a rule - isRule = false, isDetail = true; + isCorrect = true; + boolean isConnect = false; + boolean isMap = true; + boolean isRule = false; + boolean isDetail = true; private boolean algebra = false; private boolean isMatch = false; private boolean initMode = false; @@ -193,7 +189,7 @@ public static void setFactory(DQPFactory aFactory) { private boolean isService = false; - private boolean isBind = false; + private final boolean isBind = false; private boolean isSynchronized = false; private boolean lock = true; @@ -207,7 +203,7 @@ public static void setFactory(DQPFactory aFactory) { private boolean isAllResult = false; private Exp templateGroup, templateNL; - private List argList; + private final List argList; private Mapping mapping; private List edgeList; private String name; @@ -227,35 +223,34 @@ public static void setFactory(DQPFactory aFactory) { private String service; public Query(){ - super(QUERY); - from = new ArrayList(); - named = new ArrayList(); - selectExp = new ArrayList(); - //selectWithExp = new ArrayList(); - orderBy = new ArrayList(); - groupBy = new ArrayList(); - failure = new ArrayList(); - pathFilter = new ArrayList(); - funList = new ArrayList(); + super(Type.QUERY); + from = new ArrayList<>(); + named = new ArrayList<>(); + selectExp = new ArrayList<>(); + orderBy = new ArrayList<>(); + groupBy = new ArrayList<>(); + failure = new ArrayList<>(); + pathFilter = new ArrayList<>(); + funList = new ArrayList<>(); compiler = new Compile(this); - table = new HashMap(); - ftable = new HashMap(); - pragma = new HashMap(); - tprinter = new HashMap (); - ptable = new HashMap(); - etable = new HashMap(); - queries = new ArrayList(); + table = new HashMap<>(); + ftable = new HashMap<>(); + pragma = new HashMap<>(); + tprinter = new HashMap<> (); + ptable = new HashMap<>(); + etable = new HashMap<>(); + queries = new ArrayList<>(); selectNode = new ArrayList<>(); - patternNodes = new ArrayList(); - queryNodes = new ArrayList(); - patternSelectNodes = new ArrayList(); - querySelectNodes = new ArrayList(); - bindingNodes = new ArrayList(); - relaxEdges = new ArrayList(); - argList = new ArrayList(); - queryEdgeList = new ArrayList(); + patternNodes = new ArrayList<>(); + queryNodes = new ArrayList<>(); + patternSelectNodes = new ArrayList<>(); + querySelectNodes = new ArrayList<>(); + bindingNodes = new ArrayList<>(); + relaxEdges = new ArrayList<>(); + argList = new ArrayList<>(); + queryEdgeList = new ArrayList<>(); querySorter = new QuerySorter(this); if (getFactory() != null){ @@ -504,16 +499,6 @@ void inherit(Query q) { boolean needEdge(){ return getGlobalQuery().isRelax() || getGlobalQuery().isRule(); } - - public boolean isRecDebug() { - if (isDebug()) { - return true; - } - if (getOuterQuery() == null || getOuterQuery() == this) { - return false; - } - return getOuterQuery().isRecDebug(); - } public Query getGlobalQuery() { if (query != null) { @@ -967,7 +952,7 @@ public void addSelect(Exp exp) { } public void addSelect(Node node) { - selectExp.add(Exp.create(NODE, node)); + selectExp.add(Exp.create(ExpType.Type.NODE, node)); } public void addOrderBy(Exp exp) { @@ -975,7 +960,7 @@ public void addOrderBy(Exp exp) { } public void addOrderBy(Node node) { - orderBy.add(Exp.create(NODE, node)); + orderBy.add(Exp.create(ExpType.Type.NODE, node)); } public void addGroupBy(Exp exp) { @@ -983,7 +968,7 @@ public void addGroupBy(Exp exp) { } public void addGroupBy(Node node) { - groupBy.add(Exp.create(NODE, node)); + groupBy.add(Exp.create(ExpType.Type.NODE, node)); } public void setOrderBy(List s) { @@ -1094,7 +1079,7 @@ public int nbFun() { /** * Check that select variables and expressions are compatible with group by - * & aggregates use case: + * & aggregates use case: * * SELECT ?P (COUNT(?O) AS ?C) WHERE { ?S ?P ?O } * @@ -1166,9 +1151,7 @@ boolean checkGroupBy(Exp exp) { return false; } } - } else if (!member(exp.getNode(), getGroupBy())) { - return false; - } + } else return member(exp.getNode(), getGroupBy()); return true; } @@ -1311,13 +1294,6 @@ public Query getQuery() { return this; } - public void trace() { - System.out.println("patternNodes: " + patternNodes); - System.out.println("queryNodes: " + queryNodes); - System.out.println("patternSelectNodes: " + patternSelectNodes); - System.out.println("querySelectNodes: " + querySelectNodes); - } - Node getOuterNode(Node subNode) { return getExtNode(subNode.getLabel()); @@ -1343,7 +1319,7 @@ public Node getNode(String name) { * get node with going in select sub query * go into its own select because * order by may reuse a select variable use case: transformer find node for - * select & group by + * select & group by */ public Node getProperAndSubSelectNode(String name) { return getExtNode(name, true); @@ -1526,7 +1502,7 @@ void collectExist(Expr exp) { */ int index(Query query, Exp exp, boolean isExist, int start) { int min = Integer.MAX_VALUE, n; - int type = exp.type(); + ExpType.Type type = exp.type(); switch (type) { case EDGE: @@ -1620,8 +1596,8 @@ int indexExpFilter(Query query, Exp exp, boolean isExist) { if (!isTriple(exp, var)) { // no error message for use case: // var = ?_bn = <> - Message.log(Message.UNDEF_VAR, var); - addError(Message.get(Message.UNDEF_VAR), var); + logger.warn(Message.Prefix.UNDEF_VAR.getString(), var); + addError(Message.Prefix.UNDEF_VAR.getString(), var); } } else if (!isExist && !hasExist) { int n = qIndex(query, qNode); @@ -1745,7 +1721,7 @@ void setNodeIndex(int n) { public List toExp(List lNode) { List lExp = new ArrayList<>(); for (Node node : lNode) { - lExp.add(Exp.create(NODE, node)); + lExp.add(Exp.create(ExpType.Type.NODE, node)); } return lExp; } @@ -1940,30 +1916,26 @@ boolean index(Query query, Expr exp) { */ public Query union(Query q2) { Query q1 = this; - Exp exp = Exp.create(UNION, q1, q2); - Query q = Query.create(exp).complete(q1, q2); - return q; + Exp exp = Exp.create(ExpType.Type.UNION, q1, q2); + return Query.create(exp).complete(q1, q2); } public Query and(Query q2) { Query q1 = this; - Exp exp = Exp.create(AND, q1, q2); - Query q = Query.create(exp).complete(q1, q2); - return q; + Exp exp = Exp.create(ExpType.Type.AND, q1, q2); + return Query.create(exp).complete(q1, q2); } public Query minus(Query q2) { Query q1 = this; - Exp exp = Exp.create(MINUS, q1, Exp.create(AND, q2)); - Query q = Query.create(exp).complete(q1, q2); - return q; + Exp exp = Exp.create(ExpType.Type.MINUS, q1, Exp.create(ExpType.Type.AND, q2)); + return Query.create(exp).complete(q1, q2); } public Query optional(Query q2) { Query q1 = this; - Exp exp = Exp.create(AND, q1, Exp.create(OPTION, Exp.create(AND, q2))); - Query q = Query.create(exp).complete(q1, q2); - return q; + Exp exp = Exp.create(ExpType.Type.AND, q1, Exp.create(ExpType.Type.OPTION, Exp.create(ExpType.Type.AND, q2))); + return Query.create(exp).complete(q1, q2); } public Query ifthen(Query q1, Query q2) { @@ -2382,9 +2354,7 @@ public Expr getLocalExpression(String name){ public Expr getGlobalExpression(String name) { if (getGlobalQuery() != this) { Expr ee = getGlobalQuery().getLocalExpression(name); - if (ee != null) { - return ee; - } + return ee; } return null; } @@ -2396,7 +2366,7 @@ public Iterable getLoop() { } @Override - public Object getValue(String var, int n) { + public Object getValue(String variable, int n) { List list = getEdges(); if (n >= list.size()) { return null; diff --git a/src/main/java/fr/inria/corese/core/kgram/core/QuerySorter.java b/src/main/java/fr/inria/corese/core/kgram/core/QuerySorter.java index aa2c02655..08ec041df 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/QuerySorter.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/QuerySorter.java @@ -19,8 +19,8 @@ */ public class QuerySorter implements ExpType { - private boolean isSort = true; - private boolean testJoin = false; + private final boolean isSort = true; + private final boolean testJoin = false; private Sorter sort; private Query query; @@ -88,7 +88,7 @@ void modifier(Query q) { * the List of variables already bound */ Exp compile(Exp exp, VString varList, boolean option) { - int type = exp.type(); + Type type = exp.type(); switch (type) { case EDGE: @@ -120,7 +120,7 @@ Exp compile(Exp exp, VString varList, boolean option) { // continue with subquery body default: - if (type == OPTIONAL || type == UNION || type == MINUS) { + if (type == Type.OPTIONAL || type == Type.UNION || type == Type.MINUS) { option = true; } @@ -149,7 +149,7 @@ Exp compile(Exp exp, VString varList, boolean option) { varList.clear(size); - if (testJoin && exp.type() == AND) { + if (testJoin && exp.type() == Type.AND) { // group in separate BGP statements that are not connected // by variables // generate a JOIN between BGP. @@ -268,13 +268,13 @@ void setBind(Query q, Exp exp){ void setBind(Exp exp, List bindings) { for (Exp bid : bindings) { Node n = bid.get(0).getNode(); - if (bid.type() == OPT_BIND + if (bid.type() == ExpType.Type.OPT_BIND // no bind (?x = ?y) in case of JOIN && (!Query.testJoin || bid.isBindCst())) { for (Exp g : exp) { if (((g.isEdge() || g.isPath()) && g.getEdge().contains(n)) - && (bid.isBindCst() ? g.bind(bid.first().getNode()) : true)) { + && (!bid.isBindCst() || g.bind(bid.first().getNode()))) { if (g.getBind() == null) { bid.status(true); g.setBind(bid); @@ -302,9 +302,6 @@ void compile(Filter f, VString lVar, boolean opt) { void compile(Expr exp, VString lVar, boolean opt) { if (exp.oper() == ExprType.EXIST) { compile(getQuery().getPattern(exp), lVar, opt); - if (getQuery().isValidate()) { - System.out.println("QuerySorter exists: \n" + getQuery().getPattern(exp)); - } } else { for (Expr ee : exp.getExpList()) { compile(ee, lVar, opt); @@ -390,7 +387,7 @@ void sortFilter(Exp exp, VString varList) { } /** - * Identify remarkable filter ?x < ?y ?x = ?y or ?x = cst or !bound() filter + * Identify remarkable filter ?x < ?y ?x = ?y or ?x = cst or !bound() filter * is tagged */ public List findBindings(Exp exp) { @@ -430,8 +427,8 @@ void service(Exp exp) { boolean isService(Exp exp) { switch (exp.type()) { - case Exp.SERVICE: return true; - case Exp.UNION: return unionService(exp); + case SERVICE: return true; + case UNION: return unionService(exp); } return false; } @@ -464,7 +461,7 @@ void service(Exp exp, int nbService) { int count = 0; int i = 0; - Exp and = Exp.create(Exp.AND); + Exp and = Exp.create(ExpType.Type.AND); while (count < nbService) { // there are services @@ -481,8 +478,8 @@ void service(Exp exp, int nbService) { if (and.size() == 0) { and.add(exp.get(i)); } else { - Exp join = Exp.create(Exp.JOIN, and, exp.get(i)); - and = Exp.create(Exp.AND); + Exp join = Exp.create(ExpType.Type.JOIN, and, exp.get(i)); + and = Exp.create(ExpType.Type.AND); and.add(join); } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/Sorter.java b/src/main/java/fr/inria/corese/core/kgram/core/Sorter.java index e1a77193c..79c553533 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/Sorter.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/Sorter.java @@ -71,7 +71,6 @@ void check(Query q, Exp exp, List list) { if (!connect) { q.addInfo("Disconnected: ", exp); - System.out.println("Disconnect: " + exp); } } @@ -120,9 +119,7 @@ protected boolean beforeBind(Query q, Exp e2, Exp e1) { if (e1.bind(map)) { return false; } - if (e2.bind(map)) { - return true; - } + return e2.bind(map); } return false; } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/SorterNew.java b/src/main/java/fr/inria/corese/core/kgram/core/SorterNew.java index 02ed81378..34b647c6e 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/SorterNew.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/SorterNew.java @@ -1,21 +1,17 @@ package fr.inria.corese.core.kgram.core; -import static fr.inria.corese.core.kgram.api.core.ExpType.BIND; -import static fr.inria.corese.core.kgram.api.core.ExpType.GRAPH; +import fr.inria.corese.core.kgram.api.core.ExpType; import fr.inria.corese.core.kgram.api.query.Producer; -import static fr.inria.corese.core.kgram.sorter.core.Const.plannable; -import fr.inria.corese.core.kgram.sorter.core.QPGraph; import fr.inria.corese.core.kgram.sorter.core.IEstimate; import fr.inria.corese.core.kgram.sorter.core.ISort; import fr.inria.corese.core.kgram.sorter.core.QPGNode; +import fr.inria.corese.core.kgram.sorter.core.QPGraph; import fr.inria.corese.core.kgram.sorter.impl.qpv1.DepthFirstBestSearch; import fr.inria.corese.core.kgram.sorter.impl.qpv1.HeuristicsBasedEstimation; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; + +import java.util.*; import java.util.Map.Entry; +import static fr.inria.corese.core.kgram.sorter.core.Const.plannable; /** * A new sorter for QP @@ -33,7 +29,6 @@ public void sort(Exp expression, List bindings, Producer prod, int planType Map> ESGs = tokenize(expression); if (ESGs.isEmpty()) return; - message("** Before sorting [whole]" + expression); long start = System.currentTimeMillis(); // === Iterate each sub set and create ESG and sorting === @@ -41,8 +36,6 @@ public void sort(Exp expression, List bindings, Producer prod, int planType Integer startIndex = entrySet.getKey(); List exps = entrySet.getValue(); - message(" -- Sorting [before], " + exps.size() + " :" + exps); - // ** 1 create graph (list of nodes and their edges) ** QPGraph bpg = new QPGraph(exps, bindings); long stop1 = System.currentTimeMillis(); @@ -76,11 +69,11 @@ public void sort(Exp expression, List bindings, Producer prod, int planType //** is used. //** bind ( as ?g) //** graph ?g {?x ?p ?y} - List graphs = bpg.getAllNodes(GRAPH); + List graphs = bpg.getAllNodes(ExpType.Type.GRAPH); for (QPGNode graph : graphs) { List linkedNodes = bpg.getLinkedNodes(graph); for (QPGNode bind : linkedNodes) { - if (bind.getType() == BIND) { + if (bind.getType() == ExpType.Type.BIND) { int iBind = l.indexOf(bind); int iGraph = l.indexOf(graph); if (iBind > iGraph) { @@ -90,17 +83,11 @@ public void sort(Exp expression, List bindings, Producer prod, int planType } } } - - message(" -- Sorting time:" + (System.currentTimeMillis() - stop1) + "ms"); - message(" -- Sorting [after] :" + exps+ "\n"); // ** 4 rewrite ** is.rewrite(expression, l, startIndex); } - message("** After sorting [whole]:" + expression); - message("** Query sorting time:" + (System.currentTimeMillis() - start) + "ms **\n"); - } // === Split one expression into several subsets that can be sorted @@ -125,10 +112,6 @@ private Map> tokenize(Exp e) { aESG.add(ee); } - - if (ee.type() == GRAPH) { - - } } // == 2.remove the ones containing less that 2 expressions @@ -141,10 +124,4 @@ private Map> tokenize(Exp e) { return ESGs; } - - private void message(String msg) { - if (print) { - System.out.println(msg); - } - } } diff --git a/src/main/java/fr/inria/corese/core/kgram/core/Stack.java b/src/main/java/fr/inria/corese/core/kgram/core/Stack.java index 1fe4cdeab..826efac36 100644 --- a/src/main/java/fr/inria/corese/core/kgram/core/Stack.java +++ b/src/main/java/fr/inria/corese/core/kgram/core/Stack.java @@ -108,7 +108,7 @@ void reset(int n, Exp exp){ * begin: WATCH * next: CONTINUE/BACKJUMP */ - Stack watch(Exp exp, int start, int next, boolean skip, int n){ + Stack watch(Exp exp, ExpType.Type start, ExpType.Type next, boolean skip, int n){ Exp end = Exp.create(next); Exp begin = Exp.create(start, end); end.add(begin); diff --git a/src/main/java/fr/inria/corese/core/kgram/event/EvalListener.java b/src/main/java/fr/inria/corese/core/kgram/event/EvalListener.java index 59a2d2735..5783e2cb9 100644 --- a/src/main/java/fr/inria/corese/core/kgram/event/EvalListener.java +++ b/src/main/java/fr/inria/corese/core/kgram/event/EvalListener.java @@ -1,302 +1,275 @@ package fr.inria.corese.core.kgram.event; -import java.util.Hashtable; - import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.core.Eval; import fr.inria.corese.core.kgram.core.Exp; +import java.util.Hashtable; + /** * Event Listener to trace KGRAM execution - * @author Olivier Corby, Edelweiss, INRIA 2010 * + * @author Olivier Corby, Edelweiss, INRIA 2010 */ public class EvalListener implements EventListener, User { - - Hashtable table; - User user; - - Object object; - Exp exp; - Eval kgram; - - boolean - debug = true, - complete = false, - skip = false, - verbose = false, - go = true; - - int state = Event.STEP; - - int index = -1, nbResult = 0, nbPathStep = 0; - - public EvalListener(){ - init(true); - user = new UserImpl(); - } - - - public static EvalListener create(){ - EvalListener el = new EvalListener(); - return el; - } - - public static EvalListener create(int n){ - EvalListener el = create(); - el.index = n; - return el; - } - - void init(boolean b){ - table = new Hashtable(); - handle(Event.ALL, b); - } - - public String help(){ - return null; - } - - public int get(){ - return Event.STEP; - } - - @Override - public boolean handle(int sort) { - // TODO Auto-generated method stub - return table.get(sort); - } - - public boolean handle(int sort, boolean b){ - if (sort == Event.ALL){ - for (int e = Event.BEGIN; e <= Event.END; e++){ - table.put(e, b); - } - } - else { - table.put(sort, b); - } - return b; - } - - - /** - * Proxy to User Interaction: - * return next, skip, quit, etc. - */ - public void setUser(User b){ - user = b; - } - - - public boolean send(Event e) { - - if (!handle(e.getSort())){ - return true; - } - else if (! debug){ - if (verbose){ - log(e); - } - return true; - } - - switch (e.getSort()){ - case Event.LIMIT: state = Event.STEP; exp = null; break; - case Event.BEGIN: nbResult = 0; nbPathStep = 0; break; - case Event.RESULT: nbResult++; break; - case Event.PATHSTEP: nbPathStep++; break; - - } - - - - switch (state){ - - case Event.COMPLETE: - // eval silently until end of exp - if (! (e.getSort() == Event.FINISH && e.getExp() == exp)){ - if (verbose) log(e); - return true; - } - else { - state = Event.STEP; - exp = null; - } - break; - - - case Event.NEXT: - // next candidate - if (e.getExp() == exp){ - state = Event.STEP; - exp = null; - break; - } - else { - if (verbose) { - log(e); - } - return true; - } - - - case Event.SUCCESS: - // wait success of a filter or enumeration - if ((e.getSort() == Event.FILTER || e.getSort() == Event.ENUM) && - e.getExp() == exp && e.isSuccess()){ - state = Event.STEP; - exp = null; - break; - } - else { - if (verbose) log(e); - return true; - } - - case Event.FORWARD: - // try to get higher in stack: - if (e.getExp() != exp){ - state = Event.STEP; - exp = null; - break; - } - else { - if (verbose) log(e); - return true; - } - - } - - - - - switch (e.getSort()){ - - case Event.ENUM: - // skip enumeration that fail !!! - // stop only when success !!! - log(e); - if (! e.isSuccess()) return true; - break; - - case Event.START: - case Event.FINISH: - if (e.getExp().isFilter()) return true; - log(e); - break; - - case Event.PATHSTEP: break; - - default: - switch (e.getSort()){ - - case Event.RESULT: - log("** Results: " + nbResult); - log("** Path Step: " + nbPathStep); - } - - log(e); - - } - - return process(e); - - } - - - /** - * What does the user want ? - */ - boolean process(Event e){ - boolean wait = true; - while (wait){ - - int res = user.get(); - - wait = false; - - switch (res){ - - case Event.STEP: - // next elementary step - break; - - - case Event.FORWARD: - // next exp in stack - case Event.COMPLETE: - // eval until end of exp - state = res; exp = e.getExp(); - break; - - - case Event.NEXT: - // skip until next candidate of exp - state = res; exp = e.getExp(); - break; - - case Event.SUCCESS: - // eval until success of filter or success of enum - state = res; exp = e.getExp(); - break; - - - - case Event.QUIT: - // complete query - debug = false; break; - - - - case Event.VERBOSE: - verbose = true; - log("Mode verbose ok"); - wait = true; - break; - - case Event.NONVERBOSE: - verbose = false; - log("Fin du mode verbose"); - wait = true; - break; - - case Event.MAP: - log(getKGRAM().getEnvironment()); - wait = true; - break; - - case Event.HELP: - log(user.help()); - wait = true; - break; - } - } - return true; - } - - - Node getNode(Node qNode){ - return kgram.getEnvironment().getNode(qNode); - } - - @Override - public void setObject(Object obj) { - if (obj instanceof Eval){ - kgram = (Eval) obj; - } - else { - object = obj; - } - } - - public Eval getKGRAM(){ - return kgram; - } - - public void log(Object obj){ - System.out.println(obj); - } - - + + Hashtable table; + User user; + + Object object; + Exp exp; + Eval kgram; + + boolean complete = false; + boolean skip = false; + boolean go = true; + + int state = Event.STEP; + + int index = -1; + int nbResult = 0; + int nbPathStep = 0; + + public EvalListener() { + init(true); + user = new UserImpl(); + } + + + public static EvalListener create() { + EvalListener el = new EvalListener(); + return el; + } + + public static EvalListener create(int n) { + EvalListener el = create(); + el.index = n; + return el; + } + + void init(boolean b) { + table = new Hashtable(); + handle(Event.ALL, b); + } + + public String help() { + return null; + } + + public int get() { + return Event.STEP; + } + + @Override + public boolean handle(int sort) { + return table.get(sort); + } + + public boolean handle(int sort, boolean b) { + if (sort == Event.ALL) { + for (int e = Event.BEGIN; e <= Event.END; e++) { + table.put(e, b); + } + } else { + table.put(sort, b); + } + return b; + } + + + /** + * Proxy to User Interaction: + * return next, skip, quit, etc. + */ + public void setUser(User b) { + user = b; + } + + + public boolean send(Event e) { + + if (!handle(e.getSort())) { + return true; + } + + switch (e.getSort()) { + case Event.LIMIT: + state = Event.STEP; + exp = null; + break; + case Event.BEGIN: + nbResult = 0; + nbPathStep = 0; + break; + case Event.RESULT: + nbResult++; + break; + case Event.PATHSTEP: + nbPathStep++; + break; + + } + + + switch (state) { + + case Event.COMPLETE: + // eval silently until end of exp + if (!(e.getSort() == Event.FINISH && e.getExp() == exp)) { + return true; + } else { + state = Event.STEP; + exp = null; + } + break; + + + case Event.NEXT: + // next candidate + if (e.getExp() == exp) { + state = Event.STEP; + exp = null; + break; + } else { + return true; + } + + + case Event.SUCCESS: + // wait success of a filter or enumeration + if ((e.getSort() == Event.FILTER || e.getSort() == Event.ENUM) && + e.getExp() == exp && e.isSuccess()) { + state = Event.STEP; + exp = null; + break; + } else { + return true; + } + + case Event.FORWARD: + // try to get higher in stack: + if (e.getExp() != exp) { + state = Event.STEP; + exp = null; + break; + } else { + return true; + } + + } + + + switch (e.getSort()) { + + case Event.ENUM: + // skip enumeration that fail !!! + // stop only when success !!! + if (!e.isSuccess()) return true; + break; + + case Event.START: + case Event.FINISH: + if (e.getExp().isFilter()) return true; + break; + + case Event.PATHSTEP: + break; + + default: + switch (e.getSort()) { + + case Event.RESULT: + } + + } + + return process(e); + + } + + + /** + * What does the user want ? + */ + boolean process(Event e) { + boolean wait = true; + while (wait) { + + int res = user.get(); + + wait = false; + + switch (res) { + + case Event.STEP: + // next elementary step + break; + + + case Event.FORWARD: + // next exp in stack + case Event.COMPLETE: + // eval until end of exp + state = res; + exp = e.getExp(); + break; + + + case Event.NEXT: + // skip until next candidate of exp + state = res; + exp = e.getExp(); + break; + + case Event.SUCCESS: + // eval until success of filter or success of enum + state = res; + exp = e.getExp(); + break; + + + case Event.QUIT: + // complete query + break; + + + case Event.VERBOSE: + wait = true; + break; + + case Event.NONVERBOSE: + wait = true; + break; + + case Event.MAP: + wait = true; + break; + + case Event.HELP: + wait = true; + break; + } + } + return true; + } + + + Node getNode(Node qNode) { + return kgram.getEnvironment().getNode(qNode); + } + + @Override + public void setObject(Object obj) { + if (obj instanceof Eval) { + kgram = (Eval) obj; + } else { + object = obj; + } + } + + public Eval getKGRAM() { + return kgram; + } + + } diff --git a/src/main/java/fr/inria/corese/core/kgram/event/Event.java b/src/main/java/fr/inria/corese/core/kgram/event/Event.java index 982b414df..ba619ba07 100644 --- a/src/main/java/fr/inria/corese/core/kgram/event/Event.java +++ b/src/main/java/fr/inria/corese/core/kgram/event/Event.java @@ -10,70 +10,70 @@ */ public interface Event { - public static final int BEGIN = 0; - public static final int START = 1; - public static final int ENUM = 2; - public static final int MATCH = 3; - public static final int FILTER = 4; - public static final int BIND = 5; - public static final int GRAPH = 6; - public static final int PATH = 7; - public static final int PATHSTEP = 8; - - - public static final int AGG = 13; + int BEGIN = 0; + int START = 1; + int ENUM = 2; + int MATCH = 3; + int FILTER = 4; + int BIND = 5; + int GRAPH = 6; + int PATH = 7; + int PATHSTEP = 8; + + + int AGG = 13; - public static final int FINISH = 14; - public static final int DISTINCT = 15; - public static final int LIMIT = 16; + int FINISH = 14; + int DISTINCT = 15; + int LIMIT = 16; - public static final int RESULT = 19; - public static final int END = 20; + int RESULT = 19; + int END = 20; // warning events - public static final int UNDEF_PROPERTY = 30; - public static final int UNDEF_CLASS = 31; - public static final int UNDEF_GRAPH = 32; + int UNDEF_PROPERTY = 30; + int UNDEF_CLASS = 31; + int UNDEF_GRAPH = 32; - public static final int ALL = 50; + int ALL = 50; // events from user to listener // next step - public static final int STEP = 101; + int STEP = 101; // next edge/node/path - public static final int NEXT = 102; + int NEXT = 102; // skip trace until next expression in stack - public static final int FORWARD = 103; + int FORWARD = 103; // eval current expression silently - public static final int COMPLETE = 104; + int COMPLETE = 104; // eval until current expression succeed - public static final int SUCCESS = 105; + int SUCCESS = 105; // resume execution silently - public static final int QUIT = 109; + int QUIT = 109; // pprint current Mapping - public static final int MAP = 110; - public static final int VERBOSE = 111; - public static final int NONVERBOSE = 113; - public static final int HELP = 112; + int MAP = 110; + int VERBOSE = 111; + int NONVERBOSE = 113; + int HELP = 112; diff --git a/src/main/java/fr/inria/corese/core/kgram/event/StatListener.java b/src/main/java/fr/inria/corese/core/kgram/event/StatListener.java index 9f8705f86..0e52b1f6b 100644 --- a/src/main/java/fr/inria/corese/core/kgram/event/StatListener.java +++ b/src/main/java/fr/inria/corese/core/kgram/event/StatListener.java @@ -1,6 +1,8 @@ package fr.inria.corese.core.kgram.event; import java.text.NumberFormat; +import java.util.EnumMap; +import java.util.Map; import fr.inria.corese.core.kgram.api.core.Edge; import fr.inria.corese.core.kgram.api.core.ExpType; @@ -21,7 +23,7 @@ public class StatListener extends EvalListener { result = 0, query = 0, total = 0, imax =0; int[] stat = new int[Event.END + 1]; - int[] statExp = new int[ExpType.TITLE.length]; + Map statExp = new EnumMap<>(ExpType.Type.class); int[] counter = new int[MAX], @@ -44,8 +46,8 @@ void start(){ for (int i=0; i table; Hashtable tableButton; @@ -71,7 +75,7 @@ public int get() { } catch (IOException e) { // TODO Auto-generated catch block - e.printStackTrace(); + logger.error("Operation failure", e); } return Event.STEP; diff --git a/src/main/java/fr/inria/corese/core/kgram/filter/Checker.java b/src/main/java/fr/inria/corese/core/kgram/filter/Checker.java index 1e79d8472..dad930187 100644 --- a/src/main/java/fr/inria/corese/core/kgram/filter/Checker.java +++ b/src/main/java/fr/inria/corese/core/kgram/filter/Checker.java @@ -11,12 +11,12 @@ /** * Filter Exp Checker - * + * * Check presence of patterns that are always true or always false * Such as: * ?x != ?x - * ?x > ?y && ?x < ?y - * + * ?x > ?y && ?x < ?y + * * @author Olivier Corby, Edelweiss, INRIA 2010 * */ @@ -87,15 +87,12 @@ boolean match(Expr ee){ boolean match(Expr ee, List pat, String mes){ - //System.out.println(exp1 + " " + exp2); boolean suc = false, b; for (Pattern p : pat){ b = matcher.match(p, ee); - //System.out.println(p + " " + ee + " " + b); if (b){ suc = true; - log(ee, mes); } } @@ -103,28 +100,6 @@ boolean match(Expr ee, List pat, String mes){ } - void log(Expr ee, String mes){ - - if (isPattern(ee) && ee.oper() == AND){ - query.addInfo(mes + ": " , ee.getExp(0) + " && " + ee.getExp(1)); - - log(mes + " " + ee.getExp(0) + " && " + ee.getExp(1)); - if (mes.equals(AFALSE)){ - query.addFailure(ee.getExp(0).getFilter()); - query.addFailure(ee.getExp(1).getFilter()); - } - } - else { - query.addInfo(mes + ": ", ee); - - log(mes + " " + ee); - if (mes.equals(AFALSE)){ - query.addFailure(ee.getFilter()); - } - } - } - - /**************************************************************** * * Always true @@ -524,26 +499,6 @@ Pattern fun(int ope, Pattern e1){ return pat(FUNCTION, ope, e1); } - - - void log(Object obj){ - if (verbose) Message.log(Message.CHECK, count++ + " " + obj); - } - - /** - * Called on path regex - */ - void test(Expr path){ - Pattern p1 = pat(JOKER); - Pattern p2 = pat(JOKER); - - Pattern or = fun(JOKER, or(p1, p2)); - Pattern seq = fun(MULT, term(DIV, p1, p2)); - - boolean b = matcher.match(or, path); - //if (b) System.out.println("** Check: " + path); - } - diff --git a/src/main/java/fr/inria/corese/core/kgram/filter/Compile.java b/src/main/java/fr/inria/corese/core/kgram/filter/Compile.java index 222703a51..a4494c486 100644 --- a/src/main/java/fr/inria/corese/core/kgram/filter/Compile.java +++ b/src/main/java/fr/inria/corese/core/kgram/filter/Compile.java @@ -3,11 +3,7 @@ import java.util.ArrayList; import java.util.List; -import fr.inria.corese.core.kgram.api.core.Expr; -import fr.inria.corese.core.kgram.api.core.ExprType; -import fr.inria.corese.core.kgram.api.core.Filter; -import fr.inria.corese.core.kgram.api.core.Node; -import fr.inria.corese.core.kgram.api.core.Regex; +import fr.inria.corese.core.kgram.api.core.*; import fr.inria.corese.core.kgram.core.Exp; import fr.inria.corese.core.kgram.core.Query; @@ -63,11 +59,6 @@ public boolean check(Exp exp){ public boolean check(Exp exp1, Exp exp2){ return checker.check(exp1.getFilter().getExp(), exp2.getFilter().getExp()); } - - public void test(Regex exp){ - if (exp instanceof Expr) - checker.test((Expr) exp); - } /** * exp is a FILTER Exp @@ -140,9 +131,9 @@ void eq(Exp exp){ // compute Node list corresponding to variables List lNode = query.getNodes(exp); if (lNode.size()==2){ - Exp bind = Exp.create(Exp.OPT_BIND); + Exp bind = Exp.create(ExpType.Type.OPT_BIND); for (Node qNode : lNode){ - Exp var = Exp.create(Exp.NODE, qNode); + Exp var = Exp.create(ExpType.Type.NODE, qNode); bind.add(var); } exp.add(bind); @@ -150,7 +141,7 @@ void eq(Exp exp){ } // ?x = 'constant' else if (matcher.match(new Pattern(TERM, EQ, VARIABLE, CONSTANT), ee)){ - Exp bind = buildCst(exp, Exp.OPT_BIND); + Exp bind = buildCst(exp, ExpType.Type.OPT_BIND); if (bind != null){ exp.add(bind); } @@ -159,14 +150,14 @@ else if (matcher.match(new Pattern(TERM, EQ, VARIABLE, CONSTANT), ee)){ - Exp buildCst(Exp exp, int type){ + Exp buildCst(Exp exp, ExpType.Type type){ Filter ff = exp.getFilter(); Expr ee = ff.getExp(); Node node = query.getProperAndSubSelectNode(ff.getVariables().get(0)); if (node != null){ // variable ?x - Exp bind = Exp.create(type, Exp.create(Exp.NODE, node)); - List list = new ArrayList(); + Exp bind = Exp.create(type, Exp.create(ExpType.Type.NODE, node)); + List list = new ArrayList<>(); list.add(getConstants(ee).get(0)); bind.setObject(list); return bind; @@ -174,12 +165,12 @@ Exp buildCst(Exp exp, int type){ return null; } - Exp buildVar(Exp exp, int type){ + Exp buildVar(Exp exp, ExpType.Type type){ List lNode = query.getNodes(exp); if (lNode.size()==2){ Exp bind = Exp.create(type); for (Node node : lNode){ - bind.add(Exp.create(Exp.NODE, node)); + bind.add(Exp.create(ExpType.Type.NODE, node)); } return bind; } @@ -196,14 +187,14 @@ void gl(Exp exp){ Expr ee = ff.getExp(); Pattern pat = new Pattern(TERM, GL, VARIABLE, CONSTANT); if (matcher.match(pat, ee)){ - Exp test = buildCst(exp, Exp.TEST); + Exp test = buildCst(exp, ExpType.Type.TEST); if (test!=null) exp.add(test); } else { pat = new Pattern(TERM, GL, VARIABLE, VARIABLE); if (matcher.match(pat, ee)){ - Exp test = buildVar(exp, Exp.TEST); + Exp test = buildVar(exp, ExpType.Type.TEST); if (test!=null) exp.add(test); } @@ -224,7 +215,7 @@ void or(Exp exp){ Node node = query.getProperAndSubSelectNode(ff.getVariables().get(0)); if (node != null){ List list = getConstants(ee); - Exp bind = Exp.create(Exp.OPT_BIND, Exp.create(Exp.NODE, node)); + Exp bind = Exp.create(ExpType.Type.OPT_BIND, Exp.create(ExpType.Type.NODE, node)); bind.setObject(list); exp.add(bind); } @@ -256,7 +247,7 @@ void in(Exp exp) { Node node = query.getProperAndSubSelectNode(lvar.get(0)); if (node != null) { - Exp bind = Exp.create(Exp.OPT_BIND, Exp.create(Exp.NODE, node)); + Exp bind = Exp.create(ExpType.Type.OPT_BIND, Exp.create(ExpType.Type.NODE, node)); bind.setObject(list); exp.add(bind); } @@ -301,7 +292,7 @@ List getConstants(Expr exp){ List getConstants(Expr exp, List list){ switch (exp.type()){ - case CONSTANT: //System.out.println(exp); + case CONSTANT: list.add(exp); break; case VARIABLE: break; diff --git a/src/main/java/fr/inria/corese/core/kgram/filter/MatchBind.java b/src/main/java/fr/inria/corese/core/kgram/filter/MatchBind.java index f2e98acc2..45b48d0b4 100644 --- a/src/main/java/fr/inria/corese/core/kgram/filter/MatchBind.java +++ b/src/main/java/fr/inria/corese/core/kgram/filter/MatchBind.java @@ -19,7 +19,7 @@ * */ public class MatchBind { - private static Logger logger = LoggerFactory.getLogger(MatchBind.class); + private static final Logger logger = LoggerFactory.getLogger(MatchBind.class); Hashtable table; List stack; diff --git a/src/main/java/fr/inria/corese/core/kgram/filter/Matcher.java b/src/main/java/fr/inria/corese/core/kgram/filter/Matcher.java index 16bfbe3ec..12101ab49 100644 --- a/src/main/java/fr/inria/corese/core/kgram/filter/Matcher.java +++ b/src/main/java/fr/inria/corese/core/kgram/filter/Matcher.java @@ -23,11 +23,9 @@ public boolean match(Pattern qe, Expr te){ } boolean match(Pattern qe, Expr te, MatchBind bind){ - //System.out.println("** Matcher: " + qe + " " + te); rec = qe.isRec(); matchConstant = qe.isMatchConstant(); boolean b = process(qe, te, bind); - //System.out.println("** Matcher: " + qe + " " + te + " " + b); return b; } @@ -175,20 +173,15 @@ else if (rec){ return false; } - //System.out.println("** M2: " + qarg + " " + targ); - if (process(qarg, targ, bind)){ // OK } - //System.out.println("** M3: " + qarg + " " + targ); - else if (rec){ - //System.out.println("** M4: " + qarg + " " + targ); + else if (rec){ // recursive match of Pattern qe on argument targ // qe = OR(EXP) // qarg = EXP // targ = OR(EXP1, EXP2) if (process(qe, targ, bind)){ - //System.out.println("** M5: " + qe + " " + targ); // OK } else { @@ -201,7 +194,6 @@ else if (rec){ return false; } } - //System.out.println("** M6: " + qe + " " + te); if (! bind.hasValue(qe)){ // because when rec = true, qe may have already been bound to an arg of te @@ -232,8 +224,6 @@ else if (inverse(qe.oper(), te.oper())){ process(fst, te.getExp(0), bind) && process(snd, te.getExp(1), bind); - //System.out.println("** M9: " + qe + " " + te + " " + b); - if (! b){ bind.clean(size); @@ -242,8 +232,7 @@ else if (inverse(qe.oper(), te.oper())){ // switch ?x = ?y to ?y = ?x b = process(snd, te.getExp(0), bind) && - process(fst, te.getExp(1), bind); - //System.out.println("** M10: " + qe + " " + te + " " + b); + process(fst, te.getExp(1), bind); } } diff --git a/src/main/java/fr/inria/corese/core/kgram/filter/Pattern.java b/src/main/java/fr/inria/corese/core/kgram/filter/Pattern.java index 7f0b4ef5a..6dbf9a989 100644 --- a/src/main/java/fr/inria/corese/core/kgram/filter/Pattern.java +++ b/src/main/java/fr/inria/corese/core/kgram/filter/Pattern.java @@ -27,8 +27,8 @@ public class Pattern implements ExprType, Expr { String label; // recursive pattern, ako * boolean rec = false, - matchConstant = true;; - List args; + matchConstant = true; + List args; Expr exp; Pattern(){ diff --git a/src/main/java/fr/inria/corese/core/kgram/path/Automaton.java b/src/main/java/fr/inria/corese/core/kgram/path/Automaton.java index 0f2c92923..459d745ec 100644 --- a/src/main/java/fr/inria/corese/core/kgram/path/Automaton.java +++ b/src/main/java/fr/inria/corese/core/kgram/path/Automaton.java @@ -101,7 +101,6 @@ void compile(Regex exp){ if (pending.size()>0){ // complete pending transitions to final state out = create(); - //System.out.println("** A1: " + out); for (Step step : pending){ step.setState(out); } @@ -110,12 +109,9 @@ void compile(Regex exp){ else { // use case: star(Exp) out = current; - //System.out.println("** A2: " + out); } out.setOut(true); compile(); - - //System.out.println(this); } void compile(){ @@ -136,8 +132,6 @@ void compile(){ */ void compute(Regex exp, Regex star, boolean or, boolean inverse, boolean reverse){ - //if (exp.getExpr()!=null) System.out.println("** A: " + exp + " " + exp.getExpr() + " " + exp.isSeq()); - if (exp.isReverse()){ // ?x ^ ex:prop ?y // SPARQL 1.1 inverse edge @@ -227,7 +221,6 @@ else if (exp.isAlt()){ // csave: A->? ; B->? compute(e, star, true, inverse, reverse); current = csave; - //System.out.println("**A2: " + current); } // A->? ; B->? psave.addAll(pending); diff --git a/src/main/java/fr/inria/corese/core/kgram/path/GraphPath.java b/src/main/java/fr/inria/corese/core/kgram/path/GraphPath.java index 8fa9c8de5..18139418e 100644 --- a/src/main/java/fr/inria/corese/core/kgram/path/GraphPath.java +++ b/src/main/java/fr/inria/corese/core/kgram/path/GraphPath.java @@ -13,9 +13,9 @@ public class GraphPath extends Thread { //private Buffer buf; - private Buffer mbuf; - private Environment mem; - private PathFinder finder; + private final Buffer mbuf; + private final Environment mem; + private final PathFinder finder; diff --git a/src/main/java/fr/inria/corese/core/kgram/path/Path.java b/src/main/java/fr/inria/corese/core/kgram/path/Path.java index 92d4434ad..1e1dbf571 100644 --- a/src/main/java/fr/inria/corese/core/kgram/path/Path.java +++ b/src/main/java/fr/inria/corese/core/kgram/path/Path.java @@ -152,7 +152,7 @@ public Edge get(int n) { public Edge getEdge(int n) { Edge ent = path.get(n); if (ent instanceof EdgeInv) { - return (EdgeInv) ent; + return ent; } return ent.getEdge(); } @@ -238,7 +238,7 @@ public Iterator nodeIterator() { private int i = 0; private int j = 0; private int ii; - private boolean hasNext = length() > 0 ? true : false; + private boolean hasNext = length() > 0; @Override public boolean hasNext() { @@ -289,15 +289,6 @@ public String toString() { return str; } - public void trace() { - int i = 0; - for (Iterator it = nodeIterator(); it.hasNext();) { - Node cc = it.next(); - System.out.println(i++ + " " + cc + " "); - } - System.out.println(); - } - @Override public Iterable getEdges(Node gNode, List from, Edge qEdge, Environment env) { return path; diff --git a/src/main/java/fr/inria/corese/core/kgram/path/PathFinder.java b/src/main/java/fr/inria/corese/core/kgram/path/PathFinder.java index 16f1347cb..5d00dbf7b 100644 --- a/src/main/java/fr/inria/corese/core/kgram/path/PathFinder.java +++ b/src/main/java/fr/inria/corese/core/kgram/path/PathFinder.java @@ -74,7 +74,7 @@ */ public class PathFinder { - private static Logger logger = LoggerFactory.getLogger(PathFinder.class); + private static final Logger logger = LoggerFactory.getLogger(PathFinder.class); public static long cedge = 0, cresult = 0, ctest = 0; // thread that enumerates the path private GraphPath path; @@ -100,29 +100,29 @@ public class PathFinder { private int index = 0; // the inverse of the index (i.e. the other arg) private int other; - private boolean isStop = false, - hasEvent = false, - hasListener = false, - // true if breadth first (else depth first) - isBreadth, - isDistinct = !true, - defaultBreadth = !true, - // true if accept subproperty in regexp - isSubProperty, - isReverse, - isShort, - isOne, - // if true: return list of path instead of thread buffer: 50% faster but enumerate all path - isList = false, - checkLoop = false, - isCountPath = false, - isCache = !true, - trace = true; + private boolean isStop = false; + private boolean hasEvent = false; + private boolean hasListener = false; + private boolean// true if breadth first (else depth first) + isBreadth; + private boolean isDistinct = !true; + private boolean defaultBreadth = !true; + private boolean// true if accept subproperty in regexp + isSubProperty; + private boolean isReverse; + private boolean isShort; + private boolean isOne; + private boolean// if true: return list of path instead of thread buffer: 50% faster but enumerate all path + isList = false; + private boolean checkLoop = false; + private boolean isCountPath = false; + private boolean isCache = !true; + private final boolean trace = true; private int maxLength = Integer.MAX_VALUE, min = 0, max = maxLength, userMin = -1, userMax = -1; - private int count = 0; + private final int count = 0; private Regex regexp1, regexp; // depth or width first private String mode = ""; @@ -412,7 +412,7 @@ public void interrupt() { } /** - * init at creation time, no need to change. pmax comes from pathLength() <= + * init at creation time, no need to change. pmax comes from pathLength() <= * pmax */ public void init(Regex exp, Object smode, int pmin, int pmax) { @@ -527,7 +527,7 @@ void process(Node cstart, Environment memory) { * memory the list of edges */ private Mapping result(Path path, Node gNode, Node src, Node start, boolean isReverse) { - //if (edge.getIndex()==1)System.out.println(producer.getGraphNode(edge, edge) + " " + edge); + //if (edge.getIndex()==1)logger.debug(producer.getGraphNode(edge, edge) + " " + edge); Edge ee = edge; int length = 3; int ip = 2, is = 3; @@ -609,18 +609,13 @@ private boolean check(Node n0, Node n1) { if (!matcher.match(edge.getNode(1), n1, memory)) { return false; } - if (targetNode != null && !targetNode.match(n1)) { - return false; - } + return targetNode == null || targetNode.match(n1); } else { if (!matcher.match(edge.getNode(0), n0, memory)) { return false; } - if (targetNode != null && !targetNode.match(n0)) { - return false; - } + return targetNode == null || targetNode.match(n0); } - return true; } /** @@ -770,7 +765,7 @@ void eval(Record stack, Path path, Node start, Node src) { Regex exp = stack.pop(); - //System.out.println(exp.toString() + " " + start); + //logger.debug(exp.toString() + " " + start); switch (exp.retype()) { @@ -1321,10 +1316,6 @@ void plus(Regex exp, Record stack, Path path, Node start, Node src) { } - void trace(Object str) { - System.out.println("** PF: " + str); - } - /** * exp{n,m} exp{n,} */ diff --git a/src/main/java/fr/inria/corese/core/kgram/path/Record.java b/src/main/java/fr/inria/corese/core/kgram/path/Record.java index e39009581..a7df1a28d 100644 --- a/src/main/java/fr/inria/corese/core/kgram/path/Record.java +++ b/src/main/java/fr/inria/corese/core/kgram/path/Record.java @@ -48,7 +48,6 @@ Record set(Regex exp){ Regex pop(){ if (size() == 0){ - System.out.println("** PP: pop empty"); return null; } Regex exp = get(size()-1); diff --git a/src/main/java/fr/inria/corese/core/kgram/path/Stack.java b/src/main/java/fr/inria/corese/core/kgram/path/Stack.java index ad5b35539..160e23673 100644 --- a/src/main/java/fr/inria/corese/core/kgram/path/Stack.java +++ b/src/main/java/fr/inria/corese/core/kgram/path/Stack.java @@ -40,9 +40,8 @@ void pop(Step st, Path path){ boolean loop(Step st, Path path){ int index = steps.lastIndexOf(st); if (index == -1) return false; - if (sizes.get(index) == path.size()) return true; - return false; - } + return sizes.get(index) == path.size(); + } int size(Step st){ int index = steps.lastIndexOf(st); diff --git a/src/main/java/fr/inria/corese/core/kgram/path/State.java b/src/main/java/fr/inria/corese/core/kgram/path/State.java index cc4c44d18..2089ec537 100644 --- a/src/main/java/fr/inria/corese/core/kgram/path/State.java +++ b/src/main/java/fr/inria/corese/core/kgram/path/State.java @@ -63,9 +63,7 @@ void incCount(int n){ boolean endLoop(){ if (isBound()){ - if (getCount() >= getMax()){ - return true; - } + return getCount() >= getMax(); } return false; } diff --git a/src/main/java/fr/inria/corese/core/kgram/path/Visit.java b/src/main/java/fr/inria/corese/core/kgram/path/Visit.java index fb0815820..b5e8306c8 100644 --- a/src/main/java/fr/inria/corese/core/kgram/path/Visit.java +++ b/src/main/java/fr/inria/corese/core/kgram/path/Visit.java @@ -159,9 +159,6 @@ void add(Node n) { void remove(Node n) { if (isReverse) { - if (!list.get(list.size() - 1).equals(n)) { - System.out.println("** ERROR Visit: " + n + " " + list); - } list.remove(list.size() - 1); } else { table.remove(n); @@ -490,280 +487,4 @@ Integer getLength(Node n, Regex exp) { return ltable.getLength(n, exp); } -// void setRegex(Node n, Regex e) { -// n.setProperty(Node.REGEX, e); -// } -// -// Regex getRegex(Node n) { -// return (Regex) n.getProperty(Node.REGEX); -// } - - /** - * *********************************** - * Old version - */ -// boolean loop(Regex exp, Node start) { -// if (isReverse) { -// insert(exp, start); -// if (revLoop(exp)) { -// remove(exp, start); -// return true; -// } -// } else if (eLoop(exp, start)) { -// return true; -// } else { -// insert(exp, start); -// } -// -// return false; -// } -// -// void start(Node node) { -// for (Regex exp : regexList) { -// add(exp, node); -// } -// } -// -// void leave(Node node) { -// for (Regex exp : regexList) { -// remove(exp, node); -// } -// } -// -// void set(Regex exp, Table t) { -// if (t != null) { -// eetable.put(exp, t); -// } -// } -// -// Table unset(Regex exp) { -// Table t = eetable.get(exp); -// eetable.remove(exp); -// return t; -// } -// -// void insert(Regex exp, Node start) { -// if (start == null) { -// // subscribe exp to start() above because start node is not bound yet -// regexList.add(exp); -// } else { -// add(exp, start); -// } -// } -// -// void add(Regex exp, Node node) { -// if (isReverse) { -// ladd(exp, node); -// } else { -// eadd(exp, node); -// } -// } -// -// // reverse case: add node in list -// void ladd(Regex exp, Node node) { -// List list = etable.get(exp); -// if (list == null) { -// list = new ArrayList(); -// etable.put(exp, list); -// } -// list.add(node); -// } -// -// // forward case: add in table -// void eadd(Regex exp, Node node) { -// if (speedUp) { -// node.setProperty(Node.STATUS, true); -// return; -// } -// Table table = eetable.get(exp); -// if (table == null) { -// table = new Table(); -// eetable.put(exp, table); -// } -// table.put(node, node); -// } -// -// void remove(Regex exp, Node node) { -// if (node == null) { -// regexList.remove(exp); -// return; -// } -// -// if (isReverse) { -// lremove(exp, node); -// } else { -// eremove(exp, node); -// } -// } -// -// // reverse case -// void lremove(Regex exp, Node node) { -// List list = etable.get(exp); -// if (!list.get(list.size() - 1).equals(node)) { -// System.out.println("** ERROR Visit: " + node + " " + list); -// } -// list.remove(list.size() - 1); -// } -// -// // forward case -// void eremove(Regex exp, Node node) { -// if (speedUp) { -// node.setProperty(Node.STATUS, false); -// return; -// } -// Table table = eetable.get(exp); -// table.remove(node); -// } -// -// // forward case -// boolean eLoop(Regex exp, Node start) { -// if (speedUp) { -// return (start != null && start.getProperty(Node.STATUS) == Boolean.TRUE); -// } -// Table table = eetable.get(exp); -// if (table == null) { -// return false; -// } -// return table.containsKey(start); -// } -// -// /** -// * Test if there is a loop on path of exp path isReverse -// */ -// boolean revLoop(Regex exp) { -// -// List list = etable.get(exp); -// if (list == null || list.size() < 2) { -// return false; -// } -// int last = list.size() - 1; -// -// // use case: ?s {2,} ex:uri -// // Walk through the list backward (from to ?s), skip 2 first nodes -// // cf W3C pp test case -// Node node = null; -// int count = 0; -// int min = exp.getMin(); -// for (int i = last; i >= 0; i--) { -// if (count < min) { -// count++; -// continue; -// } else if (count == min) { -// node = list.get(i); -// } else { -// if (list.get(i).equals(node)) { -// return true; -// } -// } -// count++; -// } -// -// return false; -// } - - /** - * ******************* - * - * States are deprecated - */ -// List get(State state) { -// return table.get(state); -// } -// -// void put(State state, List list) { -// table.put(state, list); -// } -// -// public void add(State state, Node node) { -// List list = get(state); -// if (list == null) { -// list = new ArrayList(); -// put(state, list); -// } -// list.add(node); -// } -// -// public void remove(State state, Node node) { -// List list = get(state); -// if (!list.get(list.size() - 1).equals(node)) { -// System.out.println("** ERROR Visit: " + node + " " + list); -// } -// list.remove(list.size() - 1); -// } -// -// /** -// * Check whether the last visited node has already been visited as an -// * intermediate node use case: ?x p{2,} ?y : skip the first two nodes (no -// * loop with two first) ?x p{2,} ex:uri : walk backward through the list -// * -// * @deprecated -// * -// */ -// public boolean loop(State state) { -// if (!state.isCheckLoop()) { -// return false; -// } -// -// List list = get(state); -// if (list == null || list.size() < 2) { -// return false; -// } -// int last = list.size() - 1; -// int min = 0; -// if (state.isBound() && !state.isPlus()) { -// min = state.getMin(); -// } -// -// if (isReverse) { -// // use case: ?s {2,} ex:uri -// // Walk through the list backward (from to ?s), skip 2 first nodes -// // cf W3C pp test case -// Node node = null; -// int count = 0; -// for (int i = last; i >= 0; i--) { -// if (count < min) { -// count++; -// continue; -// } else if (count == min) { -// node = list.get(i); -// } else { -// if (list.get(i).equals(node)) { -// return true; -// } -// } -// count++; -// } -// } else { -// Node node = list.get(last); -// for (int i = 0; i < last; i++) { -// if (i < min) { -// continue; -// } -// if (list.get(i).equals(node)) { -// return true; -// } -// } -// } -// -// return false; -// } -// -// /** -// * @deprecated -// */ -// public boolean loop2(State state) { -// List list = get(state); -// if (list == null || list.size() < 2) { -// return false; -// } -// int last = list.size() - 1; -// Node node = list.get(last); -// for (int i = 0; i < last; i++) { -// if (list.get(i).equals(node)) { -// return true; -// } -// } -// return false; -// } - } diff --git a/src/main/java/fr/inria/corese/core/kgram/sorter/core/Const.java b/src/main/java/fr/inria/corese/core/kgram/sorter/core/Const.java index 5818b4d57..6801b5788 100644 --- a/src/main/java/fr/inria/corese/core/kgram/sorter/core/Const.java +++ b/src/main/java/fr/inria/corese/core/kgram/sorter/core/Const.java @@ -1,11 +1,6 @@ package fr.inria.corese.core.kgram.sorter.core; -import static fr.inria.corese.core.kgram.api.core.ExpType.BIND; -import static fr.inria.corese.core.kgram.api.core.ExpType.EDGE; -import static fr.inria.corese.core.kgram.api.core.ExpType.FILTER; -import static fr.inria.corese.core.kgram.api.core.ExpType.GRAPH; -import static fr.inria.corese.core.kgram.api.core.ExpType.OPTIONAL; -import static fr.inria.corese.core.kgram.api.core.ExpType.VALUES; +import fr.inria.corese.core.kgram.api.core.ExpType; /** * Constants @@ -24,11 +19,11 @@ public final class Const { public final static int BOUND = 0, LIST = 0, UNBOUND = Integer.MAX_VALUE; - public static final int[] EVALUABLE_TYPES = {EDGE, GRAPH}; - public static final int[] NOT_EVALUABLE_TYPES = {FILTER, VALUES, BIND, OPTIONAL}; + public static final ExpType.Type[] EVALUABLE_TYPES = {ExpType.Type.EDGE, ExpType.Type.GRAPH}; + public static final ExpType.Type[] NOT_EVALUABLE_TYPES = {ExpType.Type.FILTER, ExpType.Type.VALUES, ExpType.Type.BIND, ExpType.Type.OPTIONAL}; - public static boolean plannable(int type) { - for (int e : NOT_EVALUABLE_TYPES) { + public static boolean plannable(ExpType.Type type) { + for (ExpType.Type e : NOT_EVALUABLE_TYPES) { if (type == e) { return true; } @@ -37,8 +32,8 @@ public static boolean plannable(int type) { return evaluable(type); } - public static boolean evaluable(int type) { - for (int e : EVALUABLE_TYPES) { + public static boolean evaluable(ExpType.Type type) { + for (ExpType.Type e : EVALUABLE_TYPES) { if (type == e) { return true; } diff --git a/src/main/java/fr/inria/corese/core/kgram/sorter/core/IEstimate.java b/src/main/java/fr/inria/corese/core/kgram/sorter/core/IEstimate.java index faa1da5ae..2f16310f1 100644 --- a/src/main/java/fr/inria/corese/core/kgram/sorter/core/IEstimate.java +++ b/src/main/java/fr/inria/corese/core/kgram/sorter/core/IEstimate.java @@ -10,11 +10,11 @@ */ public interface IEstimate { - public final static double MAX_COST = 1.0; - public final static double MIN_COST = 0.0; + double MAX_COST = 1.0; + double MIN_COST = 0.0; //approximate minimum value, but not equal to 0 - public final static double MIN_COST_0 = 1.0 / Double.MAX_VALUE; - public final static double NA_COST = -1; + double MIN_COST_0 = 1.0 / Double.MAX_VALUE; + double NA_COST = -1; /** * Estimate and assign the selectvity (or other criteria) for each node in @@ -24,6 +24,6 @@ public interface IEstimate { * @param producer producer * @param parameters parameters for different implementations */ - public void estimate(QPGraph plein, Producer producer, Object parameters); + void estimate(QPGraph plein, Producer producer, Object parameters); } diff --git a/src/main/java/fr/inria/corese/core/kgram/sorter/core/IProducerQP.java b/src/main/java/fr/inria/corese/core/kgram/sorter/core/IProducerQP.java index 1ede7becb..23170dc89 100644 --- a/src/main/java/fr/inria/corese/core/kgram/sorter/core/IProducerQP.java +++ b/src/main/java/fr/inria/corese/core/kgram/sorter/core/IProducerQP.java @@ -17,7 +17,7 @@ public interface IProducerQP { * SUBJECT( PREDICATE| OBJECT): return the number of disinct SUBJECT( PREDICATE| OBJECT) * @return */ - public int getSize(int type); + int getSize(int type); /** * Return the count of triples according the given type @@ -25,5 +25,5 @@ public interface IProducerQP { * @param type * @return */ - public int getCount(QPGNode n, int type); + int getCount(QPGNode n, int type); } diff --git a/src/main/java/fr/inria/corese/core/kgram/sorter/core/ISort.java b/src/main/java/fr/inria/corese/core/kgram/sorter/core/ISort.java index 72dcd169c..1c9398a4a 100644 --- a/src/main/java/fr/inria/corese/core/kgram/sorter/core/ISort.java +++ b/src/main/java/fr/inria/corese/core/kgram/sorter/core/ISort.java @@ -17,7 +17,7 @@ public interface ISort { * @param unsorted graph * @return List of sorted QPG Node */ - public List sort(QPGraph unsorted); + List sort(QPGraph unsorted); /** * Rewrite the SPARQL exp according to give order of nodes @@ -25,5 +25,5 @@ public interface ISort { * @param nodes * @param start */ - public void rewrite(Exp exp, List nodes, int start); + void rewrite(Exp exp, List nodes, int start); } diff --git a/src/main/java/fr/inria/corese/core/kgram/sorter/core/QPGNode.java b/src/main/java/fr/inria/corese/core/kgram/sorter/core/QPGNode.java index ce8bba3ed..763b19449 100644 --- a/src/main/java/fr/inria/corese/core/kgram/sorter/core/QPGNode.java +++ b/src/main/java/fr/inria/corese/core/kgram/sorter/core/QPGNode.java @@ -1,13 +1,8 @@ package fr.inria.corese.core.kgram.sorter.core; +import fr.inria.corese.core.kgram.api.core.ExpType; import fr.inria.corese.core.kgram.sorter.impl.qpv1.QPGNodeCostModel; import fr.inria.corese.core.kgram.api.core.Edge; -import static fr.inria.corese.core.kgram.api.core.ExpType.BIND; -import static fr.inria.corese.core.kgram.api.core.ExpType.EDGE; -import static fr.inria.corese.core.kgram.api.core.ExpType.FILTER; -import static fr.inria.corese.core.kgram.api.core.ExpType.GRAPH; -import static fr.inria.corese.core.kgram.api.core.ExpType.NODE; -import static fr.inria.corese.core.kgram.api.core.ExpType.VALUES; import fr.inria.corese.core.kgram.api.core.Filter; import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.core.Exp; @@ -29,7 +24,7 @@ public class QPGNode { // the expression that the node encapsulates private final Exp exp; - private final int type; + private final ExpType.Type type; private QPGNodeCostModel costModel = null; private double cost = -1; //the nested QPG in a QPG node, ex, GRAPH @@ -51,7 +46,7 @@ public Exp getExp() { return this.exp; } - public int getType() { + public ExpType.Type getType() { return this.type; } @@ -71,7 +66,7 @@ public void setCost(double cost) { * @return */ public Node getExpNode(int i) { - if (this.type != EDGE) { + if (this.type != ExpType.Type.EDGE) { return null; } @@ -103,8 +98,8 @@ public List shared(QPGNode n) { } public List shared(QPGNode bpn1, QPGNode bpn2) { - int type1 = bpn1.exp.type(); - int type2 = bpn2.exp.type(); + ExpType.Type type1 = bpn1.exp.type(); + ExpType.Type type2 = bpn2.exp.type(); switch (type1) { case EDGE: @@ -119,7 +114,7 @@ public List shared(QPGNode bpn1, QPGNode bpn2) { return this.isShared(bpn2.exp.getNodeList(), bpn1.exp.getEdge()); case BIND: return this.isShared(bpn2.exp.getFilter(), bpn1.exp.getEdge()); - default: ; + default: } break; case GRAPH: @@ -139,7 +134,7 @@ public List shared(QPGNode bpn1, QPGNode bpn2) { else { return this.isShared(bpn2.exp.getNode(), bpn1.exp); } - default:; + default: } case BIND: switch (type2) { @@ -154,7 +149,7 @@ public List shared(QPGNode bpn1, QPGNode bpn2) { else { return this.compare(bpn2.exp.getNode(), bpn1.exp.getNode()); } - default:; + default: } default: break; @@ -239,10 +234,10 @@ private List getVariablesInGraph(Exp graph) { List l = new ArrayList(); for (Exp e : graph) { for (Exp ee : e) { - if (ee.type() == NODE) { + if (ee.type() == ExpType.Type.NODE) { l.add(ee.getNode()); } - if (ee.type() == EDGE) { + if (ee.type() == ExpType.Type.EDGE) { l.addAll(getVariablesInEdge(ee.getEdge())); } } diff --git a/src/main/java/fr/inria/corese/core/kgram/sorter/core/QPGraph.java b/src/main/java/fr/inria/corese/core/kgram/sorter/core/QPGraph.java index 80345964c..9f1ffe667 100644 --- a/src/main/java/fr/inria/corese/core/kgram/sorter/core/QPGraph.java +++ b/src/main/java/fr/inria/corese/core/kgram/sorter/core/QPGraph.java @@ -1,6 +1,6 @@ package fr.inria.corese.core.kgram.sorter.core; -import static fr.inria.corese.core.kgram.api.core.ExpType.EMPTY; +import fr.inria.corese.core.kgram.api.core.ExpType; import fr.inria.corese.core.kgram.core.Exp; import java.util.ArrayList; import java.util.HashMap; @@ -179,7 +179,7 @@ public QPGEdge getEdge(QPGNode n1, QPGNode n2) { * @return */ public List getAllNodes() { - return this.getAllNodes(EMPTY); + return this.getAllNodes(ExpType.Type.EMPTY); } /** @@ -188,7 +188,7 @@ public List getAllNodes() { * @param type EDGE, VALUES, FILTER, GRAPH, otherwise return all * @return */ - public List getAllNodes(int type) { + public List getAllNodes(ExpType.Type type) { if (Const.plannable(type)) { List list = new ArrayList<>(); for (QPGNode node : this.nodes) { diff --git a/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/BasicPatternGenerator.java b/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/BasicPatternGenerator.java index e01c89e54..72f102be3 100644 --- a/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/BasicPatternGenerator.java +++ b/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/BasicPatternGenerator.java @@ -23,7 +23,7 @@ public class BasicPatternGenerator { private final static int TRIPLE_LEN = 3, PATTERN_LEN = 8; /** - * Generate the default basic pattern orders using Np < Ns < No + * Generate the default basic pattern orders using Np < Ns < No * * @return */ diff --git a/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/DepthFirstBestSearch.java b/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/DepthFirstBestSearch.java index 96a4a7dc5..3c16dc223 100644 --- a/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/DepthFirstBestSearch.java +++ b/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/DepthFirstBestSearch.java @@ -1,23 +1,17 @@ package fr.inria.corese.core.kgram.sorter.impl.qpv1; -import static fr.inria.corese.core.kgram.api.core.ExpType.BIND; -import fr.inria.corese.core.kgram.sorter.core.QPGraph; -import fr.inria.corese.core.kgram.sorter.core.QPGNode; -import fr.inria.corese.core.kgram.sorter.core.ISort; -import static fr.inria.corese.core.kgram.api.core.ExpType.EDGE; -import static fr.inria.corese.core.kgram.api.core.ExpType.FILTER; -import static fr.inria.corese.core.kgram.api.core.ExpType.GRAPH; -import static fr.inria.corese.core.kgram.api.core.ExpType.VALUES; import fr.inria.corese.core.kgram.core.Exp; -import fr.inria.corese.core.kgram.sorter.core.QPGEdge; -import fr.inria.corese.core.kgram.sorter.core.IEstimate; +import fr.inria.corese.core.kgram.sorter.core.*; + import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import static fr.inria.corese.core.kgram.api.core.ExpType.*; + /** - * An implementation for sorting the triple pattern depth-first & best greedy + * An implementation for sorting the triple pattern depth-first & best greedy * algorithm * * 1 start with the one with least cost, if there are more than 2 with same cost @@ -27,7 +21,7 @@ * * 3 recursively search until all nodes have been visited * - * 4 every time one node is added to visited, check FILTER & VALUES + * 4 every time one node is added to visited, check FILTER & VALUES * ++ 4.1 now also check BIND 20Jan2015 * * @author Fuqi Song, Wimmics Inria I3S @@ -48,10 +42,10 @@ public DepthFirstBestSearch() { public List sort(QPGraph graph) { this.g = graph; //EDGE GRAPH - List sortableNodes = g.getAllNodes(EDGE); - sortableNodes.addAll(g.getAllNodes(GRAPH)); + List sortableNodes = g.getAllNodes(Type.EDGE); + sortableNodes.addAll(g.getAllNodes(Type.GRAPH)); notVisited.addAll(sortableNodes); - binds.addAll(g.getAllNodes(BIND)); + binds.addAll(g.getAllNodes(Type.BIND)); //each loop is a sub graph while (!notVisited.isEmpty()) { @@ -148,7 +142,7 @@ private void queue(QPGNode minNode, Map pool) { //for a filter, if all linked vairables have been visited, //then add this filter just after these triple patterns private void addFilters() { - List filters = this.g.getAllNodes(FILTER); + List filters = this.g.getAllNodes(Type.FILTER); //others.addAll(g.getNodeList(VALUES)); for (QPGNode f : filters) { @@ -162,7 +156,7 @@ private void addFilters() { //for VALUES, put it just before the vairables being used private void addValues(QPGNode min) { - List values = this.g.getAllNodes(VALUES); + List values = this.g.getAllNodes(Type.VALUES); for (QPGNode v : values) { //if the VALUES use this (first) triple pattern, then add it to @@ -211,7 +205,7 @@ private void addBinds(QPGNode min) { //for BIND, it also can have FILTERs and VALUES, and also it can depends on the //other BINDs expressions, so need to check recusively - while (q.getType()== BIND && !visited.contains(q) && !intersect(linkedBinds, notVisited, binds)) { + while (q.getType()== Type.BIND && !visited.contains(q) && !intersect(linkedBinds, notVisited, binds)) { this.addValues(q); visited.add(q); diff --git a/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/DepthFirstSearch.java b/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/DepthFirstSearch.java index dfc071934..a8f9f7ac5 100644 --- a/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/DepthFirstSearch.java +++ b/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/DepthFirstSearch.java @@ -1,21 +1,12 @@ package fr.inria.corese.core.kgram.sorter.impl.qpv1; -import fr.inria.corese.core.kgram.sorter.core.QPGraph; -import fr.inria.corese.core.kgram.sorter.core.QPGNode; -import fr.inria.corese.core.kgram.sorter.core.ISort; -import static fr.inria.corese.core.kgram.api.core.ExpType.EDGE; -import static fr.inria.corese.core.kgram.api.core.ExpType.FILTER; -import static fr.inria.corese.core.kgram.api.core.ExpType.GRAPH; -import static fr.inria.corese.core.kgram.api.core.ExpType.VALUES; +import fr.inria.corese.core.kgram.api.core.ExpType; import fr.inria.corese.core.kgram.core.Exp; -import fr.inria.corese.core.kgram.sorter.core.QPGEdge; -import fr.inria.corese.core.kgram.sorter.core.IEstimate; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import fr.inria.corese.core.kgram.sorter.core.*; + +import java.util.*; + +import static fr.inria.corese.core.kgram.api.core.ExpType.*; /** * An implementation for sorting the triple pattern Pure depth-first greedy @@ -39,8 +30,8 @@ public DepthFirstSearch() { public List sort(QPGraph graph) { this.g = graph; //EDGE GRAPH - List sortableNodes = g.getAllNodes(EDGE); - sortableNodes.addAll(g.getAllNodes(GRAPH)); + List sortableNodes = g.getAllNodes(ExpType.Type.EDGE); + sortableNodes.addAll(g.getAllNodes(ExpType.Type.GRAPH)); notVisited.addAll(sortableNodes); //each loop is a sub graph @@ -113,21 +104,14 @@ private QPGNode findNext(List lNodes) { private List getChildren(QPGNode n) { // get the linked nodes to a node and sort it (define the sequence of searching) List lNodes = this.g.getLinkedNodes(n), - children = new ArrayList(); + children = new ArrayList<>(); //1 sort the list by selectivity of nodes children.addAll(lNodes); - Collections.sort(children, new Comparator() { - @Override - public int compare(QPGNode o1, QPGNode o2) { - return Double.valueOf(o1.getCost()).compareTo(Double.valueOf(o2.getCost())); - } - }); + Collections.sort(children, (o1, o2) -> Double.valueOf(o1.getCost()).compareTo(Double.valueOf(o2.getCost()))); //1 remvoe visited nodes for (QPGNode node : visited) { - if (children.contains(node)) { - children.remove(node); - } + children.remove(node); } return children; @@ -156,9 +140,7 @@ public int compare(QPGNode n1, QPGNode n2) { //1 remvoe visited nodes for (QPGNode node : visited) { - if (children.contains(node)) { - children.remove(node); - } + children.remove(node); } return children; @@ -179,7 +161,7 @@ private void queue(QPGNode minNode) { //for a filter, if all linked vairables have been visited, //then add this filter just after these triple patterns private void addFilters() { - List filters = this.g.getAllNodes(FILTER); + List filters = this.g.getAllNodes(ExpType.Type.FILTER); //others.addAll(g.getNodeList(VALUES)); for (QPGNode f : filters) { @@ -208,7 +190,7 @@ private void addFilters() { //for VALUES, put it just before the vairables being used private void addValues(QPGNode min) { - List values = this.g.getAllNodes(VALUES); + List values = this.g.getAllNodes(ExpType.Type.VALUES); for (QPGNode v : values) { if (visited.contains(v)) { diff --git a/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/HeuristicsBasedEstimation.java b/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/HeuristicsBasedEstimation.java index f28781f66..e2cd26a90 100644 --- a/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/HeuristicsBasedEstimation.java +++ b/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/HeuristicsBasedEstimation.java @@ -1,14 +1,9 @@ package fr.inria.corese.core.kgram.sorter.impl.qpv1; -import static fr.inria.corese.core.kgram.api.core.ExpType.EDGE; -import static fr.inria.corese.core.kgram.api.core.ExpType.GRAPH; +import fr.inria.corese.core.kgram.api.core.ExpType; import fr.inria.corese.core.kgram.api.query.Producer; -import fr.inria.corese.core.kgram.sorter.core.AbstractCostModel; -import fr.inria.corese.core.kgram.sorter.core.QPGEdge; -import fr.inria.corese.core.kgram.sorter.core.QPGNode; -import fr.inria.corese.core.kgram.sorter.core.QPGraph; -import fr.inria.corese.core.kgram.sorter.core.IEstimate; -import fr.inria.corese.core.kgram.sorter.core.IProducerQP; +import fr.inria.corese.core.kgram.sorter.core.*; + import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -38,9 +33,9 @@ private void estimateNodes() { // 1. get all models of nodes in QPG List models = new ArrayList(); for (QPGNode n : this.graph.getAllNodes()) { - if (n.getType() == EDGE || n.getType() == GRAPH) { + if (n.getType() == ExpType.Type.EDGE || n.getType() == ExpType.Type.GRAPH) { QPGNodeCostModel p = n.getCostModel(); - if (n.getType() == EDGE) { + if (n.getType() == ExpType.Type.EDGE) { p.setParameters(graph); } models.add(p); diff --git a/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/QPGEdgeCostModel.java b/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/QPGEdgeCostModel.java index 0cc2bf7dc..ba7061eed 100644 --- a/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/QPGEdgeCostModel.java +++ b/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/QPGEdgeCostModel.java @@ -1,17 +1,11 @@ package fr.inria.corese.core.kgram.sorter.impl.qpv1; -import static fr.inria.corese.core.kgram.api.core.ExpType.EDGE; -import fr.inria.corese.core.kgram.sorter.core.AbstractCostModel; -import fr.inria.corese.core.kgram.sorter.core.QPGEdge; -import fr.inria.corese.core.kgram.sorter.core.QPGNode; -import static fr.inria.corese.core.kgram.api.core.ExpType.GRAPH; -import fr.inria.corese.core.kgram.sorter.core.Const; -import static fr.inria.corese.core.kgram.sorter.core.Const.OBJECT; -import static fr.inria.corese.core.kgram.sorter.core.Const.PREDICATE; -import static fr.inria.corese.core.kgram.sorter.core.Const.SUBJECT; -import fr.inria.corese.core.kgram.sorter.core.IEstimate; -import static fr.inria.corese.core.kgram.sorter.core.IEstimate.MAX_COST; +import fr.inria.corese.core.kgram.api.core.ExpType; +import fr.inria.corese.core.kgram.sorter.core.*; + import java.util.List; +import static fr.inria.corese.core.kgram.sorter.core.Const.*; +import static fr.inria.corese.core.kgram.sorter.core.IEstimate.MAX_COST; /** * Cost model for QPG edge @@ -33,7 +27,7 @@ public class QPGEdgeCostModel extends AbstractCostModel { public QPGEdgeCostModel(QPGEdge edge) { this.edge = edge; if (this.estimatable()) { - if(this.edge.get(0).getType()== EDGE &&this.edge.get(1).getType()== EDGE){ + if(this.edge.get(0).getType()== ExpType.Type.EDGE &&this.edge.get(1).getType()== ExpType.Type.EDGE){ this.setJtype(); } this.setNshare(); @@ -70,7 +64,7 @@ public void estimate(List params) { QPGNode node1 = edge.get(0), node2 = edge.get(1); - int tNode1 = node1.getType(), tNode2 = node2.getType(); + ExpType.Type tNode1 = node1.getType(), tNode2 = node2.getType(); //1. type of one of them is FILTER or VALUES or BIND, ne assign pas le weight if (!Const.evaluable(tNode1) && !Const.evaluable(tNode2)) { this.edge.setCost(MAX_COST); @@ -84,7 +78,7 @@ public void estimate(List params) { } //2 The EDGE connects at least a GRAPH - if (tNode1 == GRAPH || tNode2 == GRAPH) { + if (tNode1 == ExpType.Type.GRAPH || tNode2 == ExpType.Type.GRAPH) { this.edge.setCost(1.0 / 3.0 * Nshare); return; } diff --git a/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/QPGNodeCostModel.java b/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/QPGNodeCostModel.java index 32f4980ce..7f099a43b 100644 --- a/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/QPGNodeCostModel.java +++ b/src/main/java/fr/inria/corese/core/kgram/sorter/impl/qpv1/QPGNodeCostModel.java @@ -1,10 +1,8 @@ package fr.inria.corese.core.kgram.sorter.impl.qpv1; import fr.inria.corese.core.kgram.api.core.Edge; -import static fr.inria.corese.core.kgram.api.core.ExpType.EDGE; -import static fr.inria.corese.core.kgram.api.core.ExpType.FILTER; -import static fr.inria.corese.core.kgram.api.core.ExpType.GRAPH; -import static fr.inria.corese.core.kgram.api.core.ExpType.GRAPHNODE; + +import fr.inria.corese.core.kgram.api.core.ExpType; import fr.inria.corese.core.kgram.api.core.Node; import fr.inria.corese.core.kgram.core.Exp; import fr.inria.corese.core.kgram.sorter.core.AbstractCostModel; @@ -49,7 +47,7 @@ public QPGNodeCostModel(QPGNode n, List bindings) { //todo with GNode Node gNode = null; - if (n.getType() == EDGE) { + if (n.getType() == ExpType.Type.EDGE) { Edge e = n.getExp().getEdge(); //the value of S P O G can be: 0[bound], ?[length of constant list], Integer.MAX_VALUE[unbound] @@ -60,9 +58,9 @@ public QPGNodeCostModel(QPGNode n, List bindings) { // get the variables in the triple pattern n.getExp().getVariables(variables); - } else if (n.getType() == GRAPH) { + } else if (n.getType() == ExpType.Type.GRAPH) { //obtain the graph node - if (n.getExp().size() > 0 && n.getExp().get(0).type() == GRAPHNODE) { + if (n.getExp().size() > 0 && n.getExp().get(0).type() == ExpType.Type.GRAPHNODE) { //GRAPH{GRAPHNODE{NODE{data:aliceFoaf } } AND...} gNode = n.getExp().get(0).get(0).getNode(); this.pattern[G] = getNodeType(gNode, bindings); @@ -114,7 +112,7 @@ public void setParameters(QPGraph graph) { // FV: filter variables // FF: filter number private void setFilterNumber(QPGraph graph) { - List nodes = graph.getAllNodes(FILTER); + List nodes = graph.getAllNodes(ExpType.Type.FILTER); int noOfFilter = 0, noOfVariable = 0; @@ -196,18 +194,18 @@ public int compare(QPGNodeCostModel m1, QPGNodeCostModel m2) { public static int compareModel(QPGNodeCostModel m1, QPGNodeCostModel m2, final int[][] bp, final IProducerQP ip) { //GRAPH //rule 1: GRAPH has more priority than EDGE - int type1 = m1.node.getExp().type(); - int type2 = m2.node.getExp().type(); + ExpType.Type type1 = m1.node.getExp().type(); + ExpType.Type type2 = m2.node.getExp().type(); //to/can be extended!! //when comparing EDGE/GRAPH, EDGE has priority except if EDGE = (? ? ?) //R1 - if (type1 == GRAPH && type2 == EDGE) { + if (type1 == ExpType.Type.GRAPH && type2 == ExpType.Type.EDGE) { return (m2.match(bp) == (bp.length - 1)) ? -1 : 1; - } else if (type1 == EDGE && type2 == GRAPH) { + } else if (type1 == ExpType.Type.EDGE && type2 == ExpType.Type.GRAPH) { return (m1.match(bp) == (bp.length - 1)) ? 1 : -1; //when comparing two GRAPHs, compare by the type of named graph (bound, unbound, etc...) - } else if (type1 == GRAPH && type2 == GRAPH) { + } else if (type1 == ExpType.Type.GRAPH && type2 == ExpType.Type.GRAPH) { return m1.pattern[G] > m2.pattern[G] ? 1 : -1; } else {//EDGE - EDGE //EDGE @@ -257,12 +255,8 @@ public boolean isBound(List bindings, Node var) { @Override public boolean isParametersOK(List params) { - if (params == null || params.size() != 2 || !(params.get(0) instanceof Integer) - || !(params.get(1) instanceof Integer)) { - return false; - } - - return true; + return params != null && params.size() == 2 && params.get(0) instanceof Integer + && params.get(1) instanceof Integer; } @Override diff --git a/src/main/java/fr/inria/corese/core/kgram/tool/ApproximateSearchEnv.java b/src/main/java/fr/inria/corese/core/kgram/tool/ApproximateSearchEnv.java index 7f18f902d..832f006c9 100644 --- a/src/main/java/fr/inria/corese/core/kgram/tool/ApproximateSearchEnv.java +++ b/src/main/java/fr/inria/corese/core/kgram/tool/ApproximateSearchEnv.java @@ -19,7 +19,7 @@ public class ApproximateSearchEnv { private static int code = 0; - private int id; + private final int id; private final Map> all; public ApproximateSearchEnv() { @@ -100,9 +100,7 @@ public Double aggregate(Environment env) { */ public Double aggregate(Environment env, Expr var, double sim) { List lv = this.getVariables(); - if (lv.contains(var)) { - lv.remove(var); - } + lv.remove(var); Double cb = (lv.isEmpty()) ? 1 : aggregate(env, lv); return cb * sim; @@ -176,11 +174,8 @@ public boolean equals(Object obj) { return false; } final Key other = (Key) obj; - if (this.var != other.var && (this.var == null || !this.var.equals(other.var))) { - return false; - } + return this.var == other.var || (this.var != null && this.var.equals(other.var)); //only that var is equal is ok - return true; } @Override diff --git a/src/main/java/fr/inria/corese/core/kgram/tool/EnvironmentImpl.java b/src/main/java/fr/inria/corese/core/kgram/tool/EnvironmentImpl.java index 2fcedbcc6..7bcccd24e 100644 --- a/src/main/java/fr/inria/corese/core/kgram/tool/EnvironmentImpl.java +++ b/src/main/java/fr/inria/corese/core/kgram/tool/EnvironmentImpl.java @@ -19,7 +19,7 @@ import fr.inria.corese.core.sparql.triple.parser.ASTExtension; public class EnvironmentImpl implements Environment { - Query query; + protected Query query; public EnvironmentImpl(){ } diff --git a/src/main/java/fr/inria/corese/core/kgram/tool/Message.java b/src/main/java/fr/inria/corese/core/kgram/tool/Message.java index 05e0b1595..537a0f7d8 100644 --- a/src/main/java/fr/inria/corese/core/kgram/tool/Message.java +++ b/src/main/java/fr/inria/corese/core/kgram/tool/Message.java @@ -9,63 +9,26 @@ public class Message { static Logger logger = LoggerFactory.getLogger(Message.class); - public static final int UNDEF_VAR = 0; - public static final int FAIL = 1; - public static final int FAIL_AT = 2; - public static final int EVAL = 3; - public static final int FREE = 4; - public static final int CHECK = 5; - public static final int REWRITE = 6; - public static final int PRAGMA = 7; - public static final int LOOP = 8; - public static final int UNDEF_FUN = 9; - public static final int AGG = 10; - - public static final String NL = "\n"; - - static Hashtable table; - - public static String get(int code) { - if (table == null) { - init(); + public enum Prefix { + UNDEF_VAR("Undefined variable: "), + UNDEF_FUN("Undefined function: "), + FAIL("Corese fail at compile time"), + FAIL_AT("Corese fail at: "), + EVAL("Eval: "), + FREE("Pattern is Free: "), + CHECK("Check: "), + REWRITE("Compiler rewrite error: "), + PRAGMA("Pragma: "), + LOOP("Loop: "), + AGG("Aggregate limited to (defined) variable: "); + + private final String prefix; + Prefix(String p) { + prefix = p; + } + public String getString() { + return prefix; } - return table.get(code); - } - - static void init() { - table = new Hashtable<>(); - - def(UNDEF_VAR, "Undefined variable: "); - def(UNDEF_FUN, "Undefined function: "); - def(FAIL, "KGRAM fail at compile time"); - def(FAIL_AT, "KGRAM fail at: "); - def(EVAL, "Eval: "); - def(FREE, "Pattern is Free: "); - def(CHECK, "Check: "); - def(REWRITE, "Compiler rewrite error: "); - def(PRAGMA, "Pragma: "); - def(LOOP, "Loop: "); - def(AGG, "Aggregate limited to (defined) variable: "); - } - - static void def(int code, String mes) { - table.put(code, mes); - } - - public static void log(int code) { - logger.warn(get(code)); - } - - public static void log() { - //System.out.println(); - } - - public static void log(int code, Object mes) { - logger.warn(get(code) + mes); - } - - public static void log(Object mes) { - logger.warn(mes.toString()); } } diff --git a/src/main/java/fr/inria/corese/core/kgram/tool/ProducerDefault.java b/src/main/java/fr/inria/corese/core/kgram/tool/ProducerDefault.java index 83ffe0be0..23ad7e7f9 100644 --- a/src/main/java/fr/inria/corese/core/kgram/tool/ProducerDefault.java +++ b/src/main/java/fr/inria/corese/core/kgram/tool/ProducerDefault.java @@ -149,8 +149,6 @@ public Edge copy(Edge ent) { public void close() { } - ; - @Override public void start(Query q) { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. diff --git a/src/main/java/fr/inria/corese/core/load/AddTripleHelper.java b/src/main/java/fr/inria/corese/core/load/AddTripleHelper.java index 3cae73e06..a450b646a 100644 --- a/src/main/java/fr/inria/corese/core/load/AddTripleHelper.java +++ b/src/main/java/fr/inria/corese/core/load/AddTripleHelper.java @@ -202,7 +202,6 @@ String blankNode() { /** * Get the default graph source according to the status of graph and source * - * @param graph Graph that will be filled in * @param source The particular name to add nodes to * * @return diff --git a/src/main/java/fr/inria/corese/core/load/ILoadSerialization.java b/src/main/java/fr/inria/corese/core/load/ILoadSerialization.java index 8df060513..126b63199 100644 --- a/src/main/java/fr/inria/corese/core/load/ILoadSerialization.java +++ b/src/main/java/fr/inria/corese/core/load/ILoadSerialization.java @@ -10,8 +10,8 @@ */ public interface ILoadSerialization { - public static final int LITERAL = 10; - public static final int NON_LITERAL = 20; + int LITERAL = 10; + int NON_LITERAL = 20; /** * Add triples from parser to corese graph @@ -24,5 +24,5 @@ public interface ILoadSerialization { * @param literalType literal type (LITERAL | NON_LITERAL) * @param source */ - public void addTriple(String subj, String pred, String obj, String lang, String type, int literalType, Node source); + void addTriple(String subj, String pred, String obj, String lang, String type, int literalType, Node source); } diff --git a/src/main/java/fr/inria/corese/core/load/Load.java b/src/main/java/fr/inria/corese/core/load/Load.java index ac77fd9f4..86f4ffcd0 100644 --- a/src/main/java/fr/inria/corese/core/load/Load.java +++ b/src/main/java/fr/inria/corese/core/load/Load.java @@ -536,10 +536,8 @@ public InputStream getStream(String path, String... formats) contentType = srv.getFormat(); } if (contentType != null) { - // logger.info("Content-type: " + contentType); Loader.format myFormat = getTypeFormat(contentType, Loader.format.UNDEF_FORMAT); } - // System.out.println("load: " + contentType + " " + myFormat); } else { stream = new FileInputStream(path); diff --git a/src/main/java/fr/inria/corese/core/load/LoadException.java b/src/main/java/fr/inria/corese/core/load/LoadException.java index 309fce2d4..5f751d0a6 100644 --- a/src/main/java/fr/inria/corese/core/load/LoadException.java +++ b/src/main/java/fr/inria/corese/core/load/LoadException.java @@ -13,6 +13,14 @@ public LoadException(Exception ee) { this.set(ee); } + public LoadException(String message) { + super(message); + } + + public LoadException(String message, Throwable cause) { + super(message, cause); + } + private void set(Exception ee) { ex = ee; } @@ -68,9 +76,6 @@ public String toString() { else if (isSafetyException() && getSafetyException().getPath() != null) { str += "\n" + getSafetyException().getPath(); } -// else { -// str += "\n" + "unknown location"; -// } return str; } diff --git a/src/main/java/fr/inria/corese/core/load/LoadFormat.java b/src/main/java/fr/inria/corese/core/load/LoadFormat.java index 385db0506..8433f28f8 100644 --- a/src/main/java/fr/inria/corese/core/load/LoadFormat.java +++ b/src/main/java/fr/inria/corese/core/load/LoadFormat.java @@ -3,6 +3,8 @@ import fr.inria.corese.core.api.Loader; import fr.inria.corese.core.transform.Transformer; import fr.inria.corese.core.sparql.triple.parser.NSManager; +import fr.inria.corese.core.transform.TransformerUtils; + import java.util.HashMap; /** @@ -82,10 +84,10 @@ static void init(){ dtable = new HashMap(); - ddefine(Transformer.TURTLE, Loader.format.TURTLE_FORMAT); + ddefine(TransformerUtils.TURTLE, Loader.format.TURTLE_FORMAT); ddefine(NT_FORMAT, Loader.format.NT_FORMAT); - ddefine(Transformer.RDFXML, Loader.format.RDFXML_FORMAT); - ddefine(Transformer.JSON, Loader.format.JSONLD_FORMAT); + ddefine(TransformerUtils.RDFXML, Loader.format.RDFXML_FORMAT); + ddefine(TransformerUtils.JSON, Loader.format.JSONLD_FORMAT); } diff --git a/src/main/java/fr/inria/corese/core/load/QueryLoad.java b/src/main/java/fr/inria/corese/core/load/QueryLoad.java index b9746cf46..78f4c2e9a 100644 --- a/src/main/java/fr/inria/corese/core/load/QueryLoad.java +++ b/src/main/java/fr/inria/corese/core/load/QueryLoad.java @@ -1,37 +1,33 @@ package fr.inria.corese.core.load; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.Writer; -import java.net.URL; - -import fr.inria.corese.core.sparql.exceptions.EngineException; import fr.inria.corese.core.compiler.parser.Pragma; import fr.inria.corese.core.kgram.core.Query; import fr.inria.corese.core.query.QueryEngine; import fr.inria.corese.core.sparql.api.IDatatype; +import fr.inria.corese.core.sparql.exceptions.EngineException; import fr.inria.corese.core.sparql.triple.function.term.TermEval; import fr.inria.corese.core.sparql.triple.parser.Access; import fr.inria.corese.core.sparql.triple.parser.NSManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.BufferedWriter; +import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.BufferedReader; + import java.net.MalformedURLException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import java.net.URL; + public class QueryLoad extends Load { - private static Logger logger = LoggerFactory.getLogger(QueryLoad.class); - static final String HTTP = "http://"; - static final String FILE = "file://"; - static final String FTP = "ftp://"; - static final String[] PROTOCOLS = {HTTP, FILE, FTP}; + private static final Logger logger = LoggerFactory.getLogger(QueryLoad.class); static final String NL = "\n"; QueryEngine engine; @@ -71,8 +67,7 @@ public void parse(String name) throws LoadException { } } } - - @Deprecated + public void load(Reader read) throws LoadException { parse(read); } @@ -89,7 +84,7 @@ public void parse(Reader read) throws LoadException { } @Override - boolean isURL(String path) { + boolean isURL(String path) { try { new URL(path); } catch (MalformedURLException e) { @@ -97,13 +92,12 @@ boolean isURL(String path) { } return true; } - - @Deprecated + public String read(InputStream stream) throws IOException { return read(new InputStreamReader(stream)); } - - public String readWE(InputStream stream) throws LoadException { + + public String readWE(InputStream stream) throws LoadException { try { return read(new InputStreamReader(stream)); } catch (IOException ex) { @@ -111,28 +105,27 @@ public String readWE(InputStream stream) throws LoadException { } } - @Deprecated public String read(String name) { String query = ""; try { query = readWE(name); } catch (LoadException ex) { - LoggerFactory.getLogger(QueryLoad.class.getName()).error( "", ex); + LoggerFactory.getLogger(QueryLoad.class.getName()).error("", ex); } if (query == "") { return null; } return query; } - + public String readURL(String name) throws LoadException { return readWE(name); } - + public String readProtect(String name) throws LoadException { return readWE(name); } - + public String readWE(String name, boolean protect) throws LoadException { return readWE(name); } @@ -142,34 +135,45 @@ public String readWithAccess(String name) throws LoadException { check(Access.Feature.READ_WRITE, name, TermEval.READ_MESS); return readWE(name); } - - public String readWE(String name) throws LoadException { - String query = "", str = ""; - Reader fr; - try { - if (NSManager.isResource(name)) { - fr = new InputStreamReader(getClass().getResourceAsStream(NSManager.stripResource(name))); - } - else if (isURL(name)) { - URL url = new URL(name); - fr = new InputStreamReader(url.openStream()); - } else { - fr = new FileReader(name); - } + public String readWE(String name) throws LoadException { + String query = ""; + try (Reader fr = getReaderForName(name)) { if (fr == null) { - throw LoadException.create(new IOException(name)).setPath(name); + throw LoadException.create(new IOException("Could not obtain reader for: " + name)).setPath(name); } query = read(fr); } catch (IOException ex) { throw LoadException.create(ex).setPath(name); } - if (query == "") { + if (query.isEmpty()) { return null; } return query; } + + /** + * Helper method to get a Reader based on the name (resource, URL, or file path). + * @param name The name of the resource/URL/file. + * @return A Reader for the given name. + * @throws IOException If an I/O error occurs or URL is malformed. + */ + private Reader getReaderForName(String name) throws IOException { + if (NSManager.isResource(name)) { + InputStream stream = getClass().getResourceAsStream(NSManager.stripResource(name)); + if (stream == null) { + throw new IOException("Resource not found: " + name); + } + return new InputStreamReader(stream); + } else if (isURL(name)) { + URL url = new URL(name); + return new InputStreamReader(url.openStream()); + } else { + return new FileReader(name); + } + } + public String getResource(String name) throws IOException { InputStream stream = QueryLoad.class.getResourceAsStream(name); if (stream == null) { @@ -179,17 +183,17 @@ public String getResource(String name) throws IOException { String str = read(fr); return str; } - - // TODO: clean + + // TODO: clean public String basicParse(String path) throws EngineException { String pp = (path.endsWith("/")) ? path.substring(0, path.length() - 1) : path; String str = null; try { - if (NSManager.isResource(pp)) { + if (NSManager.isResource(pp)) { // @import within transformation such as st:turtle // the import uri is st:function/test.rq // consider it as a resource - String name = NSManager.stripResource(pp); + String name = NSManager.stripResource(pp); str = getResource(name); } else { str = readWE(pp); @@ -220,88 +224,87 @@ String read(Reader fr) throws IOException { isnl = true; } sb.append(str); - //sb.append(NL); } return sb.toString(); } - - public String writeTemp(String name, String str) { - String query = ""; - try { - File file = File.createTempFile(getName(name), getSuffix(name)); - Writer fr = new FileWriter(file); - BufferedWriter fq = new BufferedWriter(fr); - fq.write(str); - fq.flush(); - fr.close(); - return file.toString(); - } catch (FileNotFoundException e) { - logger.error(e.getMessage()); - } catch (IOException e) { - logger.error(e.getMessage()); - } - return null; - } - + + public String writeTemp(String name, IDatatype dt) { - String query = ""; try { File file = File.createTempFile(getName(name), getSuffix(name)); - Writer fr = new FileWriter(file); - BufferedWriter fq = new BufferedWriter(fr); - if (dt.isList()) { - for (IDatatype elem : dt) { - fq.write(elem.stringValue()); - fq.write(NL); - } - } - else { - fq.write(dt.stringValue()); - } - fq.flush(); - fr.close(); + writeToFile(file, dt); + return file.toString(); - } catch (FileNotFoundException e) { - logger.error(e.getMessage()); } catch (IOException e) { - logger.error(e.getMessage()); + logger.error("Error writing to temporary file '{}': {}", name, e.getMessage(), e); + return null; } - return null; } - + String getName(String name) { - int index = name.indexOf("."); - if (index == -1) { - return name; - } - return name.substring(0, index); + int index = name.indexOf("."); + if (index == -1) { + return name; + } + return name.substring(0, index); } - + String getSuffix(String name) { - int index = name.indexOf("."); - if (index == -1) { - return ".txt"; - } - return name.substring(index); - } - + int index = name.indexOf("."); + if (index == -1) { + return ".txt"; + } + return name.substring(index); + } + public void write(String name, IDatatype dt) { write(name, dt.stringValue()); } public void write(String name, String str) { - String query = ""; - try { - Writer fr = new FileWriter(name); - BufferedWriter fq = new BufferedWriter(fr); + try (final FileWriter fr = new FileWriter(name); + final BufferedWriter fq = new BufferedWriter(fr)) { fq.write(str); fq.flush(); - fr.close(); - } catch (FileNotFoundException e) { - e.printStackTrace(); } catch (IOException e) { + logger.error("Error writing to file '{}': {}", name, e.getMessage(), e); + } + } + + /** + * Writes content to the specified file using a buffered writer. + * Uses try-with-resources to ensure proper resource cleanup. The content + * is written through the {@link #writeContentToBuffer(BufferedWriter, IDatatype)} method. + * + * @param file The file to write to + * @param dt The data content to be written + * @throws IOException If an I/O error occurs during writing + * @see java.io.BufferedWriter + */ + private void writeToFile(File file, IDatatype dt) throws IOException { + try (FileWriter fr = new FileWriter(file); + BufferedWriter fq = new BufferedWriter(fr)) { + writeContentToBuffer(fq, dt); + fq.flush(); } - } -} + /** + * Helper method to write the content of an IDatatype to a BufferedWriter. + * This method encapsulates the conditional writing logic to reduce nesting in the caller. + * + * @param fq The BufferedWriter to write to. + * @param dt The IDatatype containing the content. + * @throws IOException If an I/O error occurs during writing. + */ + private void writeContentToBuffer(BufferedWriter fq, IDatatype dt) throws IOException { + if (dt.isList()) { + for (IDatatype elem : dt) { + fq.write(elem.stringValue()); + fq.write(NL); + } + } else { + fq.write(dt.stringValue()); + } + } +} \ No newline at end of file diff --git a/src/main/java/fr/inria/corese/core/load/RuleLoad.java b/src/main/java/fr/inria/corese/core/load/RuleLoad.java index 51aec36b4..ba5ea7524 100755 --- a/src/main/java/fr/inria/corese/core/load/RuleLoad.java +++ b/src/main/java/fr/inria/corese/core/load/RuleLoad.java @@ -33,7 +33,7 @@ */ public class RuleLoad { - private static Logger logger = LoggerFactory.getLogger(Load.class); + private static final Logger logger = LoggerFactory.getLogger(Load.class); static final String NS = NSManager.RULE; static final String NS2 = "http://ns.inria.fr/edelweiss/2011/rule#"; static final String NS1 = "http://ns.inria.fr/corese/2008/rule#"; @@ -255,7 +255,7 @@ void load1(Document doc) { try { engine.defRule(rule); } catch (EngineException e) { - e.printStackTrace(); + logger.error("An error has occurred", e); } } } diff --git a/src/main/java/fr/inria/corese/core/load/Service.java b/src/main/java/fr/inria/corese/core/load/Service.java index 46ca81bd4..3296bd678 100644 --- a/src/main/java/fr/inria/corese/core/load/Service.java +++ b/src/main/java/fr/inria/corese/core/load/Service.java @@ -26,6 +26,7 @@ import java.io.UnsupportedEncodingException; import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.concurrent.TimeUnit; import jakarta.ws.rs.RedirectionException; @@ -67,7 +68,7 @@ public class Service implements URLParam { static HashMap redirect; - private ClientBuilder clientBuilder; + private final ClientBuilder clientBuilder; private boolean isDebug = false; private boolean post = true; @@ -83,7 +84,7 @@ public class Service implements URLParam { private ServiceReport report; private Response response; private boolean log = false; - private double time = 0; + private final double time = 0; static { redirect = new HashMap<>(); @@ -281,10 +282,8 @@ public String basicPost(String url, String query, String mime) { getCreateReport().setLocation(myUrl); return post(myUrl, query, mime); } - - trace(resp); + logger.info("Response status: " + resp.getStatus()); - //logger.info("From " + getURL().getURL()); if (resp.getMediaType()!=null) { recordFormat(resp.getMediaType().toString()); @@ -303,8 +302,7 @@ public String basicPost(String url, String query, String mime) { } throw ex; } - - trace(res); + return res; } catch (RedirectionException ex) { String uri = ex.getLocation().toString(); @@ -326,22 +324,6 @@ void redirect(String url1, String url2) { redirect.put(url1, url2); } - void trace(Response res) { - if (getURL().hasParameter(DISPLAY, HEADER)) { - System.out.println("service header: " + getURL().getURL()); - for (String name : res.getHeaders().keySet()) { - System.out.println("header: " + name + "=" + res.getHeaderString(name)); - } - } - } - - void trace(String str) { - if (isShowResult()) { - System.out.println("Service string result"); - System.out.println(str); - } - } - @Deprecated Builder setHeader(Builder rb) { if (getURL().hasParameter(HEADER)) { @@ -467,15 +449,11 @@ public String get(String query, String mime) { public String get(String uri, String query, String mime) { String url; - try { - if (isDebug()) { - logger.info(URLEncoder.encode(query, "UTF-8")); - } - - url = complete(uri, URLEncoder.encode(query, "UTF-8")); - } catch (UnsupportedEncodingException ex) { - url = complete(uri, query); + if (isDebug()) { + logger.info(URLEncoder.encode(query, StandardCharsets.UTF_8)); } + + url = complete(uri, URLEncoder.encode(query, StandardCharsets.UTF_8)); return getBasic(url, mime); } @@ -527,7 +505,7 @@ String dataset() { public String getBasic(String url, String mime) { Response resp = getResponse(url, mime); String res = resp.readEntity(String.class); - trace(res); + getCreateReport().setResult(res); return res; } @@ -633,8 +611,8 @@ public JSONObject getJson(String uri) { } String encoding(ASTQuery ast) { - if (ast.hasMetadata(Metadata.ENCODING)) { - return ast.getMetadata().getStringValue(Metadata.ENCODING); + if (ast.hasMetadata(Metadata.Type.ENCODING)) { + return ast.getMetadata().getStringValue(Metadata.Type.ENCODING); } return ENCODING; } @@ -757,10 +735,7 @@ void metadata(ASTQuery ast) { if (getURL().hasParameter(MODE, SHOW)) { setShowResult(true); } - if (ast.getGlobalAST().isDebug()) { - System.out.println(isPost()?"POST":"GET"); - } - getCreateParser().setTrap(getURL().hasParameter(MODE, TRAP) || ast.getGlobalAST().hasMetadata(Metadata.TRAP)); + getCreateParser().setTrap(getURL().hasParameter(MODE, TRAP) || ast.getGlobalAST().hasMetadata(Metadata.Type.TRAP)); if (! isShowResult()) { setShowResult(ast.getGlobalAST().hasMetadata(Metadata.SHOW)); getCreateParser().setShowResult(isShowResult()); @@ -770,8 +745,8 @@ void metadata(ASTQuery ast) { // use case for limit: @federate with one URL -> direct service void limit(ASTQuery ast) { if (!ast.hasLimit()) { - if (ast.getMetaValue(Metadata.LIMIT)!=null) { - ast.setLimit(ast.getMetaValue(Metadata.LIMIT).intValue()); + if (ast.getMetaValue(Metadata.Type.LIMIT)!=null) { + ast.setLimit(ast.getMetaValue(Metadata.Type.LIMIT).intValue()); } else { Integer lim = getURL().intValue(LIMIT); if (lim != -1) { diff --git a/src/main/java/fr/inria/corese/core/load/ServiceParser.java b/src/main/java/fr/inria/corese/core/load/ServiceParser.java index baf6684cf..eb790face 100644 --- a/src/main/java/fr/inria/corese/core/load/ServiceParser.java +++ b/src/main/java/fr/inria/corese/core/load/ServiceParser.java @@ -44,10 +44,6 @@ public ServiceParser(URLServer url) { public ServiceParser(String url) { this(new URLServer(url)); } - -// public Mappings parseMapping(String str) throws LoadException { -// return parseMapping(null, "", str, ENCODING); -// } public Mappings parseMapping(Query q, String query, String str, String encoding) throws LoadException { @@ -174,10 +170,6 @@ Mappings wrapper(String str) throws LoadException { IDatatype dt; try { dt = QueryProcess.create().funcall(fname, getBind(), DatatypeMap.newInstance(str)); - if (getURL().hasParameter(MODE, SHOW)) { - System.out.println("wrap: "+ name); - System.out.println(dt); - } } catch (EngineException ex) { Service.logger.error("Service wrapper error: " + name); throw new LoadException(ex); diff --git a/src/main/java/fr/inria/corese/core/load/ServiceReport.java b/src/main/java/fr/inria/corese/core/load/ServiceReport.java index 55cd1a7ac..1fdb099e6 100644 --- a/src/main/java/fr/inria/corese/core/load/ServiceReport.java +++ b/src/main/java/fr/inria/corese/core/load/ServiceReport.java @@ -48,8 +48,8 @@ boolean isReport() { return Property.getBooleanValue(SERVICE_REPORT) || getURL().hasParameter(MODE, REPORT) || (getQuery()!=null && - (getQuery().getAST().hasMetadata(Metadata.REPORT) - || getGlobalAST().hasMetadata(Metadata.REPORT))); + (getQuery().getAST().hasMetadata(Metadata.Type.REPORT) + || getGlobalAST().hasMetadata(Metadata.Type.REPORT))); } ASTQuery getGlobalAST() { @@ -68,7 +68,6 @@ Mappings serviceReport(ResponseProcessingException ex, Exception e) { set(dt, MES, e.getMessage()); } else { - //set(dt, STATUS, ex.getResponse().getStatus()); if (ex.getResponse().getStatusInfo()!=null){ set(dt, INFO, ex.getResponse().getStatusInfo().getReasonPhrase()); } @@ -89,8 +88,7 @@ Mappings serviceReport(ResponseProcessingException ex, Exception e) { void parserReport(Mappings map, String str, boolean suc) { if (isReport()) { boolean empty = getQuery() != null - && getGlobalAST().hasMetadataValue(Metadata.REPORT, Metadata.EMPTY); - //if (!suc || map.size() > 0 || empty) { + && getGlobalAST().hasMetadataValue(Metadata.Type.REPORT, Metadata.EMPTY); // if service is success but return no result: // @report generate no report (and no result Mapping) // @report empty generate report and create a fake Mapping with report @@ -109,7 +107,6 @@ void parserReport(Mappings map, String str, boolean suc) { else { map.recordReport(node(), dt); } - //} } } @@ -155,7 +152,7 @@ void completeReportHeader(Mappings map) { set(dt, TIME, getTime()); set(dt, LOCATION, getLocation()); - if (getGlobalAST().hasMetadata(Metadata.DETAIL)) { + if (getGlobalAST().hasMetadata(Metadata.Type.DETAIL)) { //set(dt, RESULT, getResult()); set(dt, RESULT, DatatypeMap.createObject(getMappings())); } @@ -166,7 +163,7 @@ void completeReportHeader(Mappings map) { * Header and Cookie as json objects */ void reportHeader(IDatatype dt) { - if (getGlobalAST().hasMetadata(Metadata.HEADER)) { + if (getGlobalAST().hasMetadata(Metadata.Type.HEADER)) { IDatatype json = DatatypeMap.json(); for (String key : resp().getHeaders().keySet()) { json.set(key, resp().getHeaderString(key)); @@ -176,7 +173,7 @@ void reportHeader(IDatatype dt) { } } - if (getGlobalAST().hasMetadata(Metadata.COOKIE)) { + if (getGlobalAST().hasMetadata(Metadata.Type.COOKIE)) { IDatatype json = DatatypeMap.json(); for (String cookie : resp().getCookies().keySet()) { json.set(cookie, resp().getCookies().get(cookie)); @@ -187,21 +184,6 @@ void reportHeader(IDatatype dt) { } } -// for (Link link : resp().getLinks()) { -// set(dt, "link", link.toString()); -// System.out.println("SR link: " + link); -// } - -// StringBuilder sb = new StringBuilder(); -// -// for (String method : resp().getAllowedMethods()) { -// sb.append(method).append("; "); -// } -// -// if (sb.length() > 0) { -// set(dt, "method", sb.toString()); -// } - Node node() { return node(getURL().getNumber()); } diff --git a/src/main/java/fr/inria/corese/core/load/jsonld/CoreseJsonTripleCallback.java b/src/main/java/fr/inria/corese/core/load/jsonld/CoreseJsonTripleCallback.java index 9e286d1f9..409eee088 100644 --- a/src/main/java/fr/inria/corese/core/load/jsonld/CoreseJsonTripleCallback.java +++ b/src/main/java/fr/inria/corese/core/load/jsonld/CoreseJsonTripleCallback.java @@ -24,7 +24,7 @@ public class CoreseJsonTripleCallback implements JsonLdTripleCallback { private AddTripleHelper helper; String source; - private Graph graph; + private final Graph graph; private DataManager dataManager; private Node graphSource, defaultGraphSource; private final static String JSONLD_DEFAULT_GRAPH = "@default"; diff --git a/src/main/java/fr/inria/corese/core/load/jsonld/JsonldLoader.java b/src/main/java/fr/inria/corese/core/load/jsonld/JsonldLoader.java index fbedfd05c..e6a31a06e 100644 --- a/src/main/java/fr/inria/corese/core/load/jsonld/JsonldLoader.java +++ b/src/main/java/fr/inria/corese/core/load/jsonld/JsonldLoader.java @@ -26,11 +26,11 @@ public class JsonldLoader { /** * logger from log4j */ - private static Logger logger = LoggerFactory.getLogger(JsonldLoader.class); + private static final Logger logger = LoggerFactory.getLogger(JsonldLoader.class); private Reader reader; private InputStream is; - private String base; + private final String base; JsonldLoader(InputStream r, String base) { this.is = r; @@ -59,7 +59,7 @@ public static JsonldLoader create(String file) { JsonldLoader p = new JsonldLoader(read, file); return p; } catch (FileNotFoundException e) { - e.printStackTrace(); + logger.error("An error has occurred", e); } return null; } diff --git a/src/main/java/fr/inria/corese/core/load/rdfa/RDFaLoader.java b/src/main/java/fr/inria/corese/core/load/rdfa/RDFaLoader.java index 25e998ac0..94756c43f 100644 --- a/src/main/java/fr/inria/corese/core/load/rdfa/RDFaLoader.java +++ b/src/main/java/fr/inria/corese/core/load/rdfa/RDFaLoader.java @@ -23,11 +23,11 @@ public class RDFaLoader { /** * logger from log4j */ - private static Logger logger = LoggerFactory.getLogger(RDFaLoader.class); + private static final Logger logger = LoggerFactory.getLogger(RDFaLoader.class); private Reader reader; private InputStream is; - private String base; + private final String base; RDFaLoader(InputStream r, String base) { this.is = r; @@ -56,7 +56,7 @@ public static RDFaLoader create(String file) { RDFaLoader p = new RDFaLoader(read, file); return p; } catch (FileNotFoundException e) { - e.printStackTrace(); + logger.error("An error has occurred", e); } return null; } diff --git a/src/main/java/fr/inria/corese/core/load/result/SPARQLRDFResult.java b/src/main/java/fr/inria/corese/core/load/result/SPARQLRDFResult.java index ae3262f7f..81317ef4a 100644 --- a/src/main/java/fr/inria/corese/core/load/result/SPARQLRDFResult.java +++ b/src/main/java/fr/inria/corese/core/load/result/SPARQLRDFResult.java @@ -10,12 +10,15 @@ import fr.inria.corese.core.kgram.core.Mapping; import fr.inria.corese.core.kgram.core.Mappings; import fr.inria.corese.core.sparql.exceptions.EngineException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * * @author corby */ public class SPARQLRDFResult { + private static final Logger logger = LoggerFactory.getLogger(SPARQLRDFResult.class); public Mappings parse(String result) throws LoadException { return parse(result, Loader.format.TURTLE_FORMAT); @@ -45,7 +48,7 @@ public Mappings parse(String result, Loader.format format) throws LoadException try { map = exec.query(query); } catch (EngineException e) { - System.out.println(e.getMessage()); + logger.error("", e); } Mappings res = translate(map); return res; diff --git a/src/main/java/fr/inria/corese/core/load/result/XMLResult.java b/src/main/java/fr/inria/corese/core/load/result/XMLResult.java index 126702669..78185c9fc 100644 --- a/src/main/java/fr/inria/corese/core/load/result/XMLResult.java +++ b/src/main/java/fr/inria/corese/core/load/result/XMLResult.java @@ -8,6 +8,7 @@ import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -38,7 +39,7 @@ import java.io.BufferedReader; import java.io.Reader; import java.util.Collection; -import java.util.logging.Level; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,7 +51,7 @@ */ public class XMLResult { - private static Logger logger = LoggerFactory.getLogger(XMLResult.class); + private static final Logger logger = LoggerFactory.getLogger(XMLResult.class); static final String NL = "\n"; // create target Node @@ -74,7 +75,6 @@ public class XMLResult { private static final int OBJECT = 12; private static final int LIST = 13; - private boolean debug = false; private boolean trapError = false; private boolean showResult = false; private List link; @@ -119,14 +119,10 @@ public Mappings parse(InputStream stream) throws ParserConfigurationException, S if (isShowResult()) { String str = read(stream); - System.out.println(str); setShowResult(false); return parseString(str); } - if (debug) { - System.out.println("start parse XML result"); - } Mappings map = new Mappings(); MyHandler handler = new MyHandler(map); @@ -134,7 +130,7 @@ public Mappings parse(InputStream stream) throws ParserConfigurationException, S factory.setNamespaceAware(true); try { SAXParser parser = factory.newSAXParser(); - InputStreamReader r = new InputStreamReader(stream, "UTF-8"); + InputStreamReader r = new InputStreamReader(stream, StandardCharsets.UTF_8); parser.parse(new InputSource(r), handler); complete(map); map.setLinkList(getLink()); @@ -144,7 +140,6 @@ public Mappings parse(InputStream stream) throws ParserConfigurationException, S logger.error(e.toString()); complete(map); map.setError(true); - System.out.println("Return partial result of size: " + map.size()); return map; } else { throw e; @@ -169,7 +164,7 @@ public void complete(Mappings map) { map.setQuery(q); map.init(q); } catch (EngineException ex) { - java.util.logging.Logger.getLogger(XMLResult.class.getName()).log(Level.SEVERE, null, ex); + logger.error("An unexpected error has occurred", ex); } } @@ -308,9 +303,6 @@ public class MyHandler extends DefaultHandler { @Override public void startDocument() { - if (debug) { - System.out.println("start document"); - } } // called for each binding @@ -347,9 +339,6 @@ Node getVariable(String var) { @Override public void startElement(String namespaceURI, String simpleName, String qualifiedName, Attributes atts) { - if (debug) { - System.out.println("open: " + qualifiedName); - } isContent = false; switch (type(simpleName)) { @@ -448,10 +437,6 @@ else if (list > 0) { @Override public void endElement(String namespaceURI, String simpleName, String qualifiedName) { - if (debug) { - System.out.println("close: " + qualifiedName); - } - switch (type(simpleName)) { case SUBJECT: pushSubject(getNode()); @@ -485,15 +470,12 @@ public void endElement(String namespaceURI, String simpleName, String qualifiedN } if (isURI) { - //add(var, getURI(text)); record(getURI(text)); isURI = false; } else if (isBlank) { - //add(var, getBlank(text)); record(getBlank(text)); isBlank = false; } else if (isLiteral) { - //add(var, getLiteral(text, datatype, lang)); record(getLiteral(text, datatype, lang)); isLiteral = false; } else if (isBoolean && text.equals("true")) { @@ -504,9 +486,6 @@ public void endElement(String namespaceURI, String simpleName, String qualifiedN case RESULT: Mapping map = Mapping.create(lvar, lval); - if (debug) { - System.out.println(map); - } maps.add(map); } } @@ -518,7 +497,7 @@ public void endElement(String namespaceURI, String simpleName, String qualifiedN * element. */ @Override - public void characters(char buf[], int offset, int len) { + public void characters(char[] buf, int offset, int len) { if (isContent) { String s = new String(buf, offset, len); if (text == null) { @@ -538,7 +517,6 @@ InputStream getStream(String path) throws FileNotFoundException { try { URL uri = new URL(path); return uri.openStream(); - } catch (MalformedURLException e) { } catch (IOException e) { } @@ -582,7 +560,6 @@ String read(Reader fr) throws IOException { isnl = true; } sb.append(str); - //sb.append(NL); } return sb.toString(); } diff --git a/src/main/java/fr/inria/corese/core/load/sesame/ParserLoaderSesame.save b/src/main/java/fr/inria/corese/core/load/sesame/ParserLoaderSesame.save index 91d4253f5..739cf7bb6 100644 --- a/src/main/java/fr/inria/corese/core/load/sesame/ParserLoaderSesame.save +++ b/src/main/java/fr/inria/corese/core/load/sesame/ParserLoaderSesame.save @@ -83,7 +83,7 @@ public class ParserLoaderSesame { config.addNonFatalError(NTriplesParserSettings.FAIL_ON_NTRIPLES_INVALID_LINES); parser.setParserConfig(config); parser.setRDFHandler(handler); - //System.out.println(this.base+format); + //logger.info("Saving data: {}{}", this.base, format); parser.parse(this.reader, this.base); } } diff --git a/src/main/java/fr/inria/corese/core/logic/BrokerDistanceDataManager.java b/src/main/java/fr/inria/corese/core/logic/BrokerDistanceDataManager.java index f04d05062..d63bb258d 100644 --- a/src/main/java/fr/inria/corese/core/logic/BrokerDistanceDataManager.java +++ b/src/main/java/fr/inria/corese/core/logic/BrokerDistanceDataManager.java @@ -22,7 +22,6 @@ public class BrokerDistanceDataManager extends BrokerDistance { static final String PREDICATE = "select ?p where {values ?p {<%s>} ?x ?p ?y} limit 1"; private DataManager dataManager; - private boolean debug = false; BrokerDistanceDataManager(Graph g, DataManager man) { setGraph(g); @@ -36,8 +35,6 @@ Node getPropertyNode(String name) { try { Mappings map = exec.query(q); Node res = map.getNode("?p"); - if (isDebug()) - System.out.println("DM property: " + name + " " + res); return res; } catch (EngineException ex) { Distance.logger.error(ex.getMessage()); @@ -54,8 +51,6 @@ Node getTopLevel(String defaut, String... nameList) { try { Mappings map = exec.query(q); Node res = map.getNode("?o"); - if (isDebug()) - System.out.println("DM top: " + name + " " + res); if (res != null) { return res; } @@ -75,8 +70,6 @@ List getTopLevelList(Node predicate) { try { Mappings map = exec.query(q); List list = map.getNodeValueList("?y"); - if (isDebug()) - System.out.println("DM top level list: " + predicate + " " + list); return list; } catch (EngineException ex) { Distance.logger.error(ex.getMessage()); @@ -99,8 +92,6 @@ Iterable getNodeList(Node predicate, Node node, int index) { list.add(n); } } - if (isDebug()) - System.out.println("DM node list: " + node + " " + list); return list; } @@ -112,12 +103,4 @@ public void setDataManager(DataManager dataManager) { this.dataManager = dataManager; } - public boolean isDebug() { - return debug; - } - - public void setDebug(boolean debug) { - this.debug = debug; - } - } diff --git a/src/main/java/fr/inria/corese/core/logic/Closure.java b/src/main/java/fr/inria/corese/core/logic/Closure.java index 113292d66..ecbb982a2 100644 --- a/src/main/java/fr/inria/corese/core/logic/Closure.java +++ b/src/main/java/fr/inria/corese/core/logic/Closure.java @@ -28,7 +28,6 @@ public class Closure { boolean isDistinct = true; private boolean isConnect = false; boolean isMessage = true; - private boolean isTrace = false; // send index to data manager edge iterator private boolean filterEdgeIndex = true; @@ -65,9 +64,8 @@ public void init(Node p1, Node p2) { for (Edge ent : graph.getEdges(predicate1)) { connect(ent.getNode(0), ent.getNode(1)); } - } catch (OutOfMemoryError E) { + } catch (OutOfMemoryError e) { setConnect(false); - System.out.println("Skip Cache Out Of Memory: " + predicate1); } } } @@ -86,7 +84,6 @@ public boolean isConnected(Node p, Node n1, Node n2) { } catch (OutOfMemoryError E) { if (isMessage) { isMessage = false; - System.out.println("Skip Cache Out Of Memory: " + p); return graph.exist(p, n1, n2); } } @@ -107,7 +104,6 @@ public void connect(Node n1, Node n2) { } catch (OutOfMemoryError E) { if (isMessage) { isMessage = false; - System.out.println("Skip Cache Out Of Memory: " + predicate1); } return; } @@ -137,17 +133,12 @@ public void closure(int loop, int loopIndex, int prevIndex) { ArrayList edgeListNew = new ArrayList<>(), edgeListTemp = new ArrayList<>(); - - if (isTrace) { - System.out.println("Closure: 0 " + graph.size(predicate1)); - } + while (go) { Iterable it1 = edgeListNew; if (n == 0) { it1 = getEdges(predicate1); - } else if (isTrace) { - System.out.println("Closure: " + n + " " + +edgeListNew.size()); } n++; @@ -196,9 +187,6 @@ public void closure(int loop, int loopIndex, int prevIndex) { if (Graph.isTopRelation(p)) { p = null; } - if (isTrace) { - System.out.println("Closure: new " + edgeListTemp.size()); - } insert(p, edgeListTemp); edgeListNew = edgeListTemp; edgeListTemp = new ArrayList<>(); @@ -233,20 +221,6 @@ public void setConnect(boolean Connect) { this.isConnect = Connect; } - /** - * @return the isTrace - */ - public boolean isTrace() { - return isTrace; - } - - /** - * @param isTrace the isTrace to set - */ - public void setTrace(boolean isTrace) { - this.isTrace = isTrace; - } - Node ruleGraphNode() { return graph.addRuleGraphNode(); } diff --git a/src/main/java/fr/inria/corese/core/logic/Distance.java b/src/main/java/fr/inria/corese/core/logic/Distance.java index 0979c5a7a..41152c064 100644 --- a/src/main/java/fr/inria/corese/core/logic/Distance.java +++ b/src/main/java/fr/inria/corese/core/logic/Distance.java @@ -12,13 +12,13 @@ import fr.inria.corese.core.kgram.api.core.Node; /** - * Semantic distance & similarity with Corese 2.4 Algorithm Extended to property + * Semantic distance & similarity with Corese 2.4 Algorithm Extended to property * hierarchy distance: kg:pSimilarity * * PRAGMA: need a graph with Node set/get Depth need a root class, default is * rdfs:Resource or owl:Thing * - * If a class is not subClassOf root, depth simulate to 1 Exploit owl:sameAs & + * If a class is not subClassOf root, depth simulate to 1 Exploit owl:sameAs & * owl:equivalentClass/Property * * Generalized to property hierarchy with a step of 1/8^n instead of 1/2^n steps @@ -38,7 +38,7 @@ public class Distance { // class step is: 1 / 2^n public static double CSTEP = 2; - private static int FIRST_STEP = 5; + private static final int FIRST_STEP = 5; private Graph graph; private DataManager dataManager; @@ -590,9 +590,7 @@ Object result(Node n, double d, boolean isDist) { } if (hasEquiv) { double dd = distance(node, equivAs, ta, tb); - if (dd != -1) { - return dd; - } + return dd; } return -1; } diff --git a/src/main/java/fr/inria/corese/core/logic/Entailment.java b/src/main/java/fr/inria/corese/core/logic/Entailment.java index 2337060e9..0978f0856 100755 --- a/src/main/java/fr/inria/corese/core/logic/Entailment.java +++ b/src/main/java/fr/inria/corese/core/logic/Entailment.java @@ -23,7 +23,7 @@ * rdfs:domain rdfs:range rdfs:subPropertyOf rdfs:subClassOf * owl:SymmetricProperty owl:inverseOf * - * subPropertyOf & subClassOf are not transitive in the graph but their + * subPropertyOf & subClassOf are not transitive in the graph but their * instances are typed according to transitivity * * @author Olivier Corby, Edelweiss INRIA 2010 @@ -31,7 +31,7 @@ */ public class Entailment implements Engine { - private static Logger logger = LoggerFactory.getLogger(Entailment.class); + private static final Logger logger = LoggerFactory.getLogger(Entailment.class); private static final String S_TYPE = RDF.TYPE; private static final String S_BLI = RDF.BLI; private static final String S_PROPERTY = RDF.PROPERTY; @@ -923,9 +923,7 @@ boolean check(IDatatype dt, String range, boolean isDatatype) { if (dt.isLiteral()) { return DatatypeMap.check(dt, range); } - } else if (dt.isLiteral()) { - return false; - } + } else return !dt.isLiteral(); return true; } @@ -962,7 +960,7 @@ public void remove() { } @Override - public int type() { - return RDFS_ENGINE; + public Type type() { + return Type.RDFS_ENGINE; } } diff --git a/src/main/java/fr/inria/corese/core/logic/OWL.java b/src/main/java/fr/inria/corese/core/logic/OWL.java index dcbc9aed3..989194236 100644 --- a/src/main/java/fr/inria/corese/core/logic/OWL.java +++ b/src/main/java/fr/inria/corese/core/logic/OWL.java @@ -2,30 +2,30 @@ public interface OWL { - public static final String OWL = "http://www.w3.org/2002/07/owl#"; + String OWL = "http://www.w3.org/2002/07/owl#"; - public static final String CLASS = OWL + "Class"; - public static final String THING = OWL + "Thing"; + String CLASS = OWL + "Class"; + String THING = OWL + "Thing"; - public static final String INTERSECTIONOF = OWL + "intersectionOf"; - public static final String UNIONOF = OWL + "unionOf"; - public static final String EQUIVALENTCLASS = OWL + "equivalentClass"; - public static final String COMPLEMENTOF = OWL + "complementOf"; - public static final String DISJOINTWITH = OWL + "disjointWith"; + String INTERSECTIONOF = OWL + "intersectionOf"; + String UNIONOF = OWL + "unionOf"; + String EQUIVALENTCLASS = OWL + "equivalentClass"; + String COMPLEMENTOF = OWL + "complementOf"; + String DISJOINTWITH = OWL + "disjointWith"; - public static final String ALLVALUESFROM = OWL + "allValuesFrom"; - public static final String SOMEVALUESFROM = OWL + "someValuesFrom"; - public static final String ONCLASS = OWL + "onClass"; + String ALLVALUESFROM = OWL + "allValuesFrom"; + String SOMEVALUESFROM = OWL + "someValuesFrom"; + String ONCLASS = OWL + "onClass"; - public static final String INVERSEOF = OWL + "inverseOf"; - public static final String EQUIVALENTPROPERTY= OWL + "equivalentProperty"; - public static final String SYMMETRIC = OWL + "SymmetricProperty"; - public static final String TRANSITIVE = OWL + "TransitiveProperty"; - public static final String REFLEXIVE = OWL + "ReflexiveProperty"; + String INVERSEOF = OWL + "inverseOf"; + String EQUIVALENTPROPERTY= OWL + "equivalentProperty"; + String SYMMETRIC = OWL + "SymmetricProperty"; + String TRANSITIVE = OWL + "TransitiveProperty"; + String REFLEXIVE = OWL + "ReflexiveProperty"; - public static final String TOPOBJECTPROPERTY= OWL + "topObjectProperty"; - public static final String TOPDATAPROPERTY = OWL + "topDataProperty"; - public static final String SAMEAS = OWL + "sameAs"; + String TOPOBJECTPROPERTY= OWL + "topObjectProperty"; + String TOPDATAPROPERTY = OWL + "topDataProperty"; + String SAMEAS = OWL + "sameAs"; } diff --git a/src/main/java/fr/inria/corese/core/logic/OWLProfile.java b/src/main/java/fr/inria/corese/core/logic/OWLProfile.java index b72d6344d..6a09cfd55 100644 --- a/src/main/java/fr/inria/corese/core/logic/OWLProfile.java +++ b/src/main/java/fr/inria/corese/core/logic/OWLProfile.java @@ -9,16 +9,18 @@ import fr.inria.corese.core.sparql.datatype.DatatypeMap; import fr.inria.corese.core.sparql.exceptions.EngineException; import fr.inria.corese.core.sparql.triple.function.term.Binding; +import fr.inria.corese.core.transform.TransformerUtils; + import java.util.Map; /** * OWL Profile type checker */ public class OWLProfile { - public static final String OWL_RL = Transformer.OWL_RL; - public static final String OWL_EL = Transformer.OWL_EL; - public static final String OWL_QL = Transformer.OWL_QL; - public static final String OWL_TC = Transformer.OWL_TC; + public static final String OWL_RL = TransformerUtils.OWL_RL; + public static final String OWL_EL = TransformerUtils.OWL_EL; + public static final String OWL_QL = TransformerUtils.OWL_QL; + public static final String OWL_TC = TransformerUtils.OWL_TC; private Graph graph; private Map error; @@ -41,9 +43,9 @@ public boolean process(String type) throws EngineException { b.setTransformerVisitor(vis); checker.process(b); - Transformer printer = Transformer.create(getGraph(), Transformer.PP_ERROR); + Transformer printer = Transformer.create(getGraph(), TransformerUtils.PP_ERROR); IDatatype errors = vis.errors(); - IDatatype dt = printer.process(Transformer.PP_ERROR_DISPLAY, b, + IDatatype dt = printer.process(TransformerUtils.PP_ERROR_DISPLAY, b, DatatypeMap.newInstance(getTitle(type)), errors); if (dt !=null) { setMessage(dt.stringValue()); @@ -65,7 +67,7 @@ String getTitle(String type) { public IDatatype pretty(IDatatype dt) throws EngineException { if (dt.isBlank()) { - Transformer t = Transformer.create(getGraph(), Transformer.TURTLE); + Transformer t = Transformer.create(getGraph(), TransformerUtils.TURTLE); return t.process(dt); } else { diff --git a/src/main/java/fr/inria/corese/core/logic/OWLRule.java b/src/main/java/fr/inria/corese/core/logic/OWLRule.java deleted file mode 100644 index 044c003df..000000000 --- a/src/main/java/fr/inria/corese/core/logic/OWLRule.java +++ /dev/null @@ -1,122 +0,0 @@ -package fr.inria.corese.core.logic; - -import fr.inria.corese.core.sparql.exceptions.EngineException; -import fr.inria.corese.core.sparql.triple.parser.NSManager; -import fr.inria.corese.core.kgram.api.core.Node; -import fr.inria.corese.core.kgram.core.Mapping; -import fr.inria.corese.core.kgram.core.Mappings; -import fr.inria.corese.core.kgram.core.Query; -import fr.inria.corese.core.Graph; -import fr.inria.corese.core.query.QueryEngine; -import fr.inria.corese.core.query.QueryProcess; -import fr.inria.corese.core.rule.Rule; -import fr.inria.corese.core.rule.RuleEngine; -import fr.inria.corese.core.load.Load; -import fr.inria.corese.core.load.LoadException; - - -/** - * Generate rules for some OWL statements such as: - * property chain - * - * @author Olivier Corby, Wimmics INRIA 2012 - * - */ -public class OWLRule { - - private static final String RULE = "?rule"; - static String data = "/home/corby/workspace/kgtool/src/test/resources/data/"; - - String rules = data + "owlrule"; - - Graph graph; - RuleEngine re; - - boolean debug = true; - - - - - - OWLRule(Graph g){ - graph = g; - re = RuleEngine.create(graph); - } - - public static OWLRule create(Graph g){ - return new OWLRule(g); - } - - public void process() throws EngineException, LoadException{ - process(rules); - } - - /** - * src contains a query or is a directory of queries - * Load the queries - * Process queries (query or update) - * Query may compute and return an argument of name RULE - * In this case the rule is loaded into a RuleEngine - * Then rules are processed - * - * TODO: dependency with load - * - */ - public void process(String src) throws EngineException, LoadException{ - - Load ld = Load.create(graph); - ld.setEngine(re); - ld.parse(src); - QueryEngine qe = ld.getQueryEngine(); - - for (Rule r : re.getRules()){ - trace (r.getQuery().getAST()); - } - - if (qe != null){ - for (Query query : qe.getQueries()){ - trace(query); - process(query); - } - } - - re.process(); - } - - - - - - /** - * Process a query or update - * Query may return a RULE - * in this case, load the rule in RuleEngine - */ - void process(Query query) throws EngineException{ - - QueryProcess exec = QueryProcess.create(graph); - Mappings map = exec.query(query); - NSManager ns = exec.getAST(map).getNSM(); - - for (Mapping m : map){ - Node nrule = m.getNode(RULE); - - if (nrule != null){ - String srule = nrule.getLabel(); - srule = ns.toString() + srule; - re.defRule(srule); - trace(srule); - } - } - } - - - - void trace(Object o){ - if (debug){ - System.out.println(o); - System.out.println(); - } - } - -} diff --git a/src/main/java/fr/inria/corese/core/logic/RDF.java b/src/main/java/fr/inria/corese/core/logic/RDF.java index aaac5d609..9ba4c1451 100644 --- a/src/main/java/fr/inria/corese/core/logic/RDF.java +++ b/src/main/java/fr/inria/corese/core/logic/RDF.java @@ -2,13 +2,13 @@ public interface RDF { - public static final String RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; - public static final String TYPE = RDF + "type"; - public static final String PROPERTY = RDF + "Property"; - public static final String BLI = RDF + "_"; - public static final String FIRST = RDF + "first"; - public static final String REST = RDF + "rest"; - public static final String NIL = RDF + "nil"; - public static final String VALUE = RDF + "value"; + String RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; + String TYPE = RDF + "type"; + String PROPERTY = RDF + "Property"; + String BLI = RDF + "_"; + String FIRST = RDF + "first"; + String REST = RDF + "rest"; + String NIL = RDF + "nil"; + String VALUE = RDF + "value"; } diff --git a/src/main/java/fr/inria/corese/core/logic/RDFS.java b/src/main/java/fr/inria/corese/core/logic/RDFS.java index 833216956..d539e27a9 100644 --- a/src/main/java/fr/inria/corese/core/logic/RDFS.java +++ b/src/main/java/fr/inria/corese/core/logic/RDFS.java @@ -2,17 +2,17 @@ public interface RDFS { - public static final String RDFS = "http://www.w3.org/2000/01/rdf-schema#"; + String RDFS = "http://www.w3.org/2000/01/rdf-schema#"; - public static final String SUBPROPERTYOF = RDFS + "subPropertyOf"; - public static final String SUBCLASSOF = RDFS + "subClassOf"; - public static final String DOMAIN = RDFS + "domain"; - public static final String RANGE = RDFS + "range"; - public static final String MEMBER = RDFS + "member"; - public static final String MEMBERSHIP = RDFS + "ContainerMembershipProperty"; - public static final String CLASS = RDFS + "Class"; - public static final String RESOURCE = RDFS + "Resource"; - public static final String LABEL = RDFS + "label"; - public static final String COMMENT = RDFS + "comment"; + String SUBPROPERTYOF = RDFS + "subPropertyOf"; + String SUBCLASSOF = RDFS + "subClassOf"; + String DOMAIN = RDFS + "domain"; + String RANGE = RDFS + "range"; + String MEMBER = RDFS + "member"; + String MEMBERSHIP = RDFS + "ContainerMembershipProperty"; + String CLASS = RDFS + "Class"; + String RESOURCE = RDFS + "Resource"; + String LABEL = RDFS + "label"; + String COMMENT = RDFS + "comment"; } diff --git a/src/main/java/fr/inria/corese/core/logic/SKOS.java b/src/main/java/fr/inria/corese/core/logic/SKOS.java index e0da75724..409a9a7b3 100644 --- a/src/main/java/fr/inria/corese/core/logic/SKOS.java +++ b/src/main/java/fr/inria/corese/core/logic/SKOS.java @@ -5,9 +5,9 @@ public interface SKOS { - public static String NS = NSManager.SKOS; + String NS = NSManager.SKOS; - public static String BROADER = NS + "broader"; // has for broader = subConceptOf - public static String NARROWER = NS + "narrower"; // has for narrower + String BROADER = NS + "broader"; // has for broader = subConceptOf + String NARROWER = NS + "narrower"; // has for narrower } diff --git a/src/main/java/fr/inria/corese/core/next/api/BNode.java b/src/main/java/fr/inria/corese/core/next/api/BNode.java new file mode 100644 index 000000000..a7753de4b --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/BNode.java @@ -0,0 +1,31 @@ +package fr.inria.corese.core.next.api; + +/** + * Represents a blank node in a RDF graph. + * @see RDF-1.1 Concepts and Abstract Syntax: 3.4 Blank Nodes + */ +public interface BNode extends Resource { + + @Override + default boolean isBNode() { + return true; + } + + /** + * @return The identifier of the blank node. This identifier is unique in the context of the Model that contains it. + * @see RDF-1.1 Concepts and Abstract Syntax: 3.4 Blank Nodes + */ + String getID(); + + /** + * + * @param o + * @return true if o is a BNode and that has the same identifier as this BNode. + */ + @Override + boolean equals(Object o); + + @Override + int hashCode(); + +} diff --git a/src/main/java/fr/inria/corese/core/next/api/IRI.java b/src/main/java/fr/inria/corese/core/next/api/IRI.java new file mode 100644 index 000000000..09f3053bb --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/IRI.java @@ -0,0 +1,44 @@ +package fr.inria.corese.core.next.api; + +/** + * Represents an IRI + * @see RDF 1.1 Concepts and Abstract Syntax: Internationalized Resource Identifiers (IRIs) + */ +public interface IRI extends Resource { + + /** + * @return true if this is an IRI, false otherwise + */ + @Override + default boolean isIRI() { + return true; + } + + /** + * + * @return the namespace of the IRI + */ + String getNamespace(); + + /** + * + * @return the local name of the IRI + */ + String getLocalName(); + + /** + * + * @param o the object to compare + * @return true if the object is equal to this IRI, false otherwise + */ + @Override + boolean equals(Object o); + + /** + * + * @return the hash code of this IRI + */ + @Override + int hashCode(); + +} diff --git a/src/main/java/fr/inria/corese/core/next/api/Literal.java b/src/main/java/fr/inria/corese/core/next/api/Literal.java new file mode 100644 index 000000000..2945f5bf6 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/Literal.java @@ -0,0 +1,113 @@ +package fr.inria.corese.core.next.api; + +import fr.inria.corese.core.next.api.literal.CoreDatatype ; + +import javax.xml.datatype.XMLGregorianCalendar; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalAmount; +import java.util.Optional; + +/** + * Represents a literal value in RDF. + * A literal is composed of three elements: a lexical value, a datatype IRI and a CoreDatatype. + * The lexical value is a string that represents the value of the literal. + * The datatype IRI is an IRI that represents the datatype of the literal that can be any IRI. + * The CoreDatatype must be an implementation of the CoreDatatype interface that will direct the treatment of the literal by the library. It is based on an IRI and can have the same lexical value as the datatype IRI. + * @see RDF 1.1 Concepts and Abstract Syntax + */ +public interface Literal extends Value { + + @Override + default boolean isLiteral() { + return true; + } + + /** + * @return the lexical value of the literal + */ + String getLabel(); + + /** + * @return the language tag of the literal if it exists, empty otherwise. The language tag is a string that represents the language of the literal. + */ + Optional getLanguage(); + + /** + * @return the datatype IRI of the literal + */ + IRI getDatatype(); + + /** + * @return the value of the literal as a boolean if possible + */ + boolean booleanValue(); + + /** + * @return the value of the literal as a byte if possible + */ + byte byteValue(); + + /** + * @return the value of the literal as a short if possible + */ + short shortValue(); + + /** + * @return the value of the literal as an int if possible + */ + int intValue(); + + /** + * @return the value of the literal as a long if possible + */ + long longValue(); + + /** + * @return the value of the literal as a BigInteger if possible + */ + BigInteger integerValue(); + + /** + * @return the value of the literal as a BigDecimal if possible + */ + BigDecimal decimalValue(); + + /** + * @return the value of the literal as a float if possible + */ + float floatValue(); + + /** + * @return the value of the literal as a double if possible + */ + double doubleValue(); + + /** + * @return the value of the literal as a TemporalAccessor if possible + */ + TemporalAccessor temporalAccessorValue(); + + /** + * @return the value of the literal as a TemporalAmount if possible + */ + TemporalAmount temporalAmountValue(); + + /** + * @return the value of the literal as a XMLGregorianCalendar if possible + */ + XMLGregorianCalendar calendarValue(); + + /** + * @return the CoreDatatype of the literal + */ + CoreDatatype getCoreDatatype(); + + @Override + boolean equals(Object other); + + @Override + int hashCode(); + +} diff --git a/src/main/java/fr/inria/corese/core/next/api/Model.java b/src/main/java/fr/inria/corese/core/next/api/Model.java new file mode 100644 index 000000000..a4f7d146a --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/Model.java @@ -0,0 +1,166 @@ +package fr.inria.corese.core.next.api; + +import java.io.Serializable; +import java.util.Optional; +import java.util.Set; + +import fr.inria.corese.core.next.impl.exception.IncorrectOperationException; + +/** + * This class represents an RDF model, a set of statements. + * This is the central class to handle RDF data. + * Statements can have zero or several resources as contexts to represent the + * different graphs in the model. + * A model also handles a set of namespaces. There can be different prefixes for + * the same namespace, although it is ill-advised, how it affects serialization + * is implementation-dependant. There cannot be two namespaces with the same + * prefix. + * Statements can have zero or several resources as contexts, representing + * different named graphs within the modela + */ +public interface Model extends Set, Serializable, NamespaceAware { + + /** + * @return a "read-only" view of this model. "query" operations are possible, + * such as {@code filter()} on {@code contains()} but modifications will + * throw {@link IncorrectOperationException}. + */ + Model unmodifiable(); + + /** + * + * @param prefix a prefix for the namespace. It should be unique in the model. + * @param name the IRI of the namespace. It should be a valid IRI. + * @return the new Namespace created with the given prefix and name. + * @throws IncorrectOperationException if the Model is unmodifiable. + */ + Namespace setNamespace(String prefix, String name); + + /** + * Set the namespace of this model. The prefix should be unique in the model. + * + * @param namespace the namespace object to be added. + * @throws IncorrectOperationException if the Model is unmodifiable. + */ + void setNamespace(Namespace namespace); + + /** + * @param prefix the prefix of the namespace to be removed. + * @return the removed namespace, or an empty Optional if no namespace with the + * given prefix was found. + * @throws IncorrectOperationException if the Model is unmodifiable. + */ + Optional removeNamespace(String prefix); + + /** + * Check if a statement is present in the model. Can be used to query for + * statement pattern using {@code null} values. + * + * @param subj a Resource, subject of the statement. Can be {@code null} to + * match any subject. + * @param pred an IRI, predicate of the statement. Can be {@code null} to + * match any predicate. + * @param obj a Value, object of the statement. Can be {@code null} to + * match any object. + * @param contexts any Resource, context of the statement. Optional parameter. + * Can be {@code null} to match any context. + * @return true if a statement with the associated context is in the model, + * false otherwise. + */ + boolean contains(Resource subj, IRI pred, Value obj, Resource... contexts); + + /** + * Adds a statement to the model with optional context(s). + * If multiple contexts are provided, the statement is added once per context. + * + * @param subj the subject of the statement (must not be {@code null}) + * @param pred the predicate of the statement (must not be {@code null}) + * @param obj the object of the statement (must not be {@code null}) + * @param contexts optional contexts in which to add the statement; + * may be {@code null} or empty to add to the default graph + * @return {@code true} if the model was modified, {@code false} otherwise + * @throws IncorrectOperationException if the model is unmodifiable + * @throws IllegalArgumentException if {@code subj}, {@code pred}, or + * {@code obj} is {@code null} + */ + boolean add(Resource subj, IRI pred, Value obj, Resource... contexts); + + /** + * Remove statements from the model according to their context. If no context is + * given, all statements are removed, regardless of context. + * + * @param context a Resource, context of the statement. Optional parameter. Can + * be {@code null} to match any context. + * @return true if any statement was removed, false if none were present. + * @throws IncorrectOperationException if the Model is unmodifiable. + */ + boolean clear(Resource... context); + + /** + * Remove statements from the model. If no context is given, all corresponding + * statements are removed, regardless of context. + * + * @param subj a Resource, subject of the statement. Can be {@code null}. + * @param pred an IRI, predicate of the statement. Can be {@code null}. + * @param obj a Value, object of the statement. Can be {@code null}. + * @param contexts any Resource, context of the statement. Optional parameter. + * Can be {@code null} to match any context. + * @return true if any statement was removed, false if none were present. + * @throws IncorrectOperationException if the Model is unmodifiable. + */ + boolean remove(Resource subj, IRI pred, Value obj, Resource... contexts); + + /** + * The returned iterator must throw {@link IncorrectOperationException} if the + * model is unmodifiable and a modification is attempted. + * + * @param subj a Resource, subject of the statement. Can be {@code null} to + * match any subject. + * @param pred a an IRI, predicate of the statement. Can be {@code null} to + * match any predicate. + * @param obj a Value, object of the statement. Can be {@code null} to + * match any object. + * @param contexts any Resource, context of the statement. Optional parameter. + * Can be {@code null} to match any context. + * @return an iterator on a selection of statements. + */ + Iterable getStatements(Resource subj, IRI pred, Value obj, + Resource... contexts); + + /** + * Filter the model according to the given statement pattern. The filter is + * inclusive, meaning that if a statement matches the pattern, it will be + * included in the result. + * + * @param subj a Resource, subject of the statement. Can be {@code null} to + * match any subject. + * @param pred an IRI, predicate of the statement. Can be {@code null} to + * match any predicate. + * @param obj a Value, object of the statement. Can be {@code null} to + * match any object. + * @param contexts any Resource, context of the statement. Optional parameter. + * Can be {@code null} to match any context. + * @return a new Model containing all statements matching the given pattern. + */ + Model filter(Resource subj, IRI pred, Value obj, Resource... contexts); + + /** + * @return the set of resources used as subjects in the statements of the model. + */ + Set subjects(); + + /** + * @return the set of IRIs used as predicates in the statements of the model. + */ + Set predicates(); + + /** + * @return the set of values used as objects in the statements of the model. + */ + Set objects(); + + /** + * @return the set of resources used as contexts in the statements of the model. + */ + Set contexts(); +} diff --git a/src/main/java/fr/inria/corese/core/next/api/Namespace.java b/src/main/java/fr/inria/corese/core/next/api/Namespace.java new file mode 100644 index 000000000..76a7f3a52 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/Namespace.java @@ -0,0 +1,30 @@ +package fr.inria.corese.core.next.api; + +import java.io.Serializable; + +/** + * Represents a namespace with a prefix and the start of an IRI as its name. + */ +public interface Namespace extends Serializable, Comparable { + + /** + * @return The prefix of the namespace. + */ + String getPrefix(); + + /** + * @return The name of the namespace, which is the start of an IRI. + */ + String getName(); + + /** + * @param o + * @return true if o is a Namespace and has the same prefix and name as this Namespace. + */ + @Override + boolean equals(Object o); + + @Override + int hashCode(); + +} diff --git a/src/main/java/fr/inria/corese/core/next/api/NamespaceAware.java b/src/main/java/fr/inria/corese/core/next/api/NamespaceAware.java new file mode 100644 index 000000000..edc2e8568 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/NamespaceAware.java @@ -0,0 +1,29 @@ +package fr.inria.corese.core.next.api; + +import java.util.Optional; +import java.util.Set; + +/** + * An interface for models or stores that support RDF namespaces. + */ +public interface NamespaceAware { + + /** + * Returns the set of namespaces defined in the model. + * + * @return a set of Namespace objects + */ + Set getNamespaces(); + + /** + * Returns the namespace associated with the given prefix, if any. + * + * @param prefix the namespace prefix + * @return an Optional containing the Namespace, or empty if none found + */ + default Optional getNamespace(String prefix) { + return getNamespaces().stream() + .filter(ns -> ns.getPrefix().equals(prefix)) + .findFirst(); + } +} diff --git a/src/main/java/fr/inria/corese/core/next/api/Resource.java b/src/main/java/fr/inria/corese/core/next/api/Resource.java new file mode 100644 index 000000000..151a0f099 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/Resource.java @@ -0,0 +1,17 @@ +package fr.inria.corese.core.next.api; + +/** + * Super interface of all resources of an RDF graph (statements, IRI, blank + * nodes) as defined for RDF 1.2. + */ +public interface Resource extends Value { + + /** + * @return true + */ + @Override + default boolean isResource() { + return true; + } + +} diff --git a/src/main/java/fr/inria/corese/core/next/api/Statement.java b/src/main/java/fr/inria/corese/core/next/api/Statement.java new file mode 100644 index 000000000..415349043 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/Statement.java @@ -0,0 +1,42 @@ +package fr.inria.corese.core.next.api; + +import java.io.Serializable; + +/** + * Represents a value in RDF. Roughly equivalent to a quad with subject, predicate, object, and context. + */ +public interface Statement extends Serializable { + + /** + * Gets the subject of this statement. + */ + Resource getSubject(); + + /** + * Gets the predicate of this statement. + */ + IRI getPredicate(); + + /** + * Gets the object of this statement. + */ + Value getObject(); + + /** + * Gets the context of this statement. + */ + Resource getContext(); + + /** + * Compares this statement to another object. + */ + @Override + boolean equals(Object other); + + /** + * Computes the hash code of this statement. + */ + @Override + int hashCode(); + +} diff --git a/src/main/java/fr/inria/corese/core/next/api/Triple.java b/src/main/java/fr/inria/corese/core/next/api/Triple.java new file mode 100644 index 000000000..9042a2c07 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/Triple.java @@ -0,0 +1,31 @@ +package fr.inria.corese.core.next.api; + +public interface Triple extends Resource { + + @Override + default boolean isTriple() { + return true; + } + + /** + * @return the subject of this triple + */ + Resource getSubject(); + + /** + * @return the predicate of this triple + */ + IRI getPredicate(); + + /** + * @return the object of this triple + */ + Value getObject(); + + @Override + boolean equals(Object other); + + @Override + int hashCode(); + +} diff --git a/src/main/java/fr/inria/corese/core/next/api/Value.java b/src/main/java/fr/inria/corese/core/next/api/Value.java new file mode 100644 index 000000000..1bf971f23 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/Value.java @@ -0,0 +1,50 @@ +package fr.inria.corese.core.next.api; + +import java.io.Serializable; + +/** + * Super interface of all elements of an RDF model (triple, nodes, etc). + */ +public interface Value extends Serializable { + + /** + * @return true if this value is a blank node (i.e. an instance of BNode) + */ + default boolean isBNode() { + return false; + } + + /** + * @return true if this value is a IRI (i.e. an instance of IRI) + */ + default boolean isIRI() { + return false; + } + + /** + * @return true if this value is a resource (i.e. an instance of Resource) + */ + default boolean isResource() { + return false; + } + + /** + * @return true if this value is a literal (i.e. an instance of Literal) + */ + default boolean isLiteral() { + return false; + } + + /** + * @return true if this value is a named graph (i.e. an instance of NamedGraph) + */ + default boolean isTriple() { + return false; + } + + /** + * @return the string representation of this value (expected to be the same as the NTriples representation) + */ + String stringValue(); + +} diff --git a/src/main/java/fr/inria/corese/core/next/api/ValueFactory.java b/src/main/java/fr/inria/corese/core/next/api/ValueFactory.java new file mode 100644 index 000000000..caf60833f --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/ValueFactory.java @@ -0,0 +1,202 @@ +package fr.inria.corese.core.next.api; + +import fr.inria.corese.core.next.api.literal.CoreDatatype; + +import javax.xml.datatype.XMLGregorianCalendar; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalAmount; +import java.util.Date; + +public interface ValueFactory { + + /** + * Create an IRI from a string. + * @param iri Valid IRI string + * @return IRI + */ + IRI createIRI(String iri); + + /** + * Create an IRI from a namespace and a local name. + * @param namespace Namespace + * @param localName Local name + * @return IRI + */ + IRI createIRI(String namespace, String localName); + + /** + * Create a blank node. + * @return Blank node + */ + BNode createBNode(); + + /** + * Create a blank node with a node ID. + * @param nodeID Node ID + * @return Blank node + */ + BNode createBNode(String nodeID); + + /** + * Create a string literal from its lexical value. + * @param label lexical value + * @return Literal + */ + Literal createLiteral(String label); + + /** + * Create a string literal from its lexical value and language tag. + * @param label Lexical value + * @param language Language tag + * @return Literal + */ + Literal createLiteral(String label, String language); + + /** + * Create a typed literal from its lexical value and datatype IRI. + * If the datatype is a CoreDatatype, the coreDatatype parameter should be set to the corresponding value. + * @param label Lexical value + * @param datatype Datatype IRI + * @return Literal + */ + Literal createLiteral(String label, IRI datatype); + + /** + * Create a typed literal from its lexical value and core datatype IRI. The datatype of the literal is set to be the datatype IRI corresponding to the core datatype. + * @param label Lexical value + * @param datatype Core datatype + * @return Literal + */ + Literal createLiteral(String label, CoreDatatype datatype); + + /** + * Create a typed literal from its lexical value, datatype IRI and core datatype IRI. + * @param label Lexical value + * @param datatype Datatype IRI + * @param coreDatatype Core datatype + * @return Literal + */ + Literal createLiteral(String label, IRI datatype, CoreDatatype coreDatatype); + + /** + * Create a literal typed by xsd:boolean. + * @param value Value + * @return Literal that has a boolean value. + */ + Literal createLiteral(boolean value); + + /** + * Create a literal typed by xsd:byte. + * @param value Value + * @return Literal that has a byte value. + */ + Literal createLiteral(byte value); + + /** + * Create a literal typed by xsd:short. + * @param value Value + * @return Literal that has a short value. + */ + Literal createLiteral(short value); + + /** + * Create a literal typed by xsd:integer. + * @param value Value + * @return Literal that has an int value. + */ + Literal createLiteral(int value); + + /** + * Create a literal typed by xsd:long. + * @param value Value + * @return Literal that has a long value. + */ + Literal createLiteral(long value); + + /** + * Create a literal typed by xsd:float. + * @param value Value + * @return Literal that has a float value. + */ + Literal createLiteral(float value); + + /** + * Create a literal typed by xsd:double. + * @param value Value + * @return Literal that has a double value. + */ + Literal createLiteral(double value); + + /** + * Create a literal typed by xsd:decimal. + * @param bigDecimal Value + * @return Literal that has a BigDecimal value. + */ + Literal createLiteral(BigDecimal bigDecimal); + + /** + * Create a literal typed by xsd:integer. + * @param bigInteger Value + * @return Literal that has a BigInteger value. + */ + Literal createLiteral(BigInteger bigInteger); + + /** + * Create a literal typed by xsd:dateTime. + * @param value Value + * @return Literal that has a TemporalAccessor value. + */ + Literal createLiteral(TemporalAccessor value); + + /** + * Create a literal typed by xsd:duration. + * @param value Value + * @return Literal that has a TemporalAmount value. + */ + Literal createLiteral(TemporalAmount value); + + /** + * Create a literal typed by xsd:dateTime. + * @param calendar Value + * @return Literal that has a XMLGregorianCalendar value. + */ + Literal createLiteral(XMLGregorianCalendar calendar); + + /** + * Create a literal typed by xsd:date. + * @param date Value + * @return Literal that has a Date value. + */ + Literal createLiteral(Date date); + + /** + * Create a statement with the given subject, predicate and object. + * @param subject Resource subject of the statement + * @param predicate IRI predicate of the statement + * @param object Value object of the statement + * @return Statement without context + */ + Statement createStatement(Resource subject, IRI predicate, Value object); + + /** + * Create a statement with the given subject, predicate, object and context. + * @param subject Resource subject of the statement + * @param predicate IRI predicate of the statement + * @param object Value object of the statement + * @param context Resource context of the statement + * @return Statement with context + */ + Statement createStatement(Resource subject, IRI predicate, Value object, Resource context); + + /** + * Create a triple with the given subject, predicate and object. + * @param subject Resource subject of the triple + * @param predicate IRI predicate of the triple + * @param object Value object of the triple + * @return Triple + */ + Triple createTriple(Resource subject, IRI predicate, Value object); + +} diff --git a/src/main/java/fr/inria/corese/core/next/api/base/exception/CoreseException.java b/src/main/java/fr/inria/corese/core/next/api/base/exception/CoreseException.java new file mode 100644 index 000000000..986da1f4c --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/exception/CoreseException.java @@ -0,0 +1,43 @@ +package fr.inria.corese.core.next.api.base.exception; + +/** + * CoreseException is the superclass for all exceptions thrown by the Corese framework. + * It extends RuntimeException, allowing it to be used as an unchecked exception. + * Its constructors are redirection to the constructors of RuntimeException. + */ +public abstract class CoreseException extends RuntimeException { + private static final long serialVersionUID = 6828854064356034698L; + + /** + * Default constructor for CoreseException. + */ + protected CoreseException() { + super(); + } + + /** + * Constructor for CoreseException with a message. + * @param msg the message to be associated with the exception + */ + protected CoreseException(String msg) { + super(msg); + } + + /** + * Constructor for CoreseException with a cause. + * @param t the cause of the exception + */ + protected CoreseException(Throwable t) { + super(t); + } + + /** + * Constructor for CoreseException with a message and a cause. + * @param msg the message to be associated with the exception + * @param t the cause of the exception + */ + protected CoreseException(String msg, Throwable t) { + super(msg, t); + } +} + diff --git a/src/main/java/fr/inria/corese/core/next/api/base/io/AbstractIOOptions.java b/src/main/java/fr/inria/corese/core/next/api/base/io/AbstractIOOptions.java new file mode 100644 index 000000000..780894d7f --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/io/AbstractIOOptions.java @@ -0,0 +1,20 @@ +package fr.inria.corese.core.next.api.base.io; + +import fr.inria.corese.core.next.api.io.IOOptions; + +/** + * Abstract class for parser/serializers that sets up the necessity of implementing a builder pattern. + */ +public abstract class AbstractIOOptions implements IOOptions { + + /** + * Builder class for constructing instances of IOOptions. + */ + public abstract static class Builder< T extends IOOptions> { + protected Builder() { + + } + + public abstract T build(); + } +} diff --git a/src/main/java/fr/inria/corese/core/next/api/base/io/FileFormat.java b/src/main/java/fr/inria/corese/core/next/api/base/io/FileFormat.java new file mode 100644 index 000000000..59867eaa2 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/io/FileFormat.java @@ -0,0 +1,103 @@ +package fr.inria.corese.core.next.api.base.io; + +import java.util.List; +import java.util.Objects; + +/** + * Represents a general file format, including its name, associated file + * extensions, and MIME types. + */ +public class FileFormat { + + private final String name; + private final List extensions; + private final List mimeTypes; + + /** + * Constructs a new FileFormat instance. + * + * @param name The human-readable name of the format. + * @param extensions The list of file extensions. + * @param mimeTypes The list of MIME types. + * @throws NullPointerException if name, extensions or mimeTypes is null or + * empty. + */ + public FileFormat(String name, List extensions, List mimeTypes) { + this.name = Objects.requireNonNull(name, "Format name cannot be null"); + this.extensions = List.copyOf(Objects.requireNonNull(extensions, "Extensions list cannot be null")); + this.mimeTypes = List.copyOf(Objects.requireNonNull(mimeTypes, "MIME types list cannot be null")); + + if (extensions.isEmpty()) { + throw new IllegalArgumentException("At least one file extension must be provided"); + } + if (mimeTypes.isEmpty()) { + throw new IllegalArgumentException("At least one MIME type must be provided"); + } + } + + /** + * Returns the name of the format. + * + * @return The format name. + */ + public String getName() { + return name; + } + + /** + * Returns the list of known file extensions. + * + * @return A list of extensions. + */ + public List getExtensions() { + return extensions; + } + + /** + * Returns the list of associated MIME types. + * + * @return A list of MIME types. + */ + public List getMimeTypes() { + return mimeTypes; + } + + /** + * Returns the default (primary) file extension. + * + * @return The first extension in the list. + */ + public String getDefaultExtension() { + return extensions.get(0); + } + + /** + * Returns the default (primary) MIME type. + * + * @return The first MIME type in the list. + */ + public String getDefaultMimeType() { + return mimeTypes.get(0); + } + + @Override + public String toString() { + return "FileFormat{name='%s', extensions=%s, mimeTypes=%s}".formatted(name, extensions, mimeTypes); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!(obj instanceof FileFormat other)) + return false; + return name.equalsIgnoreCase(other.name) + && extensions.equals(other.extensions) + && mimeTypes.equals(other.mimeTypes); + } + + @Override + public int hashCode() { + return Objects.hash(name.toLowerCase(), extensions, mimeTypes); + } +} diff --git a/src/main/java/fr/inria/corese/core/next/api/base/io/RDFFormat.java b/src/main/java/fr/inria/corese/core/next/api/base/io/RDFFormat.java new file mode 100644 index 000000000..e16c3a92c --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/io/RDFFormat.java @@ -0,0 +1,190 @@ +package fr.inria.corese.core.next.api.base.io; + +import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.Optional; + +/** + * Describes a semantic RDF serialization format, extending file-level metadata + * with RDF-specific capabilities. + * This class also acts as a central registry for all known RDF formats, + * providing static constants for common formats and utility methods for lookup. + */ +public class RDFFormat extends FileFormat { + + private final boolean supportsNamespaces; + private final boolean supportsNamedGraphs; + + public static final RDFFormat TURTLE = new RDFFormat( + "Turtle", + List.of("ttl"), + List.of("text/turtle"), + true, + false); + + + public static final RDFFormat NTRIPLES = new RDFFormat( + "N-Triples", + List.of("nt"), + List.of("application/n-triples", "text/plain"), + false, + false); + + public static final RDFFormat NQUADS = new RDFFormat( + "N-Quads", + List.of("nq"), + List.of("application/n-quads"), + false, + true); + + public static final RDFFormat JSONLD = new RDFFormat( + "JSON-LD", + List.of("jsonld"), + List.of("application/ld+json", "application/json"), + true, + true); + + public static final RDFFormat RDFXML = new RDFFormat( + "RDF/XML", + List.of("rdf", "xml"), + List.of("application/rdf+xml"), + true, + false); + + public static final RDFFormat TRIG = new RDFFormat( + "TriG", + List.of("trig"), + List.of("application/trig"), + true, + true); + + public static final RDFFormat RDFC_1_0 = new RDFFormat( + "RDFC-1.0", + List.of("nq"), + List.of("application/n-quads", "application/n-quads"), + false, + true); + + /** + * Constructs a new RDF format. + * + * @param name The name of the format (e.g., "Turtle"). + * @param extensions File extensions for this format (e.g., ["ttl"]). + * @param mimeTypes MIME types for this format (e.g., + * ["text/turtle"]). + * @param supportsNamespaces Whether the format supports prefixes/namespaces. + * @param supportsNamedGraphs Whether the format supports named graphs. + * serialization. + */ + public RDFFormat( + String name, + List extensions, + List mimeTypes, + boolean supportsNamespaces, + boolean supportsNamedGraphs) { + super(name, extensions, mimeTypes); + this.supportsNamespaces = supportsNamespaces; + this.supportsNamedGraphs = supportsNamedGraphs; + } + + /** + * Whether the format supports RDF prefixes (e.g., Turtle's @prefix declarations). + * + * @return true if the format supports explicit namespace declarations, false otherwise. + */ + public boolean supportsNamespaces() { + return supportsNamespaces; + } + + /** + * Whether the format supports named graphs (e.g., TriG, N-Quads). + */ + public boolean supportsNamedGraphs() { + return supportsNamedGraphs; + } + + + /** + * Finds a known RDF format by its name (case-insensitive). + * + * @param name The name of the format (e.g., "Turtle"). + * @return An Optional containing the matching RdfFormat if found. + */ + public static Optional byName(String name) { + String n = name.toLowerCase(Locale.ROOT); + return all().stream() + .filter(format -> format.getName().equalsIgnoreCase(n)) + .findFirst(); + } + + /** + * Finds a known RDF format by file extension (case-insensitive). + * + * @param extension The file extension (e.g., "ttl"). + * @return An Optional containing the matching RdfFormat if found. + */ + public static Optional byExtension(String extension) { + String ext = extension.toLowerCase(Locale.ROOT); + return all().stream() + .filter(format -> format.getExtensions().stream() + .anyMatch(e -> e.equalsIgnoreCase(ext))) + .findFirst(); + } + + /** + * Finds a known RDF format by MIME type (case-insensitive). + * + * @param mimeType The MIME type (e.g., "text/turtle"). + * @return An Optional containing the matching RdfFormat if found. + */ + public static Optional byMimeType(String mimeType) { + String mime = mimeType.toLowerCase(Locale.ROOT); + return all().stream() + .filter(format -> format.getMimeTypes().stream() + .anyMatch(m -> m.equalsIgnoreCase(mime))) + .findFirst(); + } + + /** + * Returns a list of all known RDF formats. + * + * @return An unmodifiable List of all RdfFormat constants. + */ + public static List all() { + return List.of(TURTLE, NTRIPLES, NQUADS, JSONLD, RDFXML, TRIG); + } + + @Override + public String toString() { + return "%s [extensions: %s, mimeTypes: %s, prefixes: %s, namedGraphs: %s]".formatted( + getName(), + String.join(", ", getExtensions()), + String.join(", ", getMimeTypes()), + supportsNamespaces(), + supportsNamedGraphs()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!(obj instanceof RDFFormat other)) + return false; + return getName().equalsIgnoreCase(other.getName()) + && getExtensions().equals(other.getExtensions()) + && getMimeTypes().equals(other.getMimeTypes()) + && supportsNamespaces == other.supportsNamespaces + && supportsNamedGraphs == other.supportsNamedGraphs; + } + + @Override + public int hashCode() { + return Objects.hash( + getName().toLowerCase(), + getExtensions(), + getMimeTypes(), + supportsNamespaces, + supportsNamedGraphs); + } +} \ No newline at end of file diff --git a/src/main/java/fr/inria/corese/core/next/api/base/io/parser/AbstractRDFParser.java b/src/main/java/fr/inria/corese/core/next/api/base/io/parser/AbstractRDFParser.java new file mode 100644 index 000000000..a7670372a --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/io/parser/AbstractRDFParser.java @@ -0,0 +1,105 @@ +package fr.inria.corese.core.next.api.base.io.parser; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.util.Objects; + +import fr.inria.corese.core.next.api.Model; +import fr.inria.corese.core.next.api.ValueFactory; +import fr.inria.corese.core.next.api.base.io.AbstractIOOptions; +import fr.inria.corese.core.next.api.io.IOOptions; +import fr.inria.corese.core.next.api.io.common.BaseIRIOptions; +import fr.inria.corese.core.next.api.io.parser.RDFParser; + +/** + * Abstract class for RDFParser that set up the inner Model and ValueFactory + */ +public abstract class AbstractRDFParser implements RDFParser { + + private final Model model; + private final ValueFactory valueFactory; + private IOOptions config; + + /** + * Gets the configuration options for the parser. + * + * @return the configuration options + */ + public IOOptions getConfig() { + return config; + } + + /** + * Sets the configuration options for the parser. + * + * @param config the configuration options to be set + */ + public void setConfig(IOOptions config) { + this.config = config; + } + + /** + * Constructor for AbstractRDFParser that initializes the model and value + * factory. Ths created object will use an empty AbstractIOOptions object as configuration + * + * @param model the model to be populated by the parser + * @param factory the value factory used to create RDF values + */ + protected AbstractRDFParser(Model model, ValueFactory factory) { + this(model, factory, new AbstractIOOptions() { + }); + } + + /** + * Constructor for AbstractRDFParser that initializes the model, value factory, + * and configuration options. + * + * @param model the model to be populated by the parser + * @param factory the value factory used to create RDF values + * @param config optional configuration options for the parser + */ + protected AbstractRDFParser(Model model, ValueFactory factory, IOOptions config) { + Objects.requireNonNull(model); + Objects.requireNonNull(factory); + Objects.requireNonNull(config); + this.model = model; + this.valueFactory = factory; + this.config = config; + } + + @Override + public void parse(InputStream in) { + if(getConfig() instanceof BaseIRIOptions baseIRIOptions) { + String baseIRI = baseIRIOptions.getBaseIRI(); + parse(new InputStreamReader(in, StandardCharsets.UTF_8), baseIRI); + } else { + parse(new InputStreamReader(in, StandardCharsets.UTF_8), null); + } + } + + @Override + public void parse(Reader reader) { + if(getConfig() instanceof BaseIRIOptions baseIRIOptions) { + String baseIRI = baseIRIOptions.getBaseIRI(); + parse(reader, baseIRI); + } else { + parse(reader, null); + } + } + + /** + * @return the model populated by the parser + */ + protected Model getModel() { + return model; + } + + /** + * @return the value factory used by the parser + */ + protected ValueFactory getValueFactory() { + return valueFactory; + } +} diff --git a/src/main/java/fr/inria/corese/core/next/api/base/io/parser/AbstractRDFParserFactory.java b/src/main/java/fr/inria/corese/core/next/api/base/io/parser/AbstractRDFParserFactory.java new file mode 100644 index 000000000..38f3c142e --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/io/parser/AbstractRDFParserFactory.java @@ -0,0 +1,36 @@ +package fr.inria.corese.core.next.api.base.io.parser; + +import fr.inria.corese.core.next.api.Model; +import fr.inria.corese.core.next.api.ValueFactory; +import fr.inria.corese.core.next.api.base.io.RDFFormat; +import fr.inria.corese.core.next.api.io.parser.RDFParser; +import fr.inria.corese.core.next.api.io.parser.RDFParserFactory; + +/** + * Abstract base class for {@link RDFParserFactory}s. + */ +public abstract class AbstractRDFParserFactory implements RDFParserFactory { + + /** + * Default constructor for AbstractRDFParserFactory. + * + * The constructor is protected to prevent instantiation from outside the + * package. + */ + protected AbstractRDFParserFactory() { + } + + /** + * Creates a new RDF parser for the given RDF format and model. + * + * @param format The {@link RDFFormat} to use for parsing. + * @param model The {@link Model} to which the parsed data will be added. + * @param factory The {@link ValueFactory} factory to use for creating RDF + * values. + * @return + */ + @Override + public RDFParser createRDFParser(RDFFormat format, Model model, ValueFactory factory) { + return createRDFParser(format, model, factory, null); + } +} diff --git a/src/main/java/fr/inria/corese/core/next/api/base/model/AbstractBNode.java b/src/main/java/fr/inria/corese/core/next/api/base/model/AbstractBNode.java new file mode 100644 index 000000000..069fce952 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/model/AbstractBNode.java @@ -0,0 +1,57 @@ +package fr.inria.corese.core.next.api.base.model; + +import fr.inria.corese.core.next.api.BNode; + +/** + * Abstract implementation of the {@link BNode} interface, providing common functionality for blank node representations. + * A blank node (BNode) https://www.w3.org/TR/rdf12-concepts/#section-blank-nodes + */ +public abstract class AbstractBNode implements BNode { + + /** + * Returns the string value of this blank node, which is its unique identifier. + * This method is an implementation of {@link BNode#stringValue()} and simply returns the result of {@link #getID()}. + * + * @return The string value of the blank node (its unique identifier). + */ + @Override + public String stringValue() { + return getID(); + } + + /** + * Checks whether this blank node is equal to another object. + * Two blank nodes are considered equal if they are the same object in memory or if they have the same unique identifier (ID). + * This method is an implementation of {@link BNode#equals(Object)}. + * + * @param o The object to compare this blank node to. + * @return {@code true} if the two blank nodes are the same object or have the same unique identifier; {@code false} otherwise. + */ + @Override + public boolean equals(Object o) { + return this == o || o instanceof BNode + && getID().equals(((BNode) o).getID()); + } + + /** + * Returns the hash code for this blank node. The hash code is based on the unique identifier of the blank node, + * using the hash code of the ID returned by {@link #getID()}. + * This method is an implementation of {@link BNode#hashCode()}. + * + * @return The hash code for this blank node. + */ + @Override + public int hashCode() { + return getID().hashCode(); + } + + /** + * Returns a string representation of this blank node in the form "_:{ID}" where {ID} is the unique identifier of the blank node. + * + * @return A string representing this blank node, prefixed with "_:" and followed by its unique identifier. + */ + @Override + public String toString() { + return "_:" + getID(); + } +} \ No newline at end of file diff --git a/src/main/java/fr/inria/corese/core/next/api/base/model/AbstractIRI.java b/src/main/java/fr/inria/corese/core/next/api/base/model/AbstractIRI.java new file mode 100644 index 000000000..be3fe895a --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/model/AbstractIRI.java @@ -0,0 +1,89 @@ +package fr.inria.corese.core.next.api.base.model; + +import fr.inria.corese.core.next.api.IRI; +import fr.inria.corese.core.next.impl.common.util.IRIUtils; +import fr.inria.corese.core.next.impl.exception.IncorrectFormatException; + +/** + * Base class for IRI implementations. Includes base functionality for IRI + * handling. + */ +public abstract class AbstractIRI implements IRI, Comparable { + + private static final long serialVersionUID = -1005683238501772511L; + + private final String namespace; + private final String localName; + + /** + * Constructor for AbstractIRI. + * + * @param fullIRI the full IRI string + * @throws IncorrectFormatException if the IRI format is incorrect + */ + protected AbstractIRI(String fullIRI) { + if (!IRIUtils.isStandardIRI(fullIRI)) { + throw new IncorrectFormatException("IRI '" + fullIRI + "' must be a valid IRI"); + } + this.namespace = IRIUtils.guessNamespace(fullIRI); + this.localName = IRIUtils.guessLocalName(fullIRI); + } + + /** + * Constructor for AbstractIRI with namespace and local name. + * + * @param namespace the namespace of the IRI + * @param localName the local name of the IRI + * @throws IncorrectFormatException if the IRI format is incorrect + */ + protected AbstractIRI(String namespace, String localName) { + if (!IRIUtils.isStandardIRI(namespace + localName)) { + throw new IncorrectFormatException("IRI '" + namespace + localName + "' must be a valid IRI"); + } + this.namespace = namespace; + this.localName = localName; + } + + @Override + public boolean isIRI() { + return true; + } + + @Override + public String getNamespace() { + return this.namespace; + } + + @Override + public String getLocalName() { + return this.localName; + } + + @Override + public String stringValue() { + return this.namespace + this.localName; + } + + @Override + public int compareTo(IRI o) { + return this.stringValue().compareTo(o.stringValue()); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + AbstractIRI that = (AbstractIRI) o; + return this.stringValue().equals(that.stringValue()); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + (this.namespace == null ? 0 : this.namespace.hashCode()); + hash = 31 * hash + (this.localName == null ? 0 : this.localName.hashCode()); + return hash; + } +} diff --git a/src/main/java/fr/inria/corese/core/next/api/base/model/AbstractModel.java b/src/main/java/fr/inria/corese/core/next/api/base/model/AbstractModel.java new file mode 100644 index 000000000..34b52a249 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/model/AbstractModel.java @@ -0,0 +1,613 @@ +package fr.inria.corese.core.next.api.base.model; + +import java.util.AbstractSet; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Optional; +import java.util.Set; + +import fr.inria.corese.core.next.api.IRI; +import fr.inria.corese.core.next.api.Model; +import fr.inria.corese.core.next.api.Namespace; +import fr.inria.corese.core.next.api.Resource; +import fr.inria.corese.core.next.api.Statement; +import fr.inria.corese.core.next.api.Value; +import fr.inria.corese.core.next.impl.temp.ModelNamespace; + +/** + * Abstract class that implements the Model interface. + * This class provides default implementations for the methods in the Model + * interface, + */ +public abstract class AbstractModel extends AbstractSet implements Model { + + @Override + public Model unmodifiable() { + return new ReadOnlyModel(this); + } + + @Override + public Namespace setNamespace(String prefix, String name) { + Optional existing = getNamespace(prefix); + + if (!existing.isPresent() || !existing.get().getName().equals(name)) { + Namespace namespace = new ModelNamespace(prefix, name); + setNamespace(namespace); + return namespace; + } + + return existing.get(); + } + + @Override + public boolean clear(Resource... context) { + return remove(null, null, null, context); + } + + @Override + public Set subjects() { + return new ValueSet() { + + @Override + public boolean contains(Object object) { + if (object instanceof Resource) { + return AbstractModel.this.contains((Resource) object, null, null); + } + return false; + } + + @Override + public boolean remove(Object object) { + if (object instanceof Resource) { + return AbstractModel.this.remove((Resource) object, null, null); + } + return false; + } + + @Override + public boolean add(Resource subject) { + return AbstractModel.this.add(subject, null, null); + } + + @Override + protected Resource term(Statement statement) { + return statement.getSubject(); + } + + @Override + protected void removeIteration(Iterator iterator, Resource subject) { + AbstractModel.this.removeTermIteration(iterator, subject, null, null); + } + }; + } + + @Override + public Set predicates() { + return new ValueSet() { + + @Override + public boolean contains(Object object) { + if (object instanceof IRI) { + return AbstractModel.this.contains(null, (IRI) object, null); + } + return false; + } + + @Override + public boolean remove(Object object) { + if (object instanceof IRI) { + return AbstractModel.this.remove(null, (IRI) object, null); + } + return false; + } + + @Override + public boolean add(IRI predicate) { + return AbstractModel.this.add(null, predicate, null); + } + + @Override + protected IRI term(Statement statement) { + return statement.getPredicate(); + } + + @Override + protected void removeIteration(Iterator iterator, IRI predicate) { + AbstractModel.this.removeTermIteration(iterator, null, predicate, null); + } + }; + } + + @Override + public Set objects() { + return new ValueSet() { + + @Override + public boolean contains(Object object) { + if (object instanceof Value) { + return AbstractModel.this.contains(null, null, (Value) object); + } + return false; + } + + @Override + public boolean remove(Object object) { + if (object instanceof Value) { + return AbstractModel.this.remove(null, null, (Value) object); + } + return false; + } + + @Override + public boolean add(Value value) { + return AbstractModel.this.add(null, null, value); + } + + @Override + protected Value term(Statement statement) { + return statement.getObject(); + } + + @Override + protected void removeIteration(Iterator iterator, Value value) { + AbstractModel.this.removeTermIteration(iterator, null, null, value); + } + }; + } + + @Override + public Set contexts() { + return new ValueSet() { + + @Override + public boolean contains(Object object) { + if (object instanceof Resource || object == null) { + return AbstractModel.this.contains(null, null, null, (Resource) object); + } + return false; + } + + @Override + public boolean remove(Object object) { + if (object instanceof Resource || object == null) { + return AbstractModel.this.remove(null, null, null, (Resource) object); + } + return false; + } + + @Override + public boolean add(Resource context) { + return AbstractModel.this.add(null, null, null, context); + } + + @Override + protected Resource term(Statement statement) { + return statement.getContext(); + } + + @Override + protected void removeIteration(Iterator iterator, Resource context) { + AbstractModel.this.removeTermIteration(iterator, null, null, null, context); + } + }; + } + + private abstract class ValueSet extends AbstractSet { + + private final class ValueSetIterator implements Iterator { + + private final Iterator statementIterator; + private final Set seen = new LinkedHashSet<>(); + + private Statement currentStatement; + private Statement nextStatement; + + private ValueSetIterator(Iterator iterator) { + this.statementIterator = iterator; + } + + @Override + public boolean hasNext() { + if (nextStatement == null) { + nextStatement = findNext(); + } + return nextStatement != null; + } + + @Override + public V next() { + if (nextStatement == null) { + nextStatement = findNext(); + if (nextStatement == null) { + throw new NoSuchElementException(); + } + } + + currentStatement = nextStatement; + nextStatement = null; + + V value = term(currentStatement); + seen.add(value); + return value; + } + + @Override + public void remove() { + if (currentStatement == null) { + throw new IllegalStateException(); + } + + removeIteration(statementIterator, term(currentStatement)); + currentStatement = null; + } + + private Statement findNext() { + while (statementIterator.hasNext()) { + Statement statement = statementIterator.next(); + V value = term(statement); + if (!seen.contains(value)) { + return statement; + } + } + return null; + } + } + + @Override + public Iterator iterator() { + return new ValueSetIterator(AbstractModel.this.iterator()); + } + + @Override + public void clear() { + AbstractModel.this.clear(); + } + + @Override + public boolean isEmpty() { + return AbstractModel.this.isEmpty(); + } + + @Override + public int size() { + Iterator iterator = AbstractModel.this.iterator(); + try { + Set uniqueTerms = new LinkedHashSet<>(); + while (iterator.hasNext()) { + uniqueTerms.add(term(iterator.next())); + } + return uniqueTerms.size(); + } finally { + AbstractModel.this.closeIterator(iterator); + } + } + + @Override + public boolean removeAll(Collection collection) { + boolean modified = false; + + Iterator iterator = collection.iterator(); + try { + while (iterator.hasNext()) { + modified |= remove(iterator.next()); + } + return modified; + } finally { + closeIterator(collection, iterator); + } + } + + @Override + public Object[] toArray() { + Iterator iterator = AbstractModel.this.iterator(); + try { + Set uniqueTerms = new LinkedHashSet<>(); + while (iterator.hasNext()) { + uniqueTerms.add(term(iterator.next())); + } + return uniqueTerms.toArray(); + } finally { + AbstractModel.this.closeIterator(iterator); + } + } + + @Override + public T[] toArray(T[] array) { + Iterator iterator = AbstractModel.this.iterator(); + try { + Set uniqueTerms = new LinkedHashSet<>(); + while (iterator.hasNext()) { + uniqueTerms.add(term(iterator.next())); + } + return uniqueTerms.toArray(array); + } finally { + AbstractModel.this.closeIterator(iterator); + } + } + + @Override + public boolean containsAll(Collection collection) { + Iterator iterator = collection.iterator(); + try { + while (iterator.hasNext()) { + if (!contains(iterator.next())) { + return false; + } + } + return true; + } finally { + closeIterator(collection, iterator); + } + } + + @Override + public boolean addAll(Collection collection) { + boolean modified = false; + + Iterator iterator = collection.iterator(); + try { + while (iterator.hasNext()) { + if (add(iterator.next())) { + modified = true; + } + } + return modified; + } finally { + closeIterator(collection, iterator); + } + } + + @Override + public boolean retainAll(Collection collection) { + Iterator iterator = iterator(); + try { + boolean modified = false; + while (iterator.hasNext()) { + if (!collection.contains(iterator.next())) { + iterator.remove(); + modified = true; + } + } + return modified; + } finally { + closeIterator(iterator); + } + } + + // Must be implemented by subclasses: how to extract a term from a Statement + @Override + public abstract boolean add(V term); + + protected abstract V term(Statement statement); + + protected abstract void removeIteration(Iterator iterator, V term); + + protected void closeIterator(Iterator iterator) { + // Only close iterators of our own ValueSetIterator type + if (iterator.getClass().getSimpleName().equals("ValueSetIterator")) { + @SuppressWarnings("unchecked") + ValueSetIterator valueSetIterator = (ValueSetIterator) iterator; + AbstractModel.this.closeIterator(valueSetIterator.statementIterator); + } + } + + private void closeIterator(Collection collection, Iterator iterator) { + if (collection instanceof AbstractModel) { + ((AbstractModel) collection).closeIterator(iterator); + } else if (collection instanceof ValueSet) { + ((ValueSet) collection).closeIterator(iterator); + } + } + } + + @Override + public boolean isEmpty() { + return !contains(null, null, null); + } + + @Override + public boolean contains(Object object) { + if (object instanceof Statement) { + Statement statement = (Statement) object; + return contains( + statement.getSubject(), + statement.getPredicate(), + statement.getObject(), + statement.getContext()); + } + + return false; + } + + @Override + public Object[] toArray() { + Iterator iterator = iterator(); + try { + List collected = new ArrayList<>(size()); + + while (iterator.hasNext()) { + collected.add(iterator.next()); + } + + return collected.toArray(); + } finally { + closeIterator(iterator); + } + } + + @Override + public T[] toArray(T[] array) { + Iterator iterator = iterator(); + try { + List tempList = new ArrayList<>(size()); + while (iterator.hasNext()) { + tempList.add(iterator.next()); + } + return tempList.toArray(array); + } finally { + closeIterator(iterator); + } + } + + @Override + public boolean add(Statement statement) { + return add( + statement.getSubject(), + statement.getPredicate(), + statement.getObject(), + statement.getContext()); + } + + @Override + public boolean remove(Object object) { + if (object instanceof Statement) { + if (isEmpty()) { + return false; + } + + Statement statement = (Statement) object; + return remove( + statement.getSubject(), + statement.getPredicate(), + statement.getObject(), + statement.getContext()); + } + + return false; + } + + @Override + public boolean containsAll(Collection collection) { + Iterator iterator = collection.iterator(); + try { + while (iterator.hasNext()) { + if (!contains(iterator.next())) { + return false; + } + } + return true; + } finally { + closeIterator(collection, iterator); + } + } + + @Override + public boolean addAll(Collection collection) { + boolean modified = false; + + Iterator iterator = collection.iterator(); + try { + while (iterator.hasNext()) { + if (add(iterator.next())) { + modified = true; + } + } + + return modified; + } finally { + closeIterator(collection, iterator); + } + } + + @Override + public boolean retainAll(Collection collection) { + boolean modified = false; + + Iterator iterator = iterator(); + try { + while (iterator.hasNext()) { + if (!collection.contains(iterator.next())) { + iterator.remove(); + modified = true; + } + } + + return modified; + } finally { + closeIterator(iterator); + } + } + + @Override + public boolean removeAll(Collection collection) { + boolean modified = false; + + // Iterate over the smaller collection for better performance + if (size() > collection.size()) { + Iterator iterator = collection.iterator(); + try { + while (iterator.hasNext()) { + // Attempt to remove each element from this collection + modified |= remove(iterator.next()); + } + } finally { + closeIterator(collection, iterator); + } + } else { + Iterator iterator = iterator(); + try { + while (iterator.hasNext()) { + Object element = iterator.next(); + // Remove elements present in the input collection + if (collection.contains(element)) { + iterator.remove(); + modified = true; + } + } + } finally { + closeIterator(iterator); + } + } + + return modified; + } + + @Override + public Iterable getStatements(Resource subject, IRI predicate, Value object, Resource... contexts) { + return () -> filter(subject, predicate, object, contexts).iterator(); + } + + @Override + public void clear() { + remove(null, null, null); + } + + /** + * Releases any resources associated with the given iterator, if applicable. + *

+ * Specifically handles internal iterators used by ValueSet views, + * delegating the cleanup to the underlying statement iterator. + *

+ * + * @param iterator the iterator to release + */ + // todo: Use pattern matching to check if the iterator is of type + // ValueSet.ValueSetIterator + // when Java 17+ is used + protected void closeIterator(Iterator iterator) { + if (iterator instanceof ValueSet.ValueSetIterator) { + ValueSet.ValueSetIterator valueSetIterator = (ValueSet.ValueSetIterator) iterator; + closeIterator(valueSetIterator.statementIterator); + } + } + + public abstract void removeTermIteration(Iterator iter, Resource subj, IRI pred, Value obj, + Resource... contexts); + + /** + * Attempts to delegate iterator cleanup to the appropriate container, + * if the given collection supports it (e.g., AbstractModel or ValueSet). + */ + private void closeIterator(Collection collection, Iterator iterator) { + if (collection instanceof AbstractModel) { + ((AbstractModel) collection).closeIterator(iterator); + } else if (collection instanceof ValueSet) { + ((ValueSet) collection).closeIterator(iterator); + } + } + +} diff --git a/src/main/java/fr/inria/corese/core/next/api/base/model/AbstractNamespace.java b/src/main/java/fr/inria/corese/core/next/api/base/model/AbstractNamespace.java new file mode 100644 index 000000000..795c7959b --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/model/AbstractNamespace.java @@ -0,0 +1,69 @@ +package fr.inria.corese.core.next.api.base.model; + +import java.io.Serial; +import java.util.Comparator; +import java.util.Objects; + +import fr.inria.corese.core.next.api.Namespace; + +/** + * A base implementation of the {@link Namespace} interface. + *

+ * Provides standard implementations for {@code equals}, {@code hashCode}, + * {@code compareTo}, and {@code toString}, + * based on the prefix and URI of the namespace. + *

+ */ +public abstract class AbstractNamespace implements Namespace { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * Comparator that orders namespaces by prefix, then by URI. + * Null values are ordered first. + */ + private static final Comparator ORDERING = Comparator.nullsFirst( + Comparator.comparing(Namespace::getPrefix) + .thenComparing(Namespace::getName)); + + /** + * Compares this namespace to another based on prefix and name. + */ + @Override + public int compareTo(Namespace other) { + return ORDERING.compare(this, other); + } + + /** + * Checks equality based on prefix and name. + */ + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (!(object instanceof Namespace)) { + return false; + } + Namespace ns = (Namespace) object; + return Objects.equals(getPrefix(), ns.getPrefix()) + && Objects.equals(getName(), ns.getName()); + } + + /** + * Computes hash code from prefix and name. + */ + @Override + public int hashCode() { + return Objects.hash(getPrefix(), getName()); + } + + /** + * Returns a readable string representation of the namespace. + */ + @Override + public String toString() { + return getPrefix() + " :: " + getName(); + } +} diff --git a/src/main/java/fr/inria/corese/core/next/api/base/model/AbstractStatement.java b/src/main/java/fr/inria/corese/core/next/api/base/model/AbstractStatement.java new file mode 100644 index 000000000..3b5a5749a --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/model/AbstractStatement.java @@ -0,0 +1,68 @@ +package fr.inria.corese.core.next.api.base.model; + +import fr.inria.corese.core.next.api.Statement; +import java.util.Objects; + +/** + * An abstract implementation of the {@link Statement} interface. + * This class provides default implementations for the {@code equals}, {@code hashCode}, + * and {@code toString} methods based on the subject, predicate, object, and context of the statement. + * + *

Any subclass of {@code AbstractStatement} should implement the methods from the + * {@code Statement} interface such as {@code getSubject}, {@code getPredicate}, {@code getObject}, + * and {@code getContext} to represent a specific type of statement.

+ * + *

This class ensures that statements are compared correctly, generate a proper hash code, + * and provide a meaningful string representation.

+ */ + +public abstract class AbstractStatement implements Statement { + + /** + * Compares this statement to another object for equality. + * Two statements are considered equal if they have the same subject, predicate, object, and context. + * + * @param obj the object to compare this statement to. + * @return {@code true} if the statements are equal, otherwise {@code false}. + */ + @Override + public boolean equals(Object obj) { + return this == obj || obj instanceof Statement + && getObject().equals(((Statement) obj).getObject()) + && getSubject().equals(((Statement) obj).getSubject()) + && getPredicate().equals(((Statement) obj).getPredicate()) + && Objects.equals(getContext(), ((Statement) obj).getContext()); + } + + /** + * Returns the hash code value for this statement. + * The hash code is computed based on the subject, predicate, object, and context of the statement. + * + * @return the hash code value for this statement. + */ + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + (getSubject() == null ? 0 : getSubject().hashCode()); + hash = 31 * hash + (getPredicate() == null ? 0 : getPredicate().hashCode()); + hash = 31 * hash + (getObject() == null ? 0 : getObject().hashCode()); + hash = 31 * hash + (getContext() == null ? 0 : getContext().hashCode()); + return hash; + } + + /** + * Returns a string representation of this statement. + * The string representation includes the subject, predicate, object, and context (if present). + * + * @return a string representation of this statement. + */ + @Override + public String toString() { + return "(" + + getSubject().stringValue() + + ", " + getPredicate().stringValue() + + ", " + getObject().stringValue() + + (getContext() == null ? "" : ", " + getContext().stringValue()) + + ")"; + } +} \ No newline at end of file diff --git a/src/main/java/fr/inria/corese/core/next/api/base/model/ReadOnlyModel.java b/src/main/java/fr/inria/corese/core/next/api/base/model/ReadOnlyModel.java new file mode 100644 index 000000000..f569e85e4 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/model/ReadOnlyModel.java @@ -0,0 +1,131 @@ +package fr.inria.corese.core.next.api.base.model; + +import java.util.Collections; +import java.util.Iterator; +import java.util.Optional; +import java.util.Set; + +import fr.inria.corese.core.next.api.IRI; +import fr.inria.corese.core.next.api.Model; +import fr.inria.corese.core.next.api.Namespace; +import fr.inria.corese.core.next.api.Resource; +import fr.inria.corese.core.next.api.Statement; +import fr.inria.corese.core.next.api.Value; + +/** + * A read-only wrapper for a {@link Model}. All modification operations throw + * {@link UnsupportedOperationException}. + */ +public class ReadOnlyModel extends AbstractModel { + + private static final long serialVersionUID = 8934829374192038471L; + + // The underlying model to delegate read operations to + private final Model delegate; + + /** + * Constructs a ReadOnlyModel that wraps the given backing model. + * + * @param backingModel the model to wrap + */ + public ReadOnlyModel(Model backingModel) { + this.delegate = backingModel; + } + + /** + * Returns an unmodifiable view of the namespaces in the model. + */ + @Override + public Set getNamespaces() { + return Collections.unmodifiableSet(delegate.getNamespaces()); + } + + /** + * Returns the namespace for the given prefix, if present. + */ + @Override + public Optional getNamespace(String prefix) { + return delegate.getNamespace(prefix); + } + + /** + * Not supported. Throws UnsupportedOperationException. + */ + @Override + public Namespace setNamespace(String prefix, String name) { + throw new UnsupportedOperationException("Modifications are not supported in ReadOnlyModel"); + } + + /** + * Not supported. Throws UnsupportedOperationException. + */ + @Override + public void setNamespace(Namespace namespace) { + throw new UnsupportedOperationException("Modifications are not supported in ReadOnlyModel"); + } + + /** + * Not supported. Throws UnsupportedOperationException. + */ + @Override + public Optional removeNamespace(String prefix) { + throw new UnsupportedOperationException("Modifications are not supported in ReadOnlyModel"); + } + + /** + * Checks if the model contains a statement matching the given pattern. + */ + @Override + public boolean contains(Resource subject, IRI predicate, Value object, Resource... contexts) { + return delegate.contains(subject, predicate, object, contexts); + } + + /** + * Not supported. Throws UnsupportedOperationException. + */ + @Override + public boolean add(Resource subject, IRI predicate, Value object, Resource... contexts) { + throw new UnsupportedOperationException("Modifications are not supported in ReadOnlyModel"); + } + + /** + * Not supported. Throws UnsupportedOperationException. + */ + @Override + public boolean remove(Resource subject, IRI predicate, Value object, Resource... contexts) { + throw new UnsupportedOperationException("Modifications are not supported in ReadOnlyModel"); + } + + /** + * Returns an unmodifiable filtered view of the model. + */ + @Override + public Model filter(Resource subject, IRI predicate, Value object, Resource... contexts) { + return delegate.filter(subject, predicate, object, contexts).unmodifiable(); + } + + /** + * Returns an unmodifiable iterator over the statements in the model. + */ + @Override + public Iterator iterator() { + return Collections.unmodifiableSet(delegate).iterator(); + } + + /** + * Returns the number of statements in the model. + */ + @Override + public int size() { + return delegate.size(); + } + + /** + * Not supported. Throws UnsupportedOperationException. + */ + @Override + public void removeTermIteration(Iterator iter, Resource subject, IRI predicate, Value object, + Resource... contexts) { + throw new UnsupportedOperationException("Modifications are not supported in ReadOnlyModel"); + } +} diff --git a/src/main/java/fr/inria/corese/core/next/api/base/model/literal/AbstractDuration.java b/src/main/java/fr/inria/corese/core/next/api/base/model/literal/AbstractDuration.java new file mode 100644 index 000000000..f5475f737 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/model/literal/AbstractDuration.java @@ -0,0 +1,110 @@ +package fr.inria.corese.core.next.api.base.model.literal; + +import java.time.DateTimeException; +import java.time.temporal.TemporalAmount; +import java.time.temporal.TemporalUnit; +import java.util.Comparator; +import java.util.HashSet; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; + +import fr.inria.corese.core.next.api.literal.CoreDatatype; +import fr.inria.corese.core.next.impl.common.literal.XSD; + +/** + * Abstract class representing a duration literal in RDF. + */ +public abstract class AbstractDuration extends AbstractLiteral implements Comparable { + + /** + * Constructor for AbstractDuration. + */ + protected AbstractDuration() { + super(XSD.DURATION.getIRI()); + } + + @Override + public CoreDatatype getCoreDatatype() { + return XSD.DURATION; + } + + /** + * Comparison between two temporal literals using their temporal amount values. + * @param o + * @return -1 if this is less than o, 0 if they are equal, 1 if this is greater than o + */ + @Override + public int compareTo(AbstractDuration o) { + SortedSet theseTUnits = new TreeSet<>(Comparator.comparing(TemporalUnit::getDuration)); + theseTUnits.addAll(this.temporalAmountValue().getUnits()); + SortedSet otherTUnits = new TreeSet<>(Comparator.comparing(TemporalUnit::getDuration)); + otherTUnits.addAll(o.temporalAmountValue().getUnits()); + + TemporalAmount thisTemporalAmount = this.temporalAmountValue(); + TemporalAmount otherTemporalAmount = o.temporalAmountValue(); + + // Check if the temporal amounts have some units in common + Set intersection = new HashSet<>(theseTUnits); + intersection.retainAll(otherTUnits); + if(intersection.isEmpty()) { + // If the temporal amounts have no units in common, compare the units of highest order + return theseTUnits.first().getDuration().compareTo(otherTUnits.first().getDuration()); + } + + // Get all units and sort them by duration + SortedSet allTU = new TreeSet<>(Comparator.comparing(TemporalUnit::getDuration)); + allTU.addAll(theseTUnits); + allTU.addAll(otherTUnits); + + // Compare the values of the temporal amounts starting with the largest temporal amount + for(TemporalUnit tu : allTU) { + long thisValue = 0; + long otherValue = 0; + try { + thisValue = thisTemporalAmount.get(tu); + } catch (DateTimeException e) { + // This unit is not present in this object, so it must be present in o, making o larger + return -1; + } + try { + otherValue = otherTemporalAmount.get(tu); + } catch (DateTimeException e) { + // This unit is not present in o, so it must be present in this object, making this object larger + return 1; + } + if(thisValue != otherValue) { + return Long.compare(thisValue, otherValue) > 0 ? 1 : -1; + } + } + + return 0; + } + + /** + * Check if two temporal literals are equal. + * @param obj the object to compare with + * @return true if compareTo returns 0, false otherwise + */ + @Override + public boolean equals(Object obj) { + if(obj == this) { + return true; + } + if(obj == null || obj.getClass() != this.getClass()) { + return false; + } + AbstractDuration other = (AbstractDuration) obj; + return this.compareTo(other) == 0; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + (this.datatype == null ? 0 : this.datatype.hashCode()); + hash = 31 * hash + (this.getCoreDatatype() == null ? 0 : this.getCoreDatatype().hashCode()); + hash = 31 * hash + (this.temporalAmountValue() == null ? 0 : this.temporalAmountValue().hashCode()); + return hash; + } + +} diff --git a/src/main/java/fr/inria/corese/core/next/api/base/model/literal/AbstractLiteral.java b/src/main/java/fr/inria/corese/core/next/api/base/model/literal/AbstractLiteral.java new file mode 100644 index 000000000..350a5c30f --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/model/literal/AbstractLiteral.java @@ -0,0 +1,168 @@ +package fr.inria.corese.core.next.api.base.model.literal; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.time.temporal.TemporalAccessor; +import java.time.temporal.TemporalAmount; +import java.util.List; +import java.util.Optional; + +import javax.xml.datatype.XMLGregorianCalendar; + +import fr.inria.corese.core.next.api.IRI; +import fr.inria.corese.core.next.api.Literal; +import fr.inria.corese.core.next.api.literal.CoreDatatype; +import fr.inria.corese.core.next.impl.common.literal.XSD; +import fr.inria.corese.core.next.impl.exception.IncorrectOperationException; + +/** + * Base class for all literals. All value accessors throw an exception by default. + */ +public abstract class AbstractLiteral implements Literal { + + protected IRI datatype; + + protected static List integerXSDCoreDatatypeIRIs = List.of( + XSD.INTEGER.getIRI(), + XSD.BYTE.getIRI(), + XSD.SHORT.getIRI(), + XSD.INT.getIRI(), + XSD.LONG.getIRI(), + XSD.UNSIGNED_BYTE.getIRI(), + XSD.UNSIGNED_SHORT.getIRI(), + XSD.UNSIGNED_INT.getIRI(), + XSD.UNSIGNED_LONG.getIRI(), + XSD.POSITIVE_INTEGER.getIRI(), + XSD.NEGATIVE_INTEGER.getIRI(), + XSD.NON_NEGATIVE_INTEGER.getIRI(), + XSD.NON_POSITIVE_INTEGER.getIRI() + ); + + protected static List decimalXSDCoreDatatypeIRIs = List.of( + XSD.DECIMAL.getIRI(), + XSD.FLOAT.getIRI(), + XSD.DOUBLE.getIRI() + ); + + /** + * Constructor for AbstractLiteral. + * + * @param datatype the datatype of the literal + */ + protected AbstractLiteral(IRI datatype) { + this.datatype = datatype; + } + + /** + * @param coreDatatype a CoreDatatype + * @return true if the given core datatype is an integer core datatype, e.g xsd;integer, xsd:int, xsd:byte, etc, false otherwise + */ + public static boolean isIntegerCoreDatatype(CoreDatatype coreDatatype) { + return integerXSDCoreDatatypeIRIs.contains(coreDatatype.getIRI()); + } + + /** + * @param iri an IRI + * @return true if the given IRI is an integer core datatype, e.g xsd;integer, xsd:int, xsd:byte, etc, false otherwise + */ + public static boolean isIriOfIntegerCoreDatatype(IRI iri) { + return integerXSDCoreDatatypeIRIs.contains(iri); + } + + /** + * @param coreDatatype a CoreDatatype + * @return true if the given core datatype is a decimal core datatype, e.g xsd;decimal, xsd:float, xsd:double, etc, false otherwise + */ + public static boolean isDecimalCoreDatatype(CoreDatatype coreDatatype) { + return decimalXSDCoreDatatypeIRIs.contains(coreDatatype.getIRI()); + } + + /** + * @param iri an IRI + * @return true if the given IRI is a decimal core datatype, e.g xsd;decimal, xsd:float, xsd:double, etc, false otherwise + */ + public static boolean isIriOfDecimalCoreDatatype(IRI iri) { + return decimalXSDCoreDatatypeIRIs.contains(iri); + } + /** + * Sets the core datatype of the literal. + * + * @param coreDatatype the CoreDatatype to set + */ + protected abstract void setCoreDatatype(CoreDatatype coreDatatype); + + @Override + public boolean isLiteral() { + return true; + } + + @Override + public Optional getLanguage() { + return Optional.empty(); + } + + @Override + public IRI getDatatype() { + return this.datatype; + } + + @Override + public boolean booleanValue() { + throw new IncorrectOperationException("Cannot convert to boolean"); + } + + @Override + public byte byteValue() { + throw new IncorrectOperationException("Cannot convert to byte"); + } + + @Override + public short shortValue() { + throw new IncorrectOperationException("Cannot convert to short"); + } + + @Override + public int intValue() { + throw new IncorrectOperationException("Cannot convert to int"); + } + + @Override + public long longValue() { + throw new IncorrectOperationException("Cannot convert to long"); + } + + @Override + public BigInteger integerValue() { + throw new IncorrectOperationException("Cannot convert to integer"); + } + + @Override + public BigDecimal decimalValue() { + throw new IncorrectOperationException("Cannot convert to decimal"); + } + + @Override + public float floatValue() { + throw new IncorrectOperationException("Cannot convert to float"); + } + + @Override + public double doubleValue() { + throw new IncorrectOperationException("Cannot convert to double"); + } + + @Override + public TemporalAccessor temporalAccessorValue() { + throw new IncorrectOperationException("Cannot convert to temporal accessor"); + } + + @Override + public TemporalAmount temporalAmountValue() { + throw new IncorrectOperationException("Cannot convert to temporal amount"); + } + + @Override + public XMLGregorianCalendar calendarValue() { + throw new IncorrectOperationException("Cannot convert to XML calendar"); + } +} diff --git a/src/main/java/fr/inria/corese/core/next/api/base/model/literal/AbstractNumber.java b/src/main/java/fr/inria/corese/core/next/api/base/model/literal/AbstractNumber.java new file mode 100644 index 000000000..5fab96188 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/model/literal/AbstractNumber.java @@ -0,0 +1,19 @@ +package fr.inria.corese.core.next.api.base.model.literal; + +import fr.inria.corese.core.next.api.IRI; + +/** + * Abstract class representing a number literal in RDF. + */ +public abstract class AbstractNumber extends AbstractLiteral implements Comparable { + + + /** + * Constructor for AbstractNumber. + * + * @param datatype the datatype of the number literal + */ + protected AbstractNumber(IRI datatype) { + super(datatype); + } +} diff --git a/src/main/java/fr/inria/corese/core/next/api/base/model/literal/AbstractStringLiteral.java b/src/main/java/fr/inria/corese/core/next/api/base/model/literal/AbstractStringLiteral.java new file mode 100644 index 000000000..8804be1ee --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/model/literal/AbstractStringLiteral.java @@ -0,0 +1,34 @@ +package fr.inria.corese.core.next.api.base.model.literal; + +import fr.inria.corese.core.next.api.IRI; + +/** + * Abstract class representing a string literal in Corese. It extends {@link AbstractLiteral} + * and implements {@link Comparable} to allow comparison of string literals based on their string value. + * This class serves as a base class for all string-based literals in Corese. + */ + +public abstract class AbstractStringLiteral extends AbstractLiteral implements Comparable { + /** + * Constructs an instance of AbstractStringLiteral with the specified datatype. + * + * @param datatype The IRI representing the datatype of the literal. + */ + protected AbstractStringLiteral(IRI datatype) { + super(datatype); + } + + /** + * Returns the string value of this string literal. + * + * @return The string value of the literal. + */ + public String stringValue() { + return getLabel(); + } + + @Override + public int compareTo(AbstractStringLiteral abstractStringLiteral) { + return stringValue().compareTo(abstractStringLiteral.stringValue()); + } +} \ No newline at end of file diff --git a/src/main/java/fr/inria/corese/core/next/api/base/model/literal/AbstractTemporalPointLiteral.java b/src/main/java/fr/inria/corese/core/next/api/base/model/literal/AbstractTemporalPointLiteral.java new file mode 100644 index 000000000..ef5c158a9 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/model/literal/AbstractTemporalPointLiteral.java @@ -0,0 +1,45 @@ +package fr.inria.corese.core.next.api.base.model.literal; + +import fr.inria.corese.core.next.api.IRI; + +/** + * Represents a temporal literal representing a point in time. Typically a date or a date and time. Implements the comparison between temporal literals. + */ +public abstract class AbstractTemporalPointLiteral extends AbstractLiteral implements Comparable { + + /** + * Constructor for AbstractTemporalPointLiteral. + * + * @param datatype the datatype of the temporal point literal + */ + protected AbstractTemporalPointLiteral(IRI datatype) { + super(datatype); + } + + @Override + public int compareTo(AbstractTemporalPointLiteral literal) { + return this.calendarValue().compare(literal.calendarValue()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + AbstractTemporalPointLiteral other = (AbstractTemporalPointLiteral) obj; + return this.datatype.equals(other.datatype) && this.calendarValue().equals(other.calendarValue()); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 31 * hash + (this.datatype == null ? 0 : this.datatype.hashCode()); + hash = 31 * hash + (this.getCoreDatatype() == null ? 0 : this.getCoreDatatype().hashCode()); + hash = 31 * hash + (this.temporalAccessorValue() == null ? 0 : this.temporalAccessorValue().hashCode()); + return hash; + } + +} diff --git a/src/main/java/fr/inria/corese/core/next/api/base/model/literal/DefaultDatatype.java b/src/main/java/fr/inria/corese/core/next/api/base/model/literal/DefaultDatatype.java new file mode 100644 index 000000000..79afb087d --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/base/model/literal/DefaultDatatype.java @@ -0,0 +1,16 @@ +package fr.inria.corese.core.next.api.base.model.literal; + +import fr.inria.corese.core.next.api.IRI; +import fr.inria.corese.core.next.api.literal.CoreDatatype; + +public enum DefaultDatatype implements CoreDatatype { + NONE(); + + private DefaultDatatype() { + } + + @Override + public IRI getIRI() { + return null; + } +} diff --git a/src/main/java/fr/inria/corese/core/next/api/io/IOOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/IOOptions.java new file mode 100644 index 000000000..3992e744d --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/io/IOOptions.java @@ -0,0 +1,8 @@ +package fr.inria.corese.core.next.api.io; + +/** + * Super-interface for configuration objects for IO operations (i.e. parsing, + * serialization). + */ +public interface IOOptions { +} diff --git a/src/main/java/fr/inria/corese/core/next/api/io/common/BaseIRIOptions.java b/src/main/java/fr/inria/corese/core/next/api/io/common/BaseIRIOptions.java new file mode 100644 index 000000000..add748be1 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/io/common/BaseIRIOptions.java @@ -0,0 +1,14 @@ +package fr.inria.corese.core.next.api.io.common; + +import fr.inria.corese.core.next.api.io.IOOptions; + +/** + * Options for RDF parsers and serializers that support a base IRI. + */ +public interface BaseIRIOptions { + + /** + * @return the base IRI used to resolve relative IRIs + */ + String getBaseIRI(); +} diff --git a/src/main/java/fr/inria/corese/core/next/api/io/parser/RDFParser.java b/src/main/java/fr/inria/corese/core/next/api/io/parser/RDFParser.java new file mode 100644 index 000000000..fab2aaebf --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/io/parser/RDFParser.java @@ -0,0 +1,54 @@ +package fr.inria.corese.core.next.api.io.parser; + +import fr.inria.corese.core.next.api.base.io.RDFFormat; +import fr.inria.corese.core.next.api.io.IOOptions; + +import java.io.InputStream; +import java.io.Reader; + +/** + * An interface for parsing RDF data from an InputStream or Reader and adding statements to a model. + * + * @see RDFParserFactory + * @see RDFFormat + */ +public interface RDFParser { + + /** + * Gets the RDF format that this parser can parse. + */ + RDFFormat getRDFFormat(); + + void setConfig(IOOptions config); + IOOptions getConfig(); + + /** + * Parses RDF data from the specified InputStream or Reader and adds it to the model. + * + * @param in The InputStream to read RDF data from. + */ + void parse(InputStream in); + + /** + * Parses RDF data from the specified InputStream or Reader and adds it to the model. + * + * @param in The InputStream to read RDF data from. + * @param baseURI The base URI for resolving relative URIs in the RDF data. + */ + void parse(InputStream in, String baseURI); + + /** + * Parses RDF data from the specified InputStream or Reader and adds it to the model. + * + * @param reader The Reader to read RDF data from. + */ + void parse(Reader reader); + + /** + * Parses RDF data from the specified InputStream or Reader and adds it to the model. + * + * @param reader The Reader to read RDF data from. + * @param baseURI The base URI for resolving relative URIs in the RDF data. + */ + void parse(Reader reader, String baseURI); +} diff --git a/src/main/java/fr/inria/corese/core/next/api/io/parser/RDFParserFactory.java b/src/main/java/fr/inria/corese/core/next/api/io/parser/RDFParserFactory.java new file mode 100644 index 000000000..de6e2c6dc --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/io/parser/RDFParserFactory.java @@ -0,0 +1,33 @@ +package fr.inria.corese.core.next.api.io.parser; + +import fr.inria.corese.core.next.api.Model; +import fr.inria.corese.core.next.api.ValueFactory; +import fr.inria.corese.core.next.api.base.io.RDFFormat; +import fr.inria.corese.core.next.api.io.IOOptions; + +/** + * A factory for creating RDF parsers. + */ +public interface RDFParserFactory { + + /** + * Creates a new RDF parser for the specified format and model. + * + * @param format The RDF format to use for parsing. + * @param model The model to which the parsed data will be added. + * @return A new instance of an RDF parser for the specified format and model. + */ + RDFParser createRDFParser(RDFFormat format, Model model, ValueFactory factory); + + /** + * Creates a new RDF parser for the specified format and model. + * + * @param format The RDF format to use for parsing. + * @param model The model to which the parsed data will be added. + * @param factory The value factory to use for creating RDF values. + * @param config The configuration to use for parsing. + * @return A new instance of an RDF parser for the specified format and model. + */ + RDFParser createRDFParser(RDFFormat format, Model model, ValueFactory factory, IOOptions config); + +} diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serialization/RDFSerializer.java b/src/main/java/fr/inria/corese/core/next/api/io/serialization/RDFSerializer.java new file mode 100644 index 000000000..19d0a8b53 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/io/serialization/RDFSerializer.java @@ -0,0 +1,33 @@ +package fr.inria.corese.core.next.api.io.serialization; + +import java.io.Writer; + +import fr.inria.corese.core.next.api.Model; +import fr.inria.corese.core.next.api.base.io.RDFFormat; +import fr.inria.corese.core.next.impl.exception.SerializationException; + +/** + * Factory interface for creating {@link RDFSerializer} instances. + * This interface defines a contract for classes that are responsible + * for providing appropriate RDF serializers based on the desired + * {@link RDFFormat}, a {@link Model} to be serialized, and + * {@link SerializationOption}. + * Implementations of this factory can manage the instantiation + * and configuration of various RDF serializers, promoting + * loose coupling and extensibility in the serialization process. + */ +public interface RDFSerializer { + + /** + * A serializer that converts a {@link Model} instance + * into a specific output format and writes it to a character stream. + * Implementations may follow standard RDF serialization formats + * (e.g., Turtle, N-Triples, JSON-LD, TriG , XML ), or define custom formats. + * + * @param writer the destination {@link Writer} for the serialized + * output + * @throws SerializationException if an error occurs during the serialization + * process + */ + void write(final Writer writer) throws SerializationException; +} \ No newline at end of file diff --git a/src/main/java/fr/inria/corese/core/next/api/io/serialization/SerializerFactory.java b/src/main/java/fr/inria/corese/core/next/api/io/serialization/SerializerFactory.java new file mode 100644 index 000000000..f31bcdf48 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/io/serialization/SerializerFactory.java @@ -0,0 +1,30 @@ +package fr.inria.corese.core.next.api.io.serialization; + +import fr.inria.corese.core.next.api.Model; +import fr.inria.corese.core.next.api.base.io.RDFFormat; +import fr.inria.corese.core.next.api.io.IOOptions; + +/** + * Factory interface for creating {@link RDFSerializer} instances. + * This interface defines a contract for classes that are responsible + * for providing appropriate RDF serializers based on the desired + * {@link RDFFormat}, a {@link Model} to be serialized, and + * {@link IOOptions}. + * Implementations of this factory can manage the instantiation + * and configuration of various RDF serializers, promoting + * loose coupling and extensibility in the serialization process. + */ +public interface SerializerFactory { + + /** + * Creates a new RDF serializer for the specified format and model. + * + * @param format The {@link RDFFormat} to use for serialization. + * @param model The {@link Model} to be serialized. + * @param config The {@link IOOptions} configuration to use for + * serialization. + * @return A new instance of an RDF serializer for the specified format and + * model. + */ + RDFSerializer createSerializer(RDFFormat format, Model model, IOOptions config); +} diff --git a/src/main/java/fr/inria/corese/core/next/api/literal/CoreDatatype.java b/src/main/java/fr/inria/corese/core/next/api/literal/CoreDatatype.java new file mode 100644 index 000000000..7f8b3a765 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/api/literal/CoreDatatype.java @@ -0,0 +1,17 @@ +package fr.inria.corese.core.next.api.literal; + +import fr.inria.corese.core.next.api.IRI; +import fr.inria.corese.core.next.api.base.model.literal.DefaultDatatype; + +/** + * Represents a literal datatype. + * It is necessary to declare a datatype as implementing CoreDatatype to implement operations specific to it in the Corese engine. + */ +public interface CoreDatatype { + + CoreDatatype NONE = DefaultDatatype.NONE; + + IRI getIRI(); + +} + diff --git a/src/main/java/fr/inria/corese/core/next/impl/common/BasicIRI.java b/src/main/java/fr/inria/corese/core/next/impl/common/BasicIRI.java new file mode 100644 index 000000000..d9fa75c16 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/impl/common/BasicIRI.java @@ -0,0 +1,33 @@ +package fr.inria.corese.core.next.impl.common; + +import fr.inria.corese.core.next.api.base.model.AbstractIRI; +import fr.inria.corese.core.next.impl.exception.IncorrectFormatException; + +/** + * Basic implementation of IRI + */ +public class BasicIRI extends AbstractIRI { + + private static final long serialVersionUID = -2444556019914696994L; + /** + * Constructor for BasicIRI. + * + * @param fullIRI the full IRI string + * @throws IncorrectFormatException if fullIRI does not form a correct IRI + */ + public BasicIRI(String fullIRI) { + super(fullIRI); + } + + /** + * Constructor for BasicIRI with namespace and local name. + * + * @param namespace the namespace of the IRI + * @param localName the local name of the IRI + * @throws IncorrectFormatException if namespace and local name do not form a correct IRI + */ + public BasicIRI(String namespace, String localName) { + super(namespace, localName); + } + +} diff --git a/src/main/java/fr/inria/corese/core/next/impl/common/literal/BasicDuration.java b/src/main/java/fr/inria/corese/core/next/impl/common/literal/BasicDuration.java new file mode 100644 index 000000000..d29574925 --- /dev/null +++ b/src/main/java/fr/inria/corese/core/next/impl/common/literal/BasicDuration.java @@ -0,0 +1,353 @@ +package fr.inria.corese.core.next.impl.common.literal; + +import static java.time.temporal.ChronoUnit.DAYS; +import static java.time.temporal.ChronoUnit.HOURS; +import static java.time.temporal.ChronoUnit.MINUTES; +import static java.time.temporal.ChronoUnit.MONTHS; +import static java.time.temporal.ChronoUnit.NANOS; +import static java.time.temporal.ChronoUnit.SECONDS; +import static java.time.temporal.ChronoUnit.YEARS; + +import java.math.BigDecimal; +import java.time.temporal.ChronoUnit; +import java.time.temporal.Temporal; +import java.time.temporal.TemporalAmount; +import java.time.temporal.TemporalUnit; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import fr.inria.corese.core.next.api.Literal; +import fr.inria.corese.core.next.api.base.model.literal.AbstractDuration; +import fr.inria.corese.core.next.api.literal.CoreDatatype; +import fr.inria.corese.core.next.impl.exception.IncorrectFormatException; +import fr.inria.corese.core.next.impl.exception.IncorrectOperationException; + +/** + * A basic implementation of the {@link Literal} interface for durations. + * As there are no Java class available to represent duration as defined in the XSD specification, this class uses its own representation of durations using the {@link TemporalAmount} interface. + * + * @see XSD duration + */ +public class BasicDuration extends AbstractDuration { + + private final XSDDuration temporalAmount; + + /** + * A list of temporal units that contains all ChronoUnit covered by the XSD duration. + */ + private static final List UNITS = new ArrayList<>(EnumSet.of( + YEARS, MONTHS, DAYS, HOURS, MINUTES, SECONDS, NANOS + )); + + private static final Pattern DURATION_PATTERN = Pattern.compile( + "(?-?)P" + + "((?\\d+)Y)?" + + "((?\\d+)M)?" + + "(((?\\d+))D)?" + + "(?