MARMOTTA-584: bootstrapped a new infrastrcuture to plugin new node types in KiWi
Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/cdff84dd Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/cdff84dd Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/cdff84dd Branch: refs/heads/MARMOTTA-584 Commit: cdff84dde5bd93365b5f5717f7f4d8d448f1c0c6 Parents: b6b75d1 Author: Sergio Fernández <[email protected]> Authored: Thu Sep 17 17:17:01 2015 +0200 Committer: Sergio Fernández <[email protected]> Committed: Thu Sep 17 17:17:01 2015 +0200 ---------------------------------------------------------------------- .../hazelcast/serializer/BNodeSerializer.java | 3 +- .../geosparql/io/KiWiIOGeometryLiteral.java | 84 ++++++++++ .../org.apache.marmotta.kiwi.io.KiWiIONode | 1 + .../org/apache/marmotta/kiwi/io/KiWiIO.java | 153 ++++++++----------- .../org/apache/marmotta/kiwi/io/KiWiIONode.java | 65 ++++++++ .../kiwi/model/rdf/KiWiGeometryLiteral.java | 9 +- 6 files changed, 217 insertions(+), 98 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/marmotta/blob/cdff84dd/libraries/kiwi/kiwi-caching-hazelcast/src/main/java/org/apache/marmotta/kiwi/hazelcast/serializer/BNodeSerializer.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-caching-hazelcast/src/main/java/org/apache/marmotta/kiwi/hazelcast/serializer/BNodeSerializer.java b/libraries/kiwi/kiwi-caching-hazelcast/src/main/java/org/apache/marmotta/kiwi/hazelcast/serializer/BNodeSerializer.java index 4ec58b4..74d0141 100644 --- a/libraries/kiwi/kiwi-caching-hazelcast/src/main/java/org/apache/marmotta/kiwi/hazelcast/serializer/BNodeSerializer.java +++ b/libraries/kiwi/kiwi-caching-hazelcast/src/main/java/org/apache/marmotta/kiwi/hazelcast/serializer/BNodeSerializer.java @@ -32,8 +32,6 @@ import java.io.IOException; */ public class BNodeSerializer implements StreamSerializer<KiWiAnonResource> { - - @Override public int getTypeId() { return ExternalizerIds.BNODE; @@ -53,4 +51,5 @@ public class BNodeSerializer implements StreamSerializer<KiWiAnonResource> { public void destroy() { } + } http://git-wip-us.apache.org/repos/asf/marmotta/blob/cdff84dd/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/io/KiWiIOGeometryLiteral.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/io/KiWiIOGeometryLiteral.java b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/io/KiWiIOGeometryLiteral.java new file mode 100644 index 0000000..44aae29 --- /dev/null +++ b/libraries/kiwi/kiwi-geosparql/src/main/java/org/apache/marmotta/kiwi/sparql/geosparql/io/KiWiIOGeometryLiteral.java @@ -0,0 +1,84 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package org.apache.marmotta.kiwi.sparql.geosparql.io; + +import org.apache.marmotta.commons.io.DataIO; +import org.apache.marmotta.kiwi.io.KiWiIO; +import org.apache.marmotta.kiwi.io.KiWiIONode; +import org.apache.marmotta.kiwi.model.rdf.KiWiGeometryLiteral; +import org.apache.marmotta.kiwi.model.rdf.KiWiUriResource; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; +import java.util.Date; + +/** + * KiWi I/O operations for KiWiGeometryLiteral to efficiently serialize a to a DataOutput destination. + * Added by MARMOTA 584 (GeoSPARQL Support). + * + * @author Sergio Fernández ([email protected]) + * @author Xavier Sumba ([email protected]) + */ +public final class KiWiIOGeometryLiteral implements KiWiIONode<KiWiGeometryLiteral> { + + public static final int TYPE = 8; + + @Override + public int getType() { + return TYPE; + } + + @Override + public Class<KiWiGeometryLiteral> getNodeClass() { + return KiWiGeometryLiteral.class; + } + + @Override + public void write(DataOutput out, KiWiGeometryLiteral literal) throws IOException { + if(literal == null) { + out.writeLong(-1L); + } else { + out.writeLong(literal.getId()); + KiWiIO.writeContent(out, literal.getContent()); + if(KiWiIO.langTable.containsKey(literal.getLanguage())) { + out.writeByte(KiWiIO.langTable.get(literal.getLanguage())); + } else { + out.writeByte(KiWiIO.LANG_UNKNOWN); + DataIO.writeString(out, literal.getLanguage()); + } + KiWiIO.writeURI(out, literal.getType()); + out.writeLong(literal.getCreated().getTime()); + } + } + + @Override + public KiWiGeometryLiteral read(DataInput input) throws IOException { + final long id = input.readLong(); + if(id == -1) { + return null; + } else { + String content = KiWiIO.readContent(input); + KiWiUriResource dtype = KiWiIO.readURI(input); + Date created = new Date(input.readLong()); + KiWiGeometryLiteral literal = new KiWiGeometryLiteral(content, dtype, created); + literal.setId(id); + return literal; + } + } + +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/cdff84dd/libraries/kiwi/kiwi-geosparql/src/main/resources/META-INF/services/org.apache.marmotta.kiwi.io.KiWiIONode ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-geosparql/src/main/resources/META-INF/services/org.apache.marmotta.kiwi.io.KiWiIONode b/libraries/kiwi/kiwi-geosparql/src/main/resources/META-INF/services/org.apache.marmotta.kiwi.io.KiWiIONode new file mode 100644 index 0000000..e8899e4 --- /dev/null +++ b/libraries/kiwi/kiwi-geosparql/src/main/resources/META-INF/services/org.apache.marmotta.kiwi.io.KiWiIONode @@ -0,0 +1 @@ +org.apache.marmotta.kiwi.sparql.geosparql.io.KiWiIOGeometryLiteral \ No newline at end of file http://git-wip-us.apache.org/repos/asf/marmotta/blob/cdff84dd/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/io/KiWiIO.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/io/KiWiIO.java b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/io/KiWiIO.java index 62e8914..e87cfb6 100644 --- a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/io/KiWiIO.java +++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/io/KiWiIO.java @@ -31,16 +31,13 @@ import org.slf4j.LoggerFactory; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; -import java.util.Date; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; +import java.util.*; import java.util.zip.DataFormatException; import java.util.zip.Deflater; import java.util.zip.Inflater; /** - * KiWi triplestore Input/Output low-level implementation + * KiWi triple store Input/Output low-level operations * * @author Sebastian Schaffert ([email protected]) * @author Sergio Fernández ([email protected]) @@ -78,13 +75,12 @@ public class KiWiIO { private static final int TYPE_DOUBLE = 5; private static final int TYPE_INT = 6; private static final int TYPE_STRING = 7; - private static final int TYPE_GEOMETRY = 8; public static final int MODE_DEFAULT = 1; // no compression public static final int MODE_PREFIX = 2; // prefix compression for some known URI prefixes public static final int MODE_COMPRESSED = 3; // reserved: ZLIB string compression for long literals - private static final int LANG_UNKNOWN = 0; + public static final int LANG_UNKNOWN = 0; private static final int LANG_EN = 1; private static final int LANG_DE = 2; private static final int LANG_FR = 3; @@ -103,19 +99,42 @@ public class KiWiIO { public static final String NS_REDLINK = "http://data.redlink.io"; private static Map<Class<? extends KiWiNode>, Integer> classTable = new HashMap<>(); + private static Map<Class<? extends KiWiNode>, KiWiIONode> ioTable = new HashMap<>(); static { - classTable.put(KiWiUriResource.class, TYPE_URI); - classTable.put(KiWiAnonResource.class, TYPE_BNODE); - classTable.put(KiWiBooleanLiteral.class, TYPE_BOOLEAN); - classTable.put(KiWiDateLiteral.class, TYPE_DATE); - classTable.put(KiWiDoubleLiteral.class, TYPE_DOUBLE); - classTable.put(KiWiIntLiteral.class, TYPE_INT); - classTable.put(KiWiStringLiteral.class, TYPE_STRING); - classTable.put(KiWiGeometryLiteral.class, TYPE_GEOMETRY); + classTable.put(KiWiUriResource.class, TYPE_URI); + classTable.put(KiWiAnonResource.class, TYPE_BNODE); + classTable.put(KiWiBooleanLiteral.class, TYPE_BOOLEAN); + classTable.put(KiWiDateLiteral.class, TYPE_DATE); + classTable.put(KiWiDoubleLiteral.class, TYPE_DOUBLE); + classTable.put(KiWiIntLiteral.class, TYPE_INT); + classTable.put(KiWiStringLiteral.class, TYPE_STRING); + + loadExternalKiWiNodes(); } + /** + * Dynamically loads definitions of KiWiNodes from external modules + * + */ + private static void loadExternalKiWiNodes() { + final ServiceLoader<KiWiIONode> loader = ServiceLoader.load(KiWiIONode.class); + for (KiWiIONode impl : loader) { + //do not override the built-in nodes! + if (!classTable.containsKey(impl.getNodeClass()) + && !ioTable.containsKey(impl.getNodeClass()) + && !classTable.containsValue(impl.getType())) { + classTable.put(impl.getNodeClass(), impl.getType()); + ioTable.put(impl.getNodeClass(), impl); + log.info("Registered new KiWi Node {} (implemented by {})", + impl.getNodeClass(), impl.getClass()); + } else { + log.warn("Ignored overwrite {} I/O operation with class {} (type={})", + impl.getNodeClass(), impl.getClass(), impl.getType()); + } + } + } - private static Map<String,Integer> langTable = new HashMap<>(); + public static Map<String,Integer> langTable = new HashMap<>(); static { langTable.put("en", LANG_EN); langTable.put("de", LANG_DE); @@ -168,16 +187,17 @@ public class KiWiIO { case TYPE_STRING: writeStringLiteral(output, (KiWiStringLiteral) node); break; - case TYPE_GEOMETRY: - writeGeometryLiteral(output, (KiWiGeometryLiteral) node); - break; default: - throw new IllegalArgumentException("unknown KiWiNode type: "+node.getClass()); + if (ioTable.containsKey(node.getClass())) { + final KiWiIONode kiWiIONode = ioTable.get(node.getClass()); + kiWiIONode.write(output, node); + } else { + throw new IllegalArgumentException("unknown KiWiNode type: " + node.getClass()); + } } } } - /** * Read a KiWiNode serialized with writeNode and return it. The type indicator is used to determine which type * of resource to instantiate. @@ -205,10 +225,20 @@ public class KiWiIO { return readIntLiteral(input); case TYPE_STRING: return readStringLiteral(input); - case TYPE_GEOMETRY: - return readGeometryLiteral(input); default: - throw new IllegalArgumentException("unknown KiWiNode type: "+type); + if (classTable.containsValue(type)) { + for (Map.Entry<Class<? extends KiWiNode>, Integer> entry : classTable.entrySet()) { + if (Objects.equals(type, entry.getValue())) { + final KiWiIONode kiWiIONode = ioTable.get(entry.getKey()); + return kiWiIONode.read(input); + } + } + + //should never arrive here, just to satisfy the static checks of the compiler + throw new IllegalArgumentException("unknown KiWiNode type: " + type); + } else { + throw new IllegalArgumentException("unknown KiWiNode type: " + type); + } } } @@ -272,7 +302,6 @@ public class KiWiIO { } } - /** * Read a KiWiUriResource serialized with writeURI and return it. * @@ -286,11 +315,9 @@ public class KiWiIO { if(id == -1) { return null; } else { - - - int prefixMode = input.readByte(); - String uriPrefix = ""; - String uriSuffix = DataIO.readString(input); + final int prefixMode = input.readByte(); + final String uriPrefix; + final String uriSuffix = DataIO.readString(input); switch (prefixMode) { case PREFIX_XSD: @@ -343,7 +370,6 @@ public class KiWiIO { } } - /** * Efficiently serialize a KiWiAnonResource to a DataOutput destination. * @@ -385,7 +411,6 @@ public class KiWiIO { } } - /** * Efficiently serialize a KiWiBooleanLiteral to a DataOutput destination. * @@ -403,8 +428,7 @@ public class KiWiIO { out.writeLong(literal.getCreated().getTime()); } } - - + /** * Read a KiWiBooleanLiteral serialized with writeBooleanLiteral from a DataInput source * @@ -431,7 +455,6 @@ public class KiWiIO { } } - /** * Efficiently serialize a KiWiDateLiteral to a DataOutput destination. * @@ -451,7 +474,6 @@ public class KiWiIO { } } - /** * Read a KiWiDateLiteral serialized with writeDateLiteral from a DataInput source * @@ -478,7 +500,6 @@ public class KiWiIO { } } - /** * Efficiently serialize a KiWiDoubleLiteral to a DataOutput destination. * @@ -497,7 +518,6 @@ public class KiWiIO { } } - /** * Read a KiWiDoubleLiteral serialized with writeDoubleLiteral from a DataInput source * @@ -524,7 +544,6 @@ public class KiWiIO { } } - /** * Efficiently serialize a KiWiIntLiteral to a DataOutput destination. * @@ -543,7 +562,6 @@ public class KiWiIO { } } - /** * Read a KiWiIntLiteral serialized with writeIntLiteral from a DataInput source * @@ -570,8 +588,6 @@ public class KiWiIO { } } - - /** * Efficiently serialize a KiWiStringLiteral to a DataOutput destination. * @@ -657,8 +673,6 @@ public class KiWiIO { lang = DataIO.readString(input); } - - KiWiUriResource dtype = readURI(input); Date created = new Date(input.readLong()); @@ -671,52 +685,6 @@ public class KiWiIO { } /** - * Efficiently serialize a KiWiGeometryLiteral to a DataOutput destination. - * Added by MARMOTA 584 (GeoSPARQL Support). - * - * @param out the destination - * @param literal the KiWiGeometryLiteral to serialize - * @throws IOException - */ - public static void writeGeometryLiteral(DataOutput out, KiWiGeometryLiteral literal) throws IOException { - if(literal == null) { - out.writeLong(-1L); - } else { - out.writeLong(literal.getId()); - writeContent(out, literal.getContent()); - if(langTable.containsKey(literal.getLanguage())) { - out.writeByte(langTable.get(literal.getLanguage())); - } else { - out.writeByte(LANG_UNKNOWN); - DataIO.writeString(out, literal.getLanguage()); - } - writeURI(out, literal.getType()); - out.writeLong(literal.getCreated().getTime()); - } - } - - /** - * Read a KiWiGeometryLiteral serialized with writeGeometryLiteral from a DataInput source - * - * @param input the source - * @return the de-serialized KiWiStringLiteral - * @throws IOException - */ - public static KiWiGeometryLiteral readGeometryLiteral(DataInput input) throws IOException { - final long id = input.readLong(); - if(id == -1) { - return null; - } else { - String content = readContent(input); - KiWiUriResource dtype = readURI(input); - Date created = new Date(input.readLong()); - KiWiGeometryLiteral literal = new KiWiGeometryLiteral(content, dtype, created); - literal.setId(id); - return literal; - } - } - - /** * Efficiently serialize a KiWiTriple to a DataOutput destination. * * @param output the destination @@ -828,7 +796,7 @@ public class KiWiIO { * @return * @throws IOException */ - private static String readContent(DataInput in) throws IOException { + public static String readContent(DataInput in) throws IOException { int mode = in.readByte(); if(mode == MODE_COMPRESSED) { @@ -863,7 +831,7 @@ public class KiWiIO { * @param content string to write * @throws IOException */ - private static void writeContent(DataOutput out, String content) throws IOException { + public static void writeContent(DataOutput out, String content) throws IOException { if(content.length() > LITERAL_COMPRESS_LENGTH) { // temporary buffer of the size of bytes in the content string (assuming that the compressed data will fit into it) byte[] data = content.getBytes("UTF-8"); @@ -896,4 +864,5 @@ public class KiWiIO { DataIO.writeString(out,content); } } + } http://git-wip-us.apache.org/repos/asf/marmotta/blob/cdff84dd/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/io/KiWiIONode.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/io/KiWiIONode.java b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/io/KiWiIONode.java new file mode 100644 index 0000000..e2404a1 --- /dev/null +++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/io/KiWiIONode.java @@ -0,0 +1,65 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package org.apache.marmotta.kiwi.io; + +import org.apache.marmotta.kiwi.model.rdf.KiWiNode; + +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; + +/** + * KiWi I/O operations for custom nodes, interface + * required to be implemented for new ones. + * + * @author [email protected] + */ +public interface KiWiIONode<T extends KiWiNode> { + + /** + * Defines the _unique_ integer number that identifies the type + * in the binary representation + * + * @return + */ + int getType(); + + /** + * KiWiNode class that handles + * (TODO: Java 8 defaults) + * + * @return + */ + Class<T> getNodeClass(); + + /** + * Write KiWiNode + * + * @param output + * @param node + */ + void write(DataOutput output, T node) throws IOException; + + /** + * Read KiWiNode + * + * @param input + * @return + */ + T read(DataInput input) throws IOException; + +} http://git-wip-us.apache.org/repos/asf/marmotta/blob/cdff84dd/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/model/rdf/KiWiGeometryLiteral.java ---------------------------------------------------------------------- diff --git a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/model/rdf/KiWiGeometryLiteral.java b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/model/rdf/KiWiGeometryLiteral.java index 36d0cec..4d63b48 100644 --- a/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/model/rdf/KiWiGeometryLiteral.java +++ b/libraries/kiwi/kiwi-triplestore/src/main/java/org/apache/marmotta/kiwi/model/rdf/KiWiGeometryLiteral.java @@ -19,10 +19,10 @@ package org.apache.marmotta.kiwi.model.rdf; import java.util.Date; /** - * A RDF geometry literal (of type geo:wktLiteral), possibly with language - * information. - * <p/> + * A RDF geometry literal (geo:wktLiteral) + * * @author Xavier Sumba ([email protected]) + * @author Sergio Fernández ([email protected]) */ public class KiWiGeometryLiteral extends KiWiLiteral { @@ -77,7 +77,7 @@ public class KiWiGeometryLiteral extends KiWiLiteral { /** * Set the content of the literal to the content provided as parameter. * - * @param content + * @param srid */ public void setSRID(int srid) { this.SRID_URI = srid; @@ -100,4 +100,5 @@ public class KiWiGeometryLiteral extends KiWiLiteral { public void setContent(String content) { this.content = content; } + }
