├── .gitignore ├── LICENSE ├── README.md ├── RELEASE.md ├── crew.rdf ├── images └── blazegraph-gremlin.png ├── pom.xml ├── scripts └── publishDocs.sh └── src ├── main ├── java │ └── com │ │ └── blazegraph │ │ └── gremlin │ │ ├── console │ │ └── BlazeGremlinPlugin.java │ │ ├── embedded │ │ ├── BasicRepositoryProvider.java │ │ ├── BlazeGraphEmbedded.java │ │ ├── BlazeGraphFactory.java │ │ └── BlazeGraphReadOnly.java │ │ ├── internal │ │ ├── BlazeSailListener.java │ │ ├── ListIndexExtension.java │ │ ├── Tinkerpop3CoreVocab_v10.java │ │ ├── Tinkerpop3ExtensionFactory.java │ │ └── Tinkerpop3InlineURIFactory.java │ │ ├── listener │ │ ├── BlazeGraphAtom.java │ │ ├── BlazeGraphEdit.java │ │ └── BlazeGraphListener.java │ │ ├── structure │ │ ├── AbstractBlazeElement.java │ │ ├── BlazeBindingSet.java │ │ ├── BlazeEdge.java │ │ ├── BlazeElement.java │ │ ├── BlazeGraph.java │ │ ├── BlazeGraphFeatures.java │ │ ├── BlazeProperty.java │ │ ├── BlazeReifiedElement.java │ │ ├── BlazeValueFactory.java │ │ ├── BlazeVertex.java │ │ ├── BlazeVertexProperty.java │ │ ├── EmptyBlazeProperty.java │ │ ├── EmptyBlazeVertexProperty.java │ │ └── SparqlGenerator.java │ │ └── util │ │ ├── CloseableIterator.java │ │ ├── Code.java │ │ ├── LambdaLogger.java │ │ ├── Lambdas.java │ │ ├── Memoizer.java │ │ └── Streams.java └── resources │ └── META-INF │ └── services │ └── org.apache.tinkerpop.gremlin.groovy.plugin.GremlinPlugin └── test ├── java └── com │ └── blazegraph │ └── gremlin │ └── structure │ ├── BlazeGraphStructureStandardTest.java │ ├── EmbeddedBlazeGraphProvider.java │ ├── SampleCode.java │ ├── StructureStandardSuite.java │ ├── TestBasicOperations.java │ ├── TestBlazeGraph.java │ ├── TestBulkLoad.java │ ├── TestHistory.java │ ├── TestListeners.java │ ├── TestRepositoryProvider.java │ └── TestSearch.java └── resources └── log4j.properties /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | 14 | .classpath 15 | .project 16 | .settings/ 17 | target/ 18 | file:/ 19 | -------------------------------------------------------------------------------- /RELEASE.md: -------------------------------------------------------------------------------- 1 | ##Javadocs 2 | [Javadocs](https://blazegraph.github.io/BlazegraphBasedTPFServer/apidocs/) 3 | 4 | ##Building a release 5 | 6 | * Make sure the pom is at the latest version-SNAPSHOT, i.e. 1.0.0-SNAPSHOT 7 | * Setup your environment for Sonatype [See here](http://central.sonatype.org/pages/apache-maven.html#other-prerequisites). 8 | * Make sure to set the blazegraph version to the latest release in Maven Central. 9 | * Add and commit all changes. 10 | * `mvn -Pmaven-central release:clean release:prepare -Darguments="-DskipTests"` [See here](http://central.sonatype.org/pages/apache-maven.html#performing-a-release-deployment-with-the-maven-release-plugin). You will be prompted to enter the next version number, which should be in the form X.Y.X, i.e. 0.1.1. It's OK to accept the defaults. 11 | * `mvn -Pmaven-central release:perform -Darguments="-DskipTests"` [See here](http://central.sonatype.org/pages/apache-maven.html#performing-a-release-deployment-with-the-maven-release-plugin). 12 | * Checkout the release tag, `git checkout blazegraph-gremlin-1.0.0`, and publish the javadocs: `./scripts/publishDocs.sh`. 13 | * Reverse merge into master and commit the changes: `git checkout master`, `git merge blazegraph-gremlin-1.0.0`; `git push origin master` 14 | * Push the release branch and tag to https://github.com/blazegraph/tinkerpop3. 15 | * Got to [Github](https://github.com/blazegraph/tinkerpop3/releases) and update the release tag. 16 | 17 | -------------------------------------------------------------------------------- /crew.rdf: -------------------------------------------------------------------------------- 1 | blaze:tinkergraph rdf:type blaze:software ; 2 | blaze:name "tinkergraph" . 3 | 4 | blaze:gremlin rdf:type blaze:software ; 5 | blaze:name "gremlin" ; 6 | blaze:48f63 blaze:tinkergraph . 7 | 8 | <> rdf:type blaze:traverses . 9 | 10 | blaze:daniel rdf:type blaze:person ; 11 | blaze:name "daniel" ; 12 | blaze:81056 blaze:tinkergraph ; 13 | blaze:e09ac blaze:gremlin ; 14 | blaze:location "spremberg" ; 15 | blaze:location "kaiserslautern" ; 16 | blaze:location "aachen" . 17 | 18 | <> rdf:type blaze:uses ; 19 | blaze:skill "3"^^xsd:int . 20 | <> rdf:type blaze:uses ; 21 | blaze:skill "5"^^xsd:int . 22 | <> blaze:startTime "1982"^^xsd:int ; 23 | blaze:endTime "2005"^^xsd:int . 24 | <> blaze:startTime "2005"^^xsd:int ; 25 | blaze:endTime "2009"^^xsd:int . 26 | <> blaze:startTime "2009"^^xsd:int . 27 | 28 | blaze:marko rdf:type blaze:person ; 29 | blaze:name "marko" ; 30 | blaze:42af2 blaze:gremlin ; 31 | blaze:4edec blaze:gremlin ; 32 | blaze:61d50 blaze:tinkergraph ; 33 | blaze:68c12 blaze:tinkergraph ; 34 | blaze:location "san diego" ; 35 | blaze:location "santa cruz" ; 36 | blaze:location "brussels" ; 37 | blaze:location "santa fe" . 38 | 39 | <> rdf:type blaze:develops ; 40 | blaze:since "2009"^^xsd:int . 41 | <> rdf:type blaze:uses ; 42 | blaze:skill "4"^^xsd:int . 43 | <> rdf:type blaze:develops ; 44 | blaze:since "2010"^^xsd:int . 45 | <> rdf:type blaze:uses ; 46 | blaze:skill "5"^^xsd:int . 47 | <> blaze:startTime "1997"^^xsd:int ; 48 | blaze:endTime "2001"^^xsd:int . 49 | <> blaze:startTime "2001"^^xsd:int ; 50 | blaze:endTime "2004"^^xsd:int . 51 | <> blaze:startTime "2004"^^xsd:int ; 52 | blaze:endTime "2005"^^xsd:int . 53 | <> blaze:startTime "2005"^^xsd:int . 54 | 55 | blaze:stephen rdf:type blaze:person ; 56 | blaze:name "stephen" ; 57 | blaze:15869 blaze:tinkergraph ; 58 | blaze:1e9c3 blaze:gremlin ; 59 | blaze:bf48d blaze:tinkergraph ; 60 | blaze:bff3c blaze:gremlin ; 61 | blaze:location "centreville" ; 62 | blaze:location "dulles" ; 63 | blaze:location "purcellville" . 64 | 65 | <> rdf:type blaze:develops ; 66 | blaze:since "2011"^^xsd:int . 67 | <> rdf:type blaze:develops ; 68 | blaze:since "2010"^^xsd:int . 69 | <> rdf:type blaze:uses ; 70 | blaze:skill "4"^^xsd:int . 71 | <> rdf:type blaze:uses ; 72 | blaze:skill "5"^^xsd:int . 73 | <> blaze:startTime "1990"^^xsd:int ; 74 | blaze:endTime "2000"^^xsd:int . 75 | <> blaze:startTime "2000"^^xsd:int ; 76 | blaze:endTime "2006"^^xsd:int . 77 | <> blaze:startTime "2006"^^xsd:int . 78 | 79 | blaze:matthias rdf:type blaze:person ; 80 | blaze:name "matthias" ; 81 | blaze:7373e blaze:gremlin ; 82 | blaze:e5a5d blaze:gremlin ; 83 | blaze:ef89a blaze:tinkergraph ; 84 | blaze:location "bremen" ; 85 | blaze:location "baltimore" ; 86 | blaze:location "oakland" ; 87 | blaze:location "seattle" . 88 | 89 | <> rdf:type blaze:develops ; 90 | blaze:since "2012"^^xsd:int . 91 | <> rdf:type blaze:uses ; 92 | blaze:skill "3"^^xsd:int . 93 | <> rdf:type blaze:uses ; 94 | blaze:skill "3"^^xsd:int . 95 | <> blaze:startTime "2004"^^xsd:int ; 96 | blaze:endTime "2007"^^xsd:int . 97 | <> blaze:startTime "2007"^^xsd:int ; 98 | blaze:endTime "2011"^^xsd:int . 99 | <> blaze:startTime "2011"^^xsd:int ; 100 | blaze:endTime "2014"^^xsd:int . 101 | <> blaze:startTime "2014"^^xsd:int . -------------------------------------------------------------------------------- /images/blazegraph-gremlin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blazegraph/tinkerpop3/4b6feff7ecceed453a2f7158a394c35a3ad3ba51/images/blazegraph-gremlin.png -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 26 | 27 | 4.0.0 28 | com.blazegraph 29 | blazegraph-gremlin 30 | jar 31 | 1.0.1-SNAPSHOT 32 | blazegraph-gremlin 33 | Welcome to the Blazegraph/TinkerPop3 project. The TP3 implementation has some significant differences from the TP2 version. The data model has been changed to use RDF*, an RDF reification framework described here: https://wiki.blazegraph.com/wiki/index.php/Reification_Done_Right. 34 | 35 | The concept behind blazegraph-gremlin is that property graph (PG) data can be loaded and accessed via the TinkerPop3 API, but underneath the hood the data will be stored as RDF using the PG data model described in this document. Once PG data has been loaded you can interact with it just like you would interact with ordinary RDF - you can run SPARQL queries or interact with the data via the SAIL API. It just works. The PG data model is also customizable via a round-tripping interface called the BlazeValueFactory, also described in detail in this document. 36 | 37 | https://www.blazegraph.com/ 38 | 39 | SYSTAP, LLC DBA Blazegraph 40 | http://www.systap.com/ 41 | 42 | 2015 43 | 44 | 45 | GNU General Public License Version 2 (GPLv2) 46 | http://www.gnu.org/licenses/gpl-2.0.html 47 | 48 | 49 | 50 | 51 | Developer 52 | https://lists.sourceforge.net/lists/listinfo/bigdata-developers 53 | https://lists.sourceforge.net/lists/listinfo/bigdata-developers 54 | https://sourceforge.net/p/bigdata/mailman/bigdata-developers/ 55 | 56 | 57 | 58 | JIRA 59 | https://jira.blazegraph.com/ 60 | 61 | 62 | scm:git:https://github.com/blazegraph/tinkerpop3.git 63 | scm:git:git@github.com:blazegraph/tinkerpop3.git 64 | https://github.com/blazegraph/tinkerpop3.git 65 | 66 | 67 | UTF-8 68 | 9.2.3.v20140905 69 | 3.1.0-incubating 70 | 2.0.0 71 | 1.3.1 72 | 3.4.6 73 | 74 | 75 | 76 | Mike Personick 77 | mike@blazegraph.com 78 | SYSTAP, LLC DBA Blazegraph DBA Blazegraph 79 | http://www.blazegraph.com 80 | 81 | 82 | Bryan Thompson 83 | bryan@blazegraph.com 84 | SYSTAP, LLC DBA Blazegraph DBA Blazegraph 85 | http://www.blazegraph.com 86 | 87 | 88 | Brad Bebee 89 | beebs@blazegraph.com 90 | SYSTAP, LLC DBA Blazegraph DBA Blazegraph 91 | http://www.blazegraph.com 92 | 93 | 94 | 95 | 96 | maven-central 97 | 101 | 102 | 103 | 104 | org.apache.maven.plugins 105 | maven-gpg-plugin 106 | 1.6 107 | 108 | 109 | sign-artifacts 110 | verify 111 | 112 | sign 113 | 114 | 115 | ${gpg.keyname} 116 | ${gpg.keyname} 117 | 118 | 119 | 120 | 121 | 122 | org.sonatype.plugins 123 | nexus-staging-maven-plugin 124 | 1.6.3 125 | true 126 | 127 | ossrh 128 | https://oss.sonatype.org/ 129 | true 130 | 131 | 132 | 133 | org.apache.maven.plugins 134 | maven-source-plugin 135 | 2.2.1 136 | 137 | 138 | attach-sources 139 | 140 | jar-no-fork 141 | 142 | 143 | 144 | 145 | 146 | org.apache.maven.plugins 147 | maven-javadoc-plugin 148 | 2.9.1 149 | 150 | 151 | attach-javadocs 152 | 153 | jar 154 | 155 | 156 | 157 | 158 | 159 | 160 | org.apache.maven.plugins 161 | maven-release-plugin 162 | 2.5 163 | 164 | true 165 | false 166 | maven-central 167 | deploy 168 | 169 | 170 | 171 | 172 | 173 | 174 | ossrh 175 | https://oss.sonatype.org/content/repositories/snapshots 176 | 177 | 178 | 179 | 180 | local-deploy 181 | 182 | 183 | bigdata.snapshots 184 | bigdata(R) snapshots 185 | scpexe://www.systap.com/srv/www/htdocs/systap.com/maven/snapshots 186 | true 187 | 188 | 189 | 190 | 191 | bigdata.releases 192 | http://www.systap.com/maven/releases/ 193 | 194 | 195 | bigdata.snapshots 196 | http://www.systap.com/maven/snapshots/ 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | org.apache.maven.plugins 205 | maven-compiler-plugin 206 | 3.1 207 | 208 | 1.8 209 | 1.8 210 | 211 | 212 | 213 | org.apache.maven.plugins 214 | maven-deploy-plugin 215 | 2.8.1 216 | 217 | 218 | 219 | 220 | org.apache.maven.wagon 221 | wagon-ssh-external 222 | 1.0-beta-6 223 | 224 | 225 | 226 | 227 | 228 | 229 | apache.snapshots 230 | http://repository.apache.org/snapshots/ 231 | 232 | 233 | 234 | maven.snapshots 235 | https://oss.sonatype.org/content/repositories/snapshots/ 236 | 237 | 238 | 239 | 242 | 243 | org.hamcrest 244 | hamcrest-core 245 | 1.3 246 | test 247 | 248 | 249 | org.hamcrest 250 | hamcrest-library 251 | 1.3 252 | test 253 | 254 | 255 | 256 | org.apache.tinkerpop 257 | gremlin-core 258 | ${tp3.version} 259 | 260 | 261 | org.apache.tinkerpop 262 | gremlin-groovy 263 | ${tp3.version} 264 | 265 | 266 | org.apache.tinkerpop 267 | tinkergraph-gremlin 268 | ${tp3.version} 269 | 270 | 271 | 272 | org.apache.tinkerpop 273 | gremlin-test 274 | ${tp3.version} 275 | test 276 | 277 | 278 | org.hamcrest 279 | hamcrest-all 280 | 281 | 282 | 283 | 284 | org.apache.tinkerpop 285 | gremlin-groovy-test 286 | ${tp3.version} 287 | test 288 | 289 | 290 | 291 | com.blazegraph 292 | bigdata-core 293 | ${blaze.version} 294 | 295 | 296 | junit 297 | junit 298 | 4.13.1 299 | test 300 | 301 | 302 | org.hamcrest 303 | hamcrest-core 304 | 305 | 306 | 307 | 308 | 309 | -------------------------------------------------------------------------------- /scripts/publishDocs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Script to publish javadoc to https://blazegraph.github.com/ 3 | BASE_DIR=`dirname $0` 4 | PARENT_POM="${BASE_DIR}/../pom.xml" 5 | DEST_DIR=tinkerpop3/apidocs/ 6 | #You must have cloned https://github.com/blazegraph/blazegraph.github.io into a directory at the same level as where tinkerpop3 is checked out 7 | GITHUB_PAGES="${BASE_DIR}/../../blazegraph.github.io" 8 | 9 | if [ ! -d "${GITHUB_PAGES}" ] ; then 10 | 11 | echo "${GITHUB_PAGES} does not exist." 12 | echo "You must have cloned https://github.com/blazegraph/blazegraph.github.io into a directory at the same level as where bigdata is checked out." 13 | exit 1 14 | 15 | fi 16 | 17 | mvn -f "${PARENT_POM}" javadoc:javadoc 18 | 19 | echo "Javadoc is located in ${BASE_DIR}/../target/site/apidocs/" 20 | 21 | pushd `pwd` 22 | mkdir -p "${GITHUB_PAGES}/${DEST_DIR}" 23 | echo cp -rf "${BASE_DIR}"/../target/site/apidocs/* "${GITHUB_PAGES}/${DEST_DIR}" 24 | cp -rf "${BASE_DIR}"/../target/site/apidocs/* "${GITHUB_PAGES}/${DEST_DIR}" 25 | cd $"${GITHUB_PAGES}" 26 | git pull 27 | git add --all 28 | git commit -m "Update for Blazegraph $DEST_DIR Javadocs" 29 | git push origin master 30 | 31 | popd 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/console/BlazeGremlinPlugin.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.console; 24 | 25 | import java.util.HashSet; 26 | import java.util.Set; 27 | 28 | import org.apache.tinkerpop.gremlin.groovy.plugin.AbstractGremlinPlugin; 29 | import org.apache.tinkerpop.gremlin.groovy.plugin.IllegalEnvironmentException; 30 | import org.apache.tinkerpop.gremlin.groovy.plugin.PluginAcceptor; 31 | import org.apache.tinkerpop.gremlin.groovy.plugin.PluginInitializationException; 32 | 33 | /** 34 | * Plugin for gremlin console. 35 | * 36 | * @author mikepersonick 37 | */ 38 | public final class BlazeGremlinPlugin extends AbstractGremlinPlugin { 39 | 40 | private static final Set IMPORTS = new HashSet() {{ 41 | add(IMPORT_SPACE + "com.blazegraph.gremlin.embedded" + DOT_STAR); 42 | add(IMPORT_SPACE + "com.blazegraph.gremlin.listener" + DOT_STAR); 43 | add(IMPORT_SPACE + "com.blazegraph.gremlin.structure" + DOT_STAR); 44 | add(IMPORT_SPACE + "com.blazegraph.gremlin.util" + DOT_STAR); 45 | }}; 46 | 47 | @Override 48 | public String getName() { 49 | return "tinkerpop.blazegraph"; 50 | } 51 | 52 | @Override 53 | public void pluginTo(final PluginAcceptor pluginAcceptor) 54 | throws PluginInitializationException, IllegalEnvironmentException { 55 | pluginAcceptor.addImports(IMPORTS); 56 | } 57 | 58 | @Override 59 | public void afterPluginTo(final PluginAcceptor pluginAcceptor) 60 | throws IllegalEnvironmentException, PluginInitializationException { 61 | } 62 | 63 | @Override 64 | public boolean requireRestart() { 65 | return true; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/embedded/BasicRepositoryProvider.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.embedded; 24 | 25 | import java.util.Properties; 26 | 27 | import com.bigdata.journal.BufferMode; 28 | import com.bigdata.journal.Journal; 29 | import com.bigdata.rdf.axioms.NoAxioms; 30 | import com.bigdata.rdf.sail.BigdataSail; 31 | import com.bigdata.rdf.sail.BigdataSailRepository; 32 | import com.bigdata.rdf.sail.RDRHistory; 33 | import com.bigdata.rdf.store.AbstractTripleStore; 34 | import com.blazegraph.gremlin.internal.Tinkerpop3CoreVocab_v10; 35 | import com.blazegraph.gremlin.internal.Tinkerpop3ExtensionFactory; 36 | import com.blazegraph.gremlin.internal.Tinkerpop3InlineURIFactory; 37 | import com.blazegraph.gremlin.util.Code; 38 | 39 | /** 40 | * This utilty class is provided as a convenience for getting started with 41 | * Blazegraph. You will eventually want to create your own custom configuration 42 | * specific to your application. Visit our online 43 | * user guide for more information 44 | * on configuration and performance optimization, or contact us for more direct 45 | * developer support. 46 | * 47 | * @author mikepersonick 48 | */ 49 | public class BasicRepositoryProvider { 50 | 51 | /** 52 | * Open and initialize a BigdataSailRepository using the supplied journal 53 | * file location. If the file does not exist or is empty, the repository 54 | * will be created using the default property configuration below. 55 | * 56 | * @param journalFile 57 | * absolute path of the journal file 58 | * @return 59 | * an open and initialized repository 60 | */ 61 | public static BigdataSailRepository open(final String journalFile) { 62 | return open(getProperties(journalFile)); 63 | } 64 | 65 | /** 66 | * Open and initialize a BigdataSailRepository using the supplied config 67 | * properties. You must specify a journal file in the properties. 68 | * 69 | * @param props 70 | * config properties 71 | * @return 72 | * an open and initialized repository 73 | */ 74 | public static BigdataSailRepository open(final Properties props) { 75 | if (props.getProperty(Journal.Options.FILE) == null) { 76 | throw new IllegalArgumentException(); 77 | } 78 | 79 | final BigdataSail sail = new BigdataSail(props); 80 | final BigdataSailRepository repo = new BigdataSailRepository(sail); 81 | Code.wrapThrow(() -> repo.initialize()); 82 | return repo; 83 | } 84 | 85 | /** 86 | * Grab the default properties and set the location of the journal file. 87 | * 88 | * @param journalFile 89 | * absolute path of the journal file 90 | * @return 91 | * config properties 92 | */ 93 | public static Properties getProperties(final String journalFile) { 94 | 95 | final Properties props = getDefaultProperties(); 96 | 97 | // journal file 98 | props.setProperty(Journal.Options.FILE, journalFile); 99 | 100 | return props; 101 | 102 | } 103 | 104 | /** 105 | * Some reasonable defaults to get us up and running. Visit our online 106 | * user guide for more information 107 | * on configuration and performance optimization, or contact us for more direct 108 | * developer support. 109 | * 110 | * @return 111 | * config properties 112 | */ 113 | public static Properties getDefaultProperties() { 114 | 115 | final Properties props = new Properties(); 116 | 117 | /* 118 | * Use the RW store for persistence. 119 | */ 120 | props.setProperty(Journal.Options.BUFFER_MODE, BufferMode.DiskRW.toString()); 121 | 122 | /* 123 | * Turn off all RDFS/OWL inference. 124 | */ 125 | props.setProperty(BigdataSail.Options.AXIOMS_CLASS, NoAxioms.class.getName()); 126 | props.setProperty(BigdataSail.Options.TRUTH_MAINTENANCE, "false"); 127 | props.setProperty(BigdataSail.Options.JUSTIFY, "false"); 128 | 129 | /* 130 | * Turn on the text index. 131 | */ 132 | props.setProperty(BigdataSail.Options.TEXT_INDEX, "true"); 133 | 134 | /* 135 | * Turn off quads and turn on statement identifiers. 136 | */ 137 | props.setProperty(BigdataSail.Options.QUADS, "false"); 138 | props.setProperty(BigdataSail.Options.STATEMENT_IDENTIFIERS, "true"); 139 | 140 | /* 141 | * We will manage the grounding of sids manually. 142 | */ 143 | props.setProperty(AbstractTripleStore.Options.COMPUTE_CLOSURE_FOR_SIDS, "false"); 144 | 145 | /* 146 | * Inline string literals up to 10 characters (avoids dictionary indices 147 | * for short strings). 148 | */ 149 | props.setProperty(AbstractTripleStore.Options.INLINE_TEXT_LITERALS, "true"); 150 | props.setProperty(AbstractTripleStore.Options.MAX_INLINE_TEXT_LENGTH, "10"); 151 | 152 | /* 153 | * Custom core Tinkerpop3 vocabulary. Applications will probably want 154 | * to extend this. 155 | */ 156 | props.setProperty(AbstractTripleStore.Options.VOCABULARY_CLASS, 157 | Tinkerpop3CoreVocab_v10.class.getName()); 158 | 159 | /* 160 | * Use a multi-purpose inline URI factory that will auto-inline URIs 161 | * in the namespace. 162 | */ 163 | props.setProperty(AbstractTripleStore.Options.INLINE_URI_FACTORY_CLASS, 164 | Tinkerpop3InlineURIFactory.class.getName()); 165 | 166 | /* 167 | * Custom Tinkerpop3 extension factory for the ListIndexExtension IV, 168 | * used for Cardinality.list. 169 | */ 170 | props.setProperty(AbstractTripleStore.Options.EXTENSION_FACTORY_CLASS, 171 | Tinkerpop3ExtensionFactory.class.getName()); 172 | 173 | /* 174 | * Turn on history. You can turn history off by not setting this 175 | * property. 176 | */ 177 | props.setProperty(AbstractTripleStore.Options.RDR_HISTORY_CLASS, 178 | RDRHistory.class.getName()); 179 | 180 | return props; 181 | 182 | } 183 | 184 | } 185 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/embedded/BlazeGraphFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.embedded; 24 | 25 | import com.bigdata.rdf.sail.BigdataSailRepository; 26 | 27 | /** 28 | * Helper class for the gremlin console. 29 | * 30 | * @author mikepersonick 31 | */ 32 | public class BlazeGraphFactory { 33 | 34 | public static final BlazeGraphEmbedded open(final String journal) { 35 | final BigdataSailRepository repo = BasicRepositoryProvider.open(journal); 36 | return BlazeGraphEmbedded.open(repo); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/embedded/BlazeGraphReadOnly.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.embedded; 24 | 25 | import org.apache.commons.configuration.Configuration; 26 | 27 | import com.bigdata.rdf.sail.BigdataSailRepository; 28 | import com.bigdata.rdf.sail.BigdataSailRepositoryConnection; 29 | import com.blazegraph.gremlin.util.Code; 30 | 31 | /** 32 | * BlazeGraphReadOnly extends BlazeGraphEmbedded and thus offers all the same 33 | * operations, except write operations will not be permitted 34 | * (BlazeGraphReadOnly.tx() will throw an exception). You can open as many 35 | * read-only views as you like, but we recommend you use a connection pool so as 36 | * not to overtax system resources. Applications should be written with the 37 | * one-writer many-readers paradigm front of mind. 38 | *

39 | * Important: Make sure to close the read-only view as soon as you are done with 40 | * it. 41 | *

42 | * 43 | * @author mikepersonick 44 | */ 45 | public class BlazeGraphReadOnly extends BlazeGraphEmbedded { 46 | 47 | /** 48 | * Unlike the unisolated version (superclass), the read-only version 49 | * holds the read connection open for the duration of its lifespan, until 50 | * close() is called. 51 | */ 52 | private final BigdataSailRepositoryConnection cxn; 53 | 54 | /** 55 | * Never publicly instantiated - only by another {@link BlazeGraphEmbedded} 56 | * instance. 57 | */ 58 | BlazeGraphReadOnly(final BigdataSailRepository repo, 59 | final BigdataSailRepositoryConnection cxn, 60 | final Configuration config) { 61 | super(repo, config); 62 | 63 | this.cxn = cxn; 64 | } 65 | 66 | /** 67 | * Write operations not supported by this class. 68 | */ 69 | @Override 70 | public BlazeTransaction tx() { 71 | throw new UnsupportedOperationException("Transactions not allowed on read-only view"); 72 | } 73 | 74 | /** 75 | * Return the read-only SAIL connection. 76 | */ 77 | @Override 78 | public BigdataSailRepositoryConnection cxn() { 79 | if (closed) throw new IllegalStateException(); 80 | 81 | return cxn; 82 | } 83 | 84 | /** 85 | * Close the read-only SAIL connection. 86 | */ 87 | @Override 88 | public synchronized void close() { 89 | if (closed) 90 | return; 91 | 92 | Code.wrapThrow(() -> cxn.close()); 93 | closed = true; 94 | } 95 | 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/internal/BlazeSailListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.internal; 24 | 25 | import com.bigdata.rdf.changesets.IChangeLog; 26 | import com.bigdata.rdf.changesets.IChangeRecord; 27 | 28 | /** 29 | * Turn IChangeLog (Java 7) into a Java 8 functional interface. 30 | * 31 | * @author mikepersonick 32 | */ 33 | @FunctionalInterface 34 | public interface BlazeSailListener extends IChangeLog { 35 | 36 | @Override 37 | void changeEvent(IChangeRecord changeRecord); 38 | 39 | /** 40 | * Default no-op. 41 | */ 42 | @Override 43 | default void transactionAborted() { 44 | } 45 | 46 | /** 47 | * Default no-op. 48 | */ 49 | @Override 50 | default void transactionBegin() { 51 | } 52 | 53 | /** 54 | * Default no-op. 55 | */ 56 | @Override 57 | default void transactionCommited(long commitTime) { 58 | } 59 | 60 | /** 61 | * Default no-op. 62 | */ 63 | @Override 64 | default void transactionPrepare() { 65 | } 66 | 67 | /** 68 | * Default no-op. 69 | */ 70 | @Override 71 | default void close() { 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/internal/ListIndexExtension.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.internal; 24 | 25 | import java.util.Collections; 26 | import java.util.Set; 27 | 28 | import org.openrdf.model.Literal; 29 | import org.openrdf.model.URI; 30 | import org.openrdf.model.Value; 31 | import org.openrdf.model.impl.URIImpl; 32 | 33 | import com.bigdata.rdf.internal.IDatatypeURIResolver; 34 | import com.bigdata.rdf.internal.IExtension; 35 | import com.bigdata.rdf.internal.impl.literal.AbstractLiteralIV; 36 | import com.bigdata.rdf.internal.impl.literal.LiteralExtensionIV; 37 | import com.bigdata.rdf.internal.impl.literal.PackedLongIV; 38 | import com.bigdata.rdf.model.BigdataURI; 39 | import com.bigdata.rdf.model.BigdataValue; 40 | import com.bigdata.rdf.model.BigdataValueFactory; 41 | 42 | /** 43 | * Effective, packed representation of property graph list index typed as 44 | * {@code } 45 | * Builds on the {@link PackedLongIV} datatype for representing timestamps, 46 | * thus supporting the range [0;72057594037927935L]. Used for Cardinality.list 47 | * vertex properties. 48 | */ 49 | @SuppressWarnings("rawtypes") 50 | public class ListIndexExtension implements IExtension { 51 | 52 | private final BigdataURI datatype; 53 | 54 | public static final URI DATATYPE = 55 | new URIImpl("http://www.blazegraph.com/rdf/datatype#listIndex"); 56 | 57 | 58 | public ListIndexExtension(final IDatatypeURIResolver resolver) { 59 | datatype = resolver.resolve(DATATYPE); 60 | } 61 | 62 | public Set getDatatypes() { 63 | return Collections.singleton(datatype); 64 | } 65 | 66 | /** 67 | * Convert the supplied value into an internal representation as 68 | * PackedLongIV. 69 | */ 70 | @SuppressWarnings("unchecked") 71 | public LiteralExtensionIV createIV(final Value value) { 72 | 73 | if (value instanceof Literal == false) 74 | throw new IllegalArgumentException(); 75 | 76 | final Literal lit = (Literal) value; 77 | 78 | final AbstractLiteralIV delegate = 79 | new PackedLongIV(Long.parseLong(lit.getLabel())); 80 | return new LiteralExtensionIV(delegate, datatype.getIV()); 81 | 82 | } 83 | 84 | @SuppressWarnings("unchecked") 85 | public V asValue(final LiteralExtensionIV iv, final BigdataValueFactory vf) { 86 | 87 | AbstractLiteralIV delegate = iv.getDelegate(); 88 | if (delegate == null || !(delegate instanceof PackedLongIV)) { 89 | throw new IllegalArgumentException(); 90 | } 91 | 92 | final PackedLongIV pIv = (PackedLongIV) delegate; 93 | return (V) vf.createLiteral( 94 | String.valueOf(pIv.getInlineValue()), DATATYPE); 95 | 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/internal/Tinkerpop3CoreVocab_v10.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.internal; 24 | 25 | import com.bigdata.rdf.store.AbstractTripleStore; 26 | import com.bigdata.rdf.vocab.BaseVocabularyDecl; 27 | import com.bigdata.rdf.vocab.core.BigdataCoreVocabulary_v20151210; 28 | import com.blazegraph.gremlin.structure.BlazeValueFactory; 29 | 30 | /** 31 | * Custom core Tinkerpop3 vocabulary. Applications should extend this 32 | * vocabulary to include known constants that can be inlined into the 33 | * vocabulary, avoiding the dictionary indices for higher performance. A good 34 | * place to start for identifying these constants are known property keys in 35 | * the application space. 36 | */ 37 | public class Tinkerpop3CoreVocab_v10 extends BigdataCoreVocabulary_v20151210 { 38 | 39 | /** 40 | * Tinkerpop3 URIs to be inlined. 41 | */ 42 | private static final Object[] uris = new Object[]{ 43 | BlazeValueFactory.Defaults.NAMESPACE, 44 | ListIndexExtension.DATATYPE, 45 | }; 46 | 47 | /** 48 | * De-serialization ctor. 49 | */ 50 | public Tinkerpop3CoreVocab_v10() { 51 | super(); 52 | } 53 | 54 | /** 55 | * Used by {@link AbstractTripleStore#create()}. 56 | * 57 | * @param namespace 58 | * The namespace of the KB instance. 59 | */ 60 | public Tinkerpop3CoreVocab_v10(final String namespace) { 61 | super(namespace); 62 | } 63 | 64 | @Override 65 | protected void addValues() { 66 | super.addValues(); 67 | addDecl(new BaseVocabularyDecl(uris)); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/internal/Tinkerpop3ExtensionFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.internal; 24 | 25 | import java.util.Collection; 26 | 27 | import com.bigdata.rdf.internal.DefaultExtensionFactory; 28 | import com.bigdata.rdf.internal.IDatatypeURIResolver; 29 | import com.bigdata.rdf.internal.IExtension; 30 | import com.bigdata.rdf.internal.ILexiconConfiguration; 31 | import com.bigdata.rdf.model.BigdataLiteral; 32 | import com.bigdata.rdf.model.BigdataValue; 33 | 34 | /** 35 | * Extension factory for Tinkerpop3. Currently the only extension in use 36 | * is the {@link ListIndexExtension} for Cardinality.list. 37 | */ 38 | public class Tinkerpop3ExtensionFactory extends DefaultExtensionFactory { 39 | 40 | protected void _init(final IDatatypeURIResolver resolver, 41 | final ILexiconConfiguration lex, 42 | final Collection extensions) { 43 | 44 | /* 45 | * Add ListIndexExtension for Cardinality.list. 46 | */ 47 | extensions.add(new ListIndexExtension(resolver)); 48 | 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/internal/Tinkerpop3InlineURIFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.internal; 24 | 25 | import com.bigdata.rdf.internal.InlineURIFactory; 26 | import com.bigdata.rdf.internal.MultipurposeIDHandler; 27 | import com.blazegraph.gremlin.structure.BlazeValueFactory; 28 | 29 | /** 30 | * Use a multi-purpose inline URI factory that will auto-inline URIs 31 | * in the {@code } namespace. 32 | * 33 | * @author mikepersonick 34 | */ 35 | public class Tinkerpop3InlineURIFactory extends InlineURIFactory { 36 | 37 | public Tinkerpop3InlineURIFactory() { 38 | addHandler(new MultipurposeIDHandler(BlazeValueFactory.Defaults.NAMESPACE, 10)); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/listener/BlazeGraphAtom.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.listener; 24 | 25 | /** 26 | * An atomic unit of information about a property graph. Analogous to an RDF 27 | * statement- the atomic unit of information about an RDF graph. This is the 28 | * unit of graph information used by the listener and history APIs. 29 | * 30 | * @author mikepersonick 31 | */ 32 | public abstract class BlazeGraphAtom { 33 | 34 | /** 35 | * All atoms refer back to an element (Vertex, Edge, or VertexProperty). 36 | */ 37 | protected final String id; 38 | 39 | /** 40 | * All atoms refer back to an element (Vertex, Edge, or VertexProperty). 41 | */ 42 | protected BlazeGraphAtom(final String id) { 43 | this.id = id; 44 | } 45 | 46 | /** 47 | * The element id (Vertex, Edge, or VertexProperty) this atom refers to. 48 | */ 49 | public String elementId() { 50 | return id; 51 | } 52 | 53 | /** 54 | * Abstract base class for VertexAtom and EdgeAtom. Adds the element label. 55 | * 56 | * @author mikepersonick 57 | */ 58 | private static abstract class ElementAtom extends BlazeGraphAtom { 59 | 60 | /** 61 | * Element label. 62 | */ 63 | protected final String label; 64 | 65 | private ElementAtom(final String id, final String label) { 66 | super(id); 67 | 68 | this.label = label; 69 | } 70 | 71 | /** 72 | * Element label. 73 | */ 74 | public String label() { 75 | return label; 76 | } 77 | 78 | } 79 | 80 | /** 81 | * Vertex atom describes a vertex - id and label. 82 | * 83 | * @author mikepersonick 84 | */ 85 | public static class VertexAtom extends ElementAtom { 86 | 87 | /** 88 | * Full construct a vertex atom. 89 | */ 90 | public VertexAtom(final String id, final String label) { 91 | super(id, label); 92 | } 93 | 94 | /** 95 | * Return the vertex id. 96 | */ 97 | public String vertexId() { 98 | return id; 99 | } 100 | 101 | @Override 102 | public String toString() { 103 | return "VertexAtom [id=" + id + ", label=" + label + "]"; 104 | } 105 | 106 | } 107 | 108 | /** 109 | * Edge atom describes an edge - id, label, and from/to (vertex ids). 110 | * 111 | * @author mikepersonick 112 | */ 113 | public static class EdgeAtom extends ElementAtom { 114 | 115 | /** 116 | * From vertex id. 117 | */ 118 | private final String fromId; 119 | 120 | /** 121 | * To vertex id. 122 | */ 123 | private final String toId; 124 | 125 | /** 126 | * Fully construct an edge atom. 127 | */ 128 | public EdgeAtom(final String id, final String label, 129 | final String fromId, final String toId) { 130 | super(id, label); 131 | 132 | this.fromId = fromId; 133 | this.toId = toId; 134 | } 135 | 136 | /** 137 | * Return the edge id. 138 | */ 139 | public String edgeId() { 140 | return id; 141 | } 142 | 143 | /** 144 | * From vertex id. 145 | */ 146 | public String fromId() { 147 | return fromId; 148 | } 149 | 150 | /** 151 | * To vertex id. 152 | */ 153 | public String toId() { 154 | return toId; 155 | } 156 | 157 | @Override 158 | public String toString() { 159 | return "EdgeAtom [id=" + id + ", label=" + label + ", from=" + fromId + ", to=" + toId + "]"; 160 | } 161 | 162 | } 163 | 164 | /** 165 | * Property atom describes a property on an Edge or VertexProperty - 166 | * element id, key, and value. 167 | * 168 | * @author mikepersonick 169 | */ 170 | public static class PropertyAtom extends BlazeGraphAtom { 171 | 172 | /** 173 | * Property key (name). 174 | */ 175 | protected final String key; 176 | 177 | /** 178 | * Property value (primitive). 179 | */ 180 | protected final Object val; 181 | 182 | /** 183 | * Fully construct a property atom. 184 | */ 185 | public PropertyAtom(final String id, final String key, final Object val) { 186 | super(id); 187 | 188 | this.key = key; 189 | this.val = val; 190 | } 191 | 192 | /** 193 | * Property key (name). 194 | */ 195 | public String getKey() { 196 | return key; 197 | } 198 | 199 | /** 200 | * Property value (primitive). 201 | */ 202 | public Object getVal() { 203 | return val; 204 | } 205 | 206 | @Override 207 | public String toString() { 208 | return "PropertyAtom [elementId=" + id + ", key=" + key + ", val=" + val + "]"; 209 | } 210 | 211 | } 212 | 213 | /** 214 | * VertexProperty atom describes a property on a Vertex - vertex id, vertex 215 | * property id, key, value. 216 | * 217 | * @author mikepersonick 218 | */ 219 | public static class VertexPropertyAtom extends PropertyAtom { 220 | 221 | /** 222 | * Vertex property id. 223 | */ 224 | private final String vpId; 225 | 226 | /** 227 | * Fully construct a vertex property atom. 228 | */ 229 | public VertexPropertyAtom(final String vertexId, 230 | final String key, final Object val, final String vpId) { 231 | super(vertexId, key, val); 232 | 233 | this.vpId = vpId; 234 | } 235 | 236 | /** 237 | * Return the vertex id. 238 | */ 239 | public String vertexId() { 240 | return id; 241 | } 242 | 243 | /** 244 | * Return the vertex property id. 245 | */ 246 | public String vertexPropertyId() { 247 | return vpId; 248 | } 249 | 250 | @Override 251 | public String toString() { 252 | return "VertexPropertyAtom [vertexId=" + id + ", key=" + key + ", val=" + val + ", vertexPropertyId=" + vpId + "]"; 253 | } 254 | 255 | } 256 | 257 | } 258 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/listener/BlazeGraphEdit.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.listener; 24 | 25 | /** 26 | * An edit consists of an edit action (add or remove), the atomic unit of graph 27 | * information that was edited ({@link BlazeGraphAtom}), and the commit time of 28 | * the edit. This is the unit of graph information used by the listener and 29 | * history APIs. Listeners will get edits with no timestamp information, that 30 | * is because the edits are happening prior to a commit. Listeners will 31 | * eventually get a commit notification with a timestamp (or a rollback). 32 | * The history API will provide timestamps, since it is dealing with committed 33 | * edits that happened in the past. 34 | * 35 | * @author mikepersonick 36 | */ 37 | public class BlazeGraphEdit { 38 | 39 | /** 40 | * Edit action - add or remove. 41 | * 42 | * @author mikepersonick 43 | */ 44 | public static enum Action { 45 | 46 | /** 47 | * Graph atom added. 48 | */ 49 | Add, 50 | 51 | /** 52 | * Graph atom removed. 53 | */ 54 | Remove; 55 | 56 | } 57 | 58 | /** 59 | * Edit action. 60 | */ 61 | private final Action action; 62 | 63 | /** 64 | * Atomic unit of graph information edited. 65 | */ 66 | private final BlazeGraphAtom atom; 67 | 68 | /** 69 | * The commit time of the edit action. 70 | */ 71 | private final long timestamp; 72 | 73 | /** 74 | * Construct an edit with an unknown commit time (listener API). 75 | */ 76 | public BlazeGraphEdit(final Action action, final BlazeGraphAtom atom) { 77 | this(action, atom, 0l); 78 | } 79 | 80 | /** 81 | * Construct an edit with an known commit time (history API). 82 | */ 83 | public BlazeGraphEdit(final Action action, final BlazeGraphAtom atom, 84 | final long timestamp) { 85 | this.action = action; 86 | this.atom = atom; 87 | this.timestamp = timestamp; 88 | } 89 | 90 | /** 91 | * Return the edit action. 92 | */ 93 | public Action getAction() { 94 | return action; 95 | } 96 | 97 | /** 98 | * Return the atomic unit of graph information edited. 99 | */ 100 | public BlazeGraphAtom getAtom() { 101 | return atom; 102 | } 103 | 104 | /** 105 | * Return the commit time of the edit action or 0l if this is an 106 | * uncommitted edit. 107 | */ 108 | public long getTimestamp() { 109 | return timestamp; 110 | } 111 | 112 | @Override 113 | public String toString() { 114 | return "BlazeGraphEdit [action=" + action + ", atom=" + atom 115 | + (timestamp > 0 ? ", timestamp=" + timestamp : "") + "]"; 116 | } 117 | 118 | } 119 | 120 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/listener/BlazeGraphListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.listener; 24 | 25 | import com.blazegraph.gremlin.embedded.BlazeGraphEmbedded; 26 | 27 | /** 28 | * Listener interface for a {@link BlazeGraphEmbedded}. 29 | * 30 | * @see BlazeGraphEmbedded#addListener(BlazeGraphListener) 31 | * 32 | * @author mikepersonick 33 | */ 34 | @FunctionalInterface 35 | public interface BlazeGraphListener { 36 | 37 | /** 38 | * Notification of an edit to the graph. 39 | * 40 | * @param edit 41 | * the {@link BlazeGraphEdit} 42 | * @param rdfEdit 43 | * toString() version of the raw RDF mutation 44 | */ 45 | void graphEdited(BlazeGraphEdit edit, String rdfEdit); 46 | 47 | /** 48 | * Notification of a transaction committed. 49 | * 50 | * @param commitTime 51 | * the timestamp on the commit 52 | */ 53 | default void transactionCommited(long commitTime) { 54 | // noop default impl 55 | } 56 | 57 | /** 58 | * Notification of a transaction abort. 59 | */ 60 | default void transactionAborted() { 61 | // noop default impl 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/structure/AbstractBlazeElement.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.structure; 24 | 25 | import java.util.Objects; 26 | 27 | import org.apache.tinkerpop.gremlin.structure.Element; 28 | import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; 29 | import org.openrdf.model.URI; 30 | 31 | import com.bigdata.rdf.model.BigdataURI; 32 | 33 | /** 34 | * Abstract base class for {@link BlazeVertex} and {@link BlazeEdge}. 35 | * 36 | * @author mikepersonick 37 | */ 38 | abstract class AbstractBlazeElement implements BlazeElement { 39 | 40 | /** 41 | * {@link BlazeGraph} instance this element belongs to. 42 | */ 43 | protected final BlazeGraph graph; 44 | 45 | /** 46 | * The {@link BlazeValueFactory} provided by the graph for round-tripping 47 | * values. 48 | */ 49 | protected final BlazeValueFactory vf; 50 | 51 | /** 52 | * The URI representation of the element id. 53 | */ 54 | protected final BigdataURI uri; 55 | 56 | /** 57 | * The Literal representation of the element label. 58 | */ 59 | protected final BigdataURI label; 60 | 61 | AbstractBlazeElement(final BlazeGraph graph, final BigdataURI uri, 62 | final BigdataURI label) { 63 | Objects.requireNonNull(graph); 64 | Objects.requireNonNull(uri); 65 | Objects.requireNonNull(label); 66 | 67 | this.graph = graph; 68 | this.uri = uri; 69 | this.label = label; 70 | this.vf = graph.valueFactory(); 71 | } 72 | 73 | /** 74 | * Return element id. Tinkerpop3 interface method. 75 | * 76 | * @see Element#id() 77 | */ 78 | @Override 79 | public String id() { 80 | return vf.fromURI(uri); 81 | } 82 | 83 | /** 84 | * Return element label. Tinkerpop3 interface method. 85 | * 86 | * @see Element#label() 87 | */ 88 | @Override 89 | public String label() { 90 | return (String) vf.fromURI(label); 91 | } 92 | 93 | /** 94 | * Return the RDF representation of the label. 95 | * 96 | * @see BlazeElement#rdfLabel() 97 | */ 98 | @Override 99 | public URI rdfLabel() { 100 | return label; 101 | } 102 | 103 | /** 104 | * Return the {@link BlazeGraph} instance. 105 | */ 106 | @Override 107 | public BlazeGraph graph() { 108 | return graph; 109 | } 110 | 111 | /** 112 | * Delegates to {@link ElementHelper#hashCode(Element)} 113 | */ 114 | @Override 115 | public int hashCode() { 116 | return ElementHelper.hashCode(this); 117 | } 118 | 119 | /** 120 | * Delegates to {@link ElementHelper#areEqual(Element, Object)} 121 | */ 122 | @Override 123 | public boolean equals(final Object object) { 124 | return ElementHelper.areEqual(this, object); 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/structure/BlazeBindingSet.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.structure; 24 | 25 | import java.util.Collections; 26 | import java.util.Iterator; 27 | import java.util.Map; 28 | import java.util.Set; 29 | 30 | /** 31 | * A property graph version of a tuple query result binding set. Instead of 32 | * variable names to RDF values, this does variable names to PG values (element 33 | * ids, property keys, property values). 34 | * 35 | * @author mikepersonick 36 | */ 37 | public class BlazeBindingSet implements Iterable> { 38 | 39 | /** 40 | * The variable bindings - variable name to PG value. 41 | */ 42 | private final Map vals; 43 | 44 | /** 45 | * Construct an instance. 46 | */ 47 | BlazeBindingSet(final Map vals) { 48 | this.vals = vals; 49 | } 50 | 51 | /** 52 | * Get the PG value (element id, property key, or property value) for the 53 | * specified variable. 54 | */ 55 | public Object get(final String var) { 56 | return vals.get(var); 57 | } 58 | 59 | /** 60 | * True if the binding set has a PG value for the specified variable. 61 | */ 62 | public boolean isBound(final String var) { 63 | return vals.containsKey(var); 64 | } 65 | 66 | /** 67 | * A unmodifiable set of variables bound in this binding set. 68 | */ 69 | public Set vars() { 70 | return Collections.unmodifiableSet(vals.keySet()); 71 | } 72 | 73 | /** 74 | * An unmodifiable map of variable bindings - variable name to PG value. 75 | */ 76 | public Map map() { 77 | return Collections.unmodifiableMap(vals); 78 | } 79 | 80 | /** 81 | * An iterator of variable bindings - variable name to PG value. 82 | */ 83 | @Override 84 | public Iterator> iterator() { 85 | return vals.entrySet().iterator(); 86 | } 87 | 88 | @Override 89 | public String toString() { 90 | return "BlazeBindingSet [vals=" + vals + "]"; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/structure/BlazeEdge.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.structure; 24 | 25 | import java.util.Iterator; 26 | import java.util.stream.Stream; 27 | 28 | import org.apache.tinkerpop.gremlin.structure.Direction; 29 | import org.apache.tinkerpop.gremlin.structure.Edge; 30 | import org.apache.tinkerpop.gremlin.structure.Property; 31 | import org.apache.tinkerpop.gremlin.structure.Vertex; 32 | import org.apache.tinkerpop.gremlin.structure.util.StringFactory; 33 | 34 | import com.bigdata.rdf.model.BigdataBNode; 35 | import com.bigdata.rdf.model.BigdataStatement; 36 | import com.bigdata.rdf.model.BigdataURI; 37 | import com.bigdata.rdf.model.BigdataValueFactory; 38 | import com.blazegraph.gremlin.structure.BlazeGraphFeatures.Graph; 39 | import com.blazegraph.gremlin.util.CloseableIterator; 40 | 41 | /** 42 | * Concrete edge implementation for Blazegraph. 43 | *

44 | * Edge existence is represented as two triples as follows: 45 | *

46 | *
 47 |  * {@code
 48 |  *     :fromId :edgeId :toId .
 49 |  *     <<:fromId :edgeId :toId>> rdf:type :label .
 50 |  * }
 51 |  * 
52 | *

53 | * Edge properties are represented as follows: 54 | *

55 | *
 56 |  * {@code
 57 |  *     <<:fromId :edgeId :toId>> :key "val" .
 58 |  * }
 59 |  * 
60 | * 61 | * @author mikepersonick 62 | */ 63 | public class BlazeEdge extends AbstractBlazeElement implements Edge, BlazeReifiedElement { 64 | 65 | /** 66 | * The sid (reified statement) for this edge. 67 | */ 68 | private final BigdataBNode sid; 69 | 70 | /** 71 | * The from and to vertices. 72 | */ 73 | private final Vertices vertices; 74 | 75 | /** 76 | * Construct an instance. 77 | */ 78 | BlazeEdge(final BlazeGraph graph, final BigdataStatement stmt, 79 | final BigdataURI label, final BlazeVertex from, final BlazeVertex to) { 80 | super(graph, stmt.getPredicate(), label); 81 | final BigdataValueFactory rdfvf = graph.rdfValueFactory(); 82 | this.sid = rdfvf.createBNode(stmt); 83 | this.vertices = new Vertices(from, to); 84 | } 85 | 86 | /** 87 | * Construct an instance without vertices. Used by 88 | * {@link BlazeGraph#bulkLoad(Graph)} 89 | */ 90 | BlazeEdge(final BlazeGraph graph, final BigdataStatement stmt, 91 | final BigdataURI label) { 92 | super(graph, stmt.getPredicate(), label); 93 | final BigdataValueFactory rdfvf = graph.rdfValueFactory(); 94 | this.sid = rdfvf.createBNode(stmt); 95 | this.vertices = null; 96 | } 97 | 98 | @Override 99 | public String toString() { 100 | return StringFactory.edgeString(this); 101 | } 102 | 103 | /** 104 | * Return the sid (reified statement) for this edge. 105 | */ 106 | @Override 107 | public BigdataBNode rdfId() { 108 | return sid; 109 | } 110 | 111 | /** 112 | * @see Edge#remove() 113 | * @see BlazeGraph#remove(BlazeReifiedElement) 114 | */ 115 | @Override 116 | public void remove() { 117 | graph.remove(this); 118 | } 119 | 120 | /** 121 | * Strengthen return type to {@link BlazeProperty}. 122 | */ 123 | @Override 124 | public BlazeProperty property(String key, V val) { 125 | return BlazeReifiedElement.super.property(key, val); 126 | } 127 | 128 | /** 129 | * Strength return type to {@link CloseableIterator}. You MUST close this 130 | * iterator when finished. 131 | */ 132 | @Override 133 | public CloseableIterator> properties(final String... keys) { 134 | return BlazeReifiedElement.super.properties(keys); 135 | } 136 | 137 | /** 138 | * @see Edge#outVertex() 139 | */ 140 | @Override 141 | public Vertex outVertex() { 142 | return vertices.from; 143 | } 144 | 145 | /** 146 | * @see Edge#inVertex() 147 | */ 148 | @Override 149 | public Vertex inVertex() { 150 | return vertices.to; 151 | } 152 | 153 | /** 154 | * @see Edge#bothVertices() 155 | */ 156 | @Override 157 | public Iterator bothVertices() { 158 | return this.vertices(Direction.BOTH); 159 | } 160 | 161 | /** 162 | * @see Edge#vertices(Direction) 163 | */ 164 | @Override 165 | public Iterator vertices(final Direction direction) { 166 | final BlazeVertex from = vertices.from; 167 | final BlazeVertex to = vertices.to; 168 | final Stream stream; 169 | switch (direction) { 170 | case OUT: 171 | stream = Stream.of(from); break; 172 | case IN: 173 | stream = Stream.of(to); break; 174 | default: 175 | stream = Stream.of(from, to); break; 176 | } 177 | return stream.map(Vertex.class::cast).iterator(); 178 | } 179 | 180 | private static class Vertices { 181 | private final BlazeVertex from, to; 182 | public Vertices(final BlazeVertex from, final BlazeVertex to) { 183 | this.from = from; 184 | this.to = to; 185 | } 186 | } 187 | 188 | } 189 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/structure/BlazeElement.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.structure; 24 | 25 | import java.util.Collections; 26 | import java.util.HashSet; 27 | import java.util.Set; 28 | 29 | import org.apache.tinkerpop.gremlin.structure.Element; 30 | import org.apache.tinkerpop.gremlin.structure.Property; 31 | import org.openrdf.model.Literal; 32 | import org.openrdf.model.URI; 33 | 34 | import com.bigdata.rdf.model.BigdataResource; 35 | import com.blazegraph.gremlin.util.CloseableIterator; 36 | 37 | /** 38 | * Extends the Tinkerpop3 interface to strengthen return types from Iterator 39 | * to {@link CloseableIterator} and to expose RDF values for id and label. 40 | * 41 | * @author mikepersonick 42 | */ 43 | public interface BlazeElement extends Element { 44 | 45 | /** 46 | * Strengthen return type to {@link BlazeGraph}. 47 | */ 48 | @Override 49 | BlazeGraph graph(); 50 | 51 | /** 52 | * Return RDF value for element id (URI for Vertex, BNode for Edge and 53 | * VertexProperty). 54 | */ 55 | BigdataResource rdfId(); 56 | 57 | /** 58 | * Return RDF literal for element label. 59 | */ 60 | URI rdfLabel(); 61 | 62 | /** 63 | * Strengthen return type to {@link CloseableIterator}. You MUST close this 64 | * iterator when finished. 65 | */ 66 | @Override 67 | CloseableIterator> properties(String... keys); 68 | 69 | /** 70 | * Strengthen return type to {@link CloseableIterator}. You MUST close this 71 | * iterator when finished. 72 | */ 73 | @Override 74 | public default CloseableIterator values(final String... keys) { 75 | return CloseableIterator.of(this.properties(keys).stream().map(Property::value)); 76 | } 77 | 78 | /** 79 | * Provide safer default implementation (closes properties() iterator used 80 | * to calculate keys). 81 | */ 82 | @Override 83 | public default Set keys() { 84 | try (CloseableIterator> it = this.properties()) { 85 | final Set keys = new HashSet<>(); 86 | it.forEachRemaining(property -> keys.add(property.key())); 87 | return Collections.unmodifiableSet(keys); 88 | } 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/structure/BlazeGraphFeatures.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.structure; 24 | 25 | import org.apache.tinkerpop.gremlin.structure.Graph.Features; 26 | import org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality; 27 | import org.apache.tinkerpop.gremlin.structure.util.StringFactory; 28 | 29 | /** 30 | * The blazegraph-tinkerpop3 feature set. 31 | * 32 | * @author mikepersonick 33 | */ 34 | public class BlazeGraphFeatures implements Features { 35 | 36 | public static final BlazeGraphFeatures INSTANCE = new BlazeGraphFeatures(); 37 | 38 | private GraphFeatures graphFeatures = new Graph(); 39 | private VertexFeatures vertexFeatures = new Vertex(); 40 | private EdgeFeatures edgeFeatures = new Edge(); 41 | 42 | private BlazeGraphFeatures() { 43 | } 44 | 45 | @Override 46 | public GraphFeatures graph() { 47 | return graphFeatures; 48 | } 49 | 50 | @Override 51 | public VertexFeatures vertex() { 52 | return vertexFeatures; 53 | } 54 | 55 | @Override 56 | public EdgeFeatures edge() { 57 | return edgeFeatures; 58 | } 59 | 60 | @Override 61 | public String toString() { 62 | return StringFactory.featureString(this); 63 | } 64 | 65 | public static class Graph implements GraphFeatures { 66 | 67 | public static final boolean SUPPORTS_PERSISTENCE = true; 68 | public static final boolean SUPPORTS_TRANSACTIONS = true; 69 | public static final boolean SUPPORTS_THREADED_TRANSACTIONS = false; 70 | public static final boolean SUPPORTS_CONCURRENT_ACCESS = true; 71 | public static final boolean SUPPORTS_COMPUTER = false; 72 | 73 | private VariableFeatures variableFeatures = new Variable(); 74 | 75 | @Override 76 | public VariableFeatures variables() { 77 | return variableFeatures; 78 | } 79 | 80 | @Override 81 | public boolean supportsPersistence() { 82 | return SUPPORTS_PERSISTENCE; 83 | } 84 | 85 | @Override 86 | public boolean supportsTransactions() { 87 | return SUPPORTS_TRANSACTIONS; 88 | } 89 | 90 | @Override 91 | public boolean supportsThreadedTransactions() { 92 | return SUPPORTS_THREADED_TRANSACTIONS; 93 | } 94 | 95 | /** 96 | * One writer, many readers 97 | */ 98 | @Override 99 | public boolean supportsConcurrentAccess() { 100 | return SUPPORTS_CONCURRENT_ACCESS; 101 | } 102 | 103 | @Override 104 | public boolean supportsComputer() { 105 | return SUPPORTS_COMPUTER; 106 | } 107 | 108 | } 109 | 110 | public static class Variable extends Datatype 111 | implements VariableFeatures { 112 | 113 | public static final boolean SUPPORTS_VARIABLES = false; 114 | public static final boolean SUPPORTS_BOOLEAN_VALUES = false; 115 | public static final boolean SUPPORTS_BYTE_VALUES = false; 116 | public static final boolean SUPPORTS_DOUBLE_VALUES = false; 117 | public static final boolean SUPPORTS_FLOAT_VALUES = false; 118 | public static final boolean SUPPORTS_INTEGER_VALUES = false; 119 | public static final boolean SUPPORTS_LONG_VALUES = false; 120 | public static final boolean SUPPORTS_STRING_VALUES = false; 121 | 122 | /** 123 | * TODO FIXME 124 | */ 125 | @Override 126 | public boolean supportsVariables() { 127 | return SUPPORTS_VARIABLES; 128 | } 129 | 130 | @Override 131 | public boolean supportsBooleanValues() { 132 | return SUPPORTS_BOOLEAN_VALUES; 133 | } 134 | 135 | @Override 136 | public boolean supportsByteValues() { 137 | return SUPPORTS_BYTE_VALUES; 138 | } 139 | 140 | @Override 141 | public boolean supportsDoubleValues() { 142 | return SUPPORTS_DOUBLE_VALUES; 143 | } 144 | 145 | @Override 146 | public boolean supportsFloatValues() { 147 | return SUPPORTS_FLOAT_VALUES; 148 | } 149 | 150 | @Override 151 | public boolean supportsIntegerValues() { 152 | return SUPPORTS_INTEGER_VALUES; 153 | } 154 | 155 | @Override 156 | public boolean supportsLongValues() { 157 | return SUPPORTS_LONG_VALUES; 158 | } 159 | 160 | @Override 161 | public boolean supportsStringValues() { 162 | return SUPPORTS_STRING_VALUES; 163 | } 164 | 165 | } 166 | 167 | public static class Vertex extends Element implements VertexFeatures { 168 | 169 | public static final boolean SUPPORTS_META_PROPERTIES = true; 170 | public static final boolean SUPPORTS_MULTI_PROPERTIES = true; 171 | public static final boolean SUPPORTS_USER_SUPPLIED_IDS = true; 172 | public static final boolean SUPPORTS_ADD_VERTICES = true; 173 | public static final boolean SUPPORTS_REMOVE_VERTICES = true; 174 | 175 | private final VertexPropertyFeatures vertexPropertyFeatures = new VertexProperty(); 176 | 177 | @Override 178 | public VertexPropertyFeatures properties() { 179 | return vertexPropertyFeatures; 180 | } 181 | 182 | @Override 183 | public boolean supportsMetaProperties() { 184 | return SUPPORTS_META_PROPERTIES; 185 | } 186 | 187 | @Override 188 | public boolean supportsMultiProperties() { 189 | return SUPPORTS_MULTI_PROPERTIES; 190 | } 191 | 192 | @Override 193 | public boolean supportsUserSuppliedIds() { 194 | return SUPPORTS_USER_SUPPLIED_IDS; 195 | } 196 | 197 | /** 198 | * Really you would need to perform a Sparql query to ascertain this, 199 | * unless you have a fixed application schema. Returns Cardinality.set 200 | * by default since that is the closest match to RDF. 201 | */ 202 | @Override 203 | public Cardinality getCardinality(final String key) { 204 | return Cardinality.set; 205 | } 206 | 207 | @Override 208 | public boolean supportsAddVertices() { 209 | return SUPPORTS_ADD_VERTICES; 210 | } 211 | 212 | @Override 213 | public boolean supportsRemoveVertices() { 214 | return SUPPORTS_REMOVE_VERTICES; 215 | } 216 | 217 | } 218 | 219 | public static class Edge extends Element implements EdgeFeatures { 220 | 221 | public static final boolean SUPPORTS_ADD_EDGES = true; 222 | public static final boolean SUPPORTS_REMOVE_EDGES = true; 223 | public static final boolean SUPPORTS_REMOVE_PROPERTY = true; 224 | 225 | private final EdgePropertyFeatures edgePropertyFeatures = new EdgeProperty(); 226 | 227 | @Override 228 | public EdgePropertyFeatures properties() { 229 | return edgePropertyFeatures; 230 | } 231 | 232 | @Override 233 | public boolean supportsAddEdges() { 234 | return SUPPORTS_ADD_EDGES; 235 | } 236 | 237 | @Override 238 | public boolean supportsRemoveEdges() { 239 | return SUPPORTS_REMOVE_EDGES; 240 | } 241 | 242 | @Override 243 | public boolean supportsRemoveProperty() { 244 | return SUPPORTS_REMOVE_PROPERTY; 245 | } 246 | 247 | } 248 | 249 | public static class Element implements ElementFeatures { 250 | 251 | public static final boolean SUPPORTS_USER_SUPPLIED_IDS = true; 252 | public static final boolean SUPPORTS_STRING_IDS = true; 253 | public static final boolean SUPPORTS_ADD_PROPERTY = true; 254 | public static final boolean SUPPORTS_REMOVE_PROPERTY = true; 255 | public static final boolean SUPPORTS_UUID_IDS = false; 256 | public static final boolean SUPPORTS_ANY_IDS = false; 257 | public static final boolean SUPPORTS_CUSTOM_IDS = false; 258 | public static final boolean SUPPORTS_NUMERIC_IDS = false; 259 | 260 | @Override 261 | public boolean supportsUserSuppliedIds() { 262 | return SUPPORTS_USER_SUPPLIED_IDS; 263 | } 264 | 265 | @Override 266 | public boolean supportsStringIds() { 267 | return SUPPORTS_STRING_IDS; 268 | } 269 | 270 | @Override 271 | public boolean supportsAddProperty() { 272 | return SUPPORTS_ADD_PROPERTY; 273 | } 274 | 275 | @Override 276 | public boolean supportsRemoveProperty() { 277 | return SUPPORTS_REMOVE_PROPERTY; 278 | } 279 | 280 | @Override 281 | public boolean supportsUuidIds() { 282 | return SUPPORTS_UUID_IDS; 283 | } 284 | 285 | @Override 286 | public boolean supportsAnyIds() { 287 | return SUPPORTS_ANY_IDS; 288 | } 289 | 290 | @Override 291 | public boolean supportsCustomIds() { 292 | return SUPPORTS_CUSTOM_IDS; 293 | } 294 | 295 | @Override 296 | public boolean supportsNumericIds() { 297 | return SUPPORTS_NUMERIC_IDS; 298 | } 299 | 300 | } 301 | 302 | public static class VertexProperty extends Datatype 303 | implements VertexPropertyFeatures { 304 | 305 | public static final boolean SUPPORTS_USER_SUPPLIED_IDS = false; 306 | public static final boolean SUPPORTS_STRING_IDS = true; 307 | public static final boolean SUPPORTS_ADD_PROPERTY = true; 308 | public static final boolean SUPPORTS_REMOVE_PROPERTY = true; 309 | public static final boolean SUPPORTS_UUID_IDS = false; 310 | public static final boolean SUPPORTS_ANY_IDS = false; 311 | public static final boolean SUPPORTS_CUSTOM_IDS = false; 312 | public static final boolean SUPPORTS_NUMERIC_IDS = false; 313 | 314 | @Override 315 | public boolean supportsUserSuppliedIds() { 316 | return SUPPORTS_USER_SUPPLIED_IDS; 317 | } 318 | 319 | @Override 320 | public boolean supportsStringIds() { 321 | return SUPPORTS_STRING_IDS; 322 | } 323 | 324 | @Override 325 | public boolean supportsAddProperty() { 326 | return SUPPORTS_ADD_PROPERTY; 327 | } 328 | 329 | @Override 330 | public boolean supportsRemoveProperty() { 331 | return SUPPORTS_REMOVE_PROPERTY; 332 | } 333 | 334 | @Override 335 | public boolean supportsUuidIds() { 336 | return SUPPORTS_UUID_IDS; 337 | } 338 | 339 | @Override 340 | public boolean supportsAnyIds() { 341 | return SUPPORTS_ANY_IDS; 342 | } 343 | 344 | @Override 345 | public boolean supportsCustomIds() { 346 | return SUPPORTS_CUSTOM_IDS; 347 | } 348 | 349 | @Override 350 | public boolean supportsNumericIds() { 351 | return SUPPORTS_NUMERIC_IDS; 352 | } 353 | 354 | } 355 | 356 | public static class EdgeProperty extends Datatype 357 | implements EdgePropertyFeatures { 358 | 359 | } 360 | 361 | /** 362 | * Supports all primitives, no lists. 363 | * 364 | * @author mikepersonick 365 | */ 366 | public static class Datatype implements DataTypeFeatures { 367 | 368 | public static final boolean SUPPORTS_BOOLEAN_VALUES = true; 369 | public static final boolean SUPPORTS_BYTE_VALUES = true; 370 | public static final boolean SUPPORTS_DOUBLE_VALUES = true; 371 | public static final boolean SUPPORTS_FLOAT_VALUES = true; 372 | public static final boolean SUPPORTS_INTEGER_VALUES = true; 373 | public static final boolean SUPPORTS_LONG_VALUES = true; 374 | public static final boolean SUPPORTS_STRING_VALUES = true; 375 | public static final boolean SUPPORTS_SERIALIZABLE_VALUES = false; 376 | public static final boolean SUPPORTS_ARRAY_VALUES = false; 377 | public static final boolean SUPPORTS_LIST_VALUES = false; 378 | public static final boolean SUPPORTS_MAP_VALUES = false; 379 | 380 | /** 381 | * Supports setting of a boolean value. 382 | */ 383 | @Override 384 | public boolean supportsBooleanValues() { 385 | return SUPPORTS_BOOLEAN_VALUES; 386 | } 387 | 388 | /** 389 | * Supports setting of a byte value. 390 | */ 391 | @Override 392 | public boolean supportsByteValues() { 393 | return SUPPORTS_BYTE_VALUES; 394 | } 395 | 396 | /** 397 | * Supports setting of a double value. 398 | */ 399 | @Override 400 | public boolean supportsDoubleValues() { 401 | return SUPPORTS_DOUBLE_VALUES; 402 | } 403 | 404 | /** 405 | * Supports setting of a float value. 406 | */ 407 | @Override 408 | public boolean supportsFloatValues() { 409 | return SUPPORTS_FLOAT_VALUES; 410 | } 411 | 412 | /** 413 | * Supports setting of a integer value. 414 | */ 415 | @Override 416 | public boolean supportsIntegerValues() { 417 | return SUPPORTS_INTEGER_VALUES; 418 | } 419 | 420 | /** 421 | * Supports setting of a long value. 422 | */ 423 | @Override 424 | public boolean supportsLongValues() { 425 | return SUPPORTS_LONG_VALUES; 426 | } 427 | 428 | /** 429 | * Supports setting of a string value. 430 | */ 431 | @Override 432 | public boolean supportsStringValues() { 433 | return SUPPORTS_STRING_VALUES; 434 | } 435 | 436 | @Override 437 | public boolean supportsSerializableValues() { 438 | return SUPPORTS_SERIALIZABLE_VALUES; 439 | } 440 | 441 | @Override 442 | public boolean supportsBooleanArrayValues() { 443 | return SUPPORTS_ARRAY_VALUES; 444 | } 445 | 446 | @Override 447 | public boolean supportsByteArrayValues() { 448 | return SUPPORTS_ARRAY_VALUES; 449 | } 450 | 451 | @Override 452 | public boolean supportsDoubleArrayValues() { 453 | return SUPPORTS_ARRAY_VALUES; 454 | } 455 | 456 | @Override 457 | public boolean supportsFloatArrayValues() { 458 | return SUPPORTS_ARRAY_VALUES; 459 | } 460 | 461 | @Override 462 | public boolean supportsIntegerArrayValues() { 463 | return SUPPORTS_ARRAY_VALUES; 464 | } 465 | 466 | @Override 467 | public boolean supportsLongArrayValues() { 468 | return SUPPORTS_ARRAY_VALUES; 469 | } 470 | 471 | @Override 472 | public boolean supportsStringArrayValues() { 473 | return SUPPORTS_ARRAY_VALUES; 474 | } 475 | 476 | @Override 477 | public boolean supportsMapValues() { 478 | return SUPPORTS_MAP_VALUES; 479 | } 480 | 481 | @Override 482 | public boolean supportsMixedListValues() { 483 | return SUPPORTS_LIST_VALUES; 484 | } 485 | 486 | @Override 487 | public boolean supportsUniformListValues() { 488 | return SUPPORTS_LIST_VALUES; 489 | } 490 | 491 | } 492 | } 493 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/structure/BlazeProperty.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.structure; 24 | 25 | import java.util.NoSuchElementException; 26 | 27 | import org.apache.tinkerpop.gremlin.structure.Property; 28 | import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; 29 | import org.apache.tinkerpop.gremlin.structure.util.StringFactory; 30 | import org.openrdf.model.Literal; 31 | import org.openrdf.model.URI; 32 | 33 | /** 34 | * Concrete property implementation for Blazegraph. BlazeProperties are 35 | * attached to {@link BlazeEdge}s and {@link BlazeVertexProperty}s 36 | * (meta-properties). 37 | * 38 | * @author mikepersonick 39 | */ 40 | public class BlazeProperty implements Property { 41 | 42 | /** 43 | * {@link BlazeGraph} instance this property belongs to. 44 | */ 45 | protected final BlazeGraph graph; 46 | 47 | /** 48 | * The {@link BlazeValueFactory} provided by the graph for round-tripping 49 | * values. 50 | */ 51 | protected final BlazeValueFactory vf; 52 | 53 | /** 54 | * The {@link BlazeElement} this property belongs to. 55 | */ 56 | protected final BlazeElement element; 57 | 58 | /** 59 | * RDF representation of the property key. 60 | */ 61 | protected final URI key; 62 | 63 | /** 64 | * RDF representation of the property value. 65 | */ 66 | protected final Literal val; 67 | 68 | /** 69 | * Solely for {@link EmptyBlazeProperty}. 70 | */ 71 | protected BlazeProperty() { 72 | this.graph = null; 73 | this.vf = null; 74 | this.element = null; 75 | this.key = null; 76 | this.val = null; 77 | } 78 | 79 | BlazeProperty(final BlazeGraph graph, final BlazeElement element, 80 | final URI key, final Literal val) { 81 | this.graph = graph; 82 | this.vf = graph.valueFactory(); 83 | this.element = element; 84 | this.key = key; 85 | this.val = val; 86 | } 87 | 88 | public BlazeGraph graph() { 89 | return graph; 90 | } 91 | 92 | /** 93 | * RDF representation of the property key. 94 | */ 95 | public URI rdfKey() { 96 | return key; 97 | } 98 | 99 | /** 100 | * RDF representation of the property value. 101 | */ 102 | public Literal rdfValue() { 103 | return val; 104 | } 105 | 106 | /** 107 | * The {@link BlazeElement} this property belongs to. 108 | */ 109 | @Override 110 | public BlazeElement element() { 111 | return element; 112 | } 113 | 114 | /** 115 | * @see Property#key() 116 | */ 117 | @Override 118 | public String key() { 119 | return vf.fromURI(key); 120 | } 121 | 122 | /** 123 | * @see Property#value() 124 | */ 125 | @Override 126 | @SuppressWarnings("unchecked") 127 | public V value() throws NoSuchElementException { 128 | return (V) vf.fromLiteral(val); 129 | } 130 | 131 | /** 132 | * @see Property#isPresent() 133 | */ 134 | @Override 135 | public boolean isPresent() { 136 | return true; 137 | } 138 | 139 | /** 140 | * @see Property#remove() 141 | * @see BlazeGraph#remove(BlazeProperty) 142 | */ 143 | @Override 144 | public void remove() { 145 | graph.remove(this); 146 | } 147 | 148 | /** 149 | * Pass through to {@link ElementHelper#areEqual(Property, Object)} 150 | */ 151 | @Override 152 | public boolean equals(final Object object) { 153 | return ElementHelper.areEqual(this, object); 154 | } 155 | 156 | /** 157 | * Pass through to {@link ElementHelper#hashCode(Property)} 158 | */ 159 | @Override 160 | public int hashCode() { 161 | return ElementHelper.hashCode(this); 162 | } 163 | 164 | /** 165 | * Pass through to {@link StringFactory#propertyString(Property)} 166 | */ 167 | @Override 168 | public String toString() { 169 | return StringFactory.propertyString(this); 170 | } 171 | 172 | } 173 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/structure/BlazeReifiedElement.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.structure; 24 | 25 | import org.apache.tinkerpop.gremlin.structure.Property; 26 | import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; 27 | 28 | import com.bigdata.rdf.model.BigdataBNode; 29 | import com.blazegraph.gremlin.util.CloseableIterator; 30 | 31 | /** 32 | * Common interface for {@link BlazeEdge} and {@link BlazeVertexProperty}, 33 | * both of which use a sid (reified statement) as their RDF id for attaching 34 | * labels (BlazeEdge) and properties (both). 35 | * 36 | * @author mikepersonick 37 | */ 38 | public interface BlazeReifiedElement extends BlazeElement { 39 | 40 | /** 41 | * Strengthen return type. 42 | * 43 | * @see BlazeElement#rdfId() 44 | */ 45 | @Override 46 | BigdataBNode rdfId(); 47 | 48 | /** 49 | * Safer default implementation that closes the iterator from properties(). 50 | */ 51 | @Override 52 | default BlazeProperty property(final String key) { 53 | try (CloseableIterator> it = this.properties(key)) { 54 | return it.hasNext() ? (BlazeProperty) it.next() : EmptyBlazeProperty.instance(); 55 | } 56 | } 57 | 58 | /** 59 | * Pass through to {@link BlazeGraph#properties(BlazeReifiedElement, String...)} 60 | */ 61 | @Override 62 | default CloseableIterator> properties(final String... keys) { 63 | return graph().properties(this, keys); 64 | } 65 | 66 | /** 67 | * Pass through to {@link BlazeGraph#property(BlazeReifiedElement, String, Object)} 68 | */ 69 | default BlazeProperty property(final String key, final V val) { 70 | ElementHelper.validateProperty(key, val); 71 | return graph().property(this, key, val); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/structure/BlazeValueFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.structure; 24 | 25 | import org.openrdf.model.Literal; 26 | import org.openrdf.model.URI; 27 | import org.openrdf.model.ValueFactory; 28 | import org.openrdf.model.impl.URIImpl; 29 | import org.openrdf.model.impl.ValueFactoryImpl; 30 | import org.openrdf.model.vocabulary.RDF; 31 | 32 | import com.bigdata.rdf.internal.XSD; 33 | import com.bigdata.rdf.sail.RDRHistory; 34 | import com.blazegraph.gremlin.internal.ListIndexExtension; 35 | 36 | /** 37 | * Factory for converting Tinkerpop data (element ids, property names/values) 38 | * to RDF values (URIs, Literals) and back again. This interface comes with 39 | * reasonable default behavior for all methods. It can be overridden to give 40 | * an application a custom look and feel for the RDF values used to represent 41 | * the property graph. 42 | * 43 | * @author mikepersonick 44 | */ 45 | public interface BlazeValueFactory { 46 | 47 | /** 48 | * Default instance. 49 | */ 50 | public static final BlazeValueFactory INSTANCE = new BlazeValueFactory() {}; 51 | 52 | /** 53 | * Some default constants. 54 | * 55 | * @author mikepersonick 56 | */ 57 | public interface Defaults { 58 | 59 | /** 60 | * Namespace for RDF URIs. 61 | */ 62 | String NAMESPACE = "blaze:"; 63 | 64 | /** 65 | * URI used for typing elements. 66 | */ 67 | URI TYPE = RDF.TYPE; 68 | 69 | /** 70 | * URI used for list item values. 71 | */ 72 | URI VALUE = RDF.VALUE; 73 | 74 | /** 75 | * Datatype URI for list index for Cardinality.list vertex properties. 76 | */ 77 | URI LI_DATATYPE = ListIndexExtension.DATATYPE; 78 | 79 | /** 80 | * Template for stamping element URIs (blaze:id). 81 | */ 82 | String ELEMENT_URI_TEMPLATE = NAMESPACE + "%s"; 83 | 84 | /** 85 | * Template for stamping property key URIs (blaze:key). 86 | */ 87 | String PROPERTY_URI_TEMPLATE = ELEMENT_URI_TEMPLATE; 88 | 89 | /** 90 | * Template for stamping type URIs (blaze:type). 91 | */ 92 | String TYPE_URI_TEMPLATE = ELEMENT_URI_TEMPLATE; 93 | 94 | /** 95 | * Default RDF value factory. 96 | */ 97 | ValueFactory VF = new ValueFactoryImpl(); 98 | 99 | } 100 | 101 | /** 102 | * URI used for element labels (typing). 103 | * 104 | * @see Defaults#TYPE 105 | * 106 | * @return 107 | * URI used for element labels. 108 | */ 109 | default URI type() { 110 | return Defaults.TYPE; 111 | } 112 | 113 | /** 114 | * URI used for Cardinality.list property values. 115 | * 116 | * @see Defaults#VALUE 117 | * 118 | * @return 119 | * URI used for Cardinality.list property values. 120 | */ 121 | default URI value() { 122 | return Defaults.VALUE; 123 | } 124 | 125 | /** 126 | * URI used for Cardinality.list list index datatype. 127 | * 128 | * @see Defaults#LI_DATATYPE 129 | * 130 | * @return 131 | * URI used for Cardinality.list list index datatype. 132 | */ 133 | default URI liDatatype() { 134 | return Defaults.LI_DATATYPE; 135 | } 136 | 137 | /** 138 | * URI used for history. Only reason to override this is if a different 139 | * history implementation is used. 140 | * 141 | * @see RDRHistory 142 | * 143 | * @return 144 | * URI used for history. 145 | */ 146 | default URI historyAdded() { 147 | return RDRHistory.Vocab.ADDED; 148 | } 149 | 150 | /** 151 | * URI used for history. Only reason to override this is if a different 152 | * history implementation is used. 153 | * 154 | * @see RDRHistory 155 | * 156 | * @return 157 | * URI used for history. 158 | */ 159 | default URI historyRemoved() { 160 | return RDRHistory.Vocab.REMOVED; 161 | } 162 | 163 | /** 164 | * Convert an element id into an RDF URI. 165 | *

166 | * Default behavior is to prepend the {@code } namespace to the id. 167 | *

168 | * 169 | * @param id 170 | * property graph element id 171 | * @return 172 | * RDF URI representation 173 | */ 174 | default URI elementURI(final String id) { 175 | return new URIImpl(String.format(Defaults.ELEMENT_URI_TEMPLATE, id)); 176 | } 177 | 178 | /** 179 | * Convert an property key into an RDF URI. 180 | *

181 | * Default behavior is to prepend the {@code } namespace to the key. 182 | *

183 | * @param key 184 | * property graph property key 185 | * @return 186 | * RDF URI representation 187 | */ 188 | default URI propertyURI(final String key) { 189 | return new URIImpl(String.format(Defaults.PROPERTY_URI_TEMPLATE, key)); 190 | } 191 | 192 | /** 193 | * Convert an element label (type) into an RDF URI. 194 | *

195 | * Default behavior is to prepend the {@code } namespace to the label. 196 | *

197 | * @param label property graph element label 198 | * @return URI RDF URI representation 199 | * 200 | */ 201 | default URI typeURI(final String label) { 202 | return new URIImpl(String.format(Defaults.TYPE_URI_TEMPLATE, label)); 203 | } 204 | 205 | /** 206 | * Convert an RDF URI (element id/label or property key) back into a string. 207 | * 208 | * @param uri 209 | * RDF representation of an element id/label or property key 210 | * @return 211 | * property graph (string) representation 212 | */ 213 | default String fromURI(final URI uri) { 214 | final String s = uri.stringValue(); 215 | return s.substring(s.lastIndexOf(':')+1); 216 | } 217 | 218 | /** 219 | * Create a datatyped literal from a blueprints property value. 220 | *

221 | * Supports: Float, Double, Integer, Long, Boolean, Short, Byte, and String. 222 | */ 223 | default Literal toLiteral(final Object value) { 224 | 225 | final ValueFactory vf = Defaults.VF; 226 | 227 | if (value instanceof Float) { 228 | return vf.createLiteral((Float) value); 229 | } else if (value instanceof Double) { 230 | return vf.createLiteral((Double) value); 231 | } else if (value instanceof Integer) { 232 | return vf.createLiteral((Integer) value); 233 | } else if (value instanceof Long) { 234 | return vf.createLiteral((Long) value); 235 | } else if (value instanceof Boolean) { 236 | return vf.createLiteral((Boolean) value); 237 | } else if (value instanceof Short) { 238 | return vf.createLiteral((Short) value); 239 | } else if (value instanceof Byte) { 240 | return vf.createLiteral((Byte) value); 241 | } else if (value instanceof String) { 242 | return vf.createLiteral((String) value); 243 | } else { 244 | throw new IllegalArgumentException(String.format("not supported: %s", value)); 245 | } 246 | 247 | } 248 | 249 | /** 250 | * Create a blueprints property value from a datatyped literal. 251 | *

252 | * Return a graph property from a datatyped literal using its 253 | * XSD datatype. 254 | *

255 | * Supports: Float, Double, Integer, Long, Boolean, Short, Byte, and String. 256 | */ 257 | default Object fromLiteral(final Literal l) { 258 | 259 | final URI datatype = l.getDatatype(); 260 | 261 | if (datatype == null) { 262 | return l.getLabel(); 263 | } else if (datatype.equals(XSD.FLOAT)) { 264 | return l.floatValue(); 265 | } else if (datatype.equals(XSD.DOUBLE)) { 266 | return l.doubleValue(); 267 | } else if (datatype.equals(XSD.INT)) { 268 | return l.intValue(); 269 | } else if (datatype.equals(XSD.LONG)) { 270 | return l.longValue(); 271 | } else if (datatype.equals(XSD.BOOLEAN)) { 272 | return l.booleanValue(); 273 | } else if (datatype.equals(XSD.SHORT)) { 274 | return l.shortValue(); 275 | } else if (datatype.equals(XSD.BYTE)) { 276 | return l.byteValue(); 277 | } else { 278 | return l.getLabel(); 279 | } 280 | 281 | } 282 | 283 | } 284 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/structure/BlazeVertex.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.structure; 24 | 25 | import org.apache.tinkerpop.gremlin.structure.Direction; 26 | import org.apache.tinkerpop.gremlin.structure.Edge; 27 | import org.apache.tinkerpop.gremlin.structure.Graph; 28 | import org.apache.tinkerpop.gremlin.structure.Vertex; 29 | import org.apache.tinkerpop.gremlin.structure.VertexProperty; 30 | import org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality; 31 | import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; 32 | import org.apache.tinkerpop.gremlin.structure.util.StringFactory; 33 | import org.openrdf.model.Literal; 34 | 35 | import com.bigdata.rdf.model.BigdataURI; 36 | import com.blazegraph.gremlin.util.CloseableIterator; 37 | 38 | /** 39 | * Concrete vertex implementation for BlazeGraph. 40 | *

41 | * Vertex existence is represented as one triples as follows: 42 | *

43 | *
 44 |  *     :vertexId rdf:type :label .
 45 |  * 
46 | *

47 | * Vertex properties are represented as follows: 48 | *

49 | *
 50 |  *     :vertexId :key "val" .
 51 |  * 
52 | * 53 | * @author mikepersonick 54 | */ 55 | public class BlazeVertex extends AbstractBlazeElement implements Vertex, BlazeElement { 56 | 57 | /** 58 | * Construct an instance. 59 | */ 60 | BlazeVertex(final BlazeGraph graph, final BigdataURI uri, 61 | final BigdataURI label) { 62 | super(graph, uri, label); 63 | } 64 | 65 | /** 66 | * Strengthen return type. Vertex RDF id is its URI. 67 | */ 68 | @Override 69 | public BigdataURI rdfId() { 70 | return uri; 71 | } 72 | 73 | /** 74 | * Pass through to {@link StringFactory#vertexString(Vertex)} 75 | */ 76 | @Override 77 | public String toString() { 78 | return StringFactory.vertexString(this); 79 | } 80 | 81 | /** 82 | * Strengthen return type to {@link BlazeVertexProperty}. 83 | * 84 | * @see Vertex#property(String) 85 | * @see BlazeVertex#properties(String...) 86 | */ 87 | @Override 88 | public BlazeVertexProperty property(final String key) { 89 | try (CloseableIterator> it = this.properties(key)) { 90 | if (it.hasNext()) { 91 | final VertexProperty property = it.next(); 92 | if (it.hasNext()) 93 | throw Vertex.Exceptions.multiplePropertiesExistForProvidedKey(key); 94 | else 95 | return (BlazeVertexProperty) property; 96 | } else { 97 | return EmptyBlazeVertexProperty.instance(); 98 | } 99 | } 100 | } 101 | 102 | /** 103 | * Strengthen return type to {@link BlazeVertexProperty} and use 104 | * Cardinality.single by default. 105 | */ 106 | @Override 107 | public BlazeVertexProperty property(final String key, final V val) { 108 | return property(Cardinality.single, key, val); 109 | } 110 | 111 | /** 112 | * Strengthen return type to {@link BlazeVertexProperty}. 113 | * 114 | * @see BlazeGraph#vertexProperty(BlazeVertex, Cardinality, String, Object, Object...) 115 | */ 116 | @Override 117 | public BlazeVertexProperty property(final Cardinality cardinality, 118 | final String key, final V val, final Object... kvs) { 119 | ElementHelper.validateProperty(key, val); 120 | if (ElementHelper.getIdValue(kvs).isPresent()) 121 | throw Vertex.Exceptions.userSuppliedIdsNotSupported(); 122 | 123 | return graph.vertexProperty(this, cardinality, key, val, kvs); 124 | } 125 | 126 | /** 127 | * Strength return type to {@link CloseableIterator}. You MUST close this 128 | * iterator when finished. 129 | */ 130 | @Override 131 | public CloseableIterator> properties(String... keys) { 132 | return graph.properties(this, keys); 133 | } 134 | 135 | /** 136 | * @see Vertex#addEdge(String, Vertex, Object...) 137 | * @see BlazeGraph#addEdge(BlazeVertex, BlazeVertex, String, Object...) 138 | */ 139 | @Override 140 | public BlazeEdge addEdge(final String label, final Vertex to, final Object... kvs) { 141 | if (to == null) throw Graph.Exceptions.argumentCanNotBeNull("vertex"); 142 | return graph.addEdge(this, (BlazeVertex) to, label, kvs); 143 | } 144 | 145 | /** 146 | * Strength return type to {@link CloseableIterator}. You MUST close this 147 | * iterator when finished. 148 | * 149 | * @see Vertex#edges(Direction, String...) 150 | * @see BlazeGraph#edgesFromVertex(BlazeVertex, Direction, String...) 151 | */ 152 | @Override 153 | public CloseableIterator edges(final Direction direction, 154 | final String... edgeLabels) { 155 | return graph.edgesFromVertex(this, direction, edgeLabels); 156 | } 157 | 158 | /** 159 | * Strength return type to {@link CloseableIterator}. You MUST close this 160 | * iterator when finished. 161 | * 162 | * @see Vertex#vertices(Direction, String...) 163 | */ 164 | @Override 165 | public CloseableIterator vertices(final Direction direction, 166 | final String... edgeLabels) { 167 | return CloseableIterator.of(edges(direction, edgeLabels) 168 | .stream() 169 | .map(e -> { 170 | final BlazeEdge be = (BlazeEdge) e; 171 | return be.outVertex().equals(this) ? be.inVertex() : be.outVertex(); 172 | })); 173 | } 174 | 175 | /** 176 | * @see Vertex#remove() 177 | * @see BlazeGraph#remove(BlazeVertex) 178 | */ 179 | @Override 180 | public void remove() { 181 | graph.remove(this); 182 | } 183 | 184 | } 185 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/structure/BlazeVertexProperty.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.structure; 24 | 25 | import java.util.NoSuchElementException; 26 | 27 | import org.apache.tinkerpop.gremlin.structure.Element; 28 | import org.apache.tinkerpop.gremlin.structure.Property; 29 | import org.apache.tinkerpop.gremlin.structure.VertexProperty; 30 | import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; 31 | import org.apache.tinkerpop.gremlin.structure.util.StringFactory; 32 | import org.openrdf.model.Literal; 33 | import org.openrdf.model.URI; 34 | 35 | import com.bigdata.rdf.model.BigdataBNode; 36 | import com.blazegraph.gremlin.util.CloseableIterator; 37 | 38 | /** 39 | * Concrete vertex property implementation for Blazegraph. 40 | * 41 | *

42 | * Vertex properties can be represented in one of two ways depending on the 43 | * cardinality of the key. Cardinality.single and Cardinality.set are 44 | * represented the same way, as follows: 45 | *

46 | * 47 | *
 48 |  *     :vertexId :key "val" .
 49 |  * 
50 | * 51 | * For Cardinality.list, a list index literal with a special datatype is used 52 | * to manage duplicate list items and ordering. Cardinality.list requires two 53 | * triples instead of one: 54 | *
 55 |  * {@code
 56 |  *     :vertexId :key "0"^^blazegraph:listIndex .
 57 |  *     <<:vertexId :key "0"^^blazegraph:listIndex>> rdf:value "val" .
 58 |  * }
 59 |  * 
60 | * 61 | *

62 | * In either case, meta-properties can be attached to the reified vertex 63 | * property triple: 64 | *

65 | *
 66 |  * {@code
 67 |  *     # for Cardinality.single and Cardinality.set
 68 |  *     <<:vertexId :key "val">> :metaKey "metaVal" .
 69 |  *     # for Cardinality.list
 70 |  *     <<:vertexId :key "0"^^blazegraph:listIndex>> :metaKey "metaVal" .
 71 |  * }
 72 |  * 
73 | * @author mikepersonick 74 | * 75 | * @param 76 | */ 77 | public class BlazeVertexProperty 78 | implements VertexProperty, BlazeReifiedElement { 79 | 80 | /** 81 | * Delegation pattern, since a vertex property is a property. 82 | */ 83 | private final BlazeProperty prop; 84 | 85 | /** 86 | * The reified vertex property triple. 87 | */ 88 | private final BigdataBNode sid; 89 | 90 | /** 91 | * The RDF id - an internally generated string representation of the 92 | * reified vertex property triple. 93 | */ 94 | private final String id; 95 | 96 | /** 97 | * Solely for {@link EmptyBlazeVertexProperty}. 98 | */ 99 | protected BlazeVertexProperty() { 100 | this.prop = null; 101 | this.id = null; 102 | this.sid = null; 103 | } 104 | 105 | /** 106 | * Construct an instance. 107 | */ 108 | BlazeVertexProperty(final BlazeProperty prop, 109 | final String id, final BigdataBNode sid) { 110 | this.prop = prop; 111 | this.sid = sid; 112 | this.id = id; 113 | } 114 | 115 | /** 116 | * The reified vertex property triple. 117 | */ 118 | @Override 119 | public BigdataBNode rdfId() { 120 | return sid; 121 | } 122 | 123 | /** 124 | * The internally generated element id for this vertex property. 125 | */ 126 | @Override 127 | public String id() { 128 | return id; 129 | } 130 | 131 | /** 132 | * The {@link BlazeGraph} instance. 133 | */ 134 | @Override 135 | public BlazeGraph graph() { 136 | return prop.graph(); 137 | } 138 | 139 | /** 140 | * The vertex to which this property belongs. 141 | */ 142 | @Override 143 | public BlazeVertex element() { 144 | return (BlazeVertex) prop.element(); 145 | } 146 | 147 | /** 148 | * Property key. 149 | */ 150 | @Override 151 | public String key() { 152 | return prop.key(); 153 | } 154 | 155 | /** 156 | * Property value. 157 | */ 158 | @Override 159 | public V value() throws NoSuchElementException { 160 | return prop.value(); 161 | } 162 | 163 | /** 164 | * @see Property#isPresent() 165 | */ 166 | @Override 167 | public boolean isPresent() { 168 | return prop.isPresent(); 169 | } 170 | 171 | /** 172 | * @see Property#remove() 173 | * @see BlazeGraph#remove(BlazeReifiedElement) 174 | */ 175 | @Override 176 | public void remove() { 177 | graph().remove(this); 178 | } 179 | 180 | /** 181 | * Strengthen return type to {@link BlazeProperty}. 182 | */ 183 | @Override 184 | public BlazeProperty property(final String key, final U val) { 185 | return BlazeReifiedElement.super.property(key, val); 186 | } 187 | 188 | /** 189 | * Strength return type to {@link CloseableIterator}. You MUST close this 190 | * iterator when finished. 191 | */ 192 | @Override 193 | public CloseableIterator> properties(final String... keys) { 194 | return BlazeReifiedElement.super.properties(keys); 195 | } 196 | 197 | /** 198 | * Pass through to {@link ElementHelper#hashCode(Element)} 199 | */ 200 | @Override 201 | public int hashCode() { 202 | return ElementHelper.hashCode((Element) this); 203 | } 204 | 205 | /** 206 | * Pass through to {@link ElementHelper#areEqual(VertexProperty, Object)} 207 | */ 208 | @Override 209 | public boolean equals(final Object object) { 210 | return ElementHelper.areEqual(this, object); 211 | } 212 | 213 | /** 214 | * Pass through to {@link StringFactory#propertyString(Property)} 215 | */ 216 | @Override 217 | public String toString() { 218 | return StringFactory.propertyString(this); 219 | } 220 | 221 | /** 222 | * The element label, which is the property key. 223 | */ 224 | @Override 225 | public String label() { 226 | return key(); 227 | } 228 | 229 | /** 230 | * The RDF representation of the element label (required by 231 | * {@link BlazeElement}). 232 | */ 233 | @Override 234 | public URI rdfLabel() { 235 | return graph().valueFactory().typeURI(label()); 236 | } 237 | 238 | 239 | } 240 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/structure/EmptyBlazeProperty.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.structure; 24 | 25 | import java.util.NoSuchElementException; 26 | 27 | import org.apache.tinkerpop.gremlin.structure.util.StringFactory; 28 | import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyProperty; 29 | import org.openrdf.model.Literal; 30 | import org.openrdf.model.URI; 31 | 32 | /** 33 | * Wanted to extend TP3's {@link EmptyProperty}, but it's final. 34 | * 35 | * @author mikepersonick 36 | */ 37 | public class EmptyBlazeProperty extends BlazeProperty { 38 | 39 | @SuppressWarnings("rawtypes") 40 | public static final EmptyBlazeProperty INSTANCE = new EmptyBlazeProperty<>(); 41 | @SuppressWarnings("unchecked") 42 | public static BlazeProperty instance() { 43 | return INSTANCE; 44 | } 45 | 46 | private EmptyBlazeProperty() { 47 | super(); 48 | } 49 | 50 | @Override 51 | public URI rdfKey() { 52 | throw Exceptions.propertyDoesNotExist(); 53 | } 54 | 55 | @Override 56 | public Literal rdfValue() { 57 | throw Exceptions.propertyDoesNotExist(); 58 | } 59 | 60 | @Override 61 | public String key() { 62 | throw Exceptions.propertyDoesNotExist(); 63 | } 64 | 65 | @Override 66 | public V value() throws NoSuchElementException { 67 | throw Exceptions.propertyDoesNotExist(); 68 | } 69 | 70 | @Override 71 | public boolean isPresent() { 72 | return false; 73 | } 74 | 75 | @Override 76 | public BlazeElement element() { 77 | throw Exceptions.propertyDoesNotExist(); 78 | } 79 | 80 | @Override 81 | public void remove() { 82 | } 83 | 84 | @Override 85 | public String toString() { 86 | return StringFactory.propertyString(this); 87 | } 88 | 89 | @Override 90 | public boolean equals(final Object object) { 91 | return object instanceof EmptyBlazeProperty; 92 | } 93 | 94 | public int hashCode() { 95 | return 123456789; 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/structure/EmptyBlazeVertexProperty.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.structure; 24 | 25 | import java.util.NoSuchElementException; 26 | 27 | import org.apache.tinkerpop.gremlin.structure.Property; 28 | import org.apache.tinkerpop.gremlin.structure.util.StringFactory; 29 | import org.apache.tinkerpop.gremlin.structure.util.empty.EmptyVertexProperty; 30 | import org.openrdf.model.URI; 31 | 32 | import com.bigdata.rdf.model.BigdataBNode; 33 | import com.blazegraph.gremlin.util.CloseableIterator; 34 | 35 | /** 36 | * Wanted to extend TP3's {@link EmptyVertexProperty}, but it's final. 37 | * 38 | * @author mikepersonick 39 | */ 40 | public class EmptyBlazeVertexProperty extends BlazeVertexProperty { 41 | 42 | @SuppressWarnings("rawtypes") 43 | public static final EmptyBlazeVertexProperty INSTANCE = new EmptyBlazeVertexProperty<>(); 44 | @SuppressWarnings("unchecked") 45 | public static BlazeVertexProperty instance() { 46 | return INSTANCE; 47 | } 48 | 49 | private EmptyBlazeVertexProperty() { 50 | super(); 51 | } 52 | 53 | @Override 54 | public BigdataBNode rdfId() { 55 | throw Property.Exceptions.propertyDoesNotExist(); 56 | } 57 | 58 | @Override 59 | public URI rdfLabel() { 60 | throw Property.Exceptions.propertyDoesNotExist(); 61 | } 62 | 63 | @Override 64 | public String label() { 65 | throw Property.Exceptions.propertyDoesNotExist(); 66 | } 67 | 68 | @Override 69 | public int hashCode() { 70 | return 987654321; 71 | } 72 | 73 | @Override 74 | public boolean equals(Object object) { 75 | return object instanceof EmptyBlazeVertexProperty; 76 | } 77 | 78 | @Override 79 | public BlazeVertex element() { 80 | throw Property.Exceptions.propertyDoesNotExist(); 81 | } 82 | 83 | @Override 84 | public String id() { 85 | throw Property.Exceptions.propertyDoesNotExist(); 86 | } 87 | 88 | @Override 89 | public BlazeGraph graph() { 90 | throw Property.Exceptions.propertyDoesNotExist(); 91 | } 92 | 93 | @Override 94 | public BlazeProperty property(String key) { 95 | return EmptyBlazeProperty.instance(); 96 | } 97 | 98 | @Override 99 | public BlazeProperty property(String key, U value) { 100 | return EmptyBlazeProperty.instance(); 101 | } 102 | 103 | @Override 104 | public String key() { 105 | throw Property.Exceptions.propertyDoesNotExist(); 106 | } 107 | 108 | @Override 109 | public V value() throws NoSuchElementException { 110 | throw Property.Exceptions.propertyDoesNotExist(); 111 | } 112 | 113 | @Override 114 | public boolean isPresent() { 115 | return false; 116 | } 117 | 118 | @Override 119 | public void remove() { 120 | 121 | } 122 | 123 | @Override 124 | public String toString() { 125 | return StringFactory.propertyString(this); 126 | } 127 | 128 | @Override 129 | public CloseableIterator> properties(String... propertyKeys) { 130 | return CloseableIterator.emptyIterator(); 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/util/CloseableIterator.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.util; 24 | 25 | import static java.util.stream.Collectors.toList; 26 | 27 | import java.util.Collections; 28 | import java.util.Iterator; 29 | import java.util.List; 30 | import java.util.function.Consumer; 31 | import java.util.stream.Stream; 32 | 33 | /** 34 | * Interface that combines Iterator and AutoCloseable. Why does Java 8 not 35 | * support this natively?!? 36 | * 37 | * @author mikepersonick 38 | */ 39 | public interface CloseableIterator extends Iterator, AutoCloseable { 40 | 41 | /** 42 | * You MUST close this iterator or auto-close with a try-with-resources. 43 | */ 44 | @Override 45 | void close(); 46 | 47 | /** 48 | * Perform some action on each remaining element and then close the itertor. 49 | */ 50 | @Override 51 | default void forEachRemaining(Consumer action) { 52 | try { 53 | Iterator.super.forEachRemaining(action); 54 | } finally { 55 | close(); 56 | } 57 | } 58 | 59 | /** 60 | * You MUST close this stream or auto-close in a try-with-resources. 61 | */ 62 | default Stream stream() { 63 | return Streams.of(this).onClose(() -> close()); 64 | } 65 | 66 | /** 67 | * Collect the elements into a list. This will close the iterator. 68 | */ 69 | default List collect() { 70 | try (Stream s = stream()) { 71 | return s.collect(toList()); 72 | } 73 | } 74 | 75 | /** 76 | * Count the elements. This will close the iterator. 77 | */ 78 | default long count() { 79 | try (Stream s = stream()) { 80 | return s.count(); 81 | } 82 | } 83 | 84 | /** 85 | * Count the distinct elements. This will close the iterator. 86 | */ 87 | default long countDistinct() { 88 | try (Stream s = stream()) { 89 | return s.distinct().count(); 90 | } 91 | } 92 | 93 | /** 94 | * Construct an instance from a stream using stream.close() as the close 95 | * behavior for the iterator. 96 | */ 97 | public static CloseableIterator of(final Stream stream) { 98 | return of(stream.iterator(), () -> stream.close()); 99 | } 100 | 101 | /** 102 | * Construct an instance from the supplied iterator and the supplied 103 | * onClose behavior. 104 | */ 105 | public static 106 | CloseableIterator of(final Iterator it, final Runnable onClose) { 107 | return new CloseableIterator() { 108 | 109 | @Override 110 | public boolean hasNext() { 111 | return it.hasNext(); 112 | } 113 | 114 | @Override 115 | public T next() { 116 | return it.next(); 117 | } 118 | 119 | @Override 120 | public void remove() { 121 | it.remove(); 122 | } 123 | 124 | @Override 125 | public void close() { 126 | onClose.run(); 127 | } 128 | 129 | @Override 130 | public void forEachRemaining(Consumer action) { 131 | it.forEachRemaining(action); 132 | } 133 | 134 | }; 135 | } 136 | 137 | /** 138 | * Empty instance. 139 | */ 140 | public static CloseableIterator emptyIterator() { 141 | final Iterator it = Collections.emptyIterator(); 142 | return of(it, () -> {}); 143 | } 144 | 145 | } 146 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/util/Code.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.util; 24 | 25 | import java.util.concurrent.Callable; 26 | 27 | /** 28 | * Override of Runnable to throw exceptions instead of trapping. Useful for 29 | * lambdas. 30 | * 31 | * @author mikepersonick 32 | */ 33 | @FunctionalInterface 34 | public interface Code { 35 | 36 | /** 37 | * Execute the code block without trapping exceptions. 38 | * 39 | * @throws Exception 40 | */ 41 | public abstract void run() throws Exception; 42 | 43 | /** 44 | * Execute the callable wrapping checked exceptions inside a 45 | * RuntimeException. 46 | */ 47 | public static T wrapThrow(Callable callable) { 48 | try { 49 | return callable.call(); 50 | } catch (RuntimeException e) { 51 | // e.printStackTrace(); 52 | throw e; 53 | } catch (Exception e) { 54 | // e.printStackTrace(); 55 | throw new RuntimeException(e); 56 | } 57 | } 58 | 59 | /** 60 | * Execute the code block wrapping checked exceptions inside a 61 | * RuntimeException. 62 | */ 63 | public static void wrapThrow(Code code) { 64 | try { 65 | code.run(); 66 | } catch (RuntimeException e) { 67 | throw e; 68 | } catch (Exception e) { 69 | throw new RuntimeException(e); 70 | } 71 | } 72 | 73 | /** 74 | * Execute the callable wrapping checked exceptions inside a 75 | * RuntimeException. 76 | */ 77 | public static T wrapThrow(Callable callable, Code _finally) { 78 | try { 79 | return callable.call(); 80 | } catch (RuntimeException e) { 81 | throw e; 82 | } catch (Exception e) { 83 | throw new RuntimeException(e); 84 | } finally { 85 | wrapThrow(_finally); 86 | } 87 | } 88 | 89 | /** 90 | * Execute the code block wrapping checked exceptions inside a 91 | * RuntimeException. 92 | */ 93 | public static void wrapThrow(Code code, Code _finally) { 94 | try { 95 | code.run(); 96 | } catch (RuntimeException e) { 97 | throw e; 98 | } catch (Exception e) { 99 | throw new RuntimeException(e); 100 | } finally { 101 | wrapThrow(_finally); 102 | } 103 | } 104 | 105 | /** 106 | * Execute the callable without trapping checked exceptions. Use instead 107 | * of a wrap/re-throw pattern inside lambdas. 108 | */ 109 | public static T unchecked(Callable callable) { 110 | try { 111 | return callable.call(); 112 | } catch (Exception e) { 113 | return sneakyThrow(e); 114 | } 115 | } 116 | 117 | /** 118 | * Execute the code block without trapping checked exceptions. Use instead 119 | * of a wrap/re-throw pattern inside lambdas. 120 | */ 121 | public static void unchecked(Code code) { 122 | try { 123 | code.run(); 124 | } catch (Exception e) { 125 | sneakyThrow(e); 126 | } 127 | } 128 | 129 | /** 130 | * Execute the callable without trapping checked exceptions. Use instead 131 | * of a wrap/re-throw pattern inside lambdas. 132 | */ 133 | public static T unchecked(Callable callable, Code _finally) { 134 | try { 135 | return callable.call(); 136 | } catch (Exception e) { 137 | return sneakyThrow(e); 138 | } finally { 139 | unchecked(_finally); 140 | } 141 | } 142 | 143 | /** 144 | * Execute the code block without trapping checked exceptions. Use instead 145 | * of a wrap/re-throw pattern inside lambdas. 146 | */ 147 | public static void unchecked(Code code, Code _finally) { 148 | try { 149 | code.run(); 150 | } catch (Exception e) { 151 | sneakyThrow(e); 152 | } finally { 153 | unchecked(_finally); 154 | } 155 | } 156 | 157 | /** 158 | * Use type erasure to throw checked exceptions without declaring them, 159 | * bypassing compiler checks. Use instead of a wrap/re-throw pattern 160 | * inside lambdas. 161 | */ 162 | public static T sneakyThrow(Throwable e) { 163 | return Code. sneakyThrow0(e); 164 | } 165 | 166 | /** 167 | * Use type erasure to throw checked exceptions without declaring them, 168 | * bypassing compiler checks. Use instead of a wrap/re-throw pattern 169 | * inside lambdas. 170 | */ 171 | @SuppressWarnings("unchecked") 172 | public static T sneakyThrow0(Throwable t) throws E { 173 | throw (E) t; 174 | } 175 | 176 | } 177 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/util/LambdaLogger.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.util; 24 | 25 | import java.util.Map; 26 | import java.util.concurrent.ConcurrentHashMap; 27 | import java.util.stream.Stream; 28 | 29 | import org.apache.log4j.Level; 30 | import org.apache.log4j.Logger; 31 | import org.apache.log4j.Priority; 32 | import org.apache.log4j.spi.LocationInfo; 33 | import org.apache.log4j.spi.LoggingEvent; 34 | 35 | /** 36 | * Wrap conditional logging using Java 8 lambdas. 37 | * 38 | * To use this functionality, simply request a LambdaLogger instead of a normal Logger: 39 | * 40 | * LambdaLogger log = LambdaLogger.getLogger(Foo.class) 41 | * 42 | * To log conditionally, simply use this syntax: 43 | * 44 | * {@code log.debug(() -> getMessage()); // getMessage() only called if log level >= DEBUG } 45 | * 46 | * In this example getMessage() will not be called unless the log level is 47 | * set to DEBUG or higher. Conditional logging drastically improves 48 | * performance and should ALWAYS be preferred in production (non-test) code 49 | * over the unconditional logging syntax: 50 | * 51 | * log.debug(getMessage()); // getMessage() called regardless of log level 52 | * 53 | * @author mikepersonick 54 | */ 55 | public class LambdaLogger extends Logger { 56 | 57 | // private static String FQCN = Logger.class.getName(); 58 | private static String FQCN = LambdaLogger.class.getName(); 59 | 60 | /** 61 | * Run the supplied code, quieting the supplied log at Level.ERROR 62 | */ 63 | public static final void quiet(Class cls, Code code) throws Exception { 64 | quiet(cls, Level.OFF, code); 65 | } 66 | 67 | /** 68 | * Run the supplied code, quieting the supplied log with the specified Level 69 | */ 70 | public static final void quiet(Class cls, Level set, Code code) throws Exception { 71 | 72 | final Logger log = Logger.getLogger(cls); 73 | final Level curr = log.getLevel(); 74 | log.setLevel(set); 75 | try { 76 | code.run(); 77 | } finally { 78 | log.setLevel(curr); 79 | } 80 | 81 | } 82 | 83 | private static final Map loggers = new ConcurrentHashMap<>(); 84 | 85 | /** 86 | * Override to return a LambdaLogger. 87 | */ 88 | public static LambdaLogger getLogger(final String name) { 89 | if (loggers.containsKey(name)) { 90 | return loggers.get(name); 91 | } else { 92 | final LambdaLogger log = new LambdaLogger(Logger.getLogger(name)); 93 | final LambdaLogger curr = loggers.putIfAbsent(name, log); 94 | return curr != null ? curr : log; 95 | } 96 | } 97 | 98 | /** 99 | * Override to return a LambdaLogger. 100 | */ 101 | @SuppressWarnings("rawtypes") 102 | public static LambdaLogger getLogger(final Class c) { 103 | return LambdaLogger.getLogger(c.getName()); 104 | } 105 | 106 | private final Logger log; 107 | 108 | private LambdaLogger(final Logger log) { 109 | super(log.getName()); 110 | this.log = log; 111 | this.repository = log.getLoggerRepository(); 112 | this.parent = log.getParent(); 113 | } 114 | 115 | /** 116 | * 117 | * Checked exception throwing version of {@code Supplier}. 118 | * 119 | * @author mikepersonick 120 | */ 121 | @FunctionalInterface 122 | public interface Supplier { 123 | public T get() throws Exception ; 124 | } 125 | 126 | /** 127 | * Conditionally log at the specified level. Does not call {@code supplier.get() } 128 | * unless {@code log.getLevel() >= level} (conditional message production). 129 | * 130 | * If the supplied object is a stream, conditionally log each object in 131 | * the stream on a separate line. 132 | */ 133 | protected void log(final Level level, final Supplier supplier) { 134 | if (log.getLoggerRepository().isDisabled(level.toInt())) { 135 | return; 136 | } 137 | if (level.isGreaterOrEqual(log.getEffectiveLevel())) { 138 | final Object o = Code.wrapThrow(() -> supplier.get()); 139 | if (o instanceof Stream) { 140 | final Stream stream = (Stream) o; 141 | try { 142 | stream.forEach(msg -> { 143 | log.callAppenders(new LambdaLoggingEvent(level, msg)); 144 | }); 145 | } finally { 146 | stream.close(); 147 | } 148 | } else { 149 | log.callAppenders(new LambdaLoggingEvent(level, o)); 150 | } 151 | } 152 | } 153 | 154 | /** 155 | * Conditionally log at INFO. Does not call supplier.get() unless 156 | * log.isInfoEnabled() == true (conditional message production). 157 | * 158 | * If the supplied object is a stream, conditionally log each object in 159 | * the stream on a separate line. 160 | */ 161 | public void info(final Supplier supplier) { 162 | log(Level.INFO, supplier); 163 | } 164 | 165 | /** 166 | * Conditionally log at DEBUG. Does not call supplier.get() unless 167 | * log.isDebugEnabled() == true (conditional message production). 168 | * 169 | * If the supplied object is a stream, conditionally log each object in 170 | * the stream on a separate line. 171 | */ 172 | public void debug(final Supplier supplier) { 173 | log(Level.DEBUG, supplier); 174 | } 175 | 176 | /** 177 | * Conditionally log at TRACE. Does not call supplier.get() unless 178 | * log.isTraceEnabled() == true (conditional message production). 179 | * 180 | * If the supplied object is a stream, conditionally log each object in 181 | * the stream on a separate line. 182 | */ 183 | public void trace(final Supplier supplier) { 184 | log(Level.TRACE, supplier); 185 | } 186 | 187 | /** 188 | * Had to override this to parse the stack trace differently when dealing 189 | * with lambdas to get the correct class / method / line number. 190 | * 191 | * @author mikepersonick 192 | */ 193 | private class LambdaLoggingEvent extends LoggingEvent { 194 | private static final long serialVersionUID = 8785675398139952600L; 195 | 196 | public LambdaLoggingEvent(Priority level, Object message) { 197 | super(FQCN, LambdaLogger.this, level, message, null); 198 | } 199 | 200 | private LocationInfo location = null; 201 | public LocationInfo getLocationInformation() { 202 | if (location == null) { 203 | Throwable t = new Throwable(); 204 | // t.printStackTrace(); 205 | location = new LambdaLocation(t); 206 | } 207 | return location; 208 | } 209 | 210 | } 211 | 212 | /** 213 | * Had to override this to parse the stack trace differently when dealing 214 | * with lambdas to get the correct class / method / line number. 215 | * 216 | * @author mikepersonick 217 | */ 218 | private class LambdaLocation extends LocationInfo { 219 | private static final long serialVersionUID = -7711773641304797646L; 220 | 221 | @Override 222 | public String getClassName() { 223 | return className; 224 | } 225 | 226 | @Override 227 | public String getFileName() { 228 | return fileName; 229 | } 230 | 231 | @Override 232 | public String getLineNumber() { 233 | return lineNumber; 234 | } 235 | 236 | @Override 237 | public String getMethodName() { 238 | return methodName; 239 | } 240 | 241 | private final String className; 242 | private final String methodName; 243 | private final String fileName; 244 | private final String lineNumber; 245 | 246 | public LambdaLocation(Throwable t) { 247 | super(t, FQCN); 248 | 249 | String className = null; 250 | String methodName = null; 251 | String fileName = null; 252 | String lineNumber = null; 253 | 254 | /* 255 | * Go top-down instead of bottom up like the default impl. 256 | */ 257 | StackTraceElement[] elements = t.getStackTrace(); 258 | for (int i = 0; i < elements.length; i++) { 259 | String thisClass = elements[i].getClassName(); 260 | String thisMethod = elements[i].getMethodName(); 261 | if (FQCN.equals(thisClass) && "log".equals(thisMethod)) { 262 | int caller = i + 2; 263 | if (caller < elements.length) { 264 | className = elements[caller].getClassName(); 265 | methodName = elements[caller].getMethodName(); 266 | fileName = elements[caller].getFileName(); 267 | int line = elements[caller].getLineNumber(); 268 | lineNumber = line < 0 ? NA : String.valueOf(line); 269 | StringBuilder buf = new StringBuilder(); 270 | buf.append(className); 271 | buf.append("."); 272 | buf.append(methodName); 273 | buf.append("("); 274 | buf.append(fileName); 275 | buf.append(":"); 276 | buf.append(lineNumber); 277 | buf.append(")"); 278 | this.fullInfo = buf.toString(); 279 | } 280 | break; 281 | } 282 | } 283 | 284 | this.className = className != null ? className : NA; 285 | this.methodName = methodName != null ? methodName : NA; 286 | this.fileName = fileName != null ? fileName : NA; 287 | this.lineNumber = lineNumber != null ? lineNumber : NA; 288 | } 289 | 290 | } 291 | 292 | } 293 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/util/Lambdas.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.util; 24 | 25 | import java.util.Map; 26 | import java.util.Map.Entry; 27 | import java.util.concurrent.ConcurrentHashMap; 28 | import java.util.function.Function; 29 | import java.util.function.Predicate; 30 | import java.util.function.Supplier; 31 | import java.util.stream.Collector; 32 | import java.util.stream.Collectors; 33 | 34 | /** 35 | * Lambda helpers. 36 | * 37 | * @author mikepersonick 38 | */ 39 | public interface Lambdas { 40 | 41 | /** 42 | * Create a "distinct by property" predicate for filtering. 43 | * 44 | * Usage: 45 | * Stream distinct Person objects by name: 46 | * {@code 47 | * persons.stream().filter(distinctByKey(p -> p.getName()); 48 | * } 49 | * 50 | * @return predicate (thread-safe) 51 | */ 52 | public static Predicate distinctByKey( 53 | final Function keyExtractor) { 54 | final Map seen = new ConcurrentHashMap<>(); 55 | return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null; 56 | } 57 | 58 | /** 59 | * Collect an Map.Entry stream into a Map. 60 | * 61 | * @param the type of key in the incoming entry stream 62 | * @param the type of value in the incoming entry stream 63 | */ 64 | public static Collector, ?, Map> toMap() { 65 | return Collectors.toMap(Entry::getKey, Entry::getValue); 66 | } 67 | 68 | /** 69 | * Collect an Map.Entry stream into a Map using the specified map supplier. 70 | * 71 | * @param the type of key in the incoming entry stream 72 | * @param the type of value in the incoming entry stream 73 | * @param the type of the resulting {@code Map} 74 | */ 75 | public static > 76 | Collector, ?, M> toMap(Supplier mapSupplier) { 77 | return Collectors.toMap( 78 | Entry::getKey, 79 | Entry::getValue, 80 | /* 81 | * We should never need to merge values (assuming the entry 82 | * stream has distinct keys). 83 | */ 84 | (a, b) -> { throw new IllegalStateException( 85 | String.format("Duplicate key %s", a)); }, 86 | mapSupplier 87 | ); 88 | } 89 | 90 | /** 91 | * This is the missing toMap() method on the Collectors class - specify 92 | * the key mapper, the value mapper, and the map supplier without having 93 | * to specify the value merge function. 94 | * 95 | * @param the type of the input elements 96 | * @param the output type of the key mapping function 97 | * @param the output type of the value mapping function 98 | * @param the type of the resulting {@code Map} 99 | */ 100 | public static > 101 | Collector toMap(Function keyMapper, 102 | Function valueMapper, 103 | Supplier mapSupplier) { 104 | return Collectors.toMap( 105 | keyMapper, 106 | valueMapper, 107 | (a,b) -> { throw new IllegalStateException( 108 | String.format("Duplicate key %s", a)); }, 109 | mapSupplier 110 | ); 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/util/Memoizer.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.util; 24 | 25 | import java.util.concurrent.Callable; 26 | import java.util.concurrent.Future; 27 | import java.util.concurrent.FutureTask; 28 | import java.util.concurrent.atomic.AtomicReference; 29 | 30 | /** 31 | * Safe lazy-initialization pattern for Java 8. 32 | * 33 | * @author mikepersonick 34 | */ 35 | public class Memoizer { 36 | 37 | private final AtomicReference> cache = new AtomicReference<>(null); 38 | 39 | private final Callable compute; 40 | 41 | /** 42 | * Lazy initializer. 43 | * 44 | * @param compute 45 | * Callable to compute the value to cache. 46 | */ 47 | public Memoizer(final Callable compute) { 48 | this(compute, null); 49 | } 50 | 51 | /** 52 | * Eager initializer. 53 | * 54 | * @param compute 55 | * Callable to compute the value to cache. 56 | * @param val 57 | * Pre-computed value to cache (if non-null). 58 | */ 59 | public Memoizer(final Callable compute, final V val) { 60 | this.compute = compute; 61 | 62 | if (val != null) { 63 | final FutureTask ft = new FutureTask<>(() -> val); 64 | ft.run(); 65 | cache.set(ft); 66 | } 67 | } 68 | 69 | /** 70 | * Get the cached value (compute if necessary). 71 | * 72 | * @return 73 | * the cached value 74 | */ 75 | public V get() { 76 | if (cache.get() == null) { 77 | final FutureTask ft = new FutureTask<>(compute); 78 | if (cache.compareAndSet(null, ft)) { 79 | ft.run(); 80 | } 81 | } 82 | final Future f = cache.get(); 83 | if (f == null) { 84 | /* 85 | * Cleared by another thread, re-compute 86 | */ 87 | return get(); 88 | } 89 | return Code.wrapThrow(() -> f.get()); 90 | } 91 | 92 | /** 93 | * Clear the cache, return the old value (or null if it had not been 94 | * computed yet). 95 | * 96 | * @return 97 | * the previously cached value 98 | */ 99 | public V clear() { 100 | final Future f = cache.getAndSet(null); 101 | return f == null ? null : Code.wrapThrow(() -> f.get()); 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/com/blazegraph/gremlin/util/Streams.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016. All rights reserved. 3 | 4 | Contact: 5 | SYSTAP, LLC DBA Blazegraph 6 | 2501 Calvert ST NW #106 7 | Washington, DC 20008 8 | licenses@blazegraph.com 9 | 10 | This program is free software; you can redistribute it and/or modify 11 | it under the terms of the GNU General Public License as published by 12 | the Free Software Foundation; version 2 of the License. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; if not, write to the Free Software 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 | */ 23 | package com.blazegraph.gremlin.util; 24 | 25 | import java.util.Iterator; 26 | import java.util.Spliterator; 27 | import java.util.Spliterators; 28 | import java.util.stream.Stream; 29 | import java.util.stream.StreamSupport; 30 | 31 | /** 32 | * Additional Java 8 stream helpers. 33 | * 34 | * @author mikepersonick 35 | */ 36 | public class Streams { 37 | 38 | /** 39 | *

40 | * Obtain a Java 8 stream from an iterator. If the iterator happens to 41 | * implement AutoCloseable (e.g. {@link CloseableIterator}), the stream's 42 | * onClose behavior will close the iterator. Thus it is important to 43 | * always close the returned stream, or use within a try-with-resources: 44 | *

45 | *
46 |      * {@code
47 |      * try (Stream s = Streams.of(it)) {
48 |      *     // do something with s
49 |      * } // auto-close
50 |      * }
51 |      * 
52 |      *
53 |      */
54 |     public static final  Stream of(final Iterator it) {
55 |         final Stream s = StreamSupport.stream(
56 |                 Spliterators.spliteratorUnknownSize(it, Spliterator.ORDERED), false);
57 |         if (it instanceof AutoCloseable) {
58 |             final AutoCloseable closeable = (AutoCloseable) it;
59 |             s.onClose(() -> Code.wrapThrow(() -> closeable.close()));
60 |         }
61 |         return s;
62 |     }
63 |     
64 | }
65 | 


--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/org.apache.tinkerpop.gremlin.groovy.plugin.GremlinPlugin:
--------------------------------------------------------------------------------
1 | com.blazegraph.gremlin.console.BlazeGremlinPlugin


--------------------------------------------------------------------------------
/src/test/java/com/blazegraph/gremlin/structure/BlazeGraphStructureStandardTest.java:
--------------------------------------------------------------------------------
 1 | /**
 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.
 3 | 
 4 | Contact:
 5 |      SYSTAP, LLC DBA Blazegraph
 6 |      2501 Calvert ST NW #106
 7 |      Washington, DC 20008
 8 |      licenses@blazegraph.com
 9 | 
10 | This program is free software; you can redistribute it and/or modify
11 | it under the terms of the GNU General Public License as published by
12 | the Free Software Foundation; version 2 of the License.
13 | 
14 | This program is distributed in the hope that it will be useful,
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 | GNU General Public License for more details.
18 | 
19 | You should have received a copy of the GNU General Public License
20 | along with this program; if not, write to the Free Software
21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 | */
23 | package com.blazegraph.gremlin.structure;
24 | 
25 | import org.apache.tinkerpop.gremlin.GraphProviderClass;
26 | import org.junit.runner.RunWith;
27 | 
28 | import junit.framework.TestCase;
29 | 
30 | /**
31 |  * Run the StructureModifiedSuite, a slightly modified version of Tinkerpop's
32 |  * StructureStandardSuite.
33 |  *  
34 |  * @author mikepersonick
35 |  */
36 | @RunWith(StructureStandardSuite.class)
37 | @GraphProviderClass(provider = EmbeddedBlazeGraphProvider.class, graph = BlazeGraph.class)
38 | public class BlazeGraphStructureStandardTest extends TestCase {}
39 | 


--------------------------------------------------------------------------------
/src/test/java/com/blazegraph/gremlin/structure/EmbeddedBlazeGraphProvider.java:
--------------------------------------------------------------------------------
  1 | /**
  2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.
  3 | 
  4 | Contact:
  5 |      SYSTAP, LLC DBA Blazegraph
  6 |      2501 Calvert ST NW #106
  7 |      Washington, DC 20008
  8 |      licenses@blazegraph.com
  9 | 
 10 | This program is free software; you can redistribute it and/or modify
 11 | it under the terms of the GNU General Public License as published by
 12 | the Free Software Foundation; version 2 of the License.
 13 | 
 14 | This program is distributed in the hope that it will be useful,
 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17 | GNU General Public License for more details.
 18 | 
 19 | You should have received a copy of the GNU General Public License
 20 | along with this program; if not, write to the Free Software
 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 22 | */
 23 | package com.blazegraph.gremlin.structure;
 24 | 
 25 | import java.util.HashMap;
 26 | import java.util.HashSet;
 27 | import java.util.Map;
 28 | import java.util.Set;
 29 | 
 30 | import org.apache.commons.configuration.Configuration;
 31 | import org.apache.tinkerpop.gremlin.AbstractGraphProvider;
 32 | import org.apache.tinkerpop.gremlin.LoadGraphWith;
 33 | import org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData;
 34 | import org.apache.tinkerpop.gremlin.structure.Element;
 35 | import org.apache.tinkerpop.gremlin.structure.Graph;
 36 | 
 37 | import com.bigdata.rdf.sail.BigdataSailRepository;
 38 | import com.blazegraph.gremlin.embedded.BlazeGraphEmbedded;
 39 | 
 40 | /**
 41 |  * Tinkerpop GraphProvider for the TP3 test suites.
 42 |  * 
 43 |  * @author mikepersonick
 44 |  */
 45 | public class EmbeddedBlazeGraphProvider extends AbstractGraphProvider {
 46 | 
 47 |     public static interface Options {
 48 |         
 49 |         String REPOSITORY_NAME = EmbeddedBlazeGraphProvider.class.getName() + ".repositoryName";
 50 |         
 51 |     }
 52 |     
 53 |     @Override
 54 |     public String convertId(Object id, Class c) {
 55 |         return id instanceof String ? (String) id : id.toString();
 56 |     }
 57 | 
 58 |     @Override
 59 |     public void clear(final Graph graph, final Configuration configuration) 
 60 |             throws Exception {
 61 |         if (graph != null) {
 62 |             final BlazeGraphEmbedded blazeGraph = (BlazeGraphEmbedded) graph;
 63 |             blazeGraph.close();
 64 |             blazeGraph.__tearDownUnitTest();
 65 |         }
 66 |     }
 67 | 
 68 |     private static final Set IMPLEMENTATIONS = new HashSet() {{
 69 |         add(BlazeEdge.class);
 70 |         add(BlazeGraph.class);
 71 |         add(BlazeProperty.class);
 72 |         add(BlazeVertex.class);
 73 |         add(BlazeVertexProperty.class);
 74 |     }};
 75 | 
 76 |     @Override
 77 |     public Set getImplementations() {
 78 |         return IMPLEMENTATIONS;
 79 |     }
 80 | 
 81 |     @Override
 82 |     public Map getBaseConfiguration(
 83 |             final String graphName, final Class test, final String testMethodName,
 84 |             final GraphData loadGraphWith) {
 85 |         return new HashMap() {{
 86 |             final String name = graphName+"-"+test.getName()+"-"+testMethodName;
 87 |             put(Options.REPOSITORY_NAME, name);
 88 |             put(Graph.GRAPH, EmbeddedBlazeGraphProvider.class.getName());
 89 |         }};
 90 |     }
 91 |     
 92 |     @Override
 93 |     public void loadGraphData(final Graph graph, final LoadGraphWith loadGraphWith, final Class testClass, final String testName) {
 94 |         if (graph != null) {
 95 |             final BlazeGraphEmbedded blazeGraph = (BlazeGraphEmbedded) graph;
 96 |             blazeGraph.bulkLoad(() -> super.loadGraphData(graph, loadGraphWith, testClass, testName));
 97 |         }
 98 |     }
 99 |     
100 |     public static BlazeGraphEmbedded open(final Configuration config) {
101 |         final String name = config.getString(Options.REPOSITORY_NAME);
102 |         final BigdataSailRepository repo = getRepository(name);
103 |         return BlazeGraphEmbedded.open(repo, config);
104 |     }
105 |     
106 | 
107 |     private static final Map repos = new HashMap<>();
108 |     private static synchronized BigdataSailRepository getRepository(final String name) {
109 |         final String journal;
110 |         if (repos.containsKey(name)) {
111 |             journal = repos.get(name);
112 |         } else {
113 |             repos.put(name, journal = TestRepositoryProvider.tmpJournal());
114 |         }
115 |         return TestRepositoryProvider.open(journal);
116 |     }
117 | 
118 | }
119 | 


--------------------------------------------------------------------------------
/src/test/java/com/blazegraph/gremlin/structure/StructureStandardSuite.java:
--------------------------------------------------------------------------------
  1 | /**
  2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.
  3 | 
  4 | Contact:
  5 |      SYSTAP, LLC DBA Blazegraph
  6 |      2501 Calvert ST NW #106
  7 |      Washington, DC 20008
  8 |      licenses@blazegraph.com
  9 | 
 10 | This program is free software; you can redistribute it and/or modify
 11 | it under the terms of the GNU General Public License as published by
 12 | the Free Software Foundation; version 2 of the License.
 13 | 
 14 | This program is distributed in the hope that it will be useful,
 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17 | GNU General Public License for more details.
 18 | 
 19 | You should have received a copy of the GNU General Public License
 20 | along with this program; if not, write to the Free Software
 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 22 | */
 23 | package com.blazegraph.gremlin.structure;
 24 | 
 25 | import static org.junit.Assert.assertEquals;
 26 | 
 27 | import org.apache.tinkerpop.gremlin.AbstractGremlinSuite;
 28 | import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
 29 | import org.apache.tinkerpop.gremlin.ExceptionCoverage;
 30 | import org.apache.tinkerpop.gremlin.FeatureRequirement;
 31 | import org.apache.tinkerpop.gremlin.FeatureRequirementSet;
 32 | import org.apache.tinkerpop.gremlin.algorithm.generator.CommunityGeneratorTest;
 33 | import org.apache.tinkerpop.gremlin.algorithm.generator.DistributionGeneratorTest;
 34 | import org.apache.tinkerpop.gremlin.process.traversal.TraversalEngine;
 35 | import org.apache.tinkerpop.gremlin.structure.EdgeTest;
 36 | import org.apache.tinkerpop.gremlin.structure.FeatureSupportTest;
 37 | import org.apache.tinkerpop.gremlin.structure.Graph;
 38 | import org.apache.tinkerpop.gremlin.structure.GraphConstructionTest;
 39 | import org.apache.tinkerpop.gremlin.structure.GraphTest;
 40 | import org.apache.tinkerpop.gremlin.structure.PropertyTest;
 41 | import org.apache.tinkerpop.gremlin.structure.SerializationTest;
 42 | import org.apache.tinkerpop.gremlin.structure.TransactionTest;
 43 | import org.apache.tinkerpop.gremlin.structure.VariablesTest;
 44 | import org.apache.tinkerpop.gremlin.structure.Vertex;
 45 | import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 46 | import org.apache.tinkerpop.gremlin.structure.VertexPropertyTest;
 47 | import org.apache.tinkerpop.gremlin.structure.VertexTest;
 48 | import org.apache.tinkerpop.gremlin.structure.io.IoCustomTest;
 49 | import org.apache.tinkerpop.gremlin.structure.io.IoEdgeTest;
 50 | import org.apache.tinkerpop.gremlin.structure.io.IoGraphTest;
 51 | import org.apache.tinkerpop.gremlin.structure.io.IoPropertyTest;
 52 | import org.apache.tinkerpop.gremlin.structure.io.IoTest;
 53 | import org.apache.tinkerpop.gremlin.structure.io.IoVertexTest;
 54 | import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedEdgeTest;
 55 | import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedGraphTest;
 56 | import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedPropertyTest;
 57 | import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexPropertyTest;
 58 | import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexTest;
 59 | import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceEdgeTest;
 60 | import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceGraphTest;
 61 | import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceVertexPropertyTest;
 62 | import org.apache.tinkerpop.gremlin.structure.util.reference.ReferenceVertexTest;
 63 | import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphTest;
 64 | import org.junit.Test;
 65 | import org.junit.experimental.runners.Enclosed;
 66 | import org.junit.runner.RunWith;
 67 | import org.junit.runners.model.InitializationError;
 68 | import org.junit.runners.model.RunnerBuilder;
 69 | 
 70 | import com.blazegraph.gremlin.util.LambdaLogger;
 71 | 
 72 | /**
 73 |  * A modified version of StructureStandardSuite that either does not run or
 74 |  * fixes certain tests that are simply incompatible with the Blaze engine.
 75 |  * Tried to keep this as close to the standard suite as possible.
 76 |  * 
 77 |  * @author mikepersonick
 78 |  */
 79 | public class StructureStandardSuite extends AbstractGremlinSuite {
 80 | 
 81 |     private static final transient LambdaLogger log = LambdaLogger.getLogger(StructureStandardSuite.class);
 82 |     
 83 |     /**
 84 |      * This list of tests in the suite that will be executed.  Gremlin developers should add to this list
 85 |      * as needed to enforce tests upon implementations.
 86 |      */
 87 |     private static final Class[] allTests = new Class[]{
 88 | 
 89 |             ModifiedDetachedGraphTest.class,
 90 |             DetachedEdgeTest.class,
 91 |             DetachedVertexPropertyTest.class,
 92 |             DetachedPropertyTest.class,
 93 |             DetachedVertexTest.class,
 94 |             EdgeTest.class,
 95 |             FeatureSupportTest.class,
 96 |             GraphTest.class,
 97 |             GraphConstructionTest.class,
 98 |             ModifiedVertexPropertyTest.class,
 99 |             VariablesTest.class,
100 |             ModifiedPropertyTest.class,
101 |             ReferenceGraphTest.class,
102 |             ReferenceEdgeTest.class,
103 |             ReferenceVertexPropertyTest.class,
104 |             ReferenceVertexTest.class,
105 |             SerializationTest.class,
106 |             ModifiedStarGraphTest.class,
107 |             VertexTest.class,
108 |             ModifiedTransactionTest.class,
109 |             CommunityGeneratorTest.class,
110 |             DistributionGeneratorTest.class,
111 |             IoCustomTest.class,
112 |             IoEdgeTest.class,
113 |             IoGraphTest.class,
114 |             IoVertexTest.class,
115 |             IoPropertyTest.class,
116 |             IoTest.class,
117 |             
118 |     };
119 | 
120 |     public StructureStandardSuite(final Class klass, final RunnerBuilder builder) throws InitializationError {
121 |         super(klass, builder, allTests, null, false, TraversalEngine.Type.STANDARD);
122 |     }
123 |     
124 | //    public static class DataTest extends AbstractGremlinTest {
125 | //
126 | //        @Test
127 | //        @LoadGraphWith(LoadGraphWith.GraphData.CREW)
128 | //        public void testData() {
129 | //            
130 | ////          System.err.println(bg.dumpStore());
131 | //            try {
132 | //                final BlazeGraphEmbedded bg = (BlazeGraphEmbedded) graph;
133 | //                final RepositoryResult stmts =
134 | //                        bg.getRepository().getUnisolatedConnection().getStatements(null, null, null, false);
135 | //                while (stmts.hasNext()) {
136 | //                    final BigdataStatement stmt = (BigdataStatement) stmts.next();
137 | //                    String s = stmt.toString();
138 | //                    s = s.replace("> : Explicit", " .");
139 | //                    s = s.replace(",", "");
140 | //                    s = s.substring(1);
141 | //                    s = s.replace(RDFS.LABEL.stringValue(), "rdfs:label");
142 | //                    s = s.replace(RDF.VALUE.stringValue(), "rdf:value");
143 | //                    s = s.replace(PackedLongIV.PACKED_LONG.stringValue(), "vocab:packedLong");
144 | //                    s = s.replace(XSD.INT.stringValue(), "xsd:int");
145 | //                    System.err.println(s);
146 | //                }
147 | //                stmts.close();    
148 | //            } catch (Exception e) {
149 | //            }
150 | //            
151 | //        }
152 | //        
153 | //    }
154 |     
155 |     public static class ModifiedTest extends AbstractGremlinTest {
156 |         
157 |     }
158 |     
159 |     public static class ModifiedDetachedGraphTest extends DetachedGraphTest {
160 | 
161 |         /**
162 |          * Superclass is missing feature requirements that was causing this
163 |          * to run even though Blaze does not support user supplied ids for
164 |          * vertex properties or numeric ids for vertices.
165 |          */
166 |         @Override
167 |         @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_NUMERIC_IDS)
168 |         @FeatureRequirement(featureClass = Graph.Features.VertexPropertyFeatures.class, feature = Graph.Features.VertexPropertyFeatures.FEATURE_USER_SUPPLIED_IDS)
169 |         public void testAttachableCreateMethod() {
170 |             super.testAttachableCreateMethod();
171 |         }
172 |         
173 |     }
174 |     
175 |     public static class ModifiedStarGraphTest extends StarGraphTest {
176 |         
177 |         /**
178 |          * Superclass is missing feature requirements that was causing this
179 |          * to run even though Blaze does not support user supplied ids for
180 |          * vertex properties or numeric ids for vertices.
181 |          */
182 |         @Override
183 |         @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_NUMERIC_IDS)
184 |         @FeatureRequirement(featureClass = Graph.Features.VertexPropertyFeatures.class, feature = Graph.Features.VertexPropertyFeatures.FEATURE_USER_SUPPLIED_IDS)
185 |         public void shouldAttachWithCreateMethod() {
186 |         }
187 |         
188 |     }
189 |     
190 |     @ExceptionCoverage(exceptionClass = Vertex.Exceptions.class, methods = {
191 |             "multiplePropertiesExistForProvidedKey",
192 |     })
193 |     @RunWith(Enclosed.class)
194 |     public static class ModifiedVertexPropertyTest extends AbstractGremlinTest { // extends VertexPropertyTest {
195 | 
196 |         public static class ModifiedVertexPropertyProperties extends VertexPropertyTest.VertexPropertyProperties {
197 | 
198 |             /**
199 |              * Superclass asserts equality between blaze's empty property
200 |              * and EmptyProperty, which is a final class. 
201 |              */
202 |             @Test
203 |             @FeatureRequirementSet(FeatureRequirementSet.Package.VERTICES_ONLY)
204 |             @FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_META_PROPERTIES)
205 |             public void shouldReturnEmptyIfNoMetaProperties() {
206 |                 final Vertex v = graph.addVertex();
207 |                 final VertexProperty vp = v.property(VertexProperty.Cardinality.single, "name", "marko");
208 |                 assertEquals(EmptyBlazeProperty.instance(), vp.property("name"));
209 |             }
210 |             
211 |         }
212 | 
213 |         public static class ModifiedVertexPropertyRemoval extends VertexPropertyTest.VertexPropertyRemoval { }
214 | 
215 |         public static class ModifiedVertexPropertyAddition extends VertexPropertyTest.VertexPropertyAddition { }
216 | 
217 |         public static class ModifiedBasicVertexProperty extends VertexPropertyTest.BasicVertexProperty { }
218 | 
219 |     }
220 | 
221 |     @RunWith(Enclosed.class)
222 |     public static class ModifiedPropertyTest /* extends PropertyTest */ {
223 | 
224 |         /**
225 |          * Basic tests for the {@link org.apache.tinkerpop.gremlin.structure.Property} class.
226 |          */
227 |         public static class ModifiedBasicPropertyTest extends PropertyTest.BasicPropertyTest {
228 | 
229 |             /**
230 |              * Superclass asserts equality between blaze's empty vertex property
231 |              * and EmptyVertexProperty, which is a final class. 
232 |              */
233 |             @Test
234 |             @FeatureRequirementSet(FeatureRequirementSet.Package.VERTICES_ONLY)
235 |             public void shouldReturnEmptyPropertyIfKeyNonExistent() {
236 |                 final Vertex v = graph.addVertex("name", "marko");
237 |                 tryCommit(graph, (graph) -> {
238 |                     final Vertex v1 = graph.vertices(v.id()).next();
239 |                     final VertexProperty p = v1.property("nonexistent-key");
240 |                     assertEquals(EmptyBlazeVertexProperty.instance(), p);
241 |                 });
242 |             }
243 |             
244 |         }
245 |         
246 |         public static class ModifiedPropertyFeatureSupportTest extends PropertyTest.PropertyFeatureSupportTest { }
247 | 
248 |         public static class ModifiedPropertyValidationOnAddExceptionConsistencyTest extends PropertyTest.PropertyValidationOnAddExceptionConsistencyTest { }
249 | 
250 |         public static class ModifiedElementGetValueExceptionConsistencyTest extends PropertyTest.ElementGetValueExceptionConsistencyTest { }
251 | 
252 |         public static class ModifiedPropertyValidationOnSetExceptionConsistencyTest extends PropertyTest.PropertyValidationOnSetExceptionConsistencyTest { }
253 | 
254 |     }
255 | 
256 |     /**
257 |      * These three tests attempt to access the unisolated connection from
258 |      * multiple threads and just will not work.
259 |      * 
260 |      * @author mikepersonick
261 |      */
262 |     public static class ModifiedTransactionTest extends TransactionTest {
263 |         
264 |         public void shouldAllowReferenceOfVertexIdOutsideOfOriginalThreadManual() throws Exception { }
265 |         
266 |         public void shouldAllowReferenceOfEdgeIdOutsideOfOriginalThreadManual() throws Exception { }
267 |         
268 |         public void shouldSupportTransactionIsolationCommitCheck() throws Exception { }
269 |         
270 |     }
271 |         
272 | }
273 | 


--------------------------------------------------------------------------------
/src/test/java/com/blazegraph/gremlin/structure/TestBlazeGraph.java:
--------------------------------------------------------------------------------
 1 | /**
 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.
 3 | 
 4 | Contact:
 5 |      SYSTAP, LLC DBA Blazegraph
 6 |      2501 Calvert ST NW #106
 7 |      Washington, DC 20008
 8 |      licenses@blazegraph.com
 9 | 
10 | This program is free software; you can redistribute it and/or modify
11 | it under the terms of the GNU General Public License as published by
12 | the Free Software Foundation; version 2 of the License.
13 | 
14 | This program is distributed in the hope that it will be useful,
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 | GNU General Public License for more details.
18 | 
19 | You should have received a copy of the GNU General Public License
20 | along with this program; if not, write to the Free Software
21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 | */
23 | package com.blazegraph.gremlin.structure;
24 | 
25 | import static java.util.stream.Collectors.toList;
26 | 
27 | import java.util.Collections;
28 | import java.util.List;
29 | import java.util.Map;
30 | import java.util.stream.Stream;
31 | 
32 | import org.openrdf.model.Literal;
33 | import org.openrdf.model.Resource;
34 | import org.openrdf.model.URI;
35 | 
36 | import com.bigdata.rdf.sail.BigdataSailRepository;
37 | import com.bigdata.rdf.sail.BigdataSailRepositoryConnection;
38 | import com.blazegraph.gremlin.embedded.BlazeGraphEmbedded;
39 | import com.blazegraph.gremlin.util.CloseableIterator;
40 | import com.blazegraph.gremlin.util.LambdaLogger;
41 | 
42 | import junit.framework.TestCase;
43 | 
44 | public abstract class TestBlazeGraph extends TestCase {
45 | 
46 |     private final static transient LambdaLogger log = LambdaLogger.getLogger(TestBlazeGraph.class);
47 |     
48 |     protected BlazeGraphEmbedded graph = null;
49 |     
50 |     /**
51 |      * Subclasses can override BasicRepositoryProvider defaults for Blaze
52 |      * properties.
53 |      */
54 |     protected Map overrides() {
55 |         return Collections.emptyMap();
56 |     }
57 |     
58 |     @Override
59 |     public void setUp() throws Exception {
60 |         final BigdataSailRepository repo = TestRepositoryProvider.open(overrides()); 
61 |         this.graph = BlazeGraphEmbedded.open(repo);
62 |     }
63 |     
64 |     @Override
65 |     public void tearDown() throws Exception {
66 |         this.graph.close();
67 |         this.graph.__tearDownUnitTest();
68 |     }
69 |     
70 |     protected boolean hasStatement(final Resource s, final URI p, final Literal o) throws Exception {
71 |         final BigdataSailRepositoryConnection cxn = graph.cxn();
72 |         return cxn.hasStatement(null, p, o, true);
73 |     }
74 |     
75 |     protected  List collect(final CloseableIterator it, final Class cls) {
76 |         try (Stream s = it.stream()) {
77 |             return s.map(cls::cast).collect(toList());
78 |         }
79 |     }
80 |     
81 |     protected long count(final CloseableIterator it) {
82 |         return it.count();
83 |     }
84 |     
85 | }
86 | 


--------------------------------------------------------------------------------
/src/test/java/com/blazegraph/gremlin/structure/TestBulkLoad.java:
--------------------------------------------------------------------------------
  1 | /**
  2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.
  3 | 
  4 | Contact:
  5 |      SYSTAP, LLC DBA Blazegraph
  6 |      2501 Calvert ST NW #106
  7 |      Washington, DC 20008
  8 |      licenses@blazegraph.com
  9 | 
 10 | This program is free software; you can redistribute it and/or modify
 11 | it under the terms of the GNU General Public License as published by
 12 | the Free Software Foundation; version 2 of the License.
 13 | 
 14 | This program is distributed in the hope that it will be useful,
 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17 | GNU General Public License for more details.
 18 | 
 19 | You should have received a copy of the GNU General Public License
 20 | along with this program; if not, write to the Free Software
 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 22 | */
 23 | package com.blazegraph.gremlin.structure;
 24 | 
 25 | import java.util.LinkedList;
 26 | import java.util.List;
 27 | 
 28 | import org.apache.tinkerpop.gremlin.structure.T;
 29 | import org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality;
 30 | 
 31 | import com.blazegraph.gremlin.listener.BlazeGraphEdit;
 32 | import com.blazegraph.gremlin.listener.BlazeGraphEdit.Action;
 33 | 
 34 | /**
 35 |  * Bulk load API tests.
 36 |  * 
 37 |  * @author mikepersonick
 38 |  */
 39 | public class TestBulkLoad extends TestBlazeGraph {
 40 | 
 41 |     public void testBulkLoad1() {
 42 |         
 43 |         final List edits = new LinkedList<>();
 44 |         graph.addListener((edit,rdfEdit) -> edits.add(edit));
 45 |         
 46 |         final BlazeVertex a = graph.addVertex(T.id, "a");
 47 |         graph.bulkLoad(() -> {
 48 |             /*
 49 |              * In incremental update mode Cardinality.single would clean old
 50 |              * values when a new value is set.  If bulk load is working we
 51 |              * should see three values and no removes.  Breaks the semantics
 52 |              * of Cardinality.single which is why bulk load should be used with
 53 |              * care.
 54 |              */
 55 |             a.property(Cardinality.single, "key", "v1");
 56 |             a.property(Cardinality.single, "key", "v2");
 57 |             a.property(Cardinality.single, "key", "v3");
 58 |         });
 59 |         graph.commit();
 60 |         
 61 |         // bulk load should be off again
 62 |         assertFalse(graph.isBulkLoad());
 63 |         // three properties
 64 |         assertEquals(3, a.properties().count());
 65 |         // zero removes
 66 |         assertEquals(0, edits.stream().filter(e -> e.getAction() == Action.Remove).count());
 67 |         
 68 |     }
 69 | 
 70 |     public void testBulkLoad2() {
 71 |         
 72 |         final List edits = new LinkedList<>();
 73 |         graph.addListener((edit,rdfEdit) -> edits.add(edit));
 74 |         
 75 |         final BlazeVertex a = graph.addVertex(T.id, "a");
 76 |         graph.setBulkLoad(true);
 77 |         /*
 78 |          * In incremental update mode Cardinality.single would clean old
 79 |          * values when a new value is set.  If bulk load is working we
 80 |          * should see three values and no removes.  Breaks the semantics
 81 |          * of Cardinality.single which is why bulk load should be used with
 82 |          * care.
 83 |          */
 84 |         a.property(Cardinality.single, "key", "v1");
 85 |         a.property(Cardinality.single, "key", "v2");
 86 |         a.property(Cardinality.single, "key", "v3");
 87 |         graph.commit();
 88 |         graph.setBulkLoad(false);
 89 |         
 90 |         // bulk load should be off again
 91 |         assertFalse(graph.isBulkLoad());
 92 |         // three properties
 93 |         assertEquals(3, a.properties().count());
 94 |         // zero removes
 95 |         assertEquals(0, edits.stream().filter(e -> e.getAction() == Action.Remove).count());
 96 |         
 97 |     }
 98 | 
 99 | }
100 | 


--------------------------------------------------------------------------------
/src/test/java/com/blazegraph/gremlin/structure/TestHistory.java:
--------------------------------------------------------------------------------
  1 | /**
  2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.
  3 | 
  4 | Contact:
  5 |      SYSTAP, LLC DBA Blazegraph
  6 |      2501 Calvert ST NW #106
  7 |      Washington, DC 20008
  8 |      licenses@blazegraph.com
  9 | 
 10 | This program is free software; you can redistribute it and/or modify
 11 | it under the terms of the GNU General Public License as published by
 12 | the Free Software Foundation; version 2 of the License.
 13 | 
 14 | This program is distributed in the hope that it will be useful,
 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17 | GNU General Public License for more details.
 18 | 
 19 | You should have received a copy of the GNU General Public License
 20 | along with this program; if not, write to the Free Software
 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 22 | */
 23 | package com.blazegraph.gremlin.structure;
 24 | 
 25 | import java.util.List;
 26 | 
 27 | import org.apache.tinkerpop.gremlin.structure.Edge;
 28 | import org.apache.tinkerpop.gremlin.structure.T;
 29 | import org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality;
 30 | 
 31 | import com.blazegraph.gremlin.listener.BlazeGraphEdit;
 32 | import com.blazegraph.gremlin.util.LambdaLogger;
 33 | 
 34 | public class TestHistory extends TestBlazeGraph {
 35 | 
 36 |     private final static transient LambdaLogger log = LambdaLogger.getLogger(TestHistory.class);
 37 |     
 38 |     public void testVertexHistory() throws Exception {
 39 |         
 40 |         final BlazeVertex a = graph.addVertex(T.id, "a");
 41 |         final BlazeVertex b = graph.addVertex(T.id, "b");
 42 |         graph.commit();
 43 |         
 44 |         log.debug(() -> "\n"+graph.dumpStore());
 45 |         assertEquals(4, graph.historicalStatementCount());
 46 |         assertEquals(2, graph.vertexCount());
 47 |         countEdits(2, "a", "b");
 48 |         
 49 |         a.remove();
 50 |         graph.commit();
 51 |         
 52 |         log.debug(() -> "\n"+graph.dumpStore());
 53 |         assertEquals(5, graph.historicalStatementCount());
 54 |         assertEquals(1, graph.vertexCount());
 55 |         countEdits(2, "a");
 56 |         
 57 |         b.remove();
 58 |         graph.commit();
 59 |         
 60 |         log.debug(() -> "\n"+graph.dumpStore());
 61 |         assertEquals(6, graph.historicalStatementCount());
 62 |         assertEquals(0, graph.vertexCount());
 63 |         countEdits(2, "b");
 64 |         
 65 |         final List edits = graph.history("a", "b").collect();
 66 |         log.debug(() -> edits.stream());
 67 |         assertEquals(4, edits.size());
 68 |         
 69 |     }
 70 | 
 71 |     public void testVertexPropertyHistory() throws Exception {
 72 |         
 73 |         final BlazeVertex a = graph.addVertex(T.id, "a");
 74 |         final BlazeVertexProperty _1 = a.property(Cardinality.set, "foo", 1, "acl", "public");
 75 |         final BlazeVertexProperty _2 = a.property(Cardinality.set, "foo", 2, "acl", "private");
 76 | //        final BlazeVertex b = graph.addVertex(T.id, "b");
 77 |         graph.commit();
 78 |         
 79 |         log.debug(() -> "\n"+graph.dumpStore());
 80 |         assertEquals(10, graph.historicalStatementCount());
 81 |         assertEquals(1, graph.vertexCount());
 82 |         assertEquals(2, a.properties().count());
 83 |         assertEquals(1, _1.properties().count());
 84 |         assertEquals(1, _2.properties().count());
 85 | 
 86 |         _1.properties().forEachRemaining(p -> p.remove());
 87 |         graph.commit();
 88 |         log.debug(() -> "\n"+graph.dumpStore());
 89 |         assertEquals(11, graph.historicalStatementCount());
 90 |         assertEquals(1, graph.vertexCount());
 91 |         assertEquals(2, a.properties().count());
 92 |         assertEquals(0, _1.properties().count());
 93 |         assertEquals(1, _2.properties().count());
 94 |         
 95 |         countEdits(3, "a");
 96 |         
 97 |         try {
 98 |             graph.history(_1.id(), _2.id());
 99 |             fail("History not supported for VertexProperty elements");
100 |         } catch (IllegalArgumentException ex) {}
101 |         
102 |         _2.remove();
103 |         graph.commit();
104 |         log.debug(() -> "\n"+graph.dumpStore());
105 |         assertEquals(13, graph.historicalStatementCount());
106 |         assertEquals(1, graph.vertexCount());
107 |         assertEquals(1, a.properties().count());
108 |         countEdits(4, "a");
109 |         
110 |         a.remove();
111 |         graph.commit();
112 |         log.debug(() -> "\n"+graph.dumpStore());
113 |         assertEquals(15, graph.historicalStatementCount());
114 |         assertEquals(0, graph.vertexCount());
115 |         countEdits(6, "a");
116 |         
117 |     }
118 |     
119 |     public void testEdgeHistory() throws Exception {
120 |         
121 |         final BlazeVertex a = graph.addVertex(T.id, "a");
122 |         final BlazeVertex b = graph.addVertex(T.id, "b");
123 |         final BlazeEdge e = graph.addEdge(a, b, Edge.DEFAULT_LABEL, T.id, "e", "key", "val");
124 |         graph.commit();
125 |         
126 |         log.debug(() -> "\n"+graph.dumpStore());
127 |         assertEquals(10, graph.historicalStatementCount());
128 |         countEdits(1, a.id());
129 |         countEdits(1, b.id());
130 |         countEdits(2, e.id());
131 |         
132 |         e.properties().forEachRemaining(p -> p.remove());
133 |         graph.commit();
134 |         log.debug(() -> "\n"+graph.dumpStore());
135 |         assertEquals(11, graph.historicalStatementCount());
136 |         countEdits(1, a.id());
137 |         countEdits(1, b.id());
138 |         countEdits(3, e.id());
139 | 
140 |         e.remove();
141 |         graph.commit();
142 |         log.debug(() -> "\n"+graph.dumpStore());
143 |         assertEquals(13, graph.historicalStatementCount());
144 |         countEdits(1, a.id());
145 |         countEdits(1, b.id());
146 |         countEdits(4, e.id());
147 |         
148 |     }
149 |     
150 |     private void countEdits(final int expected, final String... ids) {
151 |         final List edits = graph.history(ids).collect();
152 |         log.debug(() -> edits.stream());
153 |         assertEquals(expected, edits.size());
154 |     }
155 | 
156 | }
157 | 


--------------------------------------------------------------------------------
/src/test/java/com/blazegraph/gremlin/structure/TestListeners.java:
--------------------------------------------------------------------------------
  1 | /**
  2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.
  3 | 
  4 | Contact:
  5 |      SYSTAP, LLC DBA Blazegraph
  6 |      2501 Calvert ST NW #106
  7 |      Washington, DC 20008
  8 |      licenses@blazegraph.com
  9 | 
 10 | This program is free software; you can redistribute it and/or modify
 11 | it under the terms of the GNU General Public License as published by
 12 | the Free Software Foundation; version 2 of the License.
 13 | 
 14 | This program is distributed in the hope that it will be useful,
 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17 | GNU General Public License for more details.
 18 | 
 19 | You should have received a copy of the GNU General Public License
 20 | along with this program; if not, write to the Free Software
 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 22 | */
 23 | package com.blazegraph.gremlin.structure;
 24 | 
 25 | import java.util.LinkedList;
 26 | import java.util.List;
 27 | 
 28 | import org.apache.tinkerpop.gremlin.structure.Edge;
 29 | import org.apache.tinkerpop.gremlin.structure.T;
 30 | import org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality;
 31 | 
 32 | import com.blazegraph.gremlin.listener.BlazeGraphEdit;
 33 | import com.blazegraph.gremlin.util.LambdaLogger;
 34 | 
 35 | public class TestListeners extends TestBlazeGraph {
 36 | 
 37 |     private final static transient LambdaLogger log = LambdaLogger.getLogger(TestListeners.class);
 38 |     
 39 |     public void testVertices() throws Exception {
 40 |         
 41 |         final List edits = new LinkedList<>();
 42 |         graph.addListener((edit,rdfEdit) -> edits.add(edit));
 43 |         
 44 |         final BlazeVertex a = graph.addVertex(T.id, "a");
 45 |         final BlazeVertex b = graph.addVertex(T.id, "b");
 46 |         graph.commit();
 47 |         
 48 |         log.debug(() -> "\n"+graph.dumpStore());
 49 |         log.debug(() -> edits.stream());
 50 | //        assertEquals(2, graph.statementCount());
 51 |         assertEquals(2, graph.vertexCount());
 52 |         assertEquals(2, edits.size());
 53 | 
 54 |         a.remove();
 55 |         graph.commit();
 56 |         
 57 |         log.debug(() -> "\n"+graph.dumpStore());
 58 |         log.debug(() -> edits.stream());
 59 | //        assertEquals(1, graph.statementCount());
 60 |         assertEquals(1, graph.vertexCount());
 61 |         assertEquals(3, edits.size());
 62 |         
 63 |         b.remove();
 64 |         graph.commit();
 65 |         
 66 |         log.debug(() -> "\n"+graph.dumpStore());
 67 |         log.debug(() -> edits.stream());
 68 | //        assertEquals(0, graph.statementCount());
 69 |         assertEquals(0, graph.vertexCount());
 70 |         assertEquals(4, edits.size());
 71 |         
 72 |         
 73 |     }
 74 | 
 75 |     public void testVertexProperties() throws Exception {
 76 |         
 77 |         final List edits = new LinkedList<>();
 78 |         graph.addListener((edit,rdfEdit) -> edits.add(edit));
 79 |         
 80 |         final BlazeVertex a = graph.addVertex(T.id, "a");
 81 |         final BlazeVertexProperty _1 = a.property(Cardinality.set, "foo", 1, "acl", "public");
 82 |         final BlazeVertexProperty _2 = a.property(Cardinality.set, "foo", 2, "acl", "private");
 83 | //        final BlazeVertex b = graph.addVertex(T.id, "b");
 84 |         graph.commit();
 85 |         
 86 |         log.debug(() -> "\n"+graph.dumpStore());
 87 |         log.debug(() -> edits.stream());
 88 | //        assertEquals(5, graph.statementCount());
 89 |         assertEquals(1, graph.vertexCount());
 90 |         assertEquals(2, a.properties().count());
 91 |         assertEquals(1, _1.properties().count());
 92 |         assertEquals(1, _2.properties().count());
 93 |         assertEquals(5, edits.size());
 94 | 
 95 |         _1.properties().forEachRemaining(p -> p.remove());
 96 |         graph.commit();
 97 |         log.debug(() -> "\n"+graph.dumpStore());
 98 |         log.debug(() -> edits.stream());
 99 | //        assertEquals(4, graph.statementCount());
100 |         assertEquals(1, graph.vertexCount());
101 |         assertEquals(2, a.properties().count());
102 |         assertEquals(0, _1.properties().count());
103 |         assertEquals(1, _2.properties().count());
104 |         assertEquals(6, edits.size());
105 |         
106 |         _2.remove();
107 |         graph.commit();
108 |         log.debug(() -> "\n"+graph.dumpStore());
109 |         log.debug(() -> edits.stream());
110 | //        assertEquals(2, graph.statementCount());
111 |         assertEquals(1, graph.vertexCount());
112 |         assertEquals(1, a.properties().count());
113 |         assertEquals(8, edits.size());
114 |         
115 |         a.remove();
116 |         graph.commit();
117 |         log.debug(() -> "\n"+graph.dumpStore());
118 |         log.debug(() -> edits.stream());
119 | //        assertEquals(0, graph.statementCount());
120 |         assertEquals(0, graph.vertexCount());
121 |         assertEquals(10, edits.size());
122 |         
123 |     }
124 |     
125 |     public void testEdges() throws Exception {
126 |         
127 |         final List edits = new LinkedList<>();
128 |         graph.addListener((edit,rdfEdit) -> {
129 |             log.debug(() -> rdfEdit);
130 |             edits.add(edit);
131 |         });
132 |         
133 |         final BlazeVertex a = graph.addVertex(T.id, "a");
134 |         final BlazeVertex b = graph.addVertex(T.id, "b");
135 |         final BlazeEdge e = graph.addEdge(a, b, Edge.DEFAULT_LABEL, T.id, "e", "key", "val");
136 |         graph.commit();
137 |         
138 |         log.debug(() -> "\n"+graph.dumpStore());
139 |         log.debug(() -> edits.stream());
140 | //        assertEquals(5, graph.statementCount());
141 |         assertEquals(4, edits.size());
142 |         
143 |         e.properties().forEachRemaining(p -> p.remove());
144 |         graph.commit();
145 |         log.debug(() -> "\n"+graph.dumpStore());
146 |         log.debug(() -> edits.stream());
147 | //        assertEquals(4, graph.statementCount());
148 |         assertEquals(5, edits.size());
149 | 
150 |         e.remove();
151 |         graph.commit();
152 |         log.debug(() -> "\n"+graph.dumpStore());
153 |         log.debug(() -> edits.stream());
154 | //        assertEquals(2, graph.statementCount());
155 |         assertEquals(6, edits.size());
156 |         
157 |     }
158 |     
159 | }
160 | 


--------------------------------------------------------------------------------
/src/test/java/com/blazegraph/gremlin/structure/TestRepositoryProvider.java:
--------------------------------------------------------------------------------
 1 | /**
 2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.
 3 | 
 4 | Contact:
 5 |      SYSTAP, LLC DBA Blazegraph
 6 |      2501 Calvert ST NW #106
 7 |      Washington, DC 20008
 8 |      licenses@blazegraph.com
 9 | 
10 | This program is free software; you can redistribute it and/or modify
11 | it under the terms of the GNU General Public License as published by
12 | the Free Software Foundation; version 2 of the License.
13 | 
14 | This program is distributed in the hope that it will be useful,
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 | GNU General Public License for more details.
18 | 
19 | You should have received a copy of the GNU General Public License
20 | along with this program; if not, write to the Free Software
21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 | */
23 | package com.blazegraph.gremlin.structure;
24 | 
25 | import java.io.File;
26 | import java.util.Map;
27 | import java.util.Properties;
28 | 
29 | import com.bigdata.rdf.sail.BigdataSailRepository;
30 | import com.blazegraph.gremlin.embedded.BasicRepositoryProvider;
31 | import com.blazegraph.gremlin.util.Code;
32 | 
33 | /**
34 |  * Extension of BasicRepositoryProvider for test cases.
35 |  * 
36 |  * @author mikepersonick
37 |  */
38 | public class TestRepositoryProvider extends BasicRepositoryProvider {
39 | 
40 |     /**
41 |      * Create a tmp journal file for test cases.
42 |      * 
43 |      * @return
44 |      *      absolute path of journal file
45 |      */
46 |     public static String tmpJournal() {
47 |         final File file = Code.wrapThrow(() -> File.createTempFile("EmbeddedBlazeGraphProvider", ".jnl"));
48 |         file.deleteOnExit();
49 |         return file.getAbsolutePath();
50 |     }
51 |     
52 |     /**
53 |      * Open with default configuration and a tmp journal file.
54 |      * 
55 |      * @return
56 |      *          an open and initialized Blaze repository
57 |      */
58 |     public static BigdataSailRepository open() {
59 |         final Properties props = getProperties(tmpJournal());
60 |         return open(props);
61 |     }
62 |     
63 |     /**
64 |      * Open with default configuration and a tmp journal file, overriding the
65 |      * default config as specified.
66 |      * 
67 |      * @return
68 |      *          an open and initialized Blaze repository
69 |      */
70 |     public static BigdataSailRepository open(final Map overrides) {
71 |         final Properties props = getProperties(tmpJournal());
72 |         overrides.entrySet().forEach(e -> {
73 |             if (e.getValue() != null) {
74 |                 props.setProperty(e.getKey(), e.getValue());
75 |             } else {
76 |                 props.remove(e.getKey());
77 |             }
78 |         });
79 |         return open(props);
80 |     }
81 |     
82 | }
83 | 


--------------------------------------------------------------------------------
/src/test/java/com/blazegraph/gremlin/structure/TestSearch.java:
--------------------------------------------------------------------------------
  1 | /**
  2 | Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.
  3 | 
  4 | Contact:
  5 |      SYSTAP, LLC DBA Blazegraph
  6 |      2501 Calvert ST NW #106
  7 |      Washington, DC 20008
  8 |      licenses@blazegraph.com
  9 | 
 10 | This program is free software; you can redistribute it and/or modify
 11 | it under the terms of the GNU General Public License as published by
 12 | the Free Software Foundation; version 2 of the License.
 13 | 
 14 | This program is distributed in the hope that it will be useful,
 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 17 | GNU General Public License for more details.
 18 | 
 19 | You should have received a copy of the GNU General Public License
 20 | along with this program; if not, write to the Free Software
 21 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 22 | */
 23 | package com.blazegraph.gremlin.structure;
 24 | 
 25 | import java.util.HashMap;
 26 | import java.util.List;
 27 | import java.util.Map;
 28 | 
 29 | import org.apache.tinkerpop.gremlin.structure.Edge;
 30 | import org.apache.tinkerpop.gremlin.structure.Property;
 31 | import org.apache.tinkerpop.gremlin.structure.T;
 32 | import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 33 | import org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality;
 34 | 
 35 | import com.blazegraph.gremlin.structure.BlazeGraph.Match;
 36 | import com.blazegraph.gremlin.util.LambdaLogger;
 37 | 
 38 | public class TestSearch extends TestBlazeGraph {
 39 | 
 40 |     private final static transient LambdaLogger log = LambdaLogger.getLogger(TestSearch.class);
 41 | 
 42 | //    @Override
 43 | //    protected Map overrides() {
 44 | //        return new HashMap() {{
 45 | //            put(AbstractTripleStore.Options.RDR_HISTORY_CLASS, null);
 46 | //        }};
 47 | //    }
 48 | 
 49 |     /**
 50 |      * Make sure we can find all five kinds of properties:
 51 |      * 

52 | *

 53 |      * Edge -> Property
 54 |      * Vertex -> VertexProperty(single/set)
 55 |      * Vertex -> VertexProperty(list)
 56 |      * VertexProperty(single/set) -> Property
 57 |      * VertexProperty(list) -> Property
 58 |      * 
59 | *

60 | */ 61 | public void testAllFiveKinds() { 62 | 63 | final BlazeVertex a = graph.addVertex(T.id, "a"); 64 | final BlazeVertex b = graph.addVertex(T.id, "b"); 65 | final BlazeEdge e = graph.addEdge(a, b, Edge.DEFAULT_LABEL, T.id, "e"); 66 | 67 | final Property ep = e.property("ep", "foo 1"); 68 | final VertexProperty vps = a.property(Cardinality.single, "vps", "foo 2"); 69 | final VertexProperty vpl = a.property(Cardinality.list, "vpl", "foo 3"); 70 | final Property vpsp = vps.property("vpsp", "foo 4"); 71 | final Property vplp = vpl.property("vplp", "foo 5"); 72 | graph.commit(); 73 | 74 | final Map> expected = 75 | new HashMap>() {{ 76 | put("foo 1", ep); 77 | put("foo 2", vps); 78 | put("foo 3", vpl); 79 | put("foo 4", vpsp); 80 | put("foo 5", vplp); 81 | }}; 82 | 83 | log.debug(() -> "\n"+graph.dumpStore()); 84 | 85 | final List> results = 86 | graph.search("foo", Match.ANY).collect(); 87 | log.debug(() -> results.stream()); 88 | assertEquals(5, results.size()); 89 | results.stream().forEach(p -> { 90 | assertEquals(expected.get(p.value()), p); 91 | }); 92 | 93 | } 94 | 95 | /** 96 | * Test for Match.ANY/ALL/EXACT. 97 | */ 98 | public void testMatchEnum() { 99 | 100 | final VertexProperty any = graph.addVertex(T.id, "any").property(Cardinality.set, "key", "foo"); 101 | final VertexProperty all = graph.addVertex(T.id, "all").property(Cardinality.set, "key", "foo bar"); 102 | final VertexProperty exact = graph.addVertex(T.id, "exact").property(Cardinality.set, "key", "bar foo"); 103 | graph.commit(); 104 | 105 | log.debug(() -> "\n"+graph.dumpStore()); 106 | 107 | { 108 | final List> results = 109 | graph.search("bar foo", Match.ANY).collect(); 110 | log.debug(() -> results.stream()); 111 | assertEquals(3, results.size()); 112 | assertTrue(results.contains(any)); 113 | assertTrue(results.contains(all)); 114 | assertTrue(results.contains(exact)); 115 | } 116 | 117 | { 118 | final List> results = 119 | graph.search("bar foo", Match.ALL).collect(); 120 | log.debug(() -> results.stream()); 121 | assertEquals(2, results.size()); 122 | assertTrue(results.contains(all)); 123 | assertTrue(results.contains(exact)); 124 | } 125 | 126 | { 127 | final List> results = 128 | graph.search("bar foo", Match.EXACT).collect(); 129 | log.debug(() -> results.stream()); 130 | assertEquals(1, results.size()); 131 | assertTrue(results.contains(exact)); 132 | } 133 | 134 | } 135 | 136 | } 137 | -------------------------------------------------------------------------------- /src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | ## 2 | # This is the default log4j configuration for distribution and CI tests. 3 | ## 4 | 5 | # Note: logging at INFO or DEBUG will significantly impact throughput! 6 | log4j.rootCategory=WARN, dest2 7 | 8 | # Use the lambda logger for conditional logging 9 | #log4j.loggerFactory=com.blazegraph.gremlin.util.LambdaLoggerFactory 10 | 11 | log4j.logger.com.bigdata=ERROR 12 | log4j.logger.com.bigdata.Banner=ERROR 13 | log4j.logger.com.bigdata.util.MillisecondTimestampFactory=ERROR 14 | log4j.logger.com.bigdata.rdf.ServiceProviderHook=ERROR 15 | log4j.logger.com.bigdata.btree=WARN 16 | log4j.logger.com.bigdata.counters.History=ERROR 17 | log4j.logger.com.bigdata.counters.XMLUtility$MyHandler=ERROR 18 | log4j.logger.com.bigdata.counters.query.CounterSetQuery=INFO 19 | log4j.logger.com.bigdata.journal.CompactTask=INFO 20 | log4j.logger.com.bigdata.relation.accesspath.BlockingBuffer=ERROR 21 | log4j.logger.com.bigdata.rdf.load=INFO 22 | log4j.logger.com.bigdata.rdf.store.DataLoader=INFO 23 | log4j.logger.com.bigdata.resources.AsynchronousOverflowTask=INFO 24 | 25 | log4j.logger.info.aduna.lang.service.ServiceRegistry=ERROR 26 | log4j.logger.org.openrdf.rio=ERROR 27 | log4j.logger.org.openrdf.query.resultio=ERROR 28 | #log4j.logger.com.bigdata.txLog=INFO 29 | 30 | #log4j.logger.com.blazegraph.gremlin=ALL 31 | #og4j.logger.com.blazegraph.gremlin.structure.BlazeGraph=DEBUG 32 | #log4j.logger.com.blazegraph.gremlin.structure.BlazeGraph.SparqlLog=TRACE 33 | #log4j.logger.com.blazegraph.gremlin.structure.StructureStandardSuite=ALL 34 | #log4j.logger.com.blazegraph.gremlin.structure.TestBasicOperations=ALL 35 | #log4j.logger.com.blazegraph.gremlin.structure.TestHistory=ALL 36 | #log4j.logger.com.blazegraph.gremlin.structure.TestListeners=ALL 37 | #log4j.logger.com.blazegraph.gremlin.structure.TestSearch=ALL 38 | log4j.logger.com.blazegraph.gremlin.structure.SampleCode=ALL 39 | 40 | 41 | # Test suite loggers. 42 | #log4j.logger.junit=INFO 43 | #log4j.logger.com.bigdata.btree.AbstractBTreeTestCase=INFO 44 | log4j.logger.junit.framework.TestCase2=ERROR 45 | 46 | # dest1 47 | log4j.appender.dest1=org.apache.log4j.ConsoleAppender 48 | log4j.appender.dest1.layout=org.apache.log4j.PatternLayout 49 | log4j.appender.dest1.layout.ConversionPattern=%-5p: %r %l: %m%n 50 | #log4j.appender.dest1.layout.ConversionPattern=%-5p: %m%n 51 | #log4j.appender.dest1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n 52 | #log4j.appender.dest1.layout.ConversionPattern=%-4r(%d) [%t] %-5p %c(%l:%M) %x - %m%n 53 | 54 | # dest2 includes the thread name and elapsed milliseconds. 55 | # Note: %r is elapsed milliseconds. 56 | # Note: %t is the thread name. 57 | # See http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PatternLayout.html 58 | log4j.appender.dest2=org.apache.log4j.ConsoleAppender 59 | log4j.appender.dest2.layout=org.apache.log4j.PatternLayout 60 | log4j.appender.dest2.layout.ConversionPattern=%-5p: %r %X{hostname} %X{serviceUUID} %X{taskname} %X{timestamp} %X{resources} %t %l: %m%n 61 | 62 | ## destPlain 63 | #log4j.appender.destPlain=org.apache.log4j.ConsoleAppender 64 | #log4j.appender.destPlain.layout=org.apache.log4j.PatternLayout 65 | #log4j.appender.destPlain.layout.ConversionPattern= 66 | 67 | ## 68 | # Summary query evaluation log (tab delimited file). 69 | #log4j.logger.com.bigdata.bop.engine.QueryLog=INFO,queryLog 70 | log4j.additivity.com.bigdata.bop.engine.QueryLog=false 71 | log4j.appender.queryLog=org.apache.log4j.FileAppender 72 | log4j.appender.queryLog.Threshold=ALL 73 | log4j.appender.queryLog.File=queryLog.csv 74 | log4j.appender.queryLog.Append=true 75 | # I find that it is nicer to have this unbuffered since you can see what 76 | # is going on and to make sure that I have complete rule evaluation logs 77 | # on shutdown. 78 | log4j.appender.queryLog.BufferedIO=false 79 | log4j.appender.queryLog.layout=org.apache.log4j.PatternLayout 80 | log4j.appender.queryLog.layout.ConversionPattern=%m 81 | 82 | ## 83 | # BOp run state trace (tab delimited file). Uncomment the next line to enable. 84 | #log4j.logger.com.bigdata.bop.engine.RunState$TableLog=INFO,queryRunStateLog 85 | log4j.additivity.com.bigdata.bop.engine.RunState$TableLog=false 86 | log4j.appender.queryRunStateLog=org.apache.log4j.FileAppender 87 | log4j.appender.queryRunStateLog.Threshold=ALL 88 | log4j.appender.queryRunStateLog.File=queryRunState.log 89 | log4j.appender.queryRunStateLog.Append=true 90 | # I find that it is nicer to have this unbuffered since you can see what 91 | # is going on and to make sure that I have complete rule evaluation logs 92 | # on shutdown. 93 | log4j.appender.queryRunStateLog.BufferedIO=false 94 | log4j.appender.queryRunStateLog.layout=org.apache.log4j.PatternLayout 95 | log4j.appender.queryRunStateLog.layout.ConversionPattern=%m 96 | --------------------------------------------------------------------------------