├── .gitignore ├── CHANGES.txt ├── LICENSE.txt ├── LICENSES.txt ├── NOTICE.txt ├── README.md ├── pom.xml └── src ├── main └── javascript │ ├── neo4j │ ├── Events.js │ ├── GraphDatabase.js │ ├── GraphDatabaseHeartbeat.js │ ├── GraphDatabaseManager.js │ ├── Promise.js │ ├── Service.js │ ├── Web.js │ ├── __init__.js │ ├── cachedFunction.js │ ├── cypher │ │ ├── ExecutionEngine.js │ │ ├── QueryResult.js │ │ ├── ResultRow.js │ │ └── __init__.js │ ├── exceptions │ │ ├── ConnectionLostException.js │ │ ├── HttpException.js │ │ ├── InvalidDataException.js │ │ ├── NotFoundException.js │ │ ├── StartNodeSameAsEndNodeException.js │ │ └── __init__.js │ ├── index │ │ ├── Index.js │ │ ├── Indexes.js │ │ ├── NodeIndex.js │ │ ├── RelationshipIndex.js │ │ └── __init__.js │ ├── log.js │ ├── models │ │ ├── JMXBean.js │ │ ├── Node.js │ │ ├── Path.js │ │ ├── PropertyContainer.js │ │ ├── Relationship.js │ │ └── __init__.js │ ├── proxy.js │ ├── services │ │ ├── BackupService.js │ │ ├── ConfigService.js │ │ ├── ConsoleService.js │ │ ├── ExportService.js │ │ ├── ImportService.js │ │ ├── JmxService.js │ │ ├── LifecycleService.js │ │ ├── MonitorService.js │ │ └── __init__.js │ ├── setInterval.js │ └── setTimeout.js │ └── underscore.js └── test ├── browser └── index.html └── javascript └── neo4j ├── GraphDatabaseTestCase.js ├── MockWebProvider.js ├── PromiseTestCase.js ├── WebTestCase.js ├── index ├── IndexTestCase.js ├── IndexesTestCase.js └── NodeIndexTestCase.js └── models ├── NodeTestCase.js ├── PropertyContainerTestCase.js └── RelationshipTestCase.js /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | \#* 3 | */target/ 4 | /target/ 5 | *.swp 6 | .project 7 | .classpath 8 | .settings 9 | *.iws 10 | *.ipr 11 | *.iml 12 | .idea/ 13 | .DS_Store 14 | -------------------------------------------------------------------------------- /CHANGES.txt: -------------------------------------------------------------------------------- 1 | 0.1 (2010-11-04) 2 | ---------------- 3 | 4 | o Initial release with only basic functionality. 5 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | Neo4j 2 | Copyright © 2002-2011 Network Engine for Objects in Lund AB (referred to 3 | in this notice as “Neo Technology”) 4 | [http://neotechnology.com] 5 | 6 | This product includes software ("Software") developed by Neo Technology. 7 | 8 | The copyright in the bundled Neo4j bundled graph database (including the 9 | Software) is owned by Neo Technology. The Software developed and owned 10 | by Neo Technology is licensed under the GNU GENERAL PUBLIC LICENSE 11 | Version 3 (http://www.fsf.org/licensing/licenses/gpl-3.0.html) ("GPL") 12 | to all third parties and that license, as required by the GPL, is 13 | included in the LICENSE.txt file. 14 | 15 | However, if you have executed an End User Software License and Services 16 | Agreement or an OEM Software License and Support Services Agreement, or 17 | another commercial license agreement with Neo Technology or one of its 18 | affiliates (each, a "Commercial Agreement"), the terms of the license in 19 | such Commercial Agreement will supersede the GPL and you may use the 20 | software solely pursuant to the terms of the relevant Commercial 21 | Agreement. 22 | 23 | Third party libraries 24 | --------------------- 25 | 26 | The bundled jQuery library is copyright 2010, John Resig 27 | and dual licensed under the MIT or GPL Version 2 licenses. 28 | http://jquery.org/license 29 | 30 | The bundled SIzzle.js library is copyright 2010, 31 | The Dojo Foundation and released under the MIT, BSD, 32 | and GPL Licenses. 33 | http://sizzlejs.com/ 34 | 35 | The bundled QUnit library is copyright (c) 2009 John Resig, 36 | Jörn Zaefferer and dual licensed under the MIT and GPL licenses. 37 | http://docs.jquery.com/Qunit 38 | 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## NOTE: This is no longer maintained 2 | 3 | Please see https://github.com/neo4j/neo4j-javascript-driver for a modern Neo4j JS Driver 4 | 5 | Neo4j server client for JavaScript 6 | ================================= 7 | 8 | The beginnings of a neo4j server client for client-side javascript. 9 | 10 | Quick example 11 | ------------- 12 | 13 | Neo4js makes heavy use of promises (also known as futures), methods that make calls to the database usually return a promise 14 | for a result of some kind. 15 | 16 | For instance: 17 | 18 | var nodePromise = graph.node("http://localhost:75"); 19 | nodePromise.then(function(node) { 20 | // Do something with the node. 21 | }); 22 | 23 | // Or just 24 | graph.node(0). 25 | 26 | Example usage: 27 | 28 | var graph = new neo4j.GraphDatabase("http://localhost:7474"); 29 | 30 | var lisaPromise = graph.node({ "name" : "Lisa" }); 31 | var bobPromise = graph.node({ "name" : "Bob" }); 32 | 33 | var lovePromise = graph.rel(lisaPromise, "LOVES", bobPromise, { "reason" : "All the bling he got." }); 34 | 35 | // Wait for the promise of a relationship to be fulfilled. 36 | lovePromise.then(function(relationship) { 37 | 38 | // Get the end node of the LOVES relationship 39 | relationship.getEndNode().then(function(bob) { 40 | 41 | // Once you have a node or relationship object, all properties are immediately available: 42 | var name = bob.getProperty("name"); 43 | 44 | // Change a property like this 45 | bob.setProperty("name", "Steven"); 46 | bob.save().then(function(steven) { 47 | // Bob is now saved. 48 | }); 49 | 50 | }); 51 | 52 | }); 53 | 54 | Build production version 55 | ------------ 56 | 57 | git clone http://github.com/neo4j/neo4js.git 58 | cd neo4js 59 | mvn package 60 | 61 | This will create target/classes/neo4js.js 62 | 63 | To use, check out the API documentation for neo4j.GraphDatabase. 64 | Note that neo4js.js requires jQuery to run. 65 | 66 | API Documentation 67 | ----------------- 68 | 69 | mvn site 70 | 71 | Documentation is then found in target/site/jsdocs 72 | 73 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | org.neo4j.drivers 4 | neo4js 5 | 0.9-SNAPSHOT 6 | Neo4j - JavaScript REST Client 7 | JavaScript API for the Neo4j REST data and management endpoints. 8 | jar 9 | 2010 10 | http://components.neo4j.org/${project.artifactId}/${project.version} 11 | 12 | 13 | org.neo4j.build 14 | parent-central 15 | 35 16 | 17 | 18 | 19 | 20 | scm:git:git://github.com/neo4j/neo4js.git 21 | scm:git:git@github.com:neo4j/neo4js.git 22 | https://github.com/neo4j/neo4js 23 | 24 | 25 | 26 | neo4js 27 | ${basedir}/src/main/javascript 28 | ${basedir}/src/test/javascript 29 | ${basedir}/src/webtest/javascript 30 | neo4js.js 31 | GPL-3-header.txt 32 | 33 | 34 | 35 | 36 | 37 | 38 | ${basedir} 39 | META-INF 40 | 41 | NOTICE* 42 | LICENSE* 43 | COPYRIGHT* 44 | README* 45 | CHANGES* 46 | 47 | 48 | 49 | ${js.dir} 50 | 51 | **/* 52 | 53 | 54 | 55 | 56 | 57 | 58 | ${js.testdir} 59 | 60 | **/* 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | net.alchim31.maven 69 | yuicompressor-maven-plugin 70 | 1.1 71 | 72 | 73 | 74 | compile 75 | 76 | compress 77 | 78 | 79 | 80 | 81 | 82 | ${js.dir} 83 | 84 | **/*.md 85 | **/*.txt 86 | 87 | 88 | 89 | 90 | 91 | true 92 | 93 | ${project.build.outputDirectory}/${js.outputfile} 94 | 95 | ${project.build.outputDirectory} 96 | 97 | 99 | 100 | underscore-min.js 101 | 102 | neo4j/__init__-min.js 103 | neo4j/services/__init__-min.js 104 | 105 | neo4j/exceptions/__init__-min.js 106 | neo4j/exceptions/HttpException-min.js 107 | neo4j/exceptions/ConnectionLostException-min.js 108 | neo4j/exceptions/NotFoundException-min.js 109 | neo4j/exceptions/InvalidDataException-min.js 110 | neo4j/exceptions/StartNodeSameAsEndNodeException-min.js 111 | 112 | neo4j/setTimeout-min.js 113 | neo4j/setInterval-min.js 114 | neo4j/Promise-min.js 115 | neo4j/cachedFunction-min.js 116 | neo4j/log-min.js 117 | neo4j/proxy-min.js 118 | neo4j/Events-min.js 119 | neo4j/Web-min.js 120 | neo4j/Service-min.js 121 | 122 | neo4j/GraphDatabaseHeartbeat-min.js 123 | 124 | neo4j/models/__init__-min.js 125 | neo4j/models/JMXBean-min.js 126 | neo4j/models/PropertyContainer-min.js 127 | neo4j/models/Node-min.js 128 | neo4j/models/Relationship-min.js 129 | neo4j/models/Path-min.js 130 | 131 | neo4j/cypher/__init__-min.js 132 | neo4j/cypher/ExecutionEngine-min.js 133 | neo4j/cypher/ResultRow-min.js 134 | neo4j/cypher/QueryResult-min.js 135 | 136 | neo4j/services/BackupService-min.js 137 | neo4j/services/ConfigService-min.js 138 | neo4j/services/ImportService-min.js 139 | neo4j/services/ExportService-min.js 140 | neo4j/services/ConsoleService-min.js 141 | neo4j/services/JmxService-min.js 142 | neo4j/services/LifecycleService-min.js 143 | neo4j/services/MonitorService-min.js 144 | 145 | neo4j/index/__init__-min.js 146 | neo4j/index/Index-min.js 147 | neo4j/index/NodeIndex-min.js 148 | neo4j/index/RelationshipIndex-min.js 149 | neo4j/index/Indexes-min.js 150 | 151 | neo4j/GraphDatabaseManager-min.js 152 | neo4j/GraphDatabase-min.js 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | maven-source-plugin 162 | 163 | 164 | 165 | 166 | attach-source 167 | 168 | jar-no-fork 169 | test-jar-no-fork 170 | 171 | 172 | 173 | 174 | 175 | 176 | org.neo4j.build.plugins 177 | license-maven-plugin 178 | 179 | 180 | **/*.js 181 | 182 | 183 | **/underscore.js 184 | **/vend/** 185 | 186 | 187 | 188 | 189 | 190 | check 191 | 192 | 193 | 194 | inject-license-in-generated-file 195 | prepare-package 196 | 197 | ${project.build.outputDirectory} 198 | 199 | neo4js.js 200 | 201 | 202 | 203 | format 204 | 205 | 206 | 207 | 208 | 209 | 210 | maven-jar-plugin 211 | 212 | ${project.build.outputDirectory} 213 | 214 | neo4js.js 215 | META-INF/* 216 | 217 | 218 | neo4j/** 219 | **-min.* 220 | 221 | 222 | 223 | 224 | attach-test-jar 225 | none 226 | 227 | 228 | 229 | 230 | 231 | maven-release-plugin 232 | 233 | ${releaseVersion} 234 | https://svn.neo4j.org/drivers/javascript/${short-name}/tags 235 | 236 | 237 | 238 | 239 | 240 | 242 | 243 | org.eclipse.m2e 244 | lifecycle-mapping 245 | 1.0.0 246 | 247 | 248 | 249 | 250 | 251 | net.alchim31.maven 252 | yuicompressor-maven-plugin 253 | [1.1,) 254 | 255 | compress 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | jsunit-tests 274 | 275 | 276 | !skipTests 277 | 278 | 279 | 280 | 281 | 282 | de.berlios.jsunit 283 | jsunit-maven2-plugin 284 | 1.3 285 | 286 | 287 | test 288 | test 289 | 290 | jsunit-test 291 | 292 | 293 | ${project.build.outputDirectory} 294 | 295 | ${js.outputfile} 296 | 297 | ${js.testdir} 298 | 299 | 300 | All tests 301 | 302 | **/*.js 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | nl.windgazer 321 | jsdoctk-plugin 322 | 2.3.0-RC1 323 | 324 | 325 | ${project.build.directory}/site/jsdoc 326 | 10 327 | js 328 | true 329 | true 330 | true 331 | src/main/javascript 332 | true 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | jsdoctk2 341 | http://jsdoctk-plugin.googlecode.com/svn/repo 342 | 343 | 344 | 345 | 346 | 347 | jakewins 348 | Jacob Hansson 349 | jacob [at] voltvoodoo.com 350 | +1 351 | 352 | Developer 353 | 354 | 355 | 356 | 357 | 358 | 359 | neo4j-site 360 | scpexe://static.neo4j.org/var/www/components.neo4j.org/${project.artifactId}/${project.version} 361 | 362 | 363 | 364 | 365 | 366 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/Events.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * A simple event-handling system. 22 | * 23 | * @class 24 | * @param context {object} (optional) context data to be included with event objects 25 | */ 26 | neo4j.Events = function(context) { 27 | 28 | this.uniqueNamespaceCount = 0; // Used to create unique namespaces 29 | this.handlers = {}; 30 | this.context = context || {}; 31 | 32 | } 33 | 34 | /** 35 | * Naive implementation to quickly get anonymous event namespaces. 36 | */ 37 | neo4j.Events.prototype.createUniqueNamespace = function() { 38 | return "uniq#" + (this.uniqueNamespaceCount++); 39 | }; 40 | 41 | /** 42 | * Bind an event listener to an event. 43 | */ 44 | neo4j.Events.prototype.bind = function(key, callback) { 45 | if (typeof (this.handlers[key]) === "undefined") 46 | { 47 | this.handlers[key] = []; 48 | } 49 | 50 | this.handlers[key].push(callback); 51 | }; 52 | 53 | /** 54 | * Trigger an event. 55 | */ 56 | neo4j.Events.prototype.trigger = function(key, data) { 57 | 58 | if (typeof (this.handlers[key]) !== "undefined") 59 | { 60 | 61 | var data = data || {}; 62 | 63 | var eventHandlers = this.handlers[key]; 64 | var event = _.extend({ 65 | key : key, 66 | data : data 67 | }, this.context); 68 | 69 | for ( var i = 0, o = eventHandlers.length; i < o; i++) 70 | { 71 | neo4j.setTimeout((function(handler) { 72 | return function() { 73 | try 74 | { 75 | handler(event); 76 | } catch (e) 77 | { 78 | neo4j.log("Event handler for event " + key + " threw exception.",e); 79 | } 80 | } 81 | })(eventHandlers[i]), 0); 82 | } 83 | } 84 | }; 85 | 86 | // 87 | // CREATE A GLOBAL EVENT HANDLER 88 | // 89 | 90 | /** 91 | * Global event handler. Instance of {@link neo4j.Events}. 92 | */ 93 | neo4j.events = new neo4j.Events() 94 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/GraphDatabaseHeartbeat.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Allows "taking the pulse" on a graph database, calling registered listeners 22 | * at regular intervals with monitoring data. 23 | */ 24 | neo4j.GraphDatabaseHeartbeat = function(db) { 25 | 26 | this.db = db; 27 | 28 | /** 29 | * Quick access to the databases monitor service. 30 | */ 31 | this.monitor = db.manage.monitor; 32 | 33 | this.listeners = {}; 34 | this.idCounter = 0; 35 | this.listenerCounter = 0; 36 | 37 | /** 38 | * These correspond to the granularities available on the server side. 39 | */ 40 | this.timespan = { 41 | year : 60 * 60 * 24 * 365, 42 | month : 60 * 60 * 24 * 31, 43 | week : 60 * 60 * 24 * 7, 44 | day : 60 * 60 * 24, 45 | hours : 60 * 60 * 6, 46 | minutes : 60 * 35 47 | }; 48 | 49 | /** 50 | * This is where the monitoring data begins. 51 | */ 52 | this.startTimestamp = Math.round( (new Date()).getTime() / 1000 ) - this.timespan.year; 53 | 54 | /** 55 | * This is where the monitoring data ends. 56 | */ 57 | this.endTimestamp = this.startTimestamp + 1; 58 | 59 | /** 60 | * List of timestamps, indexes correspond to indexes in data arrays. The is 61 | * appended as more data is fetched. 62 | */ 63 | this.timestamps = []; 64 | 65 | /** 66 | * Sets of data arrays fetched from the server. These are appended to as 67 | * more data is fetched. 68 | */ 69 | this.data = {}; 70 | 71 | /** 72 | * Set to true while the server is being polled, used to make sure only one 73 | * poll is triggered at any given moment. 74 | */ 75 | this.isPolling = false; 76 | 77 | // Bind these tightly to this object 78 | this.processMonitorData = neo4j.proxy(this.processMonitorData, this); 79 | this.beat = neo4j.proxy(this.beat, this); 80 | this.waitForPulse = neo4j.proxy(this.waitForPulse, this); 81 | 82 | // Start a pulse 83 | neo4j.setInterval(this.beat, 2000); 84 | }; 85 | 86 | /** 87 | * Register a method to be called at regular intervals with monitor data. 88 | */ 89 | neo4j.GraphDatabaseHeartbeat.prototype.addListener = function(listener) { 90 | 91 | this.listenerCounter++; 92 | this.listeners[this.idCounter++] = listener; 93 | 94 | return this.idCounter; 95 | 96 | }; 97 | 98 | /** 99 | * Remove a listener. 100 | * 101 | * @param listener 102 | * {Integer, Function} either the id returned by {@link #addListener} 103 | * or the listener method itself. 104 | */ 105 | neo4j.GraphDatabaseHeartbeat.prototype.removeListener = function(listener) { 106 | 107 | var listenerWasRemoved = false; 108 | if (typeof (listener) === "function") 109 | { 110 | for ( var key in this.listeners) 111 | { 112 | if (this.listeners[key] === listener) 113 | { 114 | delete this.listeners[key]; 115 | listenerWasRemoved; 116 | break; 117 | } 118 | } 119 | } else 120 | { 121 | if (this.listeners[listener]) 122 | { 123 | delete this.listeners[listener]; 124 | listenerWasRemoved = true; 125 | } 126 | } 127 | 128 | if (listenerWasRemoved) 129 | { 130 | this.listenerCounter--; 131 | } 132 | 133 | }; 134 | 135 | /** 136 | * Get heartbeat saved data. 137 | */ 138 | neo4j.GraphDatabaseHeartbeat.prototype.getCachedData = function() { 139 | return { 140 | timestamps : this.timestamps, 141 | data : this.data, 142 | endTimestamp : this.endTimestamp, 143 | startTimestamp : this.startTimestamp 144 | }; 145 | }; 146 | 147 | /** 148 | * Trigger a heart beat. 149 | */ 150 | neo4j.GraphDatabaseHeartbeat.prototype.beat = function() { 151 | if (this.listenerCounter > 0 && !this.isPolling && this.monitor.available) 152 | { 153 | this.isPolling = true; 154 | this.monitor.getDataFrom(this.endTimestamp, this.processMonitorData); 155 | } 156 | }; 157 | 158 | /** 159 | * Process monitor data, send any new data out to listeners. 160 | */ 161 | neo4j.GraphDatabaseHeartbeat.prototype.processMonitorData = function(data) { 162 | this.isPolling = false; 163 | 164 | if (data && !data.error) 165 | { 166 | 167 | var boundaries = this.findDataBoundaries(data); 168 | 169 | // If there is new data 170 | if (boundaries.dataEnd >= 0) 171 | { 172 | this.endTimestamp = data.timestamps[boundaries.dataEnd]; 173 | 174 | // Append the new timestamps 175 | var newTimestamps = data.timestamps.splice(boundaries.dataStart, 176 | boundaries.dataEnd - boundaries.dataStart); 177 | this.timestamps = this.timestamps.concat(newTimestamps); 178 | 179 | // Append the new data 180 | var newData = {}; 181 | for ( var key in data.data) 182 | { 183 | newData[key] = data.data[key].splice(boundaries.dataStart, 184 | boundaries.dataEnd - boundaries.dataStart); 185 | 186 | if (typeof (this.data[key]) === "undefined") 187 | { 188 | this.data[key] = []; 189 | } 190 | 191 | this.data[key] = this.data[key].concat(newData[key]); 192 | } 193 | 194 | // Update listeners 195 | var listenerData = { 196 | server : this.server, 197 | newData : { 198 | data : newData, 199 | timestamps : newTimestamps, 200 | end_time : this.endTimestamp, 201 | start_time : data.start_time 202 | }, 203 | allData : this.getCachedData() 204 | }; 205 | 206 | this.callListeners(listenerData); 207 | 208 | } else 209 | { 210 | // No new data 211 | this.adjustRequestedTimespan(); 212 | } 213 | } 214 | }; 215 | 216 | /** 217 | * Used to wait for an offline server to come online. 218 | * 219 | * @param callback 220 | * {function} Function that will be called when the server is online. 221 | */ 222 | neo4j.GraphDatabaseHeartbeat.prototype.waitForPulse = function(callback) { 223 | 224 | if(!this.pulsePromise) { 225 | var heartbeat = this, 226 | getMethod = this.db.get; 227 | this.pulsePromise = new neo4j.Promise(function(fulfill) { 228 | var args = { interval : null }; 229 | 230 | args.interval = neo4j.setInterval(function() { 231 | getMethod("", function(data) { 232 | if( data !== null ) { 233 | neo4j.clearInterval(args.interval); 234 | heartbeat.pulsePromise = null; 235 | fulfill(true); 236 | } 237 | }); 238 | }, 4000); 239 | }); 240 | } 241 | 242 | this.pulsePromise.addFulfilledHandler(callback); 243 | 244 | return this.pulsePromise; 245 | 246 | }; 247 | 248 | /** 249 | * This is used to offset a problem with monitor data granularity. This should 250 | * be the servers concern, but that is not yet implemented. 251 | * 252 | * The monitor data has a concept of granularity - if you ask for a wide enough 253 | * timespan, you won't get any data back. This is because the data available is 254 | * to "fine grained" to be visible in your wide time span (e.g. there is data 255 | * for the last hour, but you asked for data from a full year, the data from 256 | * a single hour is not considered reliable when looking at such a large time 257 | * span). 258 | * 259 | * This creates a problem since there might be data for a full year, and we'd 260 | * like to show that. So what we do is, we ask for a year. If we get an empty 261 | * result, this method will make the timespan we ask for smaller and smaller, 262 | * until we get start getting data back from the server. 263 | * 264 | * @return {object} An object with a dataStart and a dataEnd key. 265 | */ 266 | neo4j.GraphDatabaseHeartbeat.prototype.adjustRequestedTimespan = function(data) { 267 | var now = Math.round((new Date()).getTime() / 1000); 268 | var timespan = now - this.endTimestamp; 269 | 270 | if (timespan >= this.timespan.year) 271 | { 272 | this.endTimestamp = now - this.timespan.month; 273 | this.beat(); 274 | } else if (timespan >= this.timespan.month) 275 | { 276 | this.endTimestamp = now - this.timespan.week; 277 | this.beat(); 278 | } else if (timespan >= this.timespan.week) 279 | { 280 | this.endTimestamp = now - this.timespan.day; 281 | this.beat(); 282 | } else if (timespan >= this.timespan.day) 283 | { 284 | this.endTimestamp = now - this.timespan.hours; 285 | this.beat(); 286 | } else if (timespan >= this.timespan.day) 287 | { 288 | this.endTimestamp = now - this.timespan.minutes; 289 | this.beat(); 290 | } 291 | }; 292 | 293 | /** 294 | * Find the first and last index that contains a number in a given array. This 295 | * is used because the monitor service returns "pads" its result with NaN data 296 | * if it is asked for data it does not have. 297 | * 298 | * @param data 299 | * {object} Should be the data object returned by the monitor 300 | * services methods. 301 | * @return {object} An object with a dataStart and a dataEnd key. 302 | */ 303 | neo4j.GraphDatabaseHeartbeat.prototype.findDataBoundaries = function(data) { 304 | 305 | var firstKey = this.getFirstKey(data); 306 | 307 | var lastIndexWithData = -1, firstIndexWithData = -1; 308 | 309 | if (firstKey) 310 | { 311 | 312 | // Find the last timestamp that has any data associated with it 313 | for (lastIndexWithData = data.timestamps.length - 1; lastIndexWithData >= 0; lastIndexWithData--) 314 | { 315 | if (typeof (data.data[firstKey][lastIndexWithData]) === "number") 316 | { 317 | break; 318 | } 319 | } 320 | 321 | // Find the first timestamp that has any data associated with it 322 | for (firstIndexWithData = 0; firstIndexWithData <= lastIndexWithData; firstIndexWithData++) 323 | { 324 | if (typeof (data.data[firstKey][firstIndexWithData]) === "number") 325 | { 326 | break; 327 | } 328 | } 329 | } 330 | 331 | return { 332 | dataStart : firstIndexWithData, 333 | dataEnd : lastIndexWithData 334 | }; 335 | 336 | }; 337 | 338 | /** 339 | * Call all listeners with some data. 340 | */ 341 | neo4j.GraphDatabaseHeartbeat.prototype.callListeners = function(data) { 342 | for ( var i in this.listeners) 343 | { 344 | setTimeout(function(listener) { 345 | return function() { 346 | listener(data); 347 | } 348 | }(this.listeners[i]), 0); 349 | } 350 | }; 351 | 352 | /** 353 | * Return the first key encountered in some object, or null if none is 354 | * available. 355 | */ 356 | neo4j.GraphDatabaseHeartbeat.prototype.getFirstKey = function(object) { 357 | if (typeof (object) === "object") 358 | { 359 | for ( var key in object.data) 360 | { 361 | break; 362 | } 363 | } 364 | 365 | return key ? key : null; 366 | }; 367 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/GraphDatabaseManager.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Manage a neo4j REST server with management enabled. 22 | * 23 | * @class 24 | * @param url 25 | * the url to the REST management server 26 | * @returns a new GraphDatabaseManager instance 27 | */ 28 | neo4j.GraphDatabaseManager = function(db) { 29 | 30 | _.bindAll(this, 'discoverServices'); 31 | 32 | this.db = db; 33 | 34 | /** 35 | * Backup service, instance of {@link neo4j.services.BackupService} 36 | */ 37 | this.backup = new neo4j.services.BackupService(db); 38 | 39 | /** 40 | * Configuration service, instance of {@link neo4j.services.ConfigService} 41 | */ 42 | this.config = new neo4j.services.ConfigService(db); 43 | 44 | /** 45 | * Import service, instance of {@link neo4j.services.ImportService} 46 | */ 47 | this.importing = new neo4j.services.ImportService(db); 48 | 49 | /** 50 | * Export service, instance of {@link neo4j.services.ExportService} 51 | */ 52 | this.exporting = new neo4j.services.ExportService(db); 53 | 54 | /** 55 | * Console service, instance of {@link neo4j.services.ConsoleService} 56 | */ 57 | this.console = new neo4j.services.ConsoleService(db); 58 | 59 | /** 60 | * JMX service, instance of {@link neo4j.services.JmxService} 61 | */ 62 | this.jmx = new neo4j.services.JmxService(db); 63 | 64 | /** 65 | * Lifecycle service, instance of {@link neo4j.services.LifecycleService} 66 | */ 67 | this.lifecycle = new neo4j.services.LifecycleService(db); 68 | 69 | /** 70 | * Monitor service, instance of {@link neo4j.services.MonitorService} 71 | */ 72 | this.monitor = new neo4j.services.MonitorService(db); 73 | 74 | this.db.getServiceDefinition().then(this.discoverServices); 75 | }; 76 | 77 | _.extend(neo4j.GraphDatabaseManager.prototype,{ 78 | 79 | /** 80 | * Check if services have been loaded. You can also listen for the 81 | * services.loaded event. 82 | * 83 | * @returns {Boolean} true if services are loaded. 84 | */ 85 | servicesLoaded : function() { 86 | return (this.services) ? true : false; 87 | }, 88 | 89 | /** 90 | * Get a list of available services. 91 | * 92 | * @throws Error 93 | * if services have not been loaded yet (use {@link #servicesLoaded} 94 | * or the services.loaded event to check). 95 | */ 96 | availableServices : function() { 97 | if (this.services) 98 | { 99 | 100 | if (!this.serviceNames) 101 | { 102 | this.serviceNames = []; 103 | for ( var name in this.services) 104 | { 105 | this.serviceNames.push(name); 106 | } 107 | } 108 | 109 | return this.serviceNames; 110 | } else 111 | { 112 | throw new Error("Service definition has not been loaded yet.") 113 | } 114 | }, 115 | 116 | /** 117 | * Connect to the server and find out what services are available. 118 | */ 119 | discoverServices : function() { 120 | 121 | var manage = this; 122 | this.db.getDiscoveryDocument().then(function(discovery) { 123 | manage.db.web.get(discovery.management, 124 | // Success 125 | neo4j.proxy(function(serviceDefinition) { 126 | this.services = serviceDefinition.services; 127 | 128 | for ( var service in serviceDefinition.services) 129 | { 130 | if (this[service]) 131 | { 132 | this[service] 133 | .makeAvailable(serviceDefinition.services[service]); 134 | } 135 | } 136 | 137 | this.db.trigger("services.loaded"); 138 | 139 | }, manage), 140 | // Failure 141 | neo4j.proxy(function(fail) { 142 | neo4j.log("Unable to fetch service descriptions for server " 143 | + this.url + ". Server management will be unavailable."); 144 | }, this)); 145 | }); 146 | 147 | } 148 | }); 149 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/Promise.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Used to represent a future value, same or similar to "future" and "delay" 22 | * pattern. 23 | * 24 | * Inspired by Ron Bucktons lightweight Promise implementation. 25 | * 26 | * @class 27 | * @param init A function that will get passed two arguments, 28 | * fulfill and fail. Call one to either fulfill 29 | * or fail the promise. 30 | */ 31 | neo4j.Promise = function(init) { 32 | 33 | _.bindAll(this, 'then', 'fulfill', 'fail', 'addHandlers', 34 | 'addFulfilledHandler', 'addFailedHandler','_callHandlers', 35 | '_callHandler', '_addHandler'); 36 | 37 | this._handlers = []; 38 | 39 | if (typeof (init) === "function") { 40 | init(this.fulfill, this.fail); 41 | } 42 | }; 43 | 44 | /** 45 | * Ensure that a variable is a promise. If the argument passed is already a 46 | * promise, the argument will be returned as-is. If it is not a promise, the 47 | * argument will be wrapped in a promise that is instantly fulfilled. 48 | */ 49 | neo4j.Promise.wrap = function(arg) { 50 | if (arg instanceof neo4j.Promise) { 51 | return arg; 52 | } else { 53 | return neo4j.Promise.fulfilled(arg); 54 | } 55 | }; 56 | 57 | /** 58 | * Create a promise that is instantly fulfilled. Useful for wrapping values to 59 | * be sent into promise-based code. 60 | */ 61 | neo4j.Promise.fulfilled = function(value) { 62 | return new neo4j.Promise(function(fulfill) { 63 | fulfill(value); 64 | }); 65 | }; 66 | 67 | /** 68 | * Join several promises together, pass 69 | * as many promises as you like in as arguments. 70 | * @return A new promise that will be fulfilled when 71 | * all joined promises are fulfilled. 72 | */ 73 | neo4j.Promise.join = function() { 74 | var joined = _.toArray(arguments); 75 | if(joined.length == 1) { 76 | return joined[0]; 77 | } else { 78 | return new neo4j.Promise(function(fulfill, fail){ 79 | var results = []; 80 | 81 | function waitForNextPromise(promises) { 82 | if(promises.length > 0) { 83 | promises.shift().addFulfilledHandler(function(result){ 84 | results.push(result); 85 | waitForNextPromise(promises); 86 | }); 87 | } else { 88 | fulfill(results); 89 | } 90 | } 91 | 92 | // Hook directly into all failed handlers, to allow 93 | // failing early. 94 | for(var i=0, l=joined.length; i. 19 | */ 20 | /** 21 | * Creates event handling system for this service, as well as initializing 22 | * various properties. 23 | * 24 | * Sets the this.db attribute. Also hooks an event listener that waits for the 25 | * services.loaded event. If services.loaded is triggered, and this service is 26 | * not initialized, it is assumed that this service is not available. 27 | * 28 | * @class parent class that provides common items for services, such as a http 29 | * interface. 30 | */ 31 | neo4j.Service = function(db) { 32 | 33 | /** 34 | * List of commands waiting to be run as soon as the service is initialized. 35 | */ 36 | this.callsWaiting = []; 37 | 38 | this.loadServiceDefinition = neo4j.cachedFunction(this.loadServiceDefinition,0); 39 | 40 | /** 41 | * Event handler. This is unique for each service. 42 | * 43 | * @see {@link neo4j.Events} 44 | */ 45 | this.events = new neo4j.Events(); 46 | 47 | /** 48 | * Convinience access to event bind method. 49 | */ 50 | this.bind = neo4j.proxy(this.events.bind, this.events); 51 | 52 | /** 53 | * Convinience access to event trigger method. 54 | */ 55 | this.trigger = neo4j.proxy(this.events.trigger, this.events); 56 | 57 | /** 58 | * A reference to the GraphDatabase instance. 59 | */ 60 | this.db = db; 61 | 62 | this.db.bind("services.loaded", neo4j.proxy(function() { 63 | if (!this.initialized) 64 | { 65 | this.setNotAvailable(); 66 | } 67 | }, this)); 68 | }; 69 | 70 | /** 71 | * Used to generate boilerplate for service methods. 72 | * 73 | * @param args 74 | * is an argument map 75 | * 76 | * @param args.method 77 | * is the http method to call the server with 78 | * @param args.resource 79 | * is the resource key, as available in this.resources 80 | * @param args.urlArgs 81 | * (optional) is an array of named arguments that map to placeholders 82 | * in the url 83 | * @param args.after 84 | * (optional) will be called with the data from the server and the 85 | * callback waiting to have it. 86 | * @param args.before 87 | * (optional) will be called with a method to be called, and the 88 | * data passed by the user. If you supply this, you have to do 89 | * something like "method.apply(this, args);" in the least, in 90 | * order to trigger the call to the server. 91 | * @param args.errorHandler 92 | * (optional) handler for when something goes wrong. Gets an error 93 | * object and the callback waiting for a response. 94 | */ 95 | neo4j.Service.resourceFactory = function(args) { 96 | 97 | var urlArgs = args.urlArgs || []; 98 | var urlArgCount = urlArgs.length; 99 | 100 | var after = args.after ? args.after 101 | : function(data, callback) { 102 | callback(data); 103 | }; 104 | 105 | var before = args.before ? args.before : function(method, args) { 106 | method.apply(this, args); 107 | }; 108 | 109 | var errorHandler = args.errorHandler ? args.errorHandler : function(callback, error) { 110 | callback({ message : "An error occurred, please see attached error object.", error : error }); 111 | }; 112 | 113 | /** 114 | * This is the core method for accessing resources. It will perform the 115 | * actual http call and pass the result onwards. 116 | */ 117 | var resourceFunction = function() { 118 | 119 | var proxiedAfter = neo4j.proxy(after,this); 120 | var proxiedErrorHandler = neo4j.proxy(errorHandler,this); 121 | 122 | // Figure out what URL to call 123 | if (urlArgCount > 0) 124 | { 125 | var replace = {}; 126 | for ( var i = 0; i < urlArgCount; i++) 127 | { 128 | replace[urlArgs[i]] = arguments[i]; 129 | } 130 | 131 | var url = this.db.web.replace(this.resources[args.resource], replace); 132 | 133 | } else 134 | { 135 | var url = this.resources[args.resource]; 136 | } 137 | 138 | var data = null; 139 | var callback = function() { 140 | }; 141 | 142 | // Are there any extra args? 143 | if (arguments.length > urlArgCount) 144 | { 145 | if (typeof (arguments[arguments.length - 1]) === "function") 146 | { 147 | callback = arguments[arguments.length - 1]; 148 | } 149 | 150 | // Are there two extra args? 151 | if ((arguments.length - 1) > urlArgCount) 152 | { 153 | data = arguments[arguments.length - 2]; 154 | } 155 | } 156 | 157 | if (data !== null) 158 | { 159 | this.db.web.ajax(args.method, url, data, function(data) { 160 | proxiedAfter(data, callback); 161 | }, function(error) { 162 | proxiedErrorHandler(callback, error); 163 | }); 164 | } else 165 | { 166 | this.db.web.ajax(args.method, url, function(data) { 167 | proxiedAfter(data, callback); 168 | }, function(error) { 169 | proxiedErrorHandler(callback, error); 170 | }); 171 | } 172 | 173 | }; 174 | 175 | return function() { 176 | this.serviceMethodPreflight(function() { 177 | before.call(this, neo4j.proxy(resourceFunction, this), arguments); 178 | }, arguments); 179 | }; 180 | 181 | }; 182 | 183 | _.extend(neo4j.Service.prototype, { 184 | 185 | /** 186 | * Keeps track of if the init method has been called. 187 | */ 188 | initialized : false, 189 | 190 | /** 191 | * Set to true if the service is available, false if not and null if we are 192 | * still waiting for the server to tell us. 193 | */ 194 | available : null, 195 | 196 | /** 197 | * Contains URLs to the resources the service provides. This is lazily loaded 198 | * when any of the service methods are called. 199 | */ 200 | resources : null, 201 | 202 | /** 203 | * Go through the list of method calls that are waiting for this service to 204 | * initialize, and run all of them. 205 | */ 206 | handleWaitingCalls : function() { 207 | 208 | for ( var i = 0, l = this.callsWaiting.length; i < l; i++) 209 | { 210 | try 211 | { 212 | this.serviceMethodPreflight(this.callsWaiting[i].method, 213 | this.callsWaiting[i].args); 214 | } catch (e) 215 | { 216 | neo4j.log(e); 217 | } 218 | } 219 | 220 | }, 221 | 222 | /** 223 | * Do a GET-request to the root URL for this service, store the result in 224 | * this.serviceDefinition. 225 | * 226 | * Trigger service.definition.loaded-event on the service-local event handler. 227 | */ 228 | loadServiceDefinition : function(callback) { 229 | this.get("/", neo4j.proxy(function(data) { 230 | this.resources = data.resources; 231 | this.trigger("service.definition.loaded", data); 232 | callback(data); 233 | }, this)); 234 | }, 235 | 236 | /** 237 | * Initialize the service, set the base URL for api calls.
238 | * Example:
239 | * 240 | *
241 | 	 * var service = new neo4j.Service();
242 | 	 * service.init("http://localhost:9988/backup");
243 | 	 * 
244 | * 245 | * @param url 246 | * is the full url to the service (e.g. http://localhost:9988/backup) 247 | */ 248 | makeAvailable : function(url) { 249 | this.initialized = true; 250 | this.available = true; 251 | this.url = url; 252 | this.handleWaitingCalls(); 253 | }, 254 | 255 | /** 256 | * Tell this service that it is not available from the current server. This will 257 | * make the service throw exceptions when someone tries to use it. 258 | */ 259 | setNotAvailable : function() { 260 | this.initialized = true; 261 | this.available = false; 262 | this.handleWaitingCalls(); 263 | }, 264 | 265 | /** 266 | * Perform a http GET call for a given resource. 267 | * 268 | * @param resource 269 | * is the resource to fetch (e.g. /myresource) 270 | * @param data 271 | * (optional) object with data 272 | * @param success 273 | * (optional) success callback 274 | * @param failure 275 | * (optional) failure callback 276 | */ 277 | get : function(resource, data, success, failure) { 278 | this.db.web.get(this.url + resource, data, success, failure); 279 | }, 280 | 281 | /** 282 | * Perform a http DELETE call for a given resource. 283 | * 284 | * @param resource 285 | * is the resource to fetch (e.g. /myresource) 286 | * @param data 287 | * (optional) object with data 288 | * @param success 289 | * (optional) success callback 290 | * @param failure 291 | * (optional) failure callback 292 | */ 293 | del : function(resource, data, success, failure) { 294 | this.db.web.del(this.url + resource, data, success, failure); 295 | }, 296 | 297 | /** 298 | * Perform a http POST call for a given resource. 299 | * 300 | * @param resource 301 | * is the resource to fetch (e.g. /myresource) 302 | * @param data 303 | * (optional) object with data 304 | * @param success 305 | * (optional) success callback 306 | * @param failure 307 | * (optional) failure callback 308 | */ 309 | post : function(resource, data, success, failure) { 310 | this.db.web.post(this.url + resource, data, success, failure); 311 | }, 312 | 313 | /** 314 | * Perform a http PUT call for a given resource. 315 | * 316 | * @param resource 317 | * is the resource to fetch (e.g. /myresource) 318 | * @param data 319 | * (optional) object with data 320 | * @param success 321 | * (optional) success callback 322 | * @param failure 323 | * (optional) failure callback 324 | */ 325 | put : function(resource, data, success, failure) { 326 | this.db.web.put(this.url + resource, data, success, failure); 327 | }, 328 | 329 | /** 330 | * This method is called by all service methods before they do their work. It 331 | * will throw an exception if the service is not yet initialized, and it will 332 | * throw an exception if the service is not available with the current server. 333 | * 334 | * It will also check if a service definition for the given service has been 335 | * loaded. If that is not the case, this will be done. 336 | * 337 | * If all is well, the callback provided will be called with the correct "this" 338 | * context. 339 | */ 340 | serviceMethodPreflight : function(callback, args) { 341 | 342 | if (this.available === false) 343 | { 344 | throw new Error( 345 | "The service you are accessing is not available for this server."); 346 | } else if (!this.initialized) 347 | { 348 | this.callsWaiting.push({ 349 | 'method' : callback, 350 | 'args' : args 351 | }); 352 | return; 353 | } 354 | 355 | args = args || []; 356 | 357 | if (this.resources !== null) 358 | { 359 | callback.apply(this, args); 360 | } else 361 | { 362 | this.loadServiceDefinition(neo4j.proxy(function() { 363 | callback.apply(this, args); 364 | }, this)); 365 | } 366 | } 367 | 368 | }); 369 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/Web.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Web provider using jQuery. 22 | * 23 | * @namespace 24 | */ 25 | neo4j.jqueryWebProvider = { 26 | 27 | /** 28 | * Ajax call implementation. 29 | */ 30 | ajax : function(args) { 31 | 32 | var timeout = args.timeout || 6 * 60 * 60 * 1000, 33 | method = args.method, 34 | url = args.url, 35 | data = args.data, 36 | success = args.success, 37 | failure = args.failure, 38 | isGetRequest = method === "GET"; 39 | 40 | function successHandler(data, status, xhr) { 41 | if ( xhr.status === 0 ) { 42 | errorHandler(xhr); 43 | } else { 44 | success.apply(this, arguments); 45 | } 46 | } 47 | 48 | function errorHandler(req) { 49 | try { 50 | if (req.status === 200) 51 | { 52 | // This happens when the 53 | // server returns an 54 | // empty response. 55 | return success(null); 56 | } 57 | } catch (e) { 58 | // We end up here if there 59 | // is no status to read 60 | } 61 | try 62 | { 63 | if( req.status === 0 ) { 64 | failure(new neo4j.exceptions.ConnectionLostException()); 65 | } else { 66 | var error = JSON.parse(req.responseText); 67 | failure(new neo4j.exceptions.HttpException(req.status, error, req)); 68 | } 69 | } catch (e) 70 | { 71 | failure(new neo4j.exceptions.HttpException(-1, {}, req)); 72 | } 73 | } 74 | 75 | var isCrossDomain = this.isCrossDomain; 76 | (function(method, url, data, success, failure) { 77 | 78 | if (data === null || data === "null") 79 | { 80 | data = ""; 81 | } else if(!isGetRequest) 82 | { 83 | data = JSON.stringify(data); 84 | } 85 | 86 | if (isCrossDomain(url) && window.XDomainRequest) 87 | { 88 | // IE8 Cross domain 89 | // TODO 90 | if (typeof (failure) === "function") 91 | { 92 | failure(new neo4j.exceptions.HttpException(-1, null, null, "Cross-domain requests are available in IE, but are not yet implemented in neo4js.")); 93 | } 94 | } else 95 | { 96 | $.ajax({ 97 | url : url, 98 | type : method, 99 | data : data, 100 | timeout: timeout, 101 | cache: false, 102 | // Let jquery turn data map into query string 103 | // only on GET requests. 104 | processData : isGetRequest, 105 | success : successHandler, 106 | contentType : "application/json", 107 | error : errorHandler, 108 | dataType : "json" 109 | }); 110 | } 111 | })(method, url, data, success, failure); 112 | }, 113 | 114 | /** 115 | * Check if a url is cross-domain from the current window.location url. 116 | */ 117 | isCrossDomain : function(url) { 118 | if (url) 119 | { 120 | var httpIndex = url.indexOf("://"); 121 | if (httpIndex === -1 || httpIndex > 7) 122 | { 123 | return false; 124 | } else 125 | { 126 | return url.substring(httpIndex + 3).split("/", 1)[0] !== window.location.host; 127 | } 128 | } else 129 | { 130 | return false; 131 | } 132 | } 133 | }; 134 | 135 | /** 136 | * Interface to jQuery AJAX library. This is here to enable a fairly simple 137 | * expansion to make other AJAX libraries available as underlying 138 | * implementation, thus dropping dependency on jQuery. 139 | */ 140 | neo4j.Web = function(webProvider, events) { 141 | 142 | this.webProvider = webProvider || neo4j.jqueryWebProvider; 143 | this.events = events || neo4j.events; 144 | 145 | }; 146 | 147 | _.extend(neo4j.Web.prototype, { 148 | 149 | /** 150 | * Perform a GET http request to the given url. 151 | * 152 | * @param url 153 | * is the url to send the request to 154 | * @param data 155 | * (optional) javascript object to send as payload. This will 156 | * be converted to JSON. 157 | * @param success 158 | * (optional) callback called with de-serialized JSON 159 | * response data as argument 160 | * @param failure 161 | * (optional) callback called with failed request object 162 | */ 163 | get : function(url, data, success, failure) { 164 | return this.ajax("GET", url, data, success, failure); 165 | }, 166 | 167 | /** 168 | * Perform a POST http request to the given url. 169 | * 170 | * @param url 171 | * is the url to send the request to 172 | * @param data 173 | * (optional) javascript object to send as payload. This will 174 | * be converted to JSON. 175 | * @param success 176 | * (optional) callback called with de-serialized JSON 177 | * response data as argument 178 | * @param failure 179 | * (optional) callback called with failed request object 180 | */ 181 | post : function(url, data, success, failure) { 182 | return this.ajax("POST", url, data, success, failure); 183 | }, 184 | 185 | /** 186 | * Perform a PUT http request to the given url. 187 | * 188 | * @param url 189 | * is the url to send the request to 190 | * @param data 191 | * (optional) javascript object to send as payload. This will 192 | * be converted to JSON. 193 | * @param success 194 | * (optional) callback called with de-serialized JSON 195 | * response data as argument 196 | * @param failure 197 | * (optional) callback called with failed request object 198 | */ 199 | put : function(url, data, success, failure) { 200 | return this.ajax("PUT", url, data, success, failure); 201 | }, 202 | 203 | /** 204 | * Perform a DELETE http request to the given url. 205 | * 206 | * @param url 207 | * is the url to send the request to 208 | * @param data 209 | * (optional) javascript object to send as payload. This will 210 | * be converted to JSON. 211 | * @param success 212 | * (optional) callback called with de-serialized JSON 213 | * response data as argument 214 | * @param failure 215 | * (optional) callback called with failed request object 216 | */ 217 | del : function(url, data, success, failure) { 218 | return this.ajax("DELETE", url, data, success, failure); 219 | }, 220 | 221 | /** 222 | * Perform a http request to the given url. 223 | * 224 | * TODO: Refactor to sort out which arg is which at a single point. 225 | * 226 | * @param method 227 | * is the HTTP method to use (e.g. PUT, POST, GET, DELETE) 228 | * @param url 229 | * is the url to send the request to 230 | * @param data 231 | * (optional) javascript object to send as payload. This will 232 | * be converted to JSON. 233 | * @param success 234 | * (optional) Callback called with de-serialized JSON 235 | * response data as argument. You can also use the promise 236 | * returned to hook into this callback. 237 | * @param failure 238 | * (optional) Callback called with failed request object. 239 | * You can also use the promise returned to hook into this 240 | * callback. 241 | * @return A promise for a http response. 242 | */ 243 | ajax : function() { 244 | 245 | var args = this._processAjaxArguments(arguments), 246 | web = this; 247 | 248 | args.userFail = this.wrapFailureCallback(args.failure); 249 | args.userSuccess = args.success; 250 | 251 | return new neo4j.Promise(function(fulfill, fail) { 252 | args.failure = function() { 253 | fail.call(this, {error:arguments[0], args:arguments}); 254 | args.userFail.apply(this, arguments); 255 | }; 256 | 257 | args.success = function() { 258 | fulfill.call(this, {data:arguments[0],args:arguments}); 259 | args.userSuccess.apply(this, arguments); 260 | }; 261 | 262 | try { 263 | web.webProvider.ajax(args); 264 | } catch (e) { 265 | args.failure(e); 266 | } 267 | }); 268 | 269 | }, 270 | 271 | /** 272 | * Check if a given string seems to be a URL. 273 | */ 274 | looksLikeUrl : function(theUnknownString) { 275 | var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ 276 | return regexp.test(theUnknownString); 277 | }, 278 | 279 | /** 280 | * Set the provider that should be used to do ajax requests. 281 | * 282 | * @see {@link neo4j.Web#ajax} for how the provider is used 283 | */ 284 | setWebProvider : function(provider) { 285 | this.webProvider = provider; 286 | }, 287 | 288 | /** 289 | * Take a url with {placeholders} and replace them using a map of 290 | * placeholder->string. 291 | */ 292 | replace : function(url, replaceMap) { 293 | var out = {url:url}; 294 | _.each(_.keys(replaceMap), function(key) { 295 | out.url = out.url.replace("{" + key + "}", replaceMap[key]); 296 | }); 297 | return out.url; 298 | }, 299 | 300 | /** 301 | * Wraps a failure callback for web requests. This handles web errors like 302 | * connection failures, and triggers events accordingly. 303 | */ 304 | wrapFailureCallback : function(cb) { 305 | var events = this.events; 306 | return function(ex) { 307 | if( typeof(ex) != "undefined" && ex instanceof neo4j.exceptions.ConnectionLostException ) { 308 | events.trigger("web.connection_lost", _.toArray(arguments)); 309 | 310 | // For backwards compatibility 311 | events.trigger("web.connection.failed", _.toArray(arguments)); 312 | } 313 | 314 | cb.apply(this, arguments); 315 | }; 316 | }, 317 | 318 | /** 319 | * Go through the arguments array that the ajax method recieves, 320 | * and return a map containing appropriate handlers, request method, 321 | * data and url. 322 | */ 323 | _processAjaxArguments : function(args) { 324 | var method, url, data, success, failure, 325 | args = _.toArray(args); 326 | 327 | method = args.shift(); 328 | url = args.shift(); 329 | 330 | data = args.length > 0 && !_.isFunction(args[0]) ? args.shift() : null; 331 | 332 | success = args.length > 0 ? args.shift() : null; 333 | failure = args.length > 0 ? args.shift() : null; 334 | 335 | success = _.isFunction(success) ? success : function() {}; 336 | failure = _.isFunction(failure) ? failure : function() {}; 337 | 338 | return { 339 | method : method, 340 | url : url, 341 | data : data, 342 | success : success, 343 | failure : failure 344 | } 345 | } 346 | 347 | }); 348 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/__init__.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * @namespace globally available namespace under which all parts of neo4js are 22 | * available. 23 | */ 24 | var neo4j = neo4j || {}; 25 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/cachedFunction.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Used to wrap a tiny cache around a single function. Currently only works for 22 | * functions that return their result via callbacks. 23 | * 24 | * This is extremely simplistic, it does not take into account using different 25 | * parameters and so on, it simply caches the first response the function makes, 26 | * and then keeps responding with that answer. 27 | * 28 | * @param func 29 | * is the function to wrap 30 | * @param callbackArg 31 | * is the position of the callback argument to the wrapped function. 32 | * @param timeout 33 | * (optional) is the time in milliseconds before the cache becomes 34 | * invalid, default is infinity (-1). 35 | */ 36 | neo4j.cachedFunction = function(func, callbackArg, timeout) { 37 | 38 | var cachedResult = null, 39 | cachedResultContext = null, 40 | isCached = false, 41 | timeout = timeout || false, 42 | waitingList = []; 43 | 44 | return function wrap() { 45 | var callback = arguments[callbackArg]; 46 | 47 | if (isCached) 48 | { 49 | callback.apply(cachedResultContext, cachedResult); 50 | } else 51 | { 52 | 53 | waitingList.push(callback); 54 | 55 | if (waitingList.length === 1) 56 | { 57 | 58 | arguments[callbackArg] = function() { 59 | cachedResultContext = this; 60 | cachedResult = arguments; 61 | isCached = true; 62 | 63 | for ( var i in waitingList) 64 | { 65 | waitingList[i].apply(cachedResultContext, cachedResult); 66 | } 67 | 68 | waitingList = []; 69 | 70 | if (timeout) 71 | { 72 | setTimeout(function() { 73 | isCached = false; 74 | }, timeout); 75 | } 76 | }; 77 | 78 | func.apply(this, arguments); 79 | 80 | } 81 | 82 | } 83 | }; 84 | } 85 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/cypher/ExecutionEngine.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Cypher query execution. 22 | * 23 | * @class 24 | * @param db Should be a GraphDatabase instance. 25 | */ 26 | neo4j.cypher.ExecutionEngine = function(db) 27 | { 28 | 29 | /** 30 | * A GraphDatabase instance. 31 | */ 32 | this.db = db; 33 | 34 | }; 35 | 36 | _.extend(neo4j.cypher.ExecutionEngine.prototype, 37 | 38 | /** @lends neo4j.cypher.ExecutionEngine# */ 39 | { 40 | 41 | execute : function(query) { 42 | var self = this; 43 | return this.db.getServiceDefinition().then(function(urls, fulfill, fail) { 44 | self.db.web.post(urls['cypher'], {query:query}, function(result) { 45 | fulfill(new neo4j.cypher.QueryResult(self.db, result)); 46 | }, fail); 47 | }); 48 | } 49 | 50 | } 51 | ); 52 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/cypher/QueryResult.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Cypher query execution. 22 | * 23 | * @class 24 | * @param db Should be a GraphDatabase instance. 25 | * @param rawResult Should be the raw result returned by the server. 26 | */ 27 | neo4j.cypher.QueryResult = function(db, rawResult) 28 | { 29 | 30 | /** 31 | * A GraphDatabase instance. 32 | */ 33 | this.db = db; 34 | 35 | /** 36 | * The raw server result 37 | */ 38 | this.data = rawResult.data; 39 | 40 | /** 41 | * An aaray of column names 42 | */ 43 | this.columns = rawResult.columns; 44 | 45 | this.pointer = 0; 46 | 47 | this.columnMap = {}; 48 | for(var i=0;i. 19 | */ 20 | /** 21 | * QueryResult row. 22 | * 23 | * @class 24 | * @param db Should be a GraphDatabase instance. 25 | * @param row Should be an array of raw values for this row. 26 | * @param columnMap Should be a lookup table for column -> row index 27 | */ 28 | neo4j.cypher.ResultRow = function(db, row, columnMap) 29 | { 30 | 31 | /** 32 | * A GraphDatabase instance. 33 | */ 34 | this.db = db; 35 | 36 | /** 37 | * The raw server result 38 | */ 39 | this.row = row; 40 | 41 | /** 42 | * A lookup table for columns 43 | */ 44 | this.columnMap = columnMap; 45 | 46 | this.pointer = 0; 47 | 48 | }; 49 | 50 | _.extend(neo4j.cypher.ResultRow.prototype, 51 | 52 | /** @lends neo4j.cypher.ResultRow# */ 53 | { 54 | 55 | size : function() { 56 | return this.row.length; 57 | }, 58 | 59 | getByIndex : function(index) { 60 | return this._convertValue(this.row[index]); 61 | }, 62 | 63 | get : function(name) { 64 | return this.getByIndex(this.columnMap[name]); 65 | }, 66 | 67 | next : function() { 68 | return this.getByIndex(this.pointer++); 69 | }, 70 | 71 | hasNext : function() { 72 | return this.pointer < this.size(); 73 | }, 74 | 75 | reset : function() { 76 | this.pointer = 0; 77 | }, 78 | 79 | _convertValue : function(value) { 80 | if(value === null) { 81 | return null; 82 | } else if( typeof(value.data) !== "undefined") { 83 | if(typeof(value.type) !== "undefined") { // Relationship 84 | return new neo4j.models.Relationship(value, this.db); 85 | } else if(typeof(value.length) !== "undefined") { // Path 86 | // TODO 87 | return JSON.stringify(value); 88 | } else { // Node 89 | return new neo4j.models.Node(value, this.db); 90 | } 91 | } else { 92 | return value; 93 | } 94 | } 95 | 96 | } 97 | ); 98 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/cypher/__init__.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * @namespace cypher. 22 | */ 23 | neo4j.cypher = neo4j.cypher || {}; 24 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/exceptions/ConnectionLostException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Triggered when there is some error in transit or on the server 22 | * side. 23 | */ 24 | neo4j.exceptions.ConnectionLostException = function() { 25 | 26 | neo4j.exceptions.HttpException.call(this, -1, null, null, "The server connection was lost."); 27 | 28 | }; 29 | 30 | neo4j.exceptions.HttpException.prototype = new neo4j.exceptions.HttpException(); 31 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/exceptions/HttpException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Triggered when there is some error in transit or on the server 22 | * side. 23 | */ 24 | neo4j.exceptions.HttpException = function(status, data, req, message) { 25 | var message = message || "A server error or a network error occurred. Status code: " + status + "."; 26 | this.status = status; 27 | this.data = data || {}; 28 | this.req = req || {}; 29 | Error.call(this, message); 30 | }; 31 | 32 | neo4j.exceptions.HttpException.prototype = new Error(); 33 | 34 | /** 35 | * These are used to generate #isConflict(), #isNotFound() etc., 36 | * based on the keys of this map. 37 | */ 38 | neo4j.exceptions.HttpException.RESPONSE_CODES = { 39 | 'Conflict' : 409, 40 | 'NotFound' : 404 41 | }; 42 | 43 | /** 44 | * Generate methods to rapidly check what a given response 45 | * code means. 46 | */ 47 | (function() { 48 | var ex = neo4j.exceptions.HttpException.prototype, 49 | codes = neo4j.exceptions.HttpException.RESPONSE_CODES; 50 | _.each(_.keys(codes), function(key) { 51 | ex['is' + key] = function() { 52 | return this.status === codes[key]; 53 | }; 54 | }); 55 | })(); 56 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/exceptions/InvalidDataException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Triggered when instantiating a node or relationship with invalid data. 22 | */ 23 | neo4j.exceptions.InvalidDataException = function() { 24 | Error.call(this, "Unable to create relationship or node from the provided data. This may be because you tried to get a node or relationship from an invalid url."); 25 | }; 26 | 27 | neo4j.exceptions.InvalidDataException.prototype = new Error(); 28 | 29 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/exceptions/NotFoundException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Triggered when a node or relationship cannot be found. 22 | */ 23 | neo4j.exceptions.NotFoundException = function(url) { 24 | Error.call(this, "The object at url " + url + " does not exist."); 25 | this.url = url; 26 | }; 27 | 28 | neo4j.exceptions.NotFoundException.prototype = new Error(); 29 | 30 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/exceptions/StartNodeSameAsEndNodeException.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Triggered when creating self-relationships. 22 | */ 23 | neo4j.exceptions.StartNodeSameAsEndNodeException = function(url) { 24 | Error.call(this, "You cannot create a relationship with the same start and end node."); 25 | this.url = url; 26 | }; 27 | 28 | neo4j.exceptions.StartNodeSameAsEndNodeException.prototype = new Error(); 29 | 30 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/exceptions/__init__.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * @namespace Exception namespace. 22 | */ 23 | neo4j.exceptions = neo4j.exceptions || {}; 24 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/index/Index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Abstract parent class for NodeIndex and RelationshipIndex. 22 | * 23 | * @class 24 | * @param db Should be a GraphDatabase instance. 25 | * @param name Should be the index name 26 | */ 27 | neo4j.index.Index = function(db, name) 28 | { 29 | 30 | /** 31 | * A GraphDatabase instance. 32 | */ 33 | this.db = db; 34 | 35 | /** 36 | * The name of this index. 37 | */ 38 | this.name = name; 39 | 40 | /** 41 | * Configuration for this index, may be null 42 | * if config has not been fetched. 43 | */ 44 | this.config = null; 45 | 46 | /** 47 | * Provider name 48 | */ 49 | this.provider = "N/A"; 50 | 51 | _.bindAll(this, 'query', 'exactQuery', 52 | 'index', 'unindex'); 53 | 54 | }; 55 | 56 | _.extend(neo4j.index.Index.prototype, 57 | 58 | /** @lends neo4j.index.Index# */ 59 | { 60 | 61 | getUriFor : function(item) { return ""; }, // To be implemented by subclasses 62 | getObjectFor : function(itemOrUri) { return ""; }, // To be implemented by subclasses 63 | getType : function() { return ""; }, // To be implemented by subclasses 64 | createObjectFromDefinition : function(def) {}, 65 | 66 | getIdFor : function(itemPromise) { 67 | return itemPromise.then(function(item, fulfill) { 68 | fulfill(item.getId()); 69 | }); 70 | }, 71 | 72 | /** 73 | * Internal method, does not update 74 | * the actual configuration used in the DB. 75 | */ 76 | setConfig : function(config) { 77 | this.config = config; 78 | }, 79 | 80 | /** 81 | * Check if configuration info has been downloaded 82 | * for this index. Config info is automatically made 83 | * available if you get indexes via the getAllXIndexes methods. 84 | */ 85 | configAvailable : function() { 86 | return this.config !== null; 87 | }, 88 | 89 | getConfig : function() { 90 | return this.config; 91 | }, 92 | 93 | /** 94 | * Perform an index query. How to write the query depends on what index 95 | * provider you are using, which you (on purpose or indirectly) decided when you created your index. 96 | * The default one is Lucene, in which case you should use Lucene 97 | * query syntax here. 98 | * 99 | * For Lucene query syntax, see: http://lucene.apache.org/java/3_1_0/queryparsersyntax.html 100 | * 101 | * @param query A query string 102 | * @return A list of nodes or relationships, depending on index type. 103 | */ 104 | query : function(query) { 105 | var index = this; 106 | return this.db.getServiceDefinition().then(function(urls, fulfill, fail) { 107 | index.db.web.get(urls[index.getType()] + "/" + index.name, {query:query}, function(result) { 108 | var out = []; 109 | for(var i=0,l=result.length; i. 19 | */ 20 | /** 21 | * Handles node and relationship indexes. 22 | * 23 | * @class 24 | * @param db Should be a GraphDatabase instance. 25 | */ 26 | neo4j.index.Indexes = function(db) 27 | { 28 | 29 | /** 30 | * A GraphDatabase instance. 31 | */ 32 | this.db = db; 33 | 34 | this._cache = {}; 35 | 36 | _.bindAll(this, 'getNodeIndex', 'getRelationshipIndex', 37 | 'createNodeIndex', 'createRelationshipIndex', 38 | 'removeNodeIndex', 'removeRelationshipIndex'); 39 | 40 | }; 41 | 42 | _.extend(neo4j.index.Indexes.prototype, 43 | /** @lends neo4j.index.Indexes# */ 44 | { 45 | 46 | /** 47 | * List all node indexes in the database. 48 | * 49 | * Ex: 50 | * 51 | * db.indexes.getAllNodeIndexes().then(function(indexes) { 52 | * // Use indexes. 53 | * }); 54 | * 55 | * @return A promise object, promising a list of {@link neo4j.index.NodeIndex} instances. 56 | */ 57 | getAllNodeIndexes : function() { 58 | return this._listAllIndexes("node_index"); 59 | }, 60 | 61 | 62 | /** 63 | * List all relationship indexes in the database. 64 | * 65 | * Ex: 66 | * 67 | * db.indexes.getAllNodeIndexes().then(function(indexes) { 68 | * // Use indexes. 69 | * }); 70 | * 71 | * @return A promise object, promising a list of {@link neo4j.index.RelationshipIndex} instances. 72 | */ 73 | getAllRelationshipIndexes : function() { 74 | return this._listAllIndexes("relationship_index"); 75 | }, 76 | 77 | /** 78 | * Retrieve a single index by name. The index does not have 79 | * to exist, it will be created the first time you insert something 80 | * into it. You can, however, not query a non-existant index. 81 | * 82 | * @param name Should be the name of the index. 83 | * @return {@link neo4j.index.NodeIndex} 84 | */ 85 | getNodeIndex : function(name) { 86 | return this._getOrCreateLocalIndexObject("node_index", name); 87 | }, 88 | 89 | 90 | /** 91 | * Retrieve a single index by name. The index does not have 92 | * to exist, it will be created the first time you insert something 93 | * into it. You can, however, not query a non-existant index. 94 | * 95 | * @param name Should be the name of the index. 96 | * @return {@link neo4j.index.RelationshipIndex} 97 | */ 98 | getRelationshipIndex : function(name) { 99 | return this._getOrCreateLocalIndexObject("relationship_index", name); 100 | }, 101 | 102 | /** 103 | * Create a new index. 104 | * 105 | * @param name A unique index name. 106 | * @param config Optional configuration map, see neo4j server REST documentation. 107 | * @return A promise object, promising a {@link neo4j.index.NodeIndex} 108 | */ 109 | createNodeIndex : function(name, config) { 110 | return this._createIndex("node_index", name, config); 111 | }, 112 | 113 | 114 | /** 115 | * Create a new index. 116 | * 117 | * @param name A unique index name. 118 | * @param config Optional configuration map, see neo4j server REST documentation. 119 | * @return A promise object, promising a {@link neo4j.index.RelationshipIndex} 120 | */ 121 | createRelationshipIndex : function(name, config) { 122 | return this._createIndex("relationship_index", name, config); 123 | }, 124 | 125 | /** 126 | * Removes an index. 127 | * 128 | * @param name Name of index to remove. 129 | * @return A promise for the delete operation to complete. 130 | */ 131 | removeNodeIndex : function(name) { 132 | return this._removeIndex("node_index", name); 133 | }, 134 | 135 | 136 | /** 137 | * Removes an index. 138 | * 139 | * @param name Name of index to remove. 140 | * @return A promise for the delete operation to complete. 141 | */ 142 | removeRelationshipIndex : function(name) { 143 | return this._removeIndex("relationship_index", name); 144 | }, 145 | 146 | _listAllIndexes : function(type) { 147 | var db = this.db, 148 | indexes = this; 149 | return this.db.getServiceDefinition().then(function(urls, fulfill, fail){ 150 | db.web.get(urls[type], function(indexMap) { 151 | var indexList = [], 152 | indexNames = indexMap === null ? [] : _(indexMap).keys(); 153 | 154 | for(var i=0,l=indexNames.length;i. 19 | */ 20 | /** 21 | * A node index. 22 | * 23 | * @class 24 | * @extends neo4j.index.Index 25 | * @param db Should be a GraphDatabase instance. 26 | * @param name Should be the index name 27 | */ 28 | neo4j.index.NodeIndex = function(db, name) 29 | { 30 | 31 | neo4j.index.Index.call(this, db, name); 32 | 33 | }; 34 | 35 | _.extend(neo4j.index.NodeIndex.prototype, neo4j.index.Index.prototype, 36 | /** @lends neo4j.index.NodeIndex# */ 37 | { 38 | 39 | /** 40 | * @private 41 | */ 42 | getType : function() { 43 | return "node_index"; 44 | }, 45 | 46 | /** 47 | * @private 48 | */ 49 | getUriFor : function(itemPromise) { 50 | var db = this.db; 51 | return itemPromise.then(function(item, fulfill) { 52 | db.nodeUri(item).then(fulfill); 53 | }); 54 | }, 55 | 56 | /** 57 | * @private 58 | */ 59 | getObjectFor : function(unknownPromise) { 60 | var db = this.db; 61 | return unknownPromise.then(function(unknown, fulfill) { 62 | if(typeof(unknown.getSelf) != "undefined") { 63 | fulfill(unknown); 64 | } else { 65 | db.node(unknown).then(function(node) { 66 | fulfill(node); 67 | }); 68 | } 69 | }); 70 | }, 71 | 72 | /** 73 | * @private 74 | */ 75 | createObjectFromDefinition : function(def) { 76 | return new neo4j.models.Node(def, this.db); 77 | } 78 | 79 | }); 80 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/index/RelationshipIndex.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * A relationship index. 22 | * 23 | * @class 24 | * @extends neo4j.index.Index 25 | * @param db Should be a GraphDatabase instance. 26 | * @param name Should be the index name 27 | */ 28 | neo4j.index.RelationshipIndex = function(db, name) 29 | { 30 | 31 | neo4j.index.Index.call(this, db, name); 32 | 33 | }; 34 | 35 | _.extend(neo4j.index.RelationshipIndex.prototype, neo4j.index.Index.prototype, 36 | /** @lends neo4j.index.RelationshipIndex# */ 37 | { 38 | /** 39 | * @private 40 | */ 41 | getType : function() { 42 | return "relationship_index"; 43 | }, 44 | 45 | /** 46 | * @private 47 | */ 48 | getUriFor : function(itemPromise) { 49 | var db = this.db; 50 | return itemPromise.then(function(item, fulfill) { 51 | db.relUri(item).then(fulfill); 52 | }); 53 | }, 54 | 55 | /** 56 | * @private 57 | */ 58 | getObjectFor : function(unknownPromise) { 59 | var db = this.db; 60 | return unknownPromise.then(function(unknown, fulfill) { 61 | if(typeof(unknown.getSelf) != "undefined") { 62 | fulfill(unknown); 63 | } else { 64 | db.rel(unknown).then(function(rel) { 65 | fulfill(rel); 66 | }); 67 | } 68 | }); 69 | }, 70 | 71 | /** 72 | * @private 73 | */ 74 | createObjectFromDefinition : function(def) { 75 | return new neo4j.models.Relationship(def, this.db); 76 | } 77 | 78 | 79 | }); 80 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/index/__init__.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * @namespace Index utilities. 22 | */ 23 | neo4j.index = neo4j.index || {}; 24 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/log.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Thin wrapper around console.log, making sure it exists. 22 | * @param anything, all will be passed to console.log 23 | */ 24 | neo4j.log = function() { 25 | if( typeof(console) != "undefined" && typeof(console.log) === "function") { 26 | console.log.apply(this, arguments); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/models/JMXBean.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Represents a server-side JMX Bean. 22 | * 23 | * Each bean has an attribute map, containing the actual 24 | * JMX data, and a property map, which contains data parsed 25 | * from the JMX Bean name. 26 | * 27 | * Each bean also has a domain attribute, which is a string 28 | * representation of the JMX domain. 29 | */ 30 | neo4j.models.JMXBean = function(data) { 31 | 32 | this.parse(data); 33 | 34 | }; 35 | 36 | /** 37 | * Parse server-provided JSON data and use it to populate this model. 38 | */ 39 | neo4j.models.JMXBean.prototype.parse = function(bean) { 40 | 41 | var parsedNameMap = this.parseName(bean.name); 42 | 43 | this.domain = parsedNameMap.domain; 44 | delete(parsedNameMap.domain); // We don't want this in the properties map. 45 | 46 | this.properties = parsedNameMap; 47 | this.attributes = bean.attributes; 48 | this.description = bean.description; 49 | this.jmxName = bean.name; 50 | 51 | }; 52 | 53 | /** 54 | * Get a name for this bean. This will check if there is a name property 55 | * in the beanname (ie. some.domain:type=MemoryManager,name=CodeCacheManager ), 56 | * and return that. If none is available, it will return the first property, 57 | * and as a last resort, it will return the raw jmx name. 58 | */ 59 | neo4j.models.JMXBean.prototype.getName = function(bean) { 60 | if ( this.properties['name'] ) { 61 | return this.properties['name']; 62 | } else { 63 | for(var name in this.properties) { 64 | return this.properties[name]; 65 | } 66 | } 67 | 68 | return this.jmxName; 69 | }; 70 | 71 | /** 72 | * Parse jmx beanname ( something like some.domain:type=MemoryManager,name=CodeCacheManager ). 73 | */ 74 | neo4j.models.JMXBean.prototype.parseName = function(name) { 75 | 76 | var parts = name.split(":"), 77 | part, domain, 78 | parsed = {}; 79 | 80 | domain = parts[0]; 81 | parts = parts[1].split(","); 82 | 83 | for(var i = 0, l=parts.length; i. 19 | */ 20 | /** 21 | * Represents a database node. 22 | * 23 | * @class 24 | * @extends neo4j.models.PropertyContainer 25 | * @param arg 26 | * Is either a node url or, to create a new node, a map. 27 | */ 28 | neo4j.models.Node = function(arg, db) 29 | { 30 | 31 | neo4j.models.PropertyContainer.call(this); 32 | 33 | this.db = db; 34 | this._init(arg); 35 | 36 | _.bindAll(this, 'save', 'fetch', 'getRelationships', '_init'); 37 | 38 | }; 39 | 40 | neo4j.models.Node.IN = "in"; 41 | neo4j.models.Node.OUT = "out"; 42 | neo4j.models.Node.ALL = "all"; 43 | 44 | // Defined here until we break out a proper traversal subsystem 45 | neo4j.traverse = {}; 46 | neo4j.traverse.RETURN_NODES = "node"; 47 | neo4j.traverse.RETURN_RELATIONSHIPS = "relationship"; 48 | neo4j.traverse.RETURN_PATHS = "path"; 49 | 50 | _.extend(neo4j.models.Node.prototype, neo4j.models.PropertyContainer.prototype, 51 | 52 | /** @lends neo4j.models.Node# */ 53 | { 54 | 55 | /** 56 | * Save this node. Creates the node if it does not have a url. 57 | * 58 | * @return A {@link neo4j.Promise} for a saved node. 59 | */ 60 | save : function() 61 | { 62 | var node = this, web = this.db.web; 63 | if ( ! this.exists() ) 64 | { 65 | return new neo4j.Promise(function(fulfill, fail) 66 | { 67 | node.db.getServiceDefinition().then(function(dbDefinition) { 68 | web.post(dbDefinition.node, node._data).then(function(response) { 69 | node._init(response.data); 70 | fulfill(node); 71 | }, fail); 72 | }, fail); 73 | }); 74 | } else 75 | { 76 | return new neo4j.Promise(function(fulfill, fail) 77 | { 78 | web.put(node._urls.properties, node.getProperties(), function(){ 79 | fulfill(node); 80 | }, fail); 81 | }); 82 | } 83 | }, 84 | 85 | /** 86 | * Fetch data for this node. Use to populate a node that only has a _self 87 | * url, or to refresh the data in the node. 88 | * 89 | * @return A {@link neo4j.Promise} of a populated node. 90 | */ 91 | fetch : function() 92 | { 93 | var node = this, web = this.db.web; 94 | return new neo4j.Promise(function(fulfill, fail) 95 | { 96 | web.get(node._self).then(function(response) 97 | { 98 | if(response.data && response.data.self) { 99 | node._init(response.data); 100 | fulfill(node); 101 | } else { 102 | fail(new neo4j.exceptions.InvalidDataException()); 103 | } 104 | }, function(err) { 105 | fail(new neo4j.exceptions.NotFoundException(node._self)); 106 | }); 107 | }); 108 | }, 109 | 110 | /** 111 | * Remove this node. 112 | * @return A promise that will be fulfilled when the node is deleted. 113 | */ 114 | remove : function() { 115 | var node = this, web = this.db.web, hasDeletedRelationships = false, 116 | db = this.db, nodeUrl = node.getSelf(); 117 | 118 | return new neo4j.Promise(function(fulfill, fail) { 119 | web.del(node.getSelf()).then(function() { 120 | db.getReferenceNodeUrl().then(function(url) { 121 | if(url == nodeUrl) { 122 | db.forceRediscovery(); 123 | } 124 | fulfill(true); 125 | }, fail); 126 | }, function(response) { 127 | if(response.error.isConflict() && !hasDeletedRelationships) { 128 | // Need to remove relationships 129 | node.getRelationships().then(function(rels) { 130 | _.each(rels, function(rel) { 131 | rel.remove(); 132 | }); 133 | 134 | // Ensure we don't end up in recursive loop 135 | hasDeletedRelationships = true; 136 | node.remove().then(function() { 137 | fulfill(true); 138 | }, fail); 139 | }, fail); 140 | } 141 | }); 142 | }); 143 | }, 144 | 145 | getCreateRelationshipUrl : function() { 146 | if(this.exists()) { 147 | return this._urls.create_relationship; 148 | } else { 149 | throw new Error("You can't get the create relationship url until you have saved the node!"); 150 | } 151 | }, 152 | 153 | /** 154 | * Perform a traversal starting from this node. 155 | * @param traversal should be a map conforming to http://components.neo4j.org/neo4j-server/snapshot/rest.html#Traverse 156 | * @param returnType (optional) One of: 157 | * neo4j.traverse.RETURN_NODES (default) 158 | * neo4j.traverse.RETURN_RELATIONSHIPS 159 | * neo4j.traverse.RETURN_PATHS 160 | * @return A promise for an array of whatever type you asked for. 161 | */ 162 | traverse : function(traversal, returnType) { 163 | returnType = returnType || neo4j.traverse.RETURN_NODES 164 | var url = this.db.web.replace(this._urls['traverse'], {'returnType' : returnType}), 165 | node = this, 166 | modelClass; 167 | 168 | switch(returnType) { 169 | case neo4j.traverse.RETURN_RELATIONSHIPS: 170 | modelClass = neo4j.models.Relationship; 171 | break; 172 | case neo4j.traverse.RETURN_PATHS: 173 | modelClass = neo4j.models.Path; 174 | break; 175 | default: 176 | modelClass = neo4j.models.Node; 177 | break; 178 | } 179 | 180 | return new neo4j.Promise(function(fulfill, fail) { 181 | node.db.web.post(url, traversal).then(function(response) { 182 | var instances = _.map( response.data, function(r) { 183 | return new modelClass(r, node.db); 184 | }); 185 | fulfill(instances); 186 | }, fail); 187 | }); 188 | }, 189 | 190 | /** 191 | * Get relationships in some given direction for this node. 192 | * @param dir (optional) One of {@link neo4j.models.Node.IN}, {@link neo4j.models.Node.OUT}, {@link neo4j.models.Node.ALL}. 193 | * @param types (optional) A single string or an array of strings. 194 | * @return A promise for an array of relationships. 195 | */ 196 | getRelationships : function(dir, types) { 197 | var dir = dir || neo4j.models.Node.ALL, 198 | types = types || null, 199 | node = this, 200 | url; 201 | 202 | var hasTypes = types ? true : false; 203 | 204 | if(_.isArray(types)) { 205 | types = types.join("&"); 206 | } 207 | 208 | switch(dir) { 209 | case neo4j.models.Node.IN: 210 | url = hasTypes ? this._urls['incoming_typed_relationships'] : 211 | this._urls['incoming_relationships']; 212 | break; 213 | case neo4j.models.Node.OUT: 214 | url = hasTypes ? this._urls['outgoing_typed_relationships'] : 215 | this._urls['outgoing_relationships']; 216 | break; 217 | default: 218 | url = hasTypes ? this._urls['all_typed_relationships'] : 219 | this._urls['all_relationships']; 220 | break; 221 | } 222 | 223 | if(hasTypes) { 224 | url = this.db.web.replace(url, {'-list|&|types' : types}); 225 | } 226 | 227 | return new neo4j.Promise(function(fulfill, fail) { 228 | node.db.web.get(url).then(function(response) { 229 | var instances = _.map( 230 | response.data, 231 | function(r) { 232 | return new neo4j.models.Relationship(r, node.db); 233 | }); 234 | fulfill(instances); 235 | }, fail); 236 | }); 237 | }, 238 | 239 | /** 240 | * Used to initialize a node object from json data recieved from a neo4j 241 | * server. 242 | */ 243 | _init : function(definition) 244 | { 245 | this._self = definition.self || null; 246 | this._data = definition.data || {}; 247 | 248 | this._urls = { 249 | 'properties' : definition.properties || "", 250 | 'traverse' : definition.traverse || "", 251 | 'create_relationship' : definition.create_relationship || "", 252 | 'all_relationships' : definition.all_relationships || "", 253 | 'all_typed_relationships' : definition.all_typed_relationships || "", 254 | 'incoming_relationships' : definition.incoming_relationships || "", 255 | 'incoming_typed_relationships' : definition.incoming_typed_relationships || "", 256 | 'outgoing_relationships' : definition.outgoing_relationships || "", 257 | 'outgoing_typed_relationships' : definition.outgoing_typed_relationships || "" 258 | }; 259 | 260 | } 261 | 262 | }); 263 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/models/Path.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Represents a path through the graph. 22 | */ 23 | neo4j.models.Path = function(arg, db) { 24 | 25 | this.db = db; 26 | this._init(arg); 27 | 28 | _.bindAll(this, '_init'); 29 | 30 | }; 31 | 32 | _.extend(neo4j.models.Path.prototype, { 33 | 34 | /** 35 | * Used to initialize a path object from json data recieved from a neo4j 36 | * server. 37 | */ 38 | _init : function(definition) 39 | { 40 | this._start = definition.start; 41 | this._end = definition.end; 42 | this._length = definition.length; 43 | 44 | this._nodeUrls = definition.nodes; 45 | this._relationshipUrls = definition.relationships; 46 | } 47 | }); 48 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/models/PropertyContainer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Contains methods shared by nodes and relationships. 22 | */ 23 | neo4j.models.PropertyContainer = function() { 24 | 25 | _.bindAll(this, 'getSelf', 'exists', 'getProperty', 'setProperty', 'getProperties', 'setProperties'); 26 | 27 | this._data = this._data || {}; 28 | 29 | }; 30 | 31 | _.extend(neo4j.models.PropertyContainer.prototype, { 32 | 33 | /** 34 | * Get the identifier (url) for this object. Will return null if 35 | * the object is not yet saved. 36 | */ 37 | getSelf : function() 38 | { 39 | return typeof(this._self) != "undefined" ? this._self : null; 40 | }, 41 | 42 | /** 43 | * Get the numeric id for this object. Returns null if 44 | * the object is not yet saved. 45 | */ 46 | getId : function() { 47 | var url = this.getSelf(); 48 | return url == null ? null : url.substr(url.lastIndexOf("/")+1); 49 | }, 50 | 51 | /** 52 | * @return true if this object has a url. 53 | */ 54 | exists : function() { 55 | return this.getSelf() !== null; 56 | }, 57 | 58 | /** 59 | * Check if a property exists. 60 | */ 61 | hasProperty : function(key) { 62 | return key in this._data; 63 | }, 64 | 65 | /** 66 | * Get a property by key. 67 | */ 68 | getProperty : function(key) { 69 | return this._data[key] || null; 70 | }, 71 | 72 | /** 73 | * Set a property. 74 | */ 75 | setProperty : function(key, value) { 76 | this._data[key] = value; 77 | }, 78 | 79 | /** 80 | * Get all properties. 81 | * @return Map of all properties 82 | */ 83 | getProperties : function() { 84 | return this._data; 85 | }, 86 | 87 | /** 88 | * Set several properties at once. 89 | */ 90 | setProperties : function(properties) { 91 | this._data = _.extend(this._data, properties); 92 | }, 93 | 94 | /** 95 | * Remove a property. 96 | */ 97 | removeProperty : function(key) { 98 | delete(this._data[key]); 99 | } 100 | 101 | }); 102 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/models/Relationship.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Represents a database relationship. 22 | * 23 | * 24 | * @class 25 | * @extends neo4j.models.PropertyContainer 26 | * 27 | * @param arg Should be an object matching that returned by neo4j server 28 | * when fetching or creating relationships. If you are fetching a relationship, 29 | * only the "self" parameter is required. Call #fetch() to load the rest of the 30 | * data. 31 | * 32 | * If you are creating a relationship, the attributes "start", "end" and "type" 33 | * are required. Start and end can either be urls or Node objects. Call #save() 34 | * to create the relationship. 35 | */ 36 | neo4j.models.Relationship = function(arg, db) { 37 | 38 | neo4j.models.PropertyContainer.call(this); 39 | 40 | this.db = db; 41 | this._init(arg); 42 | 43 | _.bindAll(this, 'save', 'fetch', '_init'); 44 | 45 | }; 46 | 47 | _.extend(neo4j.models.Relationship.prototype, neo4j.models.PropertyContainer.prototype, 48 | 49 | /** @lends neo4j.models.Relationship# */ 50 | { 51 | 52 | /** 53 | * Save this relationship. Creates the relationship if it does not have a url. 54 | * 55 | * @return A {@link neo4j.Promise} for a saved relationship. 56 | */ 57 | save : function() 58 | { 59 | var rel = this, web = this.db.web; 60 | if ( ! this.exists() ) 61 | { 62 | return this.getStartNode().then(function(node, fulfill, fail) { 63 | var req = web.post(node.getCreateRelationshipUrl(), { 64 | to: rel._endUrl, 65 | type: rel.getType(), 66 | data: rel.getProperties()}); 67 | 68 | req.then(function(response) { 69 | rel._init(response.data); 70 | fulfill(rel); 71 | }, function(response) { 72 | if(response.error 73 | && response.error.data 74 | && response.error.data.exception) { 75 | var ex = response.error.data.exception; 76 | if(ex.indexOf("EndNodeNotFoundException") > -1 77 | || (ex.indexOf("BadInputException") > -1 && ex.indexOf(rel._endUrl) > -1) ) { 78 | return fail(new neo4j.exceptions.NotFoundException(rel._endUrl)); 79 | } else if (ex.indexOf("StartNodeSameAsEndNodeException") > -1) { 80 | return fail(new neo4j.exceptions.StartNodeSameAsEndNodeException(rel._endUrl)); 81 | } 82 | } 83 | 84 | fail(response); 85 | }); 86 | }); 87 | } else 88 | { 89 | return new neo4j.Promise(function(fulfill, fail) 90 | { 91 | web.put(rel._urls.properties, rel.getProperties()).then(function(){ 92 | fulfill(rel); 93 | }, fail); 94 | }); 95 | } 96 | }, 97 | 98 | /** 99 | * Fetch data for this relationship. Use to populate a relationship that only has a _self 100 | * url, or to refresh the data. 101 | * 102 | * @return A {@link neo4j.Promise} of a populated relationship. 103 | */ 104 | fetch : function() 105 | { 106 | var rel = this, web = this.db.web; 107 | return new neo4j.Promise(function(fulfill, fail) 108 | { 109 | web.get(rel._self).then(function(response) { 110 | if(response.data && response.data.self && response.data.start && response.data.end) { 111 | rel._init(response.data); 112 | fulfill(rel); 113 | } else { 114 | fail(new neo4j.exceptions.InvalidDataException()); 115 | } 116 | }, fail); 117 | }); 118 | }, 119 | 120 | /** 121 | * Remove this relationship. 122 | * @return A promise that will be fulfilled when the relationship 123 | * is removed. 124 | */ 125 | remove : function() { 126 | var rel = this, web = this.db.web; 127 | return new neo4j.Promise(function(fulfill, fail) { 128 | web.del(rel.getSelf()).then(function() { 129 | fulfill(true); 130 | }, fail); 131 | }); 132 | }, 133 | 134 | /** 135 | * Get the type of this relationship. 136 | */ 137 | getType : function() { 138 | return this._type || null; 139 | }, 140 | 141 | /** 142 | * Get a promise for the node this relationship originates from. 143 | */ 144 | getStartNode : function() { 145 | return this._getNode("_startNode", "_startUrl"); 146 | }, 147 | 148 | /** 149 | * Fetches the url for the start node. Use this to avoid extra calls 150 | * to the server if you only need this url. 151 | */ 152 | getStartNodeUrl : function() { 153 | return this._startUrl; 154 | }, 155 | 156 | /** 157 | * Check if a node is the start node for this relationship. 158 | * @param String url or a node object 159 | * @return boolean 160 | */ 161 | isStartNode : function(node) { 162 | if( node instanceof neo4j.models.Node ) { 163 | return this._startUrl === node.getSelf(); 164 | } else { 165 | return this._startUrl === node; 166 | } 167 | }, 168 | 169 | /** 170 | * Get a promise for the node this relationship ends at. 171 | */ 172 | getEndNode : function() { 173 | return this._getNode("_endNode", "_endUrl"); 174 | }, 175 | 176 | /** 177 | * Fetches the url for the end node. Use this to avoid extra calls 178 | * to the server if you only need this url. 179 | */ 180 | getEndNodeUrl : function() { 181 | return this._endUrl; 182 | }, 183 | 184 | /** 185 | * Check if a node is the end node for this relationship. 186 | * @param String url or a node object 187 | * @return boolean 188 | */ 189 | isEndNode : function(node) { 190 | if( node instanceof neo4j.models.Node ) { 191 | return this._endUrl === node.getSelf(); 192 | } else { 193 | return this._endUrl === node; 194 | } 195 | }, 196 | 197 | /** 198 | * If provided the end node (or end node url) return promise 199 | * for start node. If provided start node, return promise for end node. 200 | */ 201 | getOtherNode : function(node) { 202 | if(this.isStartNode(node)) { 203 | return this.getEndNode(); 204 | } else { 205 | return this.getStartNode(); 206 | } 207 | }, 208 | 209 | /** 210 | * If provided the end node (or end node url) return url 211 | * for start node. If provided start node, return url for end node. 212 | */ 213 | getOtherNodeUrl : function(node) { 214 | if(this.isStartNode(node)) { 215 | return this.getEndNodeUrl(); 216 | } else { 217 | return this.getStartNodeUrl(); 218 | } 219 | }, 220 | 221 | /** 222 | * Get a promise for a node, given a property where the node should 223 | * be cached, and a property where we can find the url of the node 224 | * if it is not cached. 225 | */ 226 | _getNode : function(nodeAttribute, urlAttribute) { 227 | if( typeof(this[nodeAttribute]) != "undefined" ) { 228 | return neo4j.Promise.fulfilled(this[nodeAttribute]); 229 | } else { 230 | var rel = this; 231 | return this.db.node(this[urlAttribute]).then(function(node, fulfill) { 232 | rel[nodeAttribute] = node; 233 | fulfill(node); 234 | }); 235 | } 236 | }, 237 | 238 | /** 239 | * Used to initialize a relationship object from json data recieved from a neo4j 240 | * server. 241 | */ 242 | _init : function(definition) 243 | { 244 | this._self = definition.self || null; 245 | this._data = definition.data || {}; 246 | this._type = definition.type || null; 247 | 248 | this._urls = { 249 | 'properties' : definition.properties || "" 250 | }; 251 | 252 | if( typeof(definition.start) != "undefined" ) { 253 | if( definition.start instanceof neo4j.models.Node) { 254 | this._startNode = definition.start; 255 | this._startUrl = definition.start.getSelf(); 256 | } else { 257 | this._startUrl = definition.start; 258 | } 259 | } 260 | 261 | if( typeof(definition.end) != "undefined" ) { 262 | if( definition.end instanceof neo4j.models.Node) { 263 | this._endNode = definition.end; 264 | this._endUrl = definition.end.getSelf(); 265 | } else { 266 | this._endUrl = definition.end; 267 | } 268 | } 269 | } 270 | }); 271 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/models/__init__.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * @namespace namespace containing data models. 22 | */ 23 | neo4j.models = neo4j.models || {}; 24 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/proxy.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * This allows wrapping methods in closures, allowing them 22 | * to always be run in some pre-determined context. 23 | */ 24 | neo4j.proxy = function(arg1, arg2) { 25 | 26 | return _.bind(arg1, arg2); 27 | 28 | }; 29 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/services/BackupService.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * @class Interface to the backup functionality of the REST server. 22 | * @extends neo4j.Service 23 | * @param db 24 | * should be a neo4j.GraphDatabase object 25 | */ 26 | neo4j.services.BackupService = function(db) { 27 | 28 | neo4j.Service.call(this,db); 29 | 30 | }; 31 | 32 | _.extend(neo4j.services.BackupService.prototype, neo4j.Service.prototype); 33 | 34 | /** 35 | * Trigger a manual backup to the manual backup path defined in the server 36 | * settings. 37 | * 38 | * @param callback 39 | * will be called when the backup is completed 40 | * @function 41 | */ 42 | neo4j.services.BackupService.prototype.triggerManual = neo4j.Service 43 | .resourceFactory({ 44 | 'resource' : 'trigger_manual', 45 | 'method' : 'POST', 46 | 'errorHandler' : function(callback, error) { 47 | if (error.exception == "NoBackupFoundationException") 48 | { 49 | callback(false); 50 | } 51 | } 52 | }); 53 | 54 | /** 55 | * Trigger backup foundation on the currently configured manual backup path. 56 | * 57 | * @param callback 58 | * will be called when the foundation is done 59 | * @function 60 | */ 61 | neo4j.services.BackupService.prototype.triggerManualFoundation = neo4j.Service 62 | .resourceFactory({ 63 | 'resource' : 'trigger_manual_foundation', 64 | 'method' : 'POST' 65 | }); 66 | 67 | /** 68 | * Get a list of scheduled backup jobs and their latest logs. 69 | * 70 | * @param callback 71 | * will be called with the list 72 | * @function 73 | */ 74 | neo4j.services.BackupService.prototype.getJobs = neo4j.Service 75 | .resourceFactory({ 76 | 'resource' : 'jobs', 77 | 'method' : 'GET' 78 | }); 79 | 80 | /** 81 | * Get a single job by id 82 | * 83 | * @param id 84 | * is the id of the job 85 | * @param callback 86 | * will be called with the job 87 | * @function 88 | */ 89 | neo4j.services.BackupService.prototype.getJob = function(id, callback) { 90 | this.getJobs(function(jobs) { 91 | for ( var i in jobs.jobList) 92 | { 93 | if (jobs.jobList[i].id == id) 94 | { 95 | callback(jobs.jobList[i]); 96 | return; 97 | } 98 | } 99 | 100 | callback(null); 101 | }); 102 | }; 103 | 104 | /** 105 | * Delete a backup job 106 | * 107 | * @param id 108 | * the id of the job 109 | * @param callback 110 | * will be called when scheduled job is deleted 111 | * @function 112 | */ 113 | neo4j.services.BackupService.prototype.deleteJob = neo4j.Service 114 | .resourceFactory({ 115 | 'resource' : 'job', 116 | 'method' : 'DELETE', 117 | 'urlArgs' : [ "id" ] 118 | }); 119 | 120 | /** 121 | * Trigger foundation for a given scheduled job. 122 | * 123 | * @param id 124 | * the id of the job 125 | * @param callback 126 | * will be called when the foundation is done 127 | * @function 128 | */ 129 | neo4j.services.BackupService.prototype.triggerJobFoundation = neo4j.Service 130 | .resourceFactory({ 131 | 'resource' : 'trigger_job_foundation', 132 | 'method' : 'POST', 133 | 'urlArgs' : [ "id" ] 134 | }); 135 | 136 | /** 137 | * Create or edit a job schedule. If you supply an id in the job object, this 138 | * will edit that job. If you omit the id, a new job is created. 139 | * 140 | * @param job 141 | * A job JSON object.
142 | * This should look like: 143 | * 144 | *
145 |  * {
146 |  *     'id' : 12,
147 |  *     'name' : "Daily backups",
148 |  *     'backupPath' : "/var/backup",
149 |  *     'cronExpression' : "0 0 12 * * ? *",
150 |  *     'autoFoundation' : true
151 |  * }
152 |  * 
153 | * 154 | * @param callback 155 | * will be called when the action is complete. 156 | * @function 157 | */ 158 | neo4j.services.BackupService.prototype.setJob = neo4j.Service.resourceFactory({ 159 | 'resource' : 'jobs', 160 | 'method' : 'PUT' 161 | }); 162 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/services/ConfigService.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * @class Interface to the config functionality of the REST server. 22 | * @extends neo4j.Service 23 | * @param db 24 | * should be a neo4j.GraphDatabase object 25 | */ 26 | neo4j.services.ConfigService = function(db) { 27 | 28 | neo4j.Service.call(this,db); 29 | 30 | }; 31 | 32 | _.extend(neo4j.services.ConfigService.prototype, neo4j.Service.prototype); 33 | 34 | /** 35 | * Get a list of all available properties. 36 | * 37 | * @param callback 38 | * will be called with the list of properties 39 | * @function 40 | */ 41 | neo4j.services.ConfigService.prototype.getProperties = neo4j.Service 42 | .resourceFactory({ 43 | 'resource' : 'properties', 44 | 'method' : 'GET', 45 | 'before' : function(method, args) { 46 | 47 | var callback = args[0]; 48 | 49 | method(function(data) { 50 | // Convert array of objects to map 51 | var props = {}; 52 | for(var i in data) { 53 | props[data[i].key] = data[i]; 54 | } 55 | 56 | callback(props); 57 | }); 58 | } 59 | }); 60 | 61 | /** 62 | * Fetch a specific property 63 | * 64 | * @param key 65 | * is the property key 66 | * @param callback 67 | * will be called with the property 68 | */ 69 | neo4j.services.ConfigService.prototype.getProperty = function(key, callback) { 70 | this.getProperties(function(properties){ 71 | for(var propKey in properties) { 72 | if(propKey === key ) { 73 | callback(properties[propKey]); 74 | return; 75 | } 76 | } 77 | 78 | callback(null); 79 | }); 80 | }; 81 | 82 | /** 83 | * Set several settings at once. This will restart the server and/or the JVM as 84 | * appropriate. 85 | * 86 | * @param settings 87 | * should be a string map. Each key should map to a property key, and 88 | * the value should be the new value of that property. 89 | * @param callback 90 | * will be called when the foundation is done 91 | * @function 92 | */ 93 | neo4j.services.ConfigService.prototype.setProperties = neo4j.Service 94 | .resourceFactory({ 95 | 'resource' : 'properties', 96 | 'method' : 'POST', 97 | 'before' : function(method, args) { 98 | 99 | // Convert map to array of objects 100 | var props = []; 101 | var prop; 102 | for ( var key in args[0]) 103 | { 104 | prop = { 105 | key : key, 106 | value : args[0][key] 107 | }; 108 | props.push(prop); 109 | this.db.trigger("config.property.set", prop); 110 | } 111 | 112 | method(props, args[1]); 113 | } 114 | }); 115 | 116 | /** 117 | * Set a specific property 118 | * 119 | * @param key 120 | * is the property key 121 | * @param value is the value to set the property to 122 | * @param callback 123 | * will be called with the property 124 | */ 125 | neo4j.services.ConfigService.prototype.setProperty = function(key, value, callback) { 126 | var props = {}; 127 | props[key] = value; 128 | this.setProperties(props, callback); 129 | }; 130 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/services/ConsoleService.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * @class Interface to the console functionality of the REST server. 22 | * @extends neo4j.Service 23 | * @param db 24 | * should be a neo4j.GraphDatabase object 25 | */ 26 | neo4j.services.ConsoleService = function(db) { 27 | 28 | neo4j.Service.call(this,db); 29 | 30 | }; 31 | 32 | _.extend(neo4j.services.ConsoleService.prototype, neo4j.Service.prototype); 33 | 34 | /** 35 | * Execute a command 36 | * 37 | * @param cmd 38 | * string command to execute. 39 | * @param engine 40 | * engine to use to run script 41 | * @param callback 42 | * will be called with the result 43 | * @function 44 | */ 45 | neo4j.services.ConsoleService.prototype.exec = neo4j.Service 46 | .resourceFactory({ 47 | 'resource' : 'exec', 48 | 'method' : 'POST', 49 | 'before': function(method, args) { 50 | method({ 51 | 'command' : args[0], 52 | 'engine' : args[1] 53 | }, args[2]); 54 | } 55 | } 56 | ); 57 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/services/ExportService.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * @class Interface to the export functionality of the REST server. 22 | * @extends neo4j.Service 23 | * @param db 24 | * should be a neo4j.GraphDatabase object 25 | */ 26 | neo4j.services.ExportService = function(db) { 27 | 28 | neo4j.Service.call(this,db); 29 | 30 | }; 31 | 32 | _.extend(neo4j.services.ExportService.prototype, neo4j.Service.prototype); 33 | 34 | /** 35 | * Export all nodes, properties and relationships. 36 | * 37 | * @param callback 38 | * will be called with an object with a single property, "url", the 39 | * value of which is a URL where you can download the export. 40 | * @function 41 | */ 42 | neo4j.services.ExportService.prototype.all = neo4j.Service 43 | .resourceFactory({ 44 | 'resource' : 'export_all', 45 | 'method' : 'POST' 46 | } 47 | ); 48 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/services/ImportService.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * Allows importing a graphml file from a URL. The server also supports html 22 | * file uploads. 23 | * 24 | * To use that, create a form like so: 25 | * 26 | *
27 |  * <form action="[GET PATH VIA {@link #getUploadPath}]" method="POST" enctype="multipart/form-data">
28 |  *    <input type="hidden" name="redirect" value="[REDIRECT TO HERE AFTER IMPORT]" />
29 |  *    <input type="file" name="file" />
30 |  *    <input type="submit" value="Import" />
31 |  * </form>
32 |  * 
33 | * 34 | * You can get the URL you should post the form to via {@link #getUploadPath}. 35 | * 36 | * @class Interface to the import functionality of the REST server. 37 | * @extends neo4j.Service 38 | * @param db 39 | * should be a neo4j.GraphDatabase object 40 | */ 41 | neo4j.services.ImportService = function(db) { 42 | 43 | neo4j.Service.call(this,db); 44 | 45 | }; 46 | 47 | _.extend(neo4j.services.ImportService.prototype, neo4j.Service.prototype); 48 | 49 | /** 50 | * Import graphml data from a url. 51 | * 52 | * @param url 53 | * is the url to load the graphml file from 54 | * @param callback 55 | * will be called when the import is complete 56 | * @function 57 | */ 58 | neo4j.services.ImportService.prototype.fromUrl = neo4j.Service 59 | .resourceFactory({ 60 | 'resource' : 'import_from_url', 61 | 'method' : 'POST', 62 | 'before': function(method, args) { 63 | method({'url' : args[0]}, args[1]); 64 | } 65 | } 66 | ); 67 | 68 | /** 69 | * Get the URL to post file uploads to. See the class constructor for info on 70 | * how the upload form should look. 71 | * 72 | * @param callback 73 | * will be called with the url as parameter 74 | */ 75 | neo4j.services.ImportService.prototype.getUploadUrl = function(cb) { 76 | this.serviceMethodPreflight(function(cb) { 77 | cb(this.resources['import_from_file']); 78 | }, arguments); // End preflight 79 | }; 80 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/services/JmxService.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * @class Interface to the jmx exposing functionality of the REST server. 22 | * @extends neo4j.Service 23 | * @param db 24 | * should be a neo4j.GraphDatabase object 25 | */ 26 | neo4j.services.JmxService = function(db) { 27 | 28 | neo4j.Service.call(this,db); 29 | 30 | // Kernelinstance gets called a lot, cache each result for two seconds 31 | this.kernelInstance = neo4j.cachedFunction( this.kernelInstance, 0, 2000); 32 | 33 | }; 34 | 35 | _.extend(neo4j.services.JmxService.prototype, neo4j.Service.prototype); 36 | 37 | /** 38 | * Get a list of all jmx domains available 39 | * 40 | * @param callback 41 | * will be called with the list of domains 42 | * @function 43 | */ 44 | neo4j.services.JmxService.prototype.getDomains = neo4j.Service 45 | .resourceFactory({ 46 | 'resource' : 'domains', 47 | 'method' : 'GET' 48 | }); 49 | 50 | /** 51 | * Get a domain and all the beans in it. 52 | * 53 | * @param domain 54 | * {String} Name of the domain 55 | * @param callback 56 | * will be called with the domain data 57 | * @function 58 | */ 59 | neo4j.services.JmxService.prototype.getDomain = neo4j.Service.resourceFactory({ 60 | 'resource' : 'domain', 61 | 'method' : 'GET', 62 | 'urlArgs' : [ 'domain' ], 63 | 'after' : function(data, callback) { 64 | var betterBeans = []; 65 | for (var i=0,l=data.beans; i. 19 | */ 20 | /** 21 | * @class Interface to the lifecycle functionality of the REST server. 22 | * @extends neo4j.Service 23 | * @param db 24 | * should be a neo4j.GraphDatabase object 25 | */ 26 | neo4j.services.LifecycleService = function(db) { 27 | 28 | neo4j.Service.call(this,db); 29 | 30 | }; 31 | 32 | _.extend(neo4j.services.LifecycleService.prototype, neo4j.Service.prototype); 33 | 34 | /** 35 | * Get the current lifecycle status of the server. 36 | * 37 | * @param callback 38 | * will be called with lifecycle status information 39 | * @function 40 | */ 41 | neo4j.services.LifecycleService.prototype.getStatus = neo4j.Service 42 | .resourceFactory({ 43 | 'resource' : 'status', 44 | 'method' : 'GET' 45 | }); 46 | 47 | /** 48 | * Start the REST server. 49 | * 50 | * @param callback 51 | * will be called with lifecycle status information 52 | * @function 53 | */ 54 | neo4j.services.LifecycleService.prototype.start = neo4j.Service 55 | .resourceFactory({ 56 | 'resource' : 'start', 57 | 'method' : 'POST' 58 | }); 59 | 60 | /** 61 | * Stop the REST server. 62 | * 63 | * @param callback 64 | * will be called with lifecycle status information 65 | * @function 66 | */ 67 | neo4j.services.LifecycleService.prototype.stop = neo4j.Service 68 | .resourceFactory({ 69 | 'resource' : 'stop', 70 | 'method' : 'POST' 71 | }); 72 | /** 73 | * Restart the REST server. 74 | * 75 | * @param callback 76 | * will be called with lifecycle status information 77 | * @function 78 | */ 79 | neo4j.services.LifecycleService.prototype.restart = neo4j.Service 80 | .resourceFactory({ 81 | 'resource' : 'restart', 82 | 'method' : 'POST' 83 | }); 84 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/services/MonitorService.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * The monitor service exposes a round-robin data sampler over the web. Through 22 | * this service, you can access various server metrics and their movement over 23 | * time. 24 | * 25 | * @class Interface to the monitoring functionality of the REST server. 26 | * @extends neo4j.Service 27 | * @param db 28 | * should be a neo4j.GraphDatabase object 29 | */ 30 | neo4j.services.MonitorService = function(db) { 31 | 32 | neo4j.Service.call(this,db); 33 | 34 | }; 35 | 36 | _.extend(neo4j.services.MonitorService.prototype, neo4j.Service.prototype); 37 | 38 | /** 39 | * Get monitoring data for a pre-defined (on the server side) time period up 40 | * until right now. 41 | * 42 | * @param callback 43 | * will be called with the monitor data 44 | * @function 45 | */ 46 | neo4j.services.MonitorService.prototype.getData = neo4j.Service 47 | .resourceFactory({ 48 | 'resource' : 'latest_data', 49 | 'method' : 'GET' 50 | }); 51 | 52 | /** 53 | * Get monitoring data from a given timestamp up until right now. 54 | * 55 | * @param from 56 | * {Integer} a UTC timestamp in milliseconds. 57 | * @param callback 58 | * will be called with the monitor data 59 | * @function 60 | */ 61 | neo4j.services.MonitorService.prototype.getDataFrom = neo4j.Service 62 | .resourceFactory({ 63 | 'resource' : 'data_from', 64 | 'method' : 'GET', 65 | 'urlArgs' : [ 'start' ] 66 | }); 67 | 68 | /** 69 | * Get monitoring data between two timestamps. 70 | * 71 | * @param from 72 | * {Integer} a UTC timestamp in milliseconds. 73 | * @param to 74 | * {Integer} a UTC timestamp in milliseconds. 75 | * @param callback 76 | * will be called with the monitor data 77 | * @function 78 | */ 79 | neo4j.services.MonitorService.prototype.getDataBetween = neo4j.Service 80 | .resourceFactory({ 81 | 'resource' : 'data_period', 82 | 'method' : 'GET', 83 | 'urlArgs' : [ 'start', 'stop' ] 84 | }); 85 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/services/__init__.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | /** 21 | * @namespace namespace containing clients to REST server services. 22 | */ 23 | neo4j.services = neo4j.services || {}; 24 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/setInterval.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | _.extend(neo4j, { 21 | 22 | /** 23 | * This checks if there is there is a setInterval method available, delegates 24 | * to that if possible, or provides its own implementation otherwise. 25 | */ 26 | setInterval : function( expression, interval ) { 27 | if(typeof(setInterval) != "undefined") { 28 | return setInterval(expression, interval); 29 | } else if(typeof(setTimeout) != "undefined") { 30 | var id = (new Date()).getTime(); 31 | 32 | function intervalCallback() { 33 | expression(); 34 | neo4j._intervals[id] = setTimeout(intervalCallback, interval); 35 | } 36 | 37 | neo4j._intervals[id] = setTimeout(intervalCallback, interval); 38 | return id; 39 | } else { 40 | neo4j.log("No timeout or interval implementation found, unable to do timed tasks."); 41 | } 42 | }, 43 | 44 | clearInterval : function(intervalId) { 45 | if(typeof(clearInterval) != "undefined") { 46 | clearInterval(intervalId); 47 | } else if (typeof(clearTimeout) != "undefined") { 48 | clearTimeout(neo4j._intervals[intervalId]); 49 | } else { 50 | neo4j.log("No timeout or interval implementation found, unable to do timed tasks."); 51 | } 52 | }, 53 | 54 | _intervals : {} 55 | }); 56 | -------------------------------------------------------------------------------- /src/main/javascript/neo4j/setTimeout.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | _.extend(neo4j, { 21 | 22 | /** 23 | * This checks if there is there is a setTimeout method available. If not, 24 | * this will trigger the method directly if timeout is 0, or throw 25 | * an exception if timeout is greater than that. 26 | */ 27 | setTimeout : function( expression, timeout ) { 28 | if(typeof(setTimeout) != "undefined") { 29 | return setTimeout(expression, timeout); 30 | } else if (timeout === 0) { 31 | expression(); 32 | } else { 33 | neo4j.log("No timeout implementation found, unable to do timed tasks."); 34 | } 35 | }, 36 | 37 | clearTimeout : function(timeoutId) { 38 | if(typeof(clearTimeout) != "undefined") { 39 | clearTimeout(intervalId); 40 | } else { 41 | neo4j.log("No timeout implementation found, unable to do timed tasks."); 42 | } 43 | }, 44 | 45 | _intervals : {} 46 | }); 47 | -------------------------------------------------------------------------------- /src/test/browser/index.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neo-technology/neo4js/a931596e13d0e9ed242b60a6e0b7023dd7173ba9/src/test/browser/index.html -------------------------------------------------------------------------------- /src/test/javascript/neo4j/MockWebProvider.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | var mockWebProvider = { 21 | 22 | definitions : { 23 | 'GET': {}, 24 | 'POST':{}, 25 | 'PUT':{}, 26 | 'DELETE':{} 27 | }, 28 | 29 | mock : function(method, url, mocker) { 30 | 31 | if (! mockWebProvider.definitions[method] ) { 32 | mockWebProvider.definitions[method] = {}; 33 | } 34 | 35 | mockWebProvider.definitions[method][url] = mocker; 36 | }, 37 | 38 | clear : function() { 39 | mockWebProvider.definitions = {}; 40 | }, 41 | 42 | /** 43 | * Add basic service mocking to the mock definitions. Basically 44 | * a quick way to mock the stuff you need to create a graph database 45 | * instance that works with /db/data and /db/manage as base urls. 46 | */ 47 | mockServiceDefinition : function() { 48 | 49 | webmock("GET", "http://localhost/", { 50 | "data" : "http://localhost:7474/db/data/", 51 | "management" : "http://localhost:7474/db/manage/" 52 | }); 53 | 54 | webmock("GET", "http://localhost:7474/db/data/", { 55 | "relationship_index" : "http://localhost:7474/db/data/index/relationship", 56 | "relationship_types" : "http://localhost:7474/db/data/relationships/types", 57 | "node" : "http://localhost:7474/db/data/node", 58 | "extensions_info" : "http://localhost:7474/db/data/ext", 59 | "node_index" : "http://localhost:7474/db/data/index/node", 60 | "cypher" : "http://localhost:7474/db/data/cypher", 61 | "batch" : "http://localhost:7474/db/data/batch", 62 | "reference_node" : "http://localhost:7474/db/data/node/0", 63 | "extensions" : { 64 | } 65 | }); 66 | webmock("GET", "http://localhost:7474/db/manage/", { 67 | "services" : { 68 | "console" : "http://localhost:7474/db/manage/server/console", 69 | "jmx" : "http://localhost:7474/db/manage/server/jmx", 70 | "monitor" : "http://localhost:7474/db/manage/server/monitor" 71 | } 72 | }); 73 | webmock("GET", "http://localhost:7474/db/data/node/0", { 74 | "outgoing_relationships" : "http://localhost:7474/db/data/node/0/relationships/out", 75 | "data" : { 76 | "mykey" : "myvalue", 77 | "myint" : "12" 78 | }, 79 | "traverse" : "http://localhost:7474/db/data/node/0/traverse/{returnType}", 80 | "all_typed_relationships" : "http://localhost:7474/db/data/node/0/relationships/all/{-list|&|types}", 81 | "property" : "http://localhost:7474/db/data/node/0/properties/{key}", 82 | "self" : "http://localhost:7474/db/data/node/0", 83 | "properties" : "http://localhost:7474/db/data/node/0/properties", 84 | "outgoing_typed_relationships" : "http://localhost:7474/db/data/node/0/relationships/out/{-list|&|types}", 85 | "incoming_relationships" : "http://localhost:7474/db/data/node/0/relationships/in", 86 | "extensions" : { 87 | }, 88 | "create_relationship" : "http://localhost:7474/db/data/node/0/relationships", 89 | "all_relationships" : "http://localhost:7474/db/data/node/0/relationships/all", 90 | "incoming_typed_relationships" : "http://localhost:7474/db/data/node/0/relationships/in/{-list|&|types}" 91 | }); 92 | }, 93 | 94 | ajax : function(args) { 95 | 96 | neo4j.log(args.method, args.url); 97 | 98 | if( typeof(mockWebProvider.definitions[args.method]) != "undefined" && typeof(mockWebProvider.definitions[args.method][args.url]) != "undefined") { 99 | var mocker = mockWebProvider.definitions[args.method][args.url]; 100 | if( typeof(mocker) === "function" ) { 101 | mocker({method:args.method, url:args.url, data:args.data, success:args.success, failure:args.failure}); 102 | } else { 103 | args.success(mocker); 104 | } 105 | } else { 106 | throw new Error("No such endpoint defined: " + args.method + " - " + args.url); 107 | } 108 | } 109 | 110 | }; 111 | 112 | /** 113 | * Convinience access. 114 | */ 115 | var webmock = mockWebProvider.mock, 116 | mockServiceDefinition= mockWebProvider.mockServiceDefinition, 117 | clearWebmock = mockWebProvider.clear, 118 | 119 | mockWeb = new neo4j.Web(mockWebProvider); 120 | 121 | function mockedGraphDatabase() { 122 | return new neo4j.GraphDatabase("http://localhost/", mockWeb); 123 | } 124 | -------------------------------------------------------------------------------- /src/test/javascript/neo4j/PromiseTestCase.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | var PromiseTest = function(name) { 21 | 22 | TestCase.call(this, "PromiseTest." + name); 23 | }; 24 | 25 | PromiseTest.prototype = new TestCase(); 26 | 27 | /** 28 | * Test that eventually fulfulling a promise allows hooking handlers 29 | * to it, and that the handlers recieve the result as expected. 30 | */ 31 | PromiseTest.prototype.testEventuallyFulfillingPromise = function() { 32 | 33 | var ctx = {}, 34 | expected = 123; 35 | 36 | var promise = new neo4j.Promise(function(fulfill) { 37 | ctx.fulfill = fulfill; 38 | }); 39 | 40 | promise.then(function(pResult) { 41 | ctx.pResult = pResult; 42 | }, function() { 43 | ctx.failCall = true; 44 | }); 45 | 46 | // Fulfill promise 47 | ctx.fulfill(expected); 48 | 49 | this.assertSame("Result should have been propagated and set by our callback method.", expected, ctx.pResult); 50 | this.assertUndefined( "Failure callback should not have been called.", ctx.failCall); 51 | }; 52 | 53 | /** 54 | * Test that eventually breaking a promise allows hooking handlers 55 | * to it, and that the handlers recieve the result as expected. 56 | */ 57 | PromiseTest.prototype.testEventuallyFailingPromise = function() { 58 | 59 | var ctx = {}, 60 | expected = 123; 61 | 62 | var promise = new neo4j.Promise(function(fulfill, fail) { 63 | ctx.fail = fail; 64 | }); 65 | 66 | promise.then(function(pResult) { 67 | ctx.fulfillCall = true; 68 | }, function(pResult) { 69 | ctx.pResult = pResult; 70 | }); 71 | 72 | // Fulfill promise 73 | ctx.fail(expected); 74 | 75 | this.assertSame("Result should have been propagated and set by our callback method.", expected, ctx.pResult); 76 | this.assertUndefined( "Fulfill callback should not have been called.", ctx.fulfillCall); 77 | }; 78 | 79 | /** 80 | * Test that fulfulling a promise immediately still allows hooking handlers 81 | * to it, and that the handlers recieve the result as expected. 82 | */ 83 | PromiseTest.prototype.testDirectlyFulfillingPromise = function() { 84 | 85 | var result = {}, 86 | expected = 123; 87 | 88 | var promise = new neo4j.Promise(function(fulfill) { 89 | fulfill(expected); 90 | }); 91 | 92 | promise.then(function(pResult) { 93 | result.pResult = pResult; 94 | }, function() { 95 | result.failCall = true; 96 | }); 97 | 98 | this.assertSame("Result should have been propagated and set by our callback method.", expected, result.pResult); 99 | this.assertUndefined( "Failure callback should not have been called.", result.failCall); 100 | }; 101 | 102 | /** 103 | * Test that breaking a promise immediately still allows hooking handlers 104 | * to it, and that the handlers recieve the result as expected. 105 | */ 106 | PromiseTest.prototype.testDirectlyFailingPromise = function() { 107 | 108 | var result = {}, 109 | expected = 123; 110 | 111 | var promise = new neo4j.Promise(function(fulfill, fail) { 112 | fail(expected); 113 | }); 114 | 115 | promise.then(function(pResult) { 116 | result.fulfillCall = true; 117 | }, function(pResult) { 118 | result.pResult = pResult; 119 | }); 120 | 121 | this.assertSame("Failed result should have been propagated and set by our callback method.", expected, result.pResult); 122 | this.assertUndefined( "Fulfill callback should not have been called.", result.fulfillCall); 123 | }; 124 | 125 | /** 126 | * Test wrapping a value in a promise. 127 | */ 128 | PromiseTest.prototype.testPromiseWrapping = function() { 129 | 130 | var value = 12, 131 | promiseValue = new neo4j.Promise(); 132 | 133 | var wrappedValue = neo4j.Promise.wrap(value), 134 | wrappedPromiseValue = neo4j.Promise.wrap(promiseValue); 135 | 136 | this.assertTrue("Wrapping a raw value should return a promise.", wrappedValue instanceof neo4j.Promise); 137 | this.assertSame("Wrapping promises should return the original promise.", promiseValue, wrappedPromiseValue); 138 | }; 139 | 140 | /** 141 | * Test fulfilling a promise with a result == false. (Regression test.) 142 | */ 143 | PromiseTest.prototype.testFulfillWithFalseResult = function() { 144 | 145 | var results = {}; 146 | 147 | var p = new neo4j.Promise(function(fulfill){ 148 | fulfill(false); 149 | }); 150 | 151 | p.then(function(result) { 152 | results.result = result; 153 | }); 154 | 155 | 156 | this.assertTrue("The promise should be fulfilled.", typeof(results.result) != "undefined"); 157 | this.assertTrue("The result should be exactly equal to false.", results.result === false); 158 | 159 | }; 160 | 161 | /** 162 | * Test joining several promises into one. 163 | */ 164 | PromiseTest.prototype.testJoinPromises = function() { 165 | 166 | var firstPromise = neo4j.Promise.fulfilled(12), 167 | secondPromise = neo4j.Promise.fulfilled(13), 168 | results = {}; 169 | 170 | var joined = neo4j.Promise.join(firstPromise, secondPromise); 171 | 172 | joined.then(function(result, fulfill, fail) { 173 | results.result = result; 174 | }); 175 | 176 | this.assertTrue("Joining promises should return a new promise.", joined instanceof neo4j.Promise); 177 | this.assertTrue("The first argument to handler of joined promise should be a list of results.", _.isArray(results.result)); 178 | 179 | this.assertEquals("The result argument should be an array of length 2.", results.result.length, 2); 180 | this.assertEquals("The first item in the results argument should be 12.", results.result[0], 12); 181 | this.assertEquals("The second item in the results argument should be 13.", results.result[1], 13); 182 | 183 | }; 184 | -------------------------------------------------------------------------------- /src/test/javascript/neo4j/WebTestCase.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | var WebTest = function(name) { 21 | TestCase.call(this, "WebTest." + name); 22 | }; 23 | 24 | WebTest.prototype = new TestCase(); 25 | 26 | _.extend(WebTest.prototype, { 27 | 28 | testServerUnresponsive : function() { 29 | var result = {eventTriggered:false, legacyEventTriggered:false}; 30 | clearWebmock(); 31 | 32 | webmock("POST", "http://localhost:7474/db/data/node", function(req) { 33 | req.failure(new neo4j.exceptions.ConnectionLostException()); 34 | }); 35 | 36 | // Legacy behaviour 37 | neo4j.events.bind("web.connection.failed", function() { 38 | result.legacyEventTriggered = true; 39 | }); 40 | 41 | neo4j.events.bind("web.connection_lost", function() { 42 | result.eventTriggered = true; 43 | }); 44 | 45 | mockWeb.post("http://localhost:7474/db/data/node"); 46 | 47 | this.assertTrue("Legacy connection failed event should have been triggered.", result.legacyEventTriggered); 48 | this.assertTrue("Connection lost event should have been triggered.", result.eventTriggered); 49 | 50 | } 51 | }); 52 | -------------------------------------------------------------------------------- /src/test/javascript/neo4j/index/IndexTestCase.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | var IndexTest = function(name) { 21 | TestCase.call(this, "IndexTest." + name); 22 | }; 23 | 24 | IndexTest.prototype = new TestCase(); 25 | 26 | _.extend(IndexTest.prototype, { 27 | 28 | testCanIndexNode : function() { 29 | clearWebmock(); 30 | mockServiceDefinition(); 31 | 32 | var indexName = "my_nodes", result = {}, key="thekey", value="thevalue", 33 | nodeId = 1, 34 | nodeUrl = "http://localhost:7474/db/data/node/" + nodeId; 35 | 36 | webmock("POST", "http://localhost:7474/db/data/index/node/" + indexName + "/" + key + "/" + value, function(req) { 37 | result.called = true; 38 | result.nodeUrl = req.data; 39 | req.success({}); 40 | }); 41 | 42 | webmock("GET", nodeUrl, function(req) { 43 | result.getNodeCalled = true; 44 | req.success({ 45 | "outgoing_relationships" : "http://localhost:7474/db/data/node/1/relationships/out", 46 | "data" : { 47 | "thekey" : value 48 | }, 49 | "traverse" : "http://localhost:7474/db/data/node/1/traverse/{returnType}", 50 | "all_typed_relationships" : "http://localhost:7474/db/data/node/1/relationships/all/{-list|&|types}", 51 | "property" : "http://localhost:7474/db/data/node/1/properties/{key}", 52 | "self" : "http://localhost:7474/db/data/node/1", 53 | "properties" : "http://localhost:7474/db/data/node/1/properties", 54 | "outgoing_typed_relationships" : "http://localhost:7474/db/data/node/1/relationships/out/{-list|&|types}", 55 | "incoming_relationships" : "http://localhost:7474/db/data/node/1/relationships/in", 56 | "extensions" : { 57 | }, 58 | "create_relationship" : "http://localhost:7474/db/data/node/1/relationships", 59 | "all_relationships" : "http://localhost:7474/db/data/node/1/relationships/all", 60 | "incoming_typed_relationships" : "http://localhost:7474/db/data/node/1/relationships/in/{-list|&|types}" 61 | }); 62 | }); 63 | 64 | var db = mockedGraphDatabase(); 65 | 66 | var index = new neo4j.index.NodeIndex(db, indexName), 67 | node = new neo4j.models.Node({self:nodeUrl}, db); 68 | 69 | index.index(node, key, value).then(function(){ 70 | result.indexObject = true; 71 | }); 72 | 73 | index.index(nodeUrl, key, value).then(function(){ 74 | result.indexUrl = true; 75 | }); 76 | 77 | index.index(nodeId, key, value).then(function(){ 78 | result.indexId = true; 79 | }); 80 | 81 | index.index(nodeId, key).then(function(){ 82 | result.indexIdFetchValue = true; 83 | }); 84 | 85 | this.assertTrue("Server should have been called.", result.called); 86 | this.assertTrue("Server should have been given correct node url", result.nodeUrl == nodeUrl); 87 | this.assertTrue("Should have indexed a node instance", result.indexObject); 88 | this.assertTrue("Should have indexed a node url", result.indexUrl); 89 | this.assertTrue("Should have indexed a node id", result.indexId); 90 | this.assertTrue("Should have indexed a node id, even when having to fetch the remote value", result.indexIdFetchValue); 91 | }, 92 | 93 | testCanIndexRelationship : function() { 94 | clearWebmock(); 95 | mockServiceDefinition(); 96 | 97 | var indexName = "my_nodes", result = {}, key="thekey", value="thevalue", 98 | relId = 1, 99 | relUrl = "http://localhost:7474/db/data/relationship/" + relId; 100 | 101 | webmock("POST", "http://localhost:7474/db/data/index/relationship/" + indexName + "/" + key + "/" + value, function(req) { 102 | result.called = true; 103 | result.relUrl = req.data; 104 | req.success({}); 105 | }); 106 | 107 | webmock("GET", relUrl, { 108 | "start" : "http://localhost:7474/db/data/node/0", 109 | "data" : { 110 | "thekey" : value 111 | }, 112 | "self" : "http://localhost:7474/db/data/relationship/1", 113 | "property" : "http://localhost:7474/db/data/relationship/1/properties/{key}", 114 | "properties" : "http://localhost:7474/db/data/relationship/1/properties", 115 | "type" : "KNOWS", 116 | "extensions" : { 117 | }, 118 | "end" : "http://localhost:7474/db/data/node/1" 119 | }); 120 | 121 | var db = mockedGraphDatabase(); 122 | 123 | var index = new neo4j.index.RelationshipIndex(db, indexName), 124 | rel = new neo4j.models.Relationship({self:relUrl}, db); 125 | 126 | index.index(rel, key, value).then(function(){ 127 | result.indexObject = true; 128 | }); 129 | 130 | index.index(relUrl, key, value).then(function(){ 131 | result.indexUrl = true; 132 | }); 133 | 134 | index.index(relId, key, value).then(function(){ 135 | result.indexId = true; 136 | }); 137 | 138 | index.index(relId, key).then(function(){ 139 | result.indexIdFetchValue = true; 140 | }); 141 | 142 | this.assertTrue("Server should have been called.", result.called); 143 | this.assertTrue("Server should have been called with correct item url.", result.relUrl == relUrl); 144 | this.assertTrue("Should have indexed a relationship instance", result.indexObject); 145 | this.assertTrue("Should have indexed a relationship url", result.indexUrl); 146 | this.assertTrue("Should have indexed a relationship id", result.indexId); 147 | this.assertTrue("Should have indexed a relationship id, even when having to fetch the remote value", result.indexIdFetchValue); 148 | }, 149 | 150 | testCanUnindexRelationship : function() { 151 | clearWebmock(); 152 | mockServiceDefinition(); 153 | 154 | var indexName = "my_nodes", result = {}, key="thekey", value="thevalue", 155 | relId = 1, 156 | relUrl = "http://localhost:7474/db/data/relationship/" + relId; 157 | 158 | webmock("DELETE", "http://localhost:7474/db/data/index/relationship/" + indexName + "/" + key + "/" + value + "/" + relId, function(req) { 159 | result.fullpathCalled = true; 160 | req.success({}); 161 | }); 162 | 163 | var db = mockedGraphDatabase(); 164 | 165 | var index = new neo4j.index.RelationshipIndex(db, indexName), 166 | rel = new neo4j.models.Relationship({self:relUrl}, db); 167 | 168 | index.unindex(rel, key, value).then(function(){ 169 | result.unindexObject = true; 170 | }); 171 | 172 | this.assertTrue("Server should have been called.", result.fullpathCalled); 173 | this.assertTrue("Should have unindexed a relationship instance", result.unindexObject); 174 | }, 175 | 176 | testCanUnindexNode : function() { 177 | clearWebmock(); 178 | mockServiceDefinition(); 179 | 180 | var indexName = "my_nodes", result = {}, key="thekey", value="thevalue", 181 | nodeId = 1, 182 | nodeUrl = "http://localhost:7474/db/data/node/" + nodeId; 183 | 184 | webmock("DELETE", "http://localhost:7474/db/data/index/node/" + indexName + "/" + key + "/" + value + "/" + nodeId, function(req) { 185 | result.fullpathCalled = true; 186 | req.success({}); 187 | }); 188 | 189 | var db = mockedGraphDatabase(); 190 | 191 | var index = new neo4j.index.NodeIndex(db, indexName), 192 | node = new neo4j.models.Node({self:nodeUrl}, db); 193 | 194 | index.unindex(node, key, value).then(function(){ 195 | result.unindexObject = true; 196 | }); 197 | 198 | this.assertTrue("Server should have been called.", result.fullpathCalled); 199 | this.assertTrue("Should have unindexed a node instance", result.unindexObject); 200 | }, 201 | 202 | testCanQueryNodeIndex : function() { 203 | clearWebmock(); 204 | mockServiceDefinition(); 205 | 206 | var indexName = "my_nodes", result = {} 207 | query = "title:\"The Right Way\" AND text:go"; 208 | 209 | webmock("GET", "http://localhost:7474/db/data/index/node/" + indexName, [ 210 | { 211 | "outgoing_relationships" : "http://localhost:7474/db/data/node/1/relationships/out", 212 | "data" : {}, 213 | "traverse" : "http://localhost:7474/db/data/node/1/traverse/{returnType}", 214 | "all_typed_relationships" : "http://localhost:7474/db/data/node/1/relationships/all/{-list|&|types}", 215 | "property" : "http://localhost:7474/db/data/node/1/properties/{key}", 216 | "self" : "http://localhost:7474/db/data/node/1", 217 | "properties" : "http://localhost:7474/db/data/node/1/properties", 218 | "outgoing_typed_relationships" : "http://localhost:7474/db/data/node/1/relationships/out/{-list|&|types}", 219 | "incoming_relationships" : "http://localhost:7474/db/data/node/1/relationships/in", 220 | "extensions" : { }, 221 | "create_relationship" : "http://localhost:7474/db/data/node/1/relationships", 222 | "all_relationships" : "http://localhost:7474/db/data/node/1/relationships/all", 223 | "incoming_typed_relationships" : "http://localhost:7474/db/data/node/1/relationships/in/{-list|&|types}" 224 | } 225 | ]); 226 | 227 | var db = mockedGraphDatabase(); 228 | 229 | var index = new neo4j.index.NodeIndex(db, indexName); 230 | 231 | index.query(query).then(function(nodes){ 232 | result.nodes = nodes; 233 | }); 234 | 235 | this.assertTrue("Should have returned one node", result.nodes.length == 1); 236 | this.assertTrue("Should have returned a node instance", result.nodes[0] instanceof neo4j.models.Node); 237 | }, 238 | 239 | testCanQueryRelationshipIndex : function() { 240 | clearWebmock(); 241 | mockServiceDefinition(); 242 | 243 | var indexName = "my_nodes", result = {} 244 | query = "title:\"The Right Way\" AND text:go"; 245 | 246 | webmock("GET", "http://localhost:7474/db/data/index/relationship/" + indexName, [ 247 | {"start" : "http://localhost:7474/db/data/node/0", 248 | "data" : { }, 249 | "self" : "http://localhost:7474/db/data/relationship/1", 250 | "property" : "http://localhost:7474/db/data/relationship/1/properties/{key}", 251 | "properties" : "http://localhost:7474/db/data/relationship/1/properties", 252 | "type" : "KNOWS", 253 | "extensions" : { }, 254 | "end" : "http://localhost:7474/db/data/node/1" } 255 | ]); 256 | 257 | var db = mockedGraphDatabase(); 258 | 259 | var index = new neo4j.index.RelationshipIndex(db, indexName); 260 | 261 | index.query(query).then(function(rels){ 262 | result.rels = rels; 263 | }); 264 | 265 | this.assertTrue("Should have returned one relationship", result.rels.length == 1); 266 | this.assertTrue("Should have returned a relationship instance", result.rels[0] instanceof neo4j.models.Relationship); 267 | }, 268 | 269 | testCanExactQueryNodeIndex : function() { 270 | clearWebmock(); 271 | mockServiceDefinition(); 272 | 273 | var indexName = "my_nodes", result = {}, key="somekey", value="somevalue"; 274 | 275 | webmock("GET", "http://localhost:7474/db/data/index/node/" + indexName + "/" + key + "/" + value, [ 276 | { 277 | "outgoing_relationships" : "http://localhost:7474/db/data/node/1/relationships/out", 278 | "data" : { }, 279 | "traverse" : "http://localhost:7474/db/data/node/1/traverse/{returnType}", 280 | "all_typed_relationships" : "http://localhost:7474/db/data/node/1/relationships/all/{-list|&|types}", 281 | "property" : "http://localhost:7474/db/data/node/1/properties/{key}", 282 | "self" : "http://localhost:7474/db/data/node/1", 283 | "properties" : "http://localhost:7474/db/data/node/1/properties", 284 | "outgoing_typed_relationships" : "http://localhost:7474/db/data/node/1/relationships/out/{-list|&|types}", 285 | "incoming_relationships" : "http://localhost:7474/db/data/node/1/relationships/in", 286 | "extensions" : { }, 287 | "create_relationship" : "http://localhost:7474/db/data/node/1/relationships", 288 | "all_relationships" : "http://localhost:7474/db/data/node/1/relationships/all", 289 | "incoming_typed_relationships" : "http://localhost:7474/db/data/node/1/relationships/in/{-list|&|types}" 290 | } 291 | ]); 292 | 293 | var db = mockedGraphDatabase(); 294 | var index = new neo4j.index.NodeIndex(db, indexName); 295 | 296 | index.exactQuery(key, value).then(function(nodes){ 297 | result.nodes = nodes; 298 | }); 299 | 300 | this.assertTrue("Should have returned one node", result.nodes.length == 1); 301 | this.assertTrue("Should have returned a node instance", result.nodes[0] instanceof neo4j.models.Node); 302 | }, 303 | 304 | testCanExactQueryRelationshipIndex : function() { 305 | clearWebmock(); 306 | mockServiceDefinition(); 307 | 308 | var indexName = "my_nodes", result = {}, key="somekey", value="somevalue"; 309 | 310 | webmock("GET", "http://localhost:7474/db/data/index/relationship/" + indexName + "/" + key + "/" + value, [ 311 | {"start" : "http://localhost:7474/db/data/node/0", 312 | "data" : { }, 313 | "self" : "http://localhost:7474/db/data/relationship/1", 314 | "property" : "http://localhost:7474/db/data/relationship/1/properties/{key}", 315 | "properties" : "http://localhost:7474/db/data/relationship/1/properties", 316 | "type" : "KNOWS", 317 | "extensions" : { }, 318 | "end" : "http://localhost:7474/db/data/node/1" } 319 | ]); 320 | 321 | var db = mockedGraphDatabase(); 322 | 323 | var index = new neo4j.index.RelationshipIndex(db, indexName); 324 | 325 | index.exactQuery(key, value).then(function(rels){ 326 | result.rels = rels; 327 | }); 328 | 329 | this.assertTrue("Should have returned one relationship", result.rels.length == 1); 330 | this.assertTrue("Should have returned a relationship instance", result.rels[0] instanceof neo4j.models.Relationship); 331 | } 332 | }); 333 | -------------------------------------------------------------------------------- /src/test/javascript/neo4j/index/IndexesTestCase.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | var IndexesTest = function(name) { 21 | TestCase.call(this, "IndexesTest." + name); 22 | }; 23 | 24 | IndexesTest.prototype = new TestCase(); 25 | 26 | _.extend(IndexesTest.prototype, { 27 | 28 | testCanCreateNodeIndex : function() { 29 | 30 | clearWebmock(); 31 | mockServiceDefinition(); 32 | 33 | var indexName = "my_nodes", result = {}; 34 | 35 | webmock("POST", "http://localhost:7474/db/data/index/node", function(req) { 36 | result.called = true; 37 | req.success({}); 38 | }); 39 | 40 | var db = mockedGraphDatabase(); 41 | 42 | var indexes = new neo4j.index.Indexes(db); 43 | 44 | indexes.createNodeIndex(indexName).then(function(index) { 45 | result.index = index; 46 | }); 47 | 48 | this.assertTrue("Server should have been called.", result.called); 49 | this.assertTrue("Should have gotten an index back", typeof(result.index) != "undefined"); 50 | this.assertTrue("Should result in a node index", result.index instanceof neo4j.index.NodeIndex); 51 | 52 | }, 53 | 54 | testCanCreateRelationshipIndex : function() { 55 | 56 | clearWebmock(); 57 | mockServiceDefinition(); 58 | 59 | var indexName = "my_rels", result = {}; 60 | 61 | webmock("POST", "http://localhost:7474/db/data/index/relationship", function(req) { 62 | result.called = true; 63 | req.success({}); 64 | }); 65 | 66 | var db = mockedGraphDatabase(); 67 | 68 | var indexes = new neo4j.index.Indexes(db); 69 | 70 | indexes.createRelationshipIndex(indexName).then(function(index) { 71 | result.index = index; 72 | }); 73 | 74 | this.assertTrue("Server should have been called.", result.called); 75 | this.assertTrue("Should have gotten an index back", typeof(result.index) != "undefined"); 76 | this.assertTrue("Should result in a relationship index", result.index instanceof neo4j.index.RelationshipIndex); 77 | 78 | }, 79 | 80 | testCanListNodeIndexes : function() { 81 | var result = {}; 82 | 83 | clearWebmock(); 84 | mockServiceDefinition(); 85 | 86 | webmock("GET", "http://localhost:7474/db/data/index/node", function(req) { 87 | result.serverCalled=true; 88 | req.success({ 89 | "my_nodes" : { 90 | "template" : "http://localhost:7474/db/data/index/node/my_nodes/{key}/{value}", 91 | "provider" : "lucene", 92 | "type" : "exact" 93 | }, 94 | "more_nodes" : { 95 | "template" : "http://localhost:7474/db/data/index/node/more_nodes/{key}/{value}", 96 | "provider" : "lucene", 97 | "type" : "fulltext" 98 | } 99 | }); 100 | }); 101 | 102 | var db = mockedGraphDatabase(), 103 | indexes = new neo4j.index.Indexes(db); 104 | 105 | indexes.getAllNodeIndexes().then(function(nodeIndexes){ 106 | result.nodeIndexes = nodeIndexes; 107 | }); 108 | 109 | this.assertTrue("Server should have been called.", result.serverCalled); 110 | this.assertTrue("Should have gotten a result", typeof(result.nodeIndexes) != "undefined"); 111 | this.assertTrue("Should result in two indexes", result.nodeIndexes.length == 2); 112 | 113 | for(var i=0,l=result.nodeIndexes.length;i. 19 | */ 20 | -------------------------------------------------------------------------------- /src/test/javascript/neo4j/models/NodeTestCase.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | var NodeTest = function(name) { 21 | TestCase.call(this, "NodeTest." + name); 22 | }; 23 | 24 | NodeTest.prototype = new TestCase(); 25 | 26 | _.extend(NodeTest.prototype, { 27 | 28 | testFailsWhenGivenNonNodeUrl : function() { 29 | var nonNodeUrl = "asd123", result={}; 30 | clearWebmock(); 31 | mockServiceDefinition(); 32 | 33 | webmock("GET", nonNodeUrl, { 34 | "management" :"", 35 | "data" : "" 36 | }); 37 | 38 | var node = new neo4j.models.Node({self:nonNodeUrl}, mockedGraphDatabase()); 39 | 40 | node.fetch().then(null, function(fail) { 41 | result.error = fail; 42 | }); 43 | 44 | this.assertTrue("Error should have been triggered", typeof(result.error) != "undefined"); 45 | this.assertTrue("Error should be InvalidDataException.", result.error instanceof neo4j.exceptions.InvalidDataException); 46 | 47 | }, 48 | 49 | testTraverseForNodes : function() { 50 | var rootTraversalUrl = "http://localhost:7474/db/data/node/0/traverse/node", result={}; 51 | clearWebmock(); 52 | mockServiceDefinition(); 53 | 54 | webmock("POST", rootTraversalUrl, [{ 55 | "outgoing_relationships" : "http://localhost:7474/db/data/node/0/relationships/out", 56 | "data" : {}, 57 | "traverse" : "http://localhost:7474/db/data/node/0/traverse/{returnType}", 58 | "all_typed_relationships" : "http://localhost:7474/db/data/node/0/relationships/all/{-list|&|types}", 59 | "property" : "http://localhost:7474/db/data/node/0/properties/{key}", 60 | "self" : "http://localhost:7474/db/data/node/0", 61 | "properties" : "http://localhost:7474/db/data/node/0/properties", 62 | "outgoing_typed_relationships" : "http://localhost:7474/db/data/node/0/relationships/out/{-list|&|types}", 63 | "incoming_relationships" : "http://localhost:7474/db/data/node/0/relationships/in", 64 | "extensions" : { 65 | }, 66 | "create_relationship" : "http://localhost:7474/db/data/node/0/relationships", 67 | "all_relationships" : "http://localhost:7474/db/data/node/0/relationships/all", 68 | "incoming_typed_relationships" : "http://localhost:7474/db/data/node/0/relationships/in/{-list|&|types}" 69 | }]); 70 | 71 | var db = mockedGraphDatabase(); 72 | 73 | db.getReferenceNode().then(function(node) { 74 | node.traverse({}).then(function(nodes) { 75 | result.nodes = nodes; 76 | }); 77 | }); 78 | 79 | this.assertTrue("Should have gotten a response", typeof(result.nodes) != "undefined"); 80 | this.assertTrue("Response type should be node", result.nodes[0] instanceof neo4j.models.Node); 81 | }, 82 | 83 | testTraverseForRelationships : function() { 84 | var rootTraversalUrl = "http://localhost:7474/db/data/node/0/traverse/relationship", result={}; 85 | clearWebmock(); 86 | mockServiceDefinition(); 87 | 88 | webmock("POST", rootTraversalUrl, [ 89 | {"start" : "http://localhost:7474/db/data/node/0", 90 | "data" : { 91 | }, 92 | "self" : "http://localhost:7474/db/data/relationship/1", 93 | "property" : "http://localhost:7474/db/data/relationship/1/properties/{key}", 94 | "properties" : "http://localhost:7474/db/data/relationship/1/properties", 95 | "type" : "KNOWS", 96 | "extensions" : { 97 | }, 98 | "end" : "http://localhost:7474/db/data/node/1" 99 | } 100 | ]); 101 | 102 | var db = mockedGraphDatabase(); 103 | 104 | db.getReferenceNode().then(function(node) { 105 | node.traverse({}, neo4j.traverse.RETURN_RELATIONSHIPS).then(function(rels) { 106 | result.rels = rels; 107 | }); 108 | }); 109 | 110 | this.assertTrue("Should have gotten a response", typeof(result.rels) != "undefined"); 111 | this.assertTrue("Response type should be node", result.rels[0] instanceof neo4j.models.Relationship); 112 | }, 113 | 114 | testTraverseForPath : function() { 115 | var rootTraversalUrl = "http://localhost:7474/db/data/node/0/traverse/path", result={}; 116 | clearWebmock(); 117 | mockServiceDefinition(); 118 | 119 | webmock("POST", rootTraversalUrl, [ { 120 | "start" : "http://localhost:7474/db/data/node/0", 121 | "nodes" : [ "http://localhost:7474/db/data/node/0", "http://localhost:7474/db/data/node/1" ], 122 | "length" : 1, 123 | "relationships" : [ "http://localhost:7474/db/data/relationship/1" ], 124 | "end" : "http://localhost:7474/db/data/node/1" 125 | } ]); 126 | 127 | var db = mockedGraphDatabase(); 128 | 129 | db.getReferenceNode().then(function(node) { 130 | node.traverse({}, neo4j.traverse.RETURN_PATHS).then(function(paths) { 131 | result.paths = paths; 132 | }); 133 | }); 134 | 135 | this.assertTrue("Should have gotten a response", typeof(result.paths) != "undefined"); 136 | this.assertTrue("Response type should be node", result.paths[0] instanceof neo4j.models.Path); 137 | } 138 | }); 139 | -------------------------------------------------------------------------------- /src/test/javascript/neo4j/models/PropertyContainerTestCase.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | var PropertyContainerTest = function(name) { 21 | TestCase.call(this, "PropertyContainerTest." + name); 22 | }; 23 | 24 | PropertyContainerTest.prototype = new TestCase(); 25 | 26 | _.extend(PropertyContainerTest.prototype, { 27 | 28 | testHasProperty : function() { 29 | 30 | var pc = new neo4j.models.PropertyContainer(); 31 | 32 | this.assertFalse("Property should not exist.", pc.hasProperty("someprop")); 33 | pc.setProperty("someprop"); 34 | this.assertTrue("Property should exist.", pc.hasProperty("someprop")); 35 | 36 | } 37 | }); 38 | -------------------------------------------------------------------------------- /src/test/javascript/neo4j/models/RelationshipTestCase.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2013 "Neo Technology," 3 | * Network Engine for Objects in Lund AB [http://neotechnology.com] 4 | * 5 | * This file is part of Neo4j. 6 | * 7 | * Neo4j is free software: you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation, either version 3 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program. If not, see . 19 | */ 20 | var RelationshipTest = function(name) { 21 | TestCase.call(this, "RelationshipTest." + name); 22 | }; 23 | 24 | RelationshipTest.prototype = new TestCase(); 25 | 26 | _.extend(RelationshipTest.prototype, { 27 | 28 | testFailsWhenGivenNonRelationshipUrl : function() { 29 | var nonNodeUrl = "asd123", result={}; 30 | clearWebmock(); 31 | mockServiceDefinition(); 32 | 33 | webmock("GET", nonNodeUrl, { 34 | "management" :"", 35 | "data" : "" 36 | }); 37 | 38 | var rel = new neo4j.models.Relationship({self:nonNodeUrl}, mockedGraphDatabase()); 39 | 40 | rel.fetch().then(null, function(fail) { 41 | result.error = fail; 42 | }); 43 | 44 | this.assertTrue("Error should have been triggered", typeof(result.error) != "undefined"); 45 | this.assertTrue("Error should be InvalidDataException.", result.error instanceof neo4j.exceptions.InvalidDataException); 46 | 47 | } 48 | }); 49 | --------------------------------------------------------------------------------