├── .gitignore ├── .project ├── BUILD.md ├── README.md ├── docs ├── Attachment.html ├── MaximoFactory.html ├── Resource.html ├── ResourceObject.html ├── ResourceSet.html ├── fonts │ ├── OpenSans-Bold-webfont.eot │ ├── OpenSans-Bold-webfont.svg │ ├── OpenSans-Bold-webfont.woff │ ├── OpenSans-BoldItalic-webfont.eot │ ├── OpenSans-BoldItalic-webfont.svg │ ├── OpenSans-BoldItalic-webfont.woff │ ├── OpenSans-Italic-webfont.eot │ ├── OpenSans-Italic-webfont.svg │ ├── OpenSans-Italic-webfont.woff │ ├── OpenSans-Light-webfont.eot │ ├── OpenSans-Light-webfont.svg │ ├── OpenSans-Light-webfont.woff │ ├── OpenSans-LightItalic-webfont.eot │ ├── OpenSans-LightItalic-webfont.svg │ ├── OpenSans-LightItalic-webfont.woff │ ├── OpenSans-Regular-webfont.eot │ ├── OpenSans-Regular-webfont.svg │ └── OpenSans-Regular-webfont.woff ├── global.html ├── index.html ├── maximofactory.js.html ├── resources_attachment.js.html ├── resources_resource.js.html ├── resources_resourceobject.js.html ├── resources_resourceset.js.html ├── scripts │ ├── linenumber.js │ └── prettify │ │ ├── Apache-License-2.0.txt │ │ ├── lang-css.js │ │ └── prettify.js └── styles │ ├── jsdoc-default.css │ ├── prettify-jsdoc.css │ └── prettify-tomorrow.css ├── error └── error.js ├── maximofactory.js ├── package-lock.json ├── package.json ├── resources ├── attachment.js ├── connectors │ ├── authconnector.js │ ├── crudconnector.js │ ├── externalconnector.js │ ├── fetchconnector.js │ ├── relatedconnector.js │ └── schemaconnector.js ├── resource.js ├── resourceobject.js └── resourceset.js └── server.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | ibm-maximo-api.iml 3 | node_modules/ -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ibm-maximo-api 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.jsdt.core.javascriptValidator 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.wst.jsdt.core.jsNature 16 | 17 | 18 | -------------------------------------------------------------------------------- /BUILD.md: -------------------------------------------------------------------------------- 1 | # Building Maximo Rest Client for NodeJS 2 | 3 | ## Quick Start 4 | 5 | This assumes that you have a git client and that nodejs is installed. 6 | 7 | ```bash 8 | git clone git@github.com:ibm-maximo-dev/maximo-nodejs-rest-client.git 9 | cd maximo-nodejs-rest-client 10 | npm install 11 | npm start 12 | ``` 13 | 14 | ## Generating JSDoc 15 | ```bash 16 | 17 | npm run jsdoc 18 | 19 | ``` 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Using Maximo Asset Management APIs 2 | 3 | [![Deploy to Bluemix](https://bluemix.net/deploy/button.png)](https://bluemix.net/deploy?repository= # [required]) 4 | 5 | ## Introduction 6 | 7 | This module includes a set of fluent APIs for interfacing with Maximo Asset Management by providing a high-level abstraction for the 8 | Maximo REST API's. The intent is to shield developers from low-level details and help them focus on their own implementation 9 | logic. 10 | 11 | ## Prerequisites 12 | 13 | Install [Node](https://nodejs.org/en/) and [Express](http://expressjs.com/). 14 | 15 | ## Installing 16 | 17 | Install the ibm-maximo-api package by using the following command: 18 | 19 | $ npm install --save ibm-maximo-api 20 | 21 | ## Usage 22 | 23 | There are three main components .... 24 | 25 | 26 | 27 | #### Requiring Maximo Asset Management 28 | 29 | Like any other Node.js module, you can load the Maximo module and assign a local reference to your code by using the built-in require() function. For example, the following require() function returns a prototype (class) and assigns it to the local Maximo variable. 30 | 31 | var Maximo = require('ibm-maximo-api'); 32 | 33 | 34 | 35 | #### Constructor and Authentication 36 | 37 | After you assign a local reference by using the require() function, you can instantiate an object. For example: 38 | 39 | var maximo = new Maximo(options,[authcookie]); 40 | 41 | 42 | The constructor accepts two parameters: 43 | 44 | options: This parameter is REQUIRED and is represented by an object like this: 45 | { 46 | protocol: 'http', 47 | hostname: 'qawin03.swg.usma.ibm.com', 48 | port: '9080', 49 | user: 'wilson', 50 | password: 'wilson', 51 | auth_scheme: '/maximo', 52 | authtype:'maxauth', 53 | islean:1 54 | } 55 | 56 | authcookie: This parameter is OPTIONAL. 57 | If this parameter is null the Create, Read, Update and Delete (CRUD) api's will attempt to 58 | authenticate with Maximo everytime a CRUD operation is invoked. 59 | 60 | If Create, Read, Update and Delete (CRUD) APIs are invoked multiple times, you should authenticate first by using the authenticate() function. If 61 | authentication is successful, a token(jsessionID) is returned. Save the token in the request session so that the token can be 62 | read and passed into the constructor for subsequent requests. The following code snippet illustrates a GET route that 63 | authenticates with Maximo Asset Management and stores the token inside the session. 64 | 65 | app.get('/authenticate', function(req, res) 66 | { 67 | var maximo = new Maximo(options); 68 | maximo.authenticate() 69 | .then(function(jsessionid) 70 | { 71 | req.session.authcookie = jsessionid; // Set the token in the session so we can use it for future requests 72 | res.json(jsessionid); // Handle the response after setting the token in the session. 73 | }) 74 | .fail(function (error) 75 | { 76 | console.log('****** Error Code = '+error); 77 | }); 78 | } 79 | 80 | Since the authenticate() function is asynchronous, a deferred [Promise](https://www.npmjs.com/package/q) is returned, 81 | which is fulfilled inside the then() function or the fail() function if the promise is rejected. 82 | In either case, the response is handled inside the callback. 83 | 84 | 85 | #### Fetch 86 | 87 | The following code snippet illustrates how to use the fetch API. This example returns a ResourceSet and uses all the basic 88 | expressions that are available. 89 | 90 | router.get('/test_resource_set', function(req, res) 91 | { 92 | var maximo = new Maximo(options); 93 | maximo.resourceobject("MXWODETAIL") 94 | .select(["wonum","description","location","status","assetnum.description"]) 95 | .where("status").in(["WAPPR","APPR"]) 96 | .and("worktype").equal('CM') 97 | .orderby('wonum','desc') 98 | .pagesize(20) 99 | .fetch() 100 | .then(function(resourceset) 101 | { 102 | jsondata = resourceset.thisResourceSet(); 103 | res.json(jsondata); 104 | }) 105 | .fail(function (error) 106 | { 107 | console.log('****** Error Code = '+error); 108 | }); 109 | }); 110 | 111 | #### Next Page 112 | 113 | The following code snippet illustrates how to use the Paging API. In this example, assume that the initial set is fetched 114 | with the pagesize() set to a low number, like 20 and stored in the session (req.session.resourcesetjson). 115 | 116 | router.get('/test_nextpage', function(req, res) 117 | { 118 | var authcookie = req.session.authcookie; 119 | var maximo = new Maximo(options,authcookie); 120 | maximo.resourceobject("MXWODETAIL") 121 | .nextpage(req.session.resourcesetjson) // The paged resource is stored in session 122 | .then(function(resourceset) 123 | { 124 | if(resourceset) 125 | { 126 | jsondata = resourceset.JSON(); 127 | req.session.resourcesetjson = jsondata; /// Store it in the session 128 | res.json(jsondata); 129 | } 130 | res.json({"status":"End of page"}) 131 | }) 132 | .fail(function (error) 133 | { 134 | console.log('****** Error Code = '+error); 135 | }); 136 | }); 137 | 138 | #### Create 139 | 140 | The following code snippet illustrates how to create a work order by using the Create API. 141 | 142 | router.get('/test_create', function(req, res) 143 | { 144 | var wo = ''; 145 | var required = 146 | { 147 | "spi:description":"Created from API", 148 | "spi:siteid":"BEDFORD" 149 | } 150 | var authcookie = req.session.authcookie; 151 | var maximo = new Maximo(options,authcookie); 152 | 153 | maximo.resourceobject("MXWODETAIL") 154 | .create(required,["spi:wonum","spi:description"]) 155 | .then(function(resource) 156 | { 157 | jsondata = resource.JSON(); 158 | res.json(jsondata); 159 | }) 160 | .fail(function (error) 161 | { 162 | console.log('****** Error Code = '+error); 163 | }); 164 | }); 165 | 166 | #### Update 167 | 168 | The following code snippet illustrates how to use the Update API. In this example, assume that the resourceset is saved 169 | in the session (req.session.myresourceset) and the first record in the set is updated by passing 170 | the resource URL (req.session.myresourceset[0]["rdf:about"]). The resource URL for the update is contained in "rdf:about". 171 | 172 | router.get('/test_update', function(req, res) 173 | { 174 | var wo = ''; 175 | var updates = 176 | { 177 | "spi:description":"Updated from Node API - test crudconnector", 178 | "spi:siteid":"BEDFORD" 179 | } 180 | // Assuming myresourceset was previously placed in session 181 | var authcookie = req.session.authcookie; 182 | var maximo = new Maximo(options,authcookie); 183 | maximo.resourceobject("MXWODETAIL") 184 | .resource(req.session.myresourceset[0]["rdf:about"]) //Pass the URI 185 | .update(updates,["spi:wonum","spi:description"]) 186 | .then(function(resource) 187 | { 188 | var jsondata = resource.JSON(); 189 | res.json(jsondata); 190 | }) 191 | .fail(function (error) 192 | { 193 | console.log('****** Error Code = '+error); 194 | }); 195 | }); 196 | 197 | #### Delete 198 | 199 | The following code snippet illustrates how to use the Delete API. In this example, assume that the resourceset is saved 200 | in the session (req.session.myresourceset) and the first record in the set is updated by passing 201 | the resource URL (req.session.myresourceset[0]["rdf:about"]). The resource URL for the update is contained in "rdf:about". 202 | 203 | router.get('/test_update', function(req, res) 204 | { 205 | // Assuming myresourceset was previously placed in session 206 | var authcookie = req.session.authcookie; 207 | var maximo = new Maximo(options,authcookie); 208 | maximo.resourceobject("MXWODETAIL") 209 | .resource(req.session.myresourceset[0]["rdf:about"]) //Pass the URI 210 | .delete(["spi:wonum","spi:description"]) 211 | .then(function(resource) 212 | { 213 | var jsondata = resource.JSON(); 214 | res.json(jsondata); 215 | }) 216 | .fail(function (error) 217 | { 218 | console.log('****** Error Code = '+error); 219 | }); 220 | }); 221 | 222 | #### Attachments 223 | 224 | The following code snippet illustrates how to use the Attachments API. 225 | 226 | router.get('/test_attachments', function(req, res) 227 | { 228 | getFileBytes('attachtestt.doc') 229 | .then(function(fileBuffer) 230 | { 231 | console.log("fileBuffer "+fileBuffer.length); 232 | var authcookie = req.session.authcookie; 233 | console.log("********* AuthCookie "+authcookie); 234 | var maximo = new Maximo(options,authcookie); 235 | //var maximo = new Maximo(options); 236 | maximo.resourceobject("MXWODETAIL") 237 | .select(["wonum","description","reportedby","location","status","assetnum.assetnum"]) 238 | .where("wonum").equal('1459') 239 | .pagesize(20) 240 | .fetch() 241 | .then(function(resourceset) 242 | { 243 | req.session.myresourceset = resourceset.thisResourceSet(); 244 | var rsrc = resourceset.resource(0); 245 | var meta = { 246 | name: 'pmr.doc', 247 | description: 'PMR Recreation Steps', 248 | type: 'FILE', 249 | storeas: 'Attachment', 250 | contentype: 'application/msword' 251 | 252 | }; 253 | var attch = rsrc.attachment(meta); 254 | attch.create(fileBuffer) 255 | .then(function(resc) 256 | { 257 | console.log("Writing Attachment response "); 258 | //jsondata = rsrc.JSON(); 259 | //res.json(jsondata); 260 | }); 261 | 262 | }) 263 | .fail(function (error) 264 | { 265 | console.log('****** Error Code = '+error); 266 | }); 267 | }); 268 | }); 269 | 270 | ## Contact 271 | 272 | - [Sachin Balagopalan](sachin.balagopalan@us.ibm.com) 273 | 274 | ## Technical Reference 275 | 276 | - [JSDoc](https://ibm-maximo-dev.github.io/maximo-nodejs-rest-client/index.html) 277 | 278 | ## License 279 | 280 | (C) Copyright IBM Corp. 2015,2018 All Rights Reserved 281 | -------------------------------------------------------------------------------- /docs/Attachment.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Class: Attachment 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Class: Attachment

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

Attachment(member, meta, cookie) → {Attachment}

32 | 33 | 34 |
35 | 36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 |

new Attachment(member, meta, cookie) → {Attachment}

45 | 46 | 47 | 48 | 49 | 50 | 51 |
52 | Attachment (doclinks) object for Maximo OSLC API 53 |
54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
Parameters:
64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 |
NameTypeDescription
member 92 | 93 |
meta 110 | 111 |
cookie 128 | 129 |
141 | 142 | 143 | 144 | 145 | 146 | 147 |
148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 |
Source:
175 |
178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 |
186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 |
Returns:
200 | 201 | 202 | 203 | 204 |
205 |
206 | Type 207 |
208 |
209 | 210 | Attachment 211 | 212 | 213 |
214 |
215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 |
224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 |

Methods

241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 |

create(buffer, datacallback) → {*}

249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 |
Parameters:
264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 |
NameTypeDescription
buffer 292 | 293 |
datacallback 310 | 311 |
323 | 324 | 325 | 326 | 327 | 328 | 329 |
330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 |
Source:
357 |
360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 |
368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 |
Returns:
382 | 383 | 384 | 385 | 386 |
387 |
388 | Type 389 |
390 |
391 | 392 | * 393 | 394 | 395 |
396 |
397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 |

JSON() → {*}

411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 |
430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 |
Source:
457 |
460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 |
468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 |
Returns:
482 | 483 | 484 | 485 | 486 |
487 |
488 | Type 489 |
490 |
491 | 492 | * 493 | 494 | 495 |
496 |
497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 |
511 | 512 |
513 | 514 | 515 | 516 | 517 |
518 | 519 | 522 | 523 |
524 | 525 | 528 | 529 | 530 | 531 | 532 | -------------------------------------------------------------------------------- /docs/MaximoFactory.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Class: MaximoFactory 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Class: MaximoFactory

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

MaximoFactory(options, cookie, callback) → {MaximoFactory}

32 | 33 | 34 |
35 | 36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 |

new MaximoFactory(options, cookie, callback) → {MaximoFactory}

45 | 46 | 47 | 48 | 49 | 50 | 51 |
52 | Creates an object for exposing Maximo OSLC API 53 |
54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
Parameters:
64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 |
NameTypeDescription
options 92 | 93 | 94 | MaximoProperties 95 | 96 | 97 | 98 |
cookie 115 | 116 |
callback 133 | 134 |
146 | 147 | 148 | 149 | 150 | 151 | 152 |
153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 |
Source:
180 |
183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 |
191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 |
Returns:
205 | 206 | 207 | 208 | 209 |
210 |
211 | Type 212 |
213 |
214 | 215 | MaximoFactory 216 | 217 | 218 |
219 |
220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 |

Members

244 | 245 | 246 | 247 |

isCookieSet

248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 |
259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 |
Source:
286 |
289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 |
297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 |

Methods

308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 |

authenticate() → {*}

316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 |
335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 |
Source:
362 |
365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 |
373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 |
Returns:
387 | 388 | 389 | 390 | 391 |
392 |
393 | Type 394 |
395 |
396 | 397 | * 398 | 399 | 400 |
401 |
402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 |

publicuri() → {string|*}

416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 |
435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 |
Source:
462 |
465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 |
473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 |
Returns:
487 | 488 | 489 | 490 | 491 |
492 |
493 | Type 494 |
495 |
496 | 497 | string 498 | | 499 | 500 | * 501 | 502 | 503 |
504 |
505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 |

resourceobject(mbo) → {ResourceObject}

519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 |
Parameters:
534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 |
NameTypeDescription
mbo 562 | 563 |
575 | 576 | 577 | 578 | 579 | 580 | 581 |
582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 |
Source:
609 |
612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 |
620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 |
Returns:
634 | 635 | 636 | 637 | 638 |
639 |
640 | Type 641 |
642 |
643 | 644 | ResourceObject 645 | 646 | 647 |
648 |
649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 |

user() → {MaximoFactory.user|*}

663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 |
682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 |
Source:
709 |
712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 |
720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 |
Returns:
734 | 735 | 736 | 737 | 738 |
739 |
740 | Type 741 |
742 |
743 | 744 | MaximoFactory.user 745 | | 746 | 747 | * 748 | 749 | 750 |
751 |
752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 |
766 | 767 |
768 | 769 | 770 | 771 | 772 |
773 | 774 | 777 | 778 |
779 | 780 | 783 | 784 | 785 | 786 | 787 | -------------------------------------------------------------------------------- /docs/ResourceObject.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Class: ResourceObject 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Class: ResourceObject

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

ResourceObject(maxfactory, mbo) → {ResourceSet}

32 | 33 | 34 |
35 | 36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 |

new ResourceObject(maxfactory, mbo) → {ResourceSet}

45 | 46 | 47 | 48 | 49 | 50 | 51 |
52 | Business object for Maximo OSLC API 53 |
54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
Parameters:
64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 |
NameTypeDescription
maxfactory 92 | 93 |
mbo 110 | 111 |
123 | 124 | 125 | 126 | 127 | 128 | 129 |
130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 |
Source:
157 |
160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 |
168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 |
Returns:
182 | 183 | 184 | 185 | 186 |
187 |
188 | Type 189 |
190 |
191 | 192 | ResourceSet 193 | 194 | 195 |
196 |
197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 |
206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 |

Methods

223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 |

name() → {*}

231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 |
250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 |
Source:
277 |
280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 |
288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 |
Returns:
302 | 303 | 304 | 305 | 306 |
307 |
308 | Type 309 |
310 |
311 | 312 | * 313 | 314 | 315 |
316 |
317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 |
331 | 332 |
333 | 334 | 335 | 336 | 337 |
338 | 339 | 342 | 343 |
344 | 345 | 348 | 349 | 350 | 351 | 352 | -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-maximo-dev/maximo-nodejs-rest-client/472f04f27f1948ea166c5c60a3bf357d978e504e/docs/fonts/OpenSans-Bold-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-maximo-dev/maximo-nodejs-rest-client/472f04f27f1948ea166c5c60a3bf357d978e504e/docs/fonts/OpenSans-Bold-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-BoldItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-maximo-dev/maximo-nodejs-rest-client/472f04f27f1948ea166c5c60a3bf357d978e504e/docs/fonts/OpenSans-BoldItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-BoldItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-maximo-dev/maximo-nodejs-rest-client/472f04f27f1948ea166c5c60a3bf357d978e504e/docs/fonts/OpenSans-BoldItalic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Italic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-maximo-dev/maximo-nodejs-rest-client/472f04f27f1948ea166c5c60a3bf357d978e504e/docs/fonts/OpenSans-Italic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-maximo-dev/maximo-nodejs-rest-client/472f04f27f1948ea166c5c60a3bf357d978e504e/docs/fonts/OpenSans-Italic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-maximo-dev/maximo-nodejs-rest-client/472f04f27f1948ea166c5c60a3bf357d978e504e/docs/fonts/OpenSans-Light-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-maximo-dev/maximo-nodejs-rest-client/472f04f27f1948ea166c5c60a3bf357d978e504e/docs/fonts/OpenSans-Light-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-LightItalic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-maximo-dev/maximo-nodejs-rest-client/472f04f27f1948ea166c5c60a3bf357d978e504e/docs/fonts/OpenSans-LightItalic-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-LightItalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-maximo-dev/maximo-nodejs-rest-client/472f04f27f1948ea166c5c60a3bf357d978e504e/docs/fonts/OpenSans-LightItalic-webfont.woff -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-maximo-dev/maximo-nodejs-rest-client/472f04f27f1948ea166c5c60a3bf357d978e504e/docs/fonts/OpenSans-Regular-webfont.eot -------------------------------------------------------------------------------- /docs/fonts/OpenSans-Regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ibm-maximo-dev/maximo-nodejs-rest-client/472f04f27f1948ea166c5c60a3bf357d978e504e/docs/fonts/OpenSans-Regular-webfont.woff -------------------------------------------------------------------------------- /docs/global.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Global 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Global

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 |

32 | 33 | 34 |
35 | 36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 |
45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 |
78 | 79 | 80 | 81 | 82 |
83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 |

Type Definitions

102 | 103 | 104 | 105 |

MaximoProperties

106 | 107 | 108 | 109 | 110 | 111 | 112 |
Type:
113 |
    114 |
  • 115 | 116 | object 117 | 118 | 119 |
  • 120 |
121 | 122 | 123 | 124 | 125 | 126 |
Properties:
127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 |
NameTypeDescription
protocol 156 | 157 | 158 | string 159 | 160 | 161 | 162 |
hostname 179 | 180 | 181 | string 182 | 183 | 184 | 185 |
port 202 | 203 | 204 | number 205 | 206 | 207 | 208 |
user 225 | 226 | 227 | string 228 | 229 | 230 | 231 |
password 248 | 249 | 250 | string 251 | 252 | 253 | 254 |
tenantcode 271 | 272 | 273 | string 274 | 275 | 276 | 277 |
auth_scheme 294 | 295 | 296 | string 297 | 298 | 299 | 300 |
authtype 317 | 318 | 319 | string 320 | 321 | 322 | 323 |
islean 340 | 341 | 342 | boolean 343 | 344 | 345 | 346 |
358 | 359 | 360 | 361 | 362 |
363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 |
Source:
390 |
393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 |
401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 |
412 | 413 |
414 | 415 | 416 | 417 | 418 |
419 | 420 | 423 | 424 |
425 | 426 | 429 | 430 | 431 | 432 | 433 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Home 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Home

21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |

30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |

IBM-Maximo-API

Deploy to Bluemix

47 |

Introduction

This module includes a set of fluent API's for interfacing with Maximo by providing a high level abstraction for the 48 | Maximo REST API's. The intent is to shield developers from low level details and help them focus on their own implementation 49 | logic.

50 |

Installing

Assumes Node and Express are installed.

51 |

$ npm install --save ibm-maximo-api

52 |

Usage

There are three main components ....

53 |

Requiring Maximo

Like any other Node.js module the "maximo" module has to be loaded and assigned a local reference in your code. The easiest 54 | way to do this is using the built-in require() function.

55 |
var Maximo = require('ibm-maximo-api');

The require() function returns a prototype (class) and assigns it to the local variable Maximo in the example above.

56 |

Constructor and Authentication

After a local reference has been assigned using the require() function you can easily instantiate an object like this:

57 |
var maximo = new Maximo(options,[authcookie]);

The constructor accepts two parameters:

58 |
options: This parameter is REQUIRED and is represented by an object like this:
 59 |           {
 60 |               protocol: 'http',
 61 |               hostname: 'qawin03.swg.usma.ibm.com',
 62 |               port: '9080',
 63 |               user: 'wilson',
 64 |               password: 'wilson',
 65 |               auth_scheme: '/maximo',
 66 |               authtype:'maxauth',
 67 |               islean:1
 68 |           }
 69 | 
 70 | authcookie: This parameter is OPTIONAL.
 71 |             If this parameter is null the Create, Read, Update and Delete (CRUD) api's will attempt to 
 72 |             authenticate with Maximo everytime a CRUD operation is invoked.

If CRUD's are invoked multiple times it is recommended to authenticate first via the authenticate() function. If the 73 | authentication is sucessful a token(jsessionID) will be returned. Save the token in the request session so it can be 74 | read and passed into the constructor for subsequent requests. The following code snippet illustrates a GET route that 75 | authenticates with maximo and stores the token inside the session.

76 |
app.get('/authenticate', function(req, res)
 77 | {
 78 |   var maximo = new Maximo(options);
 79 |   maximo.authenticate()
 80 |         .then(function(jsessionid)
 81 |         {
 82 |           req.session.authcookie = jsessionid; // Set the token in the session so we can use it for future requests
 83 |           res.json(jsessionid); // Handle the response after setting the token in the session.
 84 |         })
 85 |         .fail(function (error)
 86 |         {
 87 |               console.log('****** Error Code = '+error);
 88 |         });
 89 | }

The authenticate() function is asynchronous therefore it returns a defered Promise 90 | which is fulfilled inside the then() function or the fail() function if the promise is rejected. 91 | In either case the response is handled inside the callback as illustrated in the code snippet above.

92 |

Fetch

The following code snippet illustrates how to use the fetch API. This example returns a ResourceSet and uses all the basic 93 | expressions available.

94 |
router.get('/test_resource_set', function(req, res)
 95 | {
 96 |   var maximo = new Maximo(options);
 97 |   maximo.resourceobject("MXWODETAIL")
 98 |         .select(["wonum","description","location","status","assetnum.description"])
 99 |         .where("status").in(["WAPPR","APPR"])
100 |         .and("worktype").equal('CM')
101 |         .orderby('wonum','desc')
102 |         .pagesize(20)
103 |         .fetch()
104 |         .then(function(resourceset)
105 |         {
106 |           jsondata = resourceset.thisResourceSet();
107 |           res.json(jsondata);
108 |         })
109 |         .fail(function (error)
110 |         {
111 |               console.log('****** Error Code = '+error);
112 |         });
113 | });

Next Page

The following code snippet illustrates the Paging api. In this example we are assuming that the initial set is fetched 114 | with the pagesize() set to a low number like 20 and stored in the session (req.session.resourcesetjson).

115 |
router.get('/test_nextpage', function(req, res)
116 | {
117 |   var authcookie = req.session.authcookie;
118 |   var maximo = new Maximo(options,authcookie);
119 |   maximo.resourceobject("MXWODETAIL")
120 |         .nextpage(req.session.resourcesetjson) // The paged resource is stored in session
121 |         .then(function(resourceset)
122 |           {
123 |             if(resourceset)
124 |             {
125 |               jsondata = resourceset.JSON();
126 |               req.session.resourcesetjson = jsondata; /// Store it in the session
127 |               res.json(jsondata);
128 |             }
129 |             res.json({"status":"End of page"})
130 |           })
131 |       .fail(function (error)
132 |       {
133 |             console.log('****** Error Code = '+error);
134 |       });
135 | });

Create

The following code snippet illustrates the Create api. In this example we are creating a new Workorder.

136 |
router.get('/test_create', function(req, res)
137 | {
138 |     var wo = '';
139 |     var required =
140 |       {
141 |         "spi:description":"Created from API",
142 |         "spi:siteid":"BEDFORD"
143 |       }
144 | var authcookie = req.session.authcookie;
145 | var maximo = new Maximo(options,authcookie);
146 | 
147 | maximo.resourceobject("MXWODETAIL")
148 |       .create(required,["spi:wonum","spi:description"])
149 |       .then(function(resource)
150 |             {
151 |               jsondata = resource.JSON();
152 |               res.json(jsondata);
153 |             })
154 |         .fail(function (error)
155 |         {
156 |               console.log('****** Error Code = '+error);
157 |         });
158 | });

Update

The following code snippet illustrates the Update api. In this example we are assuming the resourceset is saved 159 | in the session (req.session.myresourceset) and we are updating the first record in the set by passing 160 | the resource URL (req.session.myresourceset[0]["rdf:about"]). The resource URL for the update is contained in "rdf:about".

161 |
router.get('/test_update', function(req, res)
162 | {
163 |   var wo = '';
164 |   var updates =
165 |   {
166 |       "spi:description":"Updated from Node API - test crudconnector",
167 |       "spi:siteid":"BEDFORD"
168 |   }
169 | // Assuming myresourceset was previously placed in session
170 |   var authcookie = req.session.authcookie;
171 |   var maximo = new Maximo(options,authcookie);
172 |   maximo.resourceobject("MXWODETAIL")
173 |     .resource(req.session.myresourceset[0]["rdf:about"]) //Pass the URI
174 |     .update(updates,["spi:wonum","spi:description"])
175 |     .then(function(resource)
176 |           {
177 |             var jsondata = resource.JSON();
178 |             res.json(jsondata);
179 |           })
180 |       .fail(function (error)
181 |       {
182 |             console.log('****** Error Code = '+error);
183 |       });
184 | });

Delete

The following code snippet illustrates the Delete api. In this example we are assuming the resourceset is saved 185 | in the session (req.session.myresourceset) and we are updating the first record in the set by passing 186 | the resource URL (req.session.myresourceset[0]["rdf:about"]). The resource URL for the update is contained in "rdf:about".

187 |
router.get('/test_update', function(req, res)
188 | {
189 |   // Assuming myresourceset was previously placed in session
190 |   var authcookie = req.session.authcookie;
191 |   var maximo = new Maximo(options,authcookie);
192 |   maximo.resourceobject("MXWODETAIL")
193 |     .resource(req.session.myresourceset[0]["rdf:about"]) //Pass the URI
194 |     .delete(["spi:wonum","spi:description"])
195 |     .then(function(resource)
196 |           {
197 |             var jsondata = resource.JSON();
198 |             res.json(jsondata);
199 |           })
200 |       .fail(function (error)
201 |       {
202 |             console.log('****** Error Code = '+error);
203 |       });
204 | });

Attachments

The following code snippet illustrates the Attachments api.

205 |
router.get('/test_attachments', function(req, res)
206 | {
207 | getFileBytes('attachtestt.doc')
208 | .then(function(fileBuffer)
209 |     {
210 |       console.log("fileBuffer "+fileBuffer.length);
211 |       var authcookie = req.session.authcookie;
212 |       console.log("********* AuthCookie "+authcookie);
213 |       var maximo = new Maximo(options,authcookie);
214 |       //var maximo = new Maximo(options);
215 |       maximo.resourceobject("MXWODETAIL")
216 |       .select(["wonum","description","reportedby","location","status","assetnum.assetnum"])
217 |       .where("wonum").equal('1459')
218 |       .pagesize(20)
219 |       .fetch()
220 |       .then(function(resourceset)
221 |         {
222 |             req.session.myresourceset = resourceset.thisResourceSet();
223 |             var rsrc = resourceset.resource(0);
224 |             var meta = {
225 |                           name: 'pmr.doc',
226 |                           description: 'PMR Recreation Steps',
227 |                           type: 'FILE',
228 |                           storeas: 'Attachment',
229 |                           contentype: 'application/msword'
230 | 
231 |                       };
232 |             var attch = rsrc.attachment(meta);
233 |             attch.create(fileBuffer)
234 |             .then(function(resc)
235 |             {
236 |                 console.log("Writing Attachment response ");
237 |                 //jsondata = rsrc.JSON();
238 |                 //res.json(jsondata);
239 |             });
240 | 
241 |         })
242 |       .fail(function (error)
243 |       {
244 |             console.log('****** Error Code = '+error);
245 |       });
246 |     });
247 | });

Contact

250 |

License

(C) Copyright IBM Corp. 2015 All Rights Reserved

251 |
252 | 253 | 254 | 255 | 256 | 257 | 258 |
259 | 260 | 263 | 264 |
265 | 266 | 269 | 270 | 271 | 272 | 273 | -------------------------------------------------------------------------------- /docs/maximofactory.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: maximofactory.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: maximofactory.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |

 30 | 'use strict';
 31 | 
 32 | module.exports = MaximoFactory;
 33 | 
 34 | var ResourceObject = require('./resources/resourceobject');
 35 | 
 36 | var InvalidArgumentError = require('./error/error');
 37 | var events = require('events');
 38 | var url = require('url');
 39 | var AuthConnector = require('./resources/connectors/authconnector');
 40 | 
 41 | /**
 42 |  @typedef MaximoProperties
 43 |  @type {object}
 44 |  @property {string} protocol
 45 |  @property {string} hostname
 46 |  @property {number} port
 47 |  @property {string} user
 48 |  @property {string} password
 49 |  @property {string} tenantcode
 50 |  @property {string} auth_scheme
 51 |  @property {string} authtype
 52 |  @property {boolean} islean
 53 |  */
 54 | 
 55 | 
 56 | /**
 57 |  *
 58 |  * Creates an object for exposing Maximo OSLC API
 59 |  *
 60 |  * @param {MaximoProperties} options
 61 |  * @param cookie
 62 |  * @param callback
 63 |  * @returns {MaximoFactory}
 64 |  * @constructor
 65 |  */
 66 | function MaximoFactory(options,cookie,callback)
 67 | {
 68 | 	this.protocol = options.protocol;
 69 | 	this.hostname = options.hostname;
 70 | 	this.port = options.port;
 71 |  	this.user = options.user;
 72 |  	this.password = options.password;
 73 |  	this.islean = 0;
 74 |  	this.tenantcode = options.tenantcode;
 75 |  	this.auth_scheme = options.auth_scheme;
 76 |  	this.authType = options.authtype;
 77 |  	this.cookie = cookie;
 78 |  	this.isCookieSet = this.cookie ? true : false;
 79 | 
 80 |  	if(this.authType && this.authType == "form")
 81 |  	{
 82 |  		this.authPath = this.auth_scheme+"/j_security_check";
 83 |  	}
 84 | 
 85 | 
 86 |  	if(options.islean != null)
 87 |  	{
 88 |  		this.islean = options.islean;
 89 |  	}
 90 | 
 91 |  	console.log("### islean "+this.islean);
 92 | 
 93 |  	this.resturl = url.parse(this.protocol+"://"+this.user+":"+this.password+"@"+this.hostname+":"+this.port);
 94 | 
 95 |  	this.resturl.auth_scheme = this.auth_scheme;
 96 | 
 97 |  	if(callback != null)
 98 |  	{
 99 | 		if(this.hostname === "" || this.user === "" || this.password === "")
100 | 		{
101 | 			callback(new Error("Invalid null arguments.",""));
102 | 		}
103 | 	}
104 | 	return this;
105 | }
106 | 
107 | /**
108 |  *
109 |  * @returns {*}
110 |  */
111 | MaximoFactory.prototype.authenticate = function()
112 | {
113 | 	this.authC = new AuthConnector(this.resturl);
114 | 	this.authC.authType = this.authType;
115 |     return this.authC.authenticate(this.authC);
116 | };
117 | 
118 | /**
119 |  *
120 |  * @param mbo
121 |  * @returns {ResourceObject}
122 |  */
123 | MaximoFactory.prototype.resourceobject = function(mbo)
124 | {
125 |     //return new ResourceSet(this.resturl,this.user,this.password,mbo);
126 |     return new ResourceObject(this,mbo);
127 | };
128 | 
129 | /**
130 |  *
131 |  * @returns {string|*}
132 |  */
133 | MaximoFactory.prototype.publicuri = function()
134 | {
135 |     return this.hostname;
136 | };
137 | 
138 | /**
139 |  *
140 |  * @returns {MaximoFactory.user|*}
141 |  */
142 | MaximoFactory.prototype.user = function()
143 | {
144 |     return this.user;
145 | };
146 | 
147 | /**
148 |  *
149 |  */
150 | MaximoFactory.prototype.isCookieSet;
151 | 
152 |
153 |
154 | 155 | 156 | 157 | 158 |
159 | 160 | 163 | 164 |
165 | 166 | 169 | 170 | 171 | 172 | 173 | 174 | -------------------------------------------------------------------------------- /docs/resources_attachment.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: resources/attachment.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: resources/attachment.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
'use strict';
 30 | module.exports = Attachment;
 31 | var url = require('url');
 32 | var buffer = require('buffer');
 33 | var http   = require('http');
 34 | var REST_PATH = '/maximo/oslc/os/';
 35 | var X_PUB_PATH = '/maximo/oslc/';
 36 | var Q = require('q');
 37 | var ResourceSet = require('./resourceset');
 38 | var Resource = require('./resource');
 39 | 
 40 | /**
 41 |  * Attachment (doclinks) object for Maximo OSLC API
 42 |  * @param member
 43 |  * @param meta
 44 |  * @param cookie
 45 |  * @returns {Attachment}
 46 |  * @constructor
 47 |  */
 48 | function Attachment(member,meta,cookie)
 49 | {
 50 |  	this.member = member;
 51 |  	//this.currentResourceSet = collection["rdfs:member"];
 52 |  	this.resourceURI = (typeof(member)==="object")? getMyResourceURI(this.member) : member;
 53 |  	this.cookie = cookie;
 54 |  	this.name = meta.name;
 55 |  	this.description = meta.description;
 56 |  	this.type = meta.type;
 57 |  	this.contenttype = meta.contentype;
 58 |  	this.storeas = meta.storeas;
 59 |  	return this;
 60 | };
 61 | 
 62 | /**
 63 |  *
 64 |  * @returns {*}
 65 |  */
 66 | Attachment.prototype.JSON= function()
 67 | {
 68 |     //return this.idx < 0 ? this.currentResourceSet : this.currentResourceSet[this.idx];
 69 |     return this.member;
 70 | };
 71 | 
 72 | 
 73 | /**
 74 |  *
 75 |  * @param buffer
 76 |  * @param datacallback
 77 |  * @returns {*}
 78 |  */
 79 | Attachment.prototype.create = function(buffer,datacallback)
 80 | {
 81 | 	return createAttachment(buffer,this,datacallback);
 82 | };
 83 | 
 84 | 
 85 | 
 86 | // Private methods
 87 | 
 88 | function getMyResourceURI(member)
 89 | {
 90 | 	// if rdf:resource is not available use rdf:about or href - one of them should definitely be available.
 91 |     var urltype = (typeof(member["rdf:about"] != "undefined") && member["rdf:about"] != null)
 92 | 								? "rdf:about"
 93 | 									: (typeof(member["rdf:resource"] != "undefined") && member["rdf:resource"] != null)
 94 | 								        ? "rdf:resource"
 95 | 								            : "href" ;
 96 | 	return member[urltype];
 97 | }
 98 | 
 99 | 
100 | function getHeaders(buffer,me)
101 | {
102 | 	console.log("Content_Type **** "+me.contenttype);
103 | 	console.log("cookie **** "+me.cookie);
104 |     return {/*'MAXAUTH': new Buffer(me.resourceURI.auth).toString('base64')*/
105 |     		'Cookie' : me.cookie,
106 |     			   'content-type': me.contenttype,
107 |     			   'slug': me.name,
108 |     			   'x-method-override': 'PATCH',
109 |     			   'x-document-description': me.description,
110 |     			   'x-document-meta':me.type+"/"+me.storeas
111 |            }
112 | }
113 | 
114 | function createAttachment(buffer,current,datacallback)
115 | {
116 | 	var method = 'POST';
117 | 	var deferred = Q.defer();
118 | 	var returndata = '';
119 | 	var client = require(current.resourceURI.split(':')[0]);
120 | 	var host = current.resourceURI.split(':')[1].split("//")[1];
121 | 	var port = current.resourceURI.split(':')[2].split("/")[0];
122 | 	var path = current.resourceURI.split(host)[1].split(port)[1];
123 | 	// If this.cookie type === object it means it's a URL so we need to login
124 | 	/*var hdr = (typeof(current.cookie) === "object")
125 | 				?
126 | 					{'MAXAUTH': new Buffer(current.cookie.auth).toString('base64'),
127 |     			  			'x-public-uri':xpublicuri.toString()}
128 |     			:
129 |     				{'Cookie' : current.cookie};*/
130 | 	var statusCode = "";
131 | 	var resourceset = "";
132 | 	var options = {
133 |         hostname: host,
134 |         port: port,
135 |         headers: getHeaders(buffer,current),
136 |         path: path,
137 |         method: method
138 |     	};
139 | 
140 |      var req = client.request(options, function(res)
141 |      {
142 |   			res.setEncoding('utf8');
143 |   			var resdata = '';
144 |   			res.on('data', function (chunk)
145 |   			{
146 |   				resdata += chunk;
147 |   			});
148 |   			res.on('error', function(err)
149 | 			{
150 | 			    console.log('Error retrieving data... ' + err.message);
151 | 			    deferred.reject("Error retrieving data...."+ err.message);
152 | 			});
153 |   			res.on('end', function()
154 | 		  	{
155 | 		  		var data = null;
156 | 		  		data = {"error code":res.statusCode,"description":"Required headers may not be set e.g. properties"};
157 | 		  		console.log("STATUS CODE: "+res.statusCode);
158 | 			  	var resourcemem = new Resource(data,current.cookie);
159 | 			  	statusCode = res.statusCode;
160 | 			  	if (datacallback)
161 | 			  	{
162 | 			  		deferred.promise.nodeify(datacallback(statusCode,resourcemem,current));
163 | 			  	} else
164 | 			  	{
165 | 			  		deferred.resolve(resourcemem);
166 | 			  	}
167 | 		   });
168 | 	});
169 | 
170 |     req.on('error', function(e)
171 |     {
172 |   		console.log('problem with request: ' + e.message);
173 | 	});
174 | 
175 | 
176 |   req.write(buffer);
177 | 	req.end();
178 |   //return this;
179 |   return deferred.promise;
180 | };
181 | 
182 |
183 |
184 | 185 | 186 | 187 | 188 |
189 | 190 | 193 | 194 |
195 | 196 | 199 | 200 | 201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /docs/resources_resource.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: resources/resource.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: resources/resource.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
'use strict';
 30 | module.exports = Resource;
 31 | var url = require('url');
 32 | var buffer = require('buffer');
 33 | var http   = require('http');
 34 | var REST_PATH = '/maximo/oslc/os/';
 35 | var X_PUB_PATH = '/maximo/oslc/';
 36 | var Q = require('q');
 37 | var ResourceSet = require('./resourceset');
 38 | var Attachment = require('./attachment');
 39 | var CRUDConnector = require('./connectors/crudconnector');
 40 | var RelatedConnector = require('./connectors/relatedconnector');
 41 | 
 42 | /**
 43 |  * Business object for Maximo OSLC API
 44 |  *
 45 |  * @param member
 46 |  * @param connection
 47 |  * @returns {Resource}
 48 |  * @constructor
 49 |  */
 50 | function Resource(member,connection)
 51 | {
 52 |  	this.member = member;
 53 |  	//this.currentResourceSet = collection["rdfs:member"];
 54 |  	this.resourceURI = (typeof(member)==="object")? getMyResourceURI(this.member) : member;
 55 |   //this.currentResourceSet = (typeof(collection["rdfs:member"]) == "undefined") ? collection: collection["rdfs:member"];
 56 |  	this.isCookieSet = false;
 57 |  	//fyi... if this.isCookieSet = true (set by the client) then the connection will be a cookie
 58 |  	//       otherwise it's a URL
 59 |  	this.connection = connection;
 60 |  	return this;
 61 | };
 62 | 
 63 | /**
 64 |  *
 65 |  */
 66 | Resource.prototype.isCookieSet;
 67 | 
 68 | /**
 69 |  *
 70 |  * @param cookie
 71 |  */
 72 | Resource.prototype.setcookie= function(cookie)
 73 | {
 74 | 	this.cookie = cookie;
 75 | 	this.isCookieSet = true;
 76 | }
 77 | 
 78 | /**
 79 |  *
 80 |  * @returns {*}
 81 |  */
 82 | Resource.prototype.JSON= function()
 83 | {
 84 |     //return this.idx < 0 ? this.currentResourceSet : this.currentResourceSet[this.idx];
 85 |     return this.member;
 86 | };
 87 | 
 88 | /**
 89 |  *
 90 |  * @param relation
 91 |  * @returns {Resource}
 92 |  */
 93 | Resource.prototype.relatedResource = function(relation)
 94 | {
 95 | 	this.relation = relation;
 96 | 	this.resourceURI = getMyResourceURI(this.member[relation]);
 97 | 	return this;
 98 | };
 99 | 
100 | /**
101 |  *
102 |  * @param props
103 |  * @returns {Resource}
104 |  */
105 | Resource.prototype.properties = function(props)
106 | {
107 | 	this.resourceURI += "?oslc.properties="+props.toString();
108 | 	return this;
109 | };
110 | 
111 | /**
112 |  *
113 |  * @param meta
114 |  * @param datacallback
115 |  * @returns {Attachment}
116 |  */
117 | Resource.prototype.attachment = function(meta,datacallback)
118 | {
119 | 	return new Attachment(this.member,meta,this.connection);
120 | };
121 | 
122 | 
123 | /**
124 |  *
125 |  * @param jsonbody
126 |  * @param props
127 |  * @param datacallback
128 |  * @returns {*}
129 |  */
130 | Resource.prototype.update = function(jsonbody,props,datacallback)
131 | {
132 | 	return getCRUDConnector(this).__crud(jsonbody,props,this,'POST','PATCH','MERGE',datacallback);
133 | 	//return crud(jsonbody,props,this,'POST',null,datacallback);
134 | };
135 | 
136 | /**
137 |  *
138 |  * @param datacallback
139 |  * @returns {*}
140 |  */
141 | Resource.prototype.fetch = function(datacallback)
142 | {
143 | 	return getRelatedConnector(this).__fetch(this,this.fconnect); // Pass this.fconnect so it's state is updated.
144 | }
145 | 
146 | /**
147 |  *
148 |  * @param jsonbody
149 |  * @param props
150 |  * @param datacallback
151 |  * @returns {*}
152 |  */
153 | Resource.prototype.merge = function(jsonbody,props,datacallback)
154 | {
155 | 	var patchtype = "MERGE";
156 | 	return crud(jsonbody,props,this,'POST',patchtype,datacallback);
157 | };
158 | 
159 | /**
160 |  *
161 |  * @param jsonbody
162 |  * @param props
163 |  * @param datacallback
164 |  * @returns {*}
165 |  */
166 | Resource.prototype.delete = function(jsonbody,props,datacallback)
167 | {
168 | 	var patchtype = "MERGE";
169 | 	return getCRUDConnector(this).__crud(jsonbody,props,this,'DELETE',null,null,datacallback);
170 | 	//return crud(jsonbody,props,this,'DELETE',null,datacallback);
171 | };
172 | 
173 | 
174 | 
175 | // Private methods
176 | 
177 | function getMyResourceURI(member)
178 | {
179 | 	// if rdf:resource is not available use rdf:about or href - one of them should definitely be available.
180 |     var urltype = (typeof(member["rdf:about"] != "undefined") && member["rdf:about"] != null)
181 | 								? "rdf:about"
182 | 									: (typeof(member["rdf:resource"] != "undefined") && member["rdf:resource"] != null)
183 | 								        ? "rdf:resource"
184 | 								            : "href" ;
185 | 	return member[urltype];
186 | }
187 | 
188 | function getCRUDConnector(me)  // Singleton
189 | {
190 | 	if(me.cconnect == null)
191 | 	{
192 | 		me.cconnect = new CRUDConnector(me.resourceURI, me.maximopath);
193 | 		me.cconnect.authType = me.authType;
194 | 		me.cconnect.cookie = me.cookie;
195 | 		me.cconnect.isCookieSet = me.cookie == null ? false : true;
196 | 	}
197 | 	return me.cconnect;
198 | }
199 | 
200 | function getRelatedConnector(cur)  // Singleton
201 | {
202 | 	if(cur.fconnect == null)
203 | 	{
204 | 		cur.fconnect = new RelatedConnector(cur.resourceURI, cur.maximopath);
205 | 		cur.fconnect.authType = cur.authType;
206 | 		cur.fconnect.cookie = cur.cookie;
207 | 		cur.fconnect.isCookieSet = cur.cookie == null ? false : true;
208 | 	}
209 | 	return cur.fconnect;
210 | }
211 | 
212 |
213 |
214 | 215 | 216 | 217 | 218 |
219 | 220 | 223 | 224 |
225 | 226 | 229 | 230 | 231 | 232 | 233 | 234 | -------------------------------------------------------------------------------- /docs/resources_resourceobject.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: resources/resourceobject.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: resources/resourceobject.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
'use strict';
30 | module.exports = ResourceObject;
31 | 
32 | var ResourceSet = require('./resourceset');
33 | 
34 | 
35 | 
36 | /**
37 |  * Business object for Maximo OSLC API
38 |  * @param maxfactory
39 |  * @param mbo
40 |  * @returns {ResourceSet}
41 |  * @constructor
42 |  */
43 | function ResourceObject(maxfactory,mbo)
44 | {
45 |  	//Return a Zombie set.
46 |  	var cookie = maxfactory.isCookieSet ? maxfactory.cookie["set-cookie"] : null;
47 |  	return new ResourceSet(null,cookie,maxfactory,mbo);
48 | };
49 | 
50 | /**
51 |  *
52 |  * @returns {*}
53 |  */
54 | ResourceObject.prototype.name = function()
55 | {
56 |     return this.mbo;
57 | };
58 | 
59 |
60 |
61 | 62 | 63 | 64 | 65 |
66 | 67 | 70 | 71 |
72 | 73 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /docs/resources_resourceset.js.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JSDoc: Source: resources/resourceset.js 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 |

Source: resources/resourceset.js

21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
'use strict';
 30 | module.exports = ResourceSet;
 31 | var url = require('url');
 32 | var buffer = require('buffer');
 33 | var http   = require('http');
 34 | var Q = require('q');
 35 | var querystring = require("querystring");
 36 | var REST_PATH = '/maximo/oslc/os/';
 37 | var X_PUB_PATH = '/maximo/oslc/';
 38 | var REST_PATH = '/maximo/oslc/os/';
 39 | 
 40 | var Resource = require('./resource');
 41 | var FetchConnector = require('./connectors/fetchconnector');
 42 | var CRUDConnector = require('./connectors/crudconnector');
 43 | var ExternalConnector = require('./connectors/externalconnector');
 44 | var SchemaConnector = require('./connectors/schemaconnector');
 45 | 
 46 | /**
 47 |  *
 48 |  * @param resourcemboset
 49 |  * @param cookie
 50 |  * @param maxfactory
 51 |  * @param mbo
 52 |  * @returns {ResourceSet}
 53 |  * @constructor
 54 |  */
 55 | function ResourceSet(resourcemboset,cookie,maxfactory,mbo)
 56 | {
 57 | 	this.cookie = cookie;
 58 | 	// Since JavaScript does not support method/constructor overloading we have
 59 |  	// to handle multiple constructors by sniffing them out manually.
 60 | 
 61 |  	// Constructor 1
 62 |  	if(resourcemboset != null && cookie !== null)
 63 |  	{
 64 |  		//console.log("Instanciating Zombie Mbo Set - Constructor 1 ");
 65 | 	 	this.resourcemboset = resourcemboset;
 66 | 	 	return this;
 67 | 	}
 68 |  	// Constructor 2
 69 |  	if(maxfactory != "undefined" && mbo != "undefined")
 70 |  	{
 71 | 		X_PUB_PATH = maxfactory.auth_scheme + '/oslc/';
 72 | 		REST_PATH = X_PUB_PATH + 'os/';
 73 | 
 74 | 	 	this.maximoRestUrl = maxfactory.resturl;
 75 | 	 	this.password = maxfactory.password;
 76 | 	 	this.mbo = mbo;
 77 | 	 	this.islean = maxfactory.islean;
 78 | 	 	console.log("this.islean ****** "+this.islean);
 79 | 	 	this.namespace = this.islean == 1 ? "" : "spi:";
 80 | 	 	this.tenantcode = maxfactory.tenantcode;
 81 | 	 	this.maximopath = REST_PATH+this.mbo+"?lean="+this.islean;
 82 | 	 	this.maximopath = this.tenantcode ? this.maximopath+"&_tenantcode="+this.tenantcode : this.maximopath;
 83 | 	 	this.schemapath = X_PUB_PATH + 'jsonschemas/'
 84 | 	 	this.nextpageurl = "";
 85 | 	 	this.authType = maxfactory.authType
 86 | 	 	if(this.authType == "form")
 87 | 	 	{
 88 | 			this.fconnect = new FetchConnector(this.maximoRestUrl, this.maximopath);
 89 | 			this.fconnect.authType = this.authType;
 90 | 			this.fconnect.authenticate(this.fconnect);
 91 | 	 	}
 92 | 
 93 | 	 	return this;
 94 | 	}
 95 | };
 96 | 
 97 | /**
 98 |  *
 99 |  */
100 | ResourceSet.prototype.cookie;
101 | 
102 | 
103 | /**
104 |  *
105 |  */
106 | ResourceSet.prototype.fconnect;
107 | 
108 | 
109 | /**
110 |  * Returns the rdfs member only
111 |  * @returns {*}
112 |  */
113 | ResourceSet.prototype.thisResourceSet = function()
114 | {
115 |     return this.resourcemboset["member"];
116 | };
117 | 
118 | /**
119 |  * Returns the complete JSON i.e all top level OR sets this set and returns the new set.
120 |  * @param resourcemboset
121 |  * @returns {*}
122 |  */
123 | ResourceSet.prototype.JSON = function(resourcemboset)
124 | {
125 | 	if (resourcemboset != null)
126 | 	{
127 | 		this.resourcemboset = resourcemboset;
128 | 	}
129 |     return this.resourcemboset;
130 | };
131 | 
132 | 
133 | /**
134 |  *
135 |  * @param datacallback
136 |  * @returns {*}
137 |  */
138 | ResourceSet.prototype.fetch = function(datacallback)
139 | {
140 | 	return getFetchConnector(this).__fetch(this.fconnect); // Pass this.fconnect so the it's state is updated.
141 | }
142 | 
143 | /**
144 |  *
145 |  * @param datacallback
146 |  * @returns {*}
147 |  */
148 | ResourceSet.prototype.schema = function(datacallback)
149 | {
150 | 	return getSchemaConnector(this).__fetch(this.sconnect); // Pass this.sconnect so the it's state is updated.
151 | }
152 | 
153 | /**
154 |  *
155 |  * @param datacallback
156 |  * @returns {*}
157 |  */
158 | ResourceSet.prototype.schemarelated = function(datacallback)
159 | {
160 | 	return getSchemaRelatedConnector(this).__fetch(this.sconnect); // Pass this.sconnect so the it's state is updated.
161 | }
162 | 
163 | /**
164 |  *
165 |  * @param np
166 |  * @param datacallback
167 |  * @returns {*}
168 |  */
169 | ResourceSet.prototype.nextpage = function(np,datacallback)
170 | {
171 | 	return getFetchConnector(this).__fetchnext(np,this.fconnect); // Pass this.fconnect so the it's state is updated.
172 | }
173 | 
174 | /**
175 |  *
176 |  * @param i
177 |  * @returns {Resource}
178 |  */
179 | ResourceSet.prototype.resource = function(i)
180 | {
181 | 	//console.log("Index type "+typeof(i));
182 | 
183 | 	var connex = (this.cookie ? this.cookie : this.maximoRestUrl);
184 | 	if(typeof(i) === "number") //Strictly a number type and we assume this set contains members
185 | 	{
186 | 		return new Resource(this.resourcemboset["rdfs:member"][i],this.cookie);
187 | 	}
188 | 	//console.log("THIS COOKIE "+this.maximoRestUrl);
189 | 	//console.log("THIS COOKIE "+i);
190 | 	//console.log("CONNEX: "+connex);
191 | 	//console.log("CONNEX: "+typeof(connex));
192 | 	// Most likely a URL so we will have to fetch/update/delete/invoke
193 | 	var res = new Resource(i,connex);
194 | 	if(this.cookie)
195 | 	{
196 | 		res.setcookie(this.cookie);
197 | 	}
198 |     return res;
199 | 
200 | };
201 | 
202 | /**
203 |  *
204 |  */
205 | ResourceSet.prototype.size = function()
206 | {
207 |     return this.resourcemboset["rdfs:member"].length;
208 | };
209 | 
210 | /**
211 |  *
212 |  * @param selects
213 |  * @returns {ResourceSet}
214 |  */
215 | ResourceSet.prototype.select = function(selects)
216 | {
217 | 	 if (selects && selects.constructor === Array)
218 | 	 {
219 | 	 	var arrayLength = selects.length;
220 | 	 	var selectStr = '';
221 | 	 	var relationships = {};
222 | 		for (var i = 0; i < arrayLength; i++) {
223 | 			var wh = selects[i];
224 | 			wh = (wh.indexOf(":") < 1) ? this.namespace+wh : wh  //prepend the name spaces
225 | 			/*if(wh.indexOf(".") > 1) // check if this attribute is a relationship and construct expression
226 | 			{
227 | 				var wharray = wh.split(".");
228 | 				//wh = wharray[0]+"{"+this.namespace+wharray[1]+"}";
229 | 
230 | 				relatedset(wharray[0],this.namespace+wharray[1],relationships);
231 | 			}*/
232 | 		    selectStr = ((arrayLength - i) > 1) ? selectStr+wh+"," : selectStr+wh;
233 | 		}
234 | 	 }
235 | 	this.select = selectStr+relationshipString(relationships);
236 | 	if(this.select != null && this.select != "")
237 | 	{
238 | 		this.maximopath = getMaximoPath(this.maximopath)+"oslc.select="+encodeURIComponent(this.select);
239 | 	}
240 | 	return this;
241 | }
242 | 
243 | /**
244 |  *
245 |  * @param prop
246 |  * @returns {ResourceSet}
247 |  */
248 | ResourceSet.prototype.where = function(prop)
249 | {
250 | 	this.where = (prop.indexOf(":") < 1) ? this.namespace+prop : prop
251 | 	//this.where = prop;
252 | 	if(this.where != null && this.where != "")
253 | 	{
254 | 		this.maximopath = (this.maximopath.indexOf("oslc.where=") > -1)
255 | 										? getMaximoPath(this.maximopath)+"and"+encodeURIComponent(this.where)
256 | 										:  getMaximoPath(this.maximopath)+"oslc.where="+encodeURIComponent(this.where);
257 | 	}
258 | 	return this;
259 | }
260 | 
261 | /**
262 |  *
263 |  * @param str
264 |  * @returns {ResourceSet}
265 |  */
266 | ResourceSet.prototype.and = function(str)
267 | {
268 | 	str = (str.indexOf(":") < 1) ? this.namespace+str : str
269 | 	this.maximopath = this.maximopath+encodeURIComponent(" and ")+encodeURIComponent(str);
270 | 
271 | 	return this;
272 | }
273 | 
274 | /**
275 |  *
276 |  * @param inarr
277 |  * @param isint
278 |  * @returns {ResourceSet}
279 |  */
280 | ResourceSet.prototype.in = function(inarr,isint)
281 | {
282 | 	if (inarr && inarr.constructor === Array)
283 | 	{
284 | 		var arrayLength = inarr.length;
285 | 	 	var inarrStr = '';
286 | 		for (var i = 0; i < arrayLength; i++) {
287 | 			var inElement = inarr[i];
288 | 		    //inarrStr = ((arrayLength - i) > 1) ? inarrStr+'"'+inElement+'",' : inarrStr+'"'+inElement+'"';
289 | 		    inarrStr = isint ? (((arrayLength - i) > 1) ? inarrStr+inElement+',' : inarrStr+inElement)
290 | 		    				 : (((arrayLength - i) > 1) ? inarrStr+'"'+inElement+'",' : inarrStr+'"'+inElement+'"');
291 | 		}
292 | 	}
293 |     this.maximopath = this.maximopath+encodeURIComponent(" in["+inarrStr+"]");
294 | 	return this;
295 | }
296 | 
297 | /**
298 |  *
299 |  * @param eq
300 |  * @returns {ResourceSet}
301 |  */
302 | ResourceSet.prototype.equal = function(eq)
303 | {
304 | 	if(this.where != null && this.where != "")
305 | 	{
306 | 		//.where("spi:status").equal('"APPR"')
307 | 		eq = (typeof(eq) === "string") ? '"'+eq+'"' : eq;
308 | 		this.maximopath = this.maximopath+"="+encodeURIComponent(eq);
309 | 	}
310 | 	return this;
311 | }
312 | 
313 | /**
314 |  *
315 |  * @param eq
316 |  * @returns {ResourceSet}
317 |  */
318 | ResourceSet.prototype.notnull = function(eq)
319 | {
320 | 	if(this.where != null && this.where != "")
321 | 	{
322 | 		var eq = '*';
323 | 		eq = (typeof(eq) === "string") ? '"'+eq+'"' : eq;
324 | 		this.maximopath = this.maximopath+"="+encodeURIComponent(eq);
325 | 	}
326 | 	return this;
327 | }
328 | 
329 | /**
330 |  *
331 |  * @param oby
332 |  * @param direction
333 |  * @returns {ResourceSet}
334 |  */
335 | ResourceSet.prototype.orderby = function(oby,direction)
336 | {
337 | 	if(this.where != null && this.where != "")
338 | 	{
339 | 		oby = (oby.indexOf(":") < 1) ? this.namespace+oby : oby
340 | 		var ascending = direction == 'desc'? 0 : 1
341 | 		oby = ascending ? "+"+oby : "-"+oby;
342 | 		this.maximopath = this.maximopath+"&oslc.orderBy="+encodeURIComponent(oby);
343 | 	}
344 | 	return this;
345 | }
346 | 
347 | /**
348 |  *
349 |  * @param pagesize
350 |  * @returns {ResourceSet}
351 |  */
352 | ResourceSet.prototype.pagesize = function(pagesize)
353 | {
354 | 	this.pagesize = pagesize;
355 | 	if(this.pagesize != null && this.pagesize != "")
356 | 	{
357 | 		this.maximopath = getMaximoPath(this.maximopath)+"oslc.pageSize="+encodeURIComponent(this.pagesize);
358 | 	}
359 | 	return this;
360 | }
361 | 
362 | /**
363 |  *
364 |  * @param action
365 |  * @returns {ResourceSet}
366 |  */
367 | ResourceSet.prototype.action = function(action)
368 | {
369 | 	this.action = action;
370 | 	return this;
371 | }
372 | 
373 | // TODO: Refactor invoke to Resource
374 | /**
375 |  *
376 |  * @param resource
377 |  * @param datacallback
378 |  * @returns {*|PromiseLike<any>}
379 |  */
380 | ResourceSet.prototype.invoke = function(resource,datacallback)
381 | {
382 | 	var myurl = resource["url"];
383 | 	var status = resource["status"];
384 | 	var memo = resource["memo"];
385 | 	var action = resource["action"];
386 | 
387 | 	myurl = myurl+"?action=wsmethod:"+this.action;
388 | 	var purl = url.parse(myurl);
389 | 
390 | 	console.log("URL: "+purl.hostname);
391 | 	console.log("URL: "+purl.port);
392 | 	console.log("URL: "+purl.path);
393 | 
394 | 	var deferred = Q.defer();
395 | 	var returndata = '';
396 | 	var client = require(this.maximoRestUrl.protocol.split(':')[0]);
397 | 	var statusCode = "";
398 | 	var resourceset = "";
399 | 	var xpublicuri = this.maximoRestUrl.protocol+"//"+this.maximoRestUrl.hostname+":"+this.maximoRestUrl.port+X_PUB_PATH;
400 | 
401 | 	var options = {
402 |         hostname: purl.hostname,
403 |         port: purl.port,
404 |         headers: {'MAXAUTH': new Buffer(this.maximoRestUrl.auth).toString('base64'),
405 |     			  'x-public-uri':xpublicuri.toString(),
406 |     			  'x-method-override': 'PATCH',
407 |     			   'content-type': 'application/json'},
408 |         path: purl.path,
409 |         method: 'POST'
410 |     	};
411 | 
412 |     var req = client.request(options, function(res)
413 |     {
414 |   			res.setEncoding('utf8');
415 |   			var resdata = '';
416 |   			res.on('data', function (chunk)
417 |   			{
418 |   				resdata += chunk;
419 |   			});
420 |   			res.on('error', function(err)
421 | 			{
422 | 			    console.log('Error retrieving data... ' + err.message);
423 | 			    deferred.reject("Error retrieving data...."+ err.message);
424 | 			});
425 |   			res.on('end', function()
426 | 		  	{
427 | 		  		console.log("RESDATA "+resdata);
428 | 			  	//var data = JSON.parse(resdata);
429 | 			  	statusCode = res.statusCode;
430 | 			  	if (datacallback)
431 | 			  	{
432 | 			  		deferred.promise.nodeify(datacallback(statusCode,resdata,this));
433 | 			  	} else
434 | 			  	{
435 | 			  		deferred.resolve(resdata);
436 | 			  	}
437 | 		  	//datacallback(response.statusCode,resourceset,this);  //Invoke the callback and pass the data back.
438 | 		   });
439 | 	});
440 | 
441 |     req.on('error', function(e)
442 |     {
443 |   		console.log('problem with request: ' + e.message);
444 | 	});
445 | 
446 | 
447 |     req.write(JSON.stringify(resource));
448 | 	req.end();
449 |   //return this;*/
450 |   return deferred.promise;
451 | }
452 | 
453 | /**
454 |  *
455 |  * @param ops
456 |  * @returns {ExternalConnector}
457 |  */
458 | ResourceSet.prototype.externalConnector = function(ops)
459 | {
460 | 	return new ExternalConnector(ops,this.resourcemboset["member"]);
461 | }
462 | 
463 | 
464 | // CRUD starts here ...
465 | 
466 | /**
467 |  *
468 |  * @param jsonbody
469 |  * @param props
470 |  * @param attachments
471 |  * @param datacallback
472 |  * @returns {*}
473 |  */
474 | ResourceSet.prototype.create = function(jsonbody,props,attachments,datacallback)
475 | {
476 | 	return getCRUDConnector(this).__create(jsonbody,props,attachments,datacallback); // Pass this.fconnect so the it's state is updated.
477 | }
478 | 
479 | 
480 | //Private Methods
481 | 
482 | 
483 | // Populates the JSON (relationships) with relationships and attributes
484 | function relatedset(relname,attribute,relationships)
485 | {
486 | 	var length = Object.keys(relationships).length;
487 | 	var attrs = null;
488 | 	if(length > 0) // the json is not empty
489 | 	{
490 | 		attrs = relationships[relname];
491 | 	}
492 | 	if(attrs == null) // the json is empty so pop in the first one.
493 | 	{
494 | 		relationships[relname] = [attribute];
495 | 	}else
496 | 	{
497 | 		attrs.push(attribute);
498 | 		relationships[relname] = attrs;
499 | 	}
500 | 	//console.log("******* "+JSON.stringify(relationships));
501 | }
502 | 
503 | // Creates the relationship string
504 | function relationshipString(relationships)
505 | {
506 | 	var length = Object.keys(relationships).length;
507 | 
508 | 	//spi:temeda{spi:event_description,spi:enginerpm,spi:idle_time_count}
509 | 	var relstr = "";
510 | 
511 | 	for(var attribute in relationships)
512 | 	{
513 | 		relstr = relstr+","+attribute+"{"+relationships[attribute]+"}";
514 | 	}
515 | 	return relstr;
516 | }
517 | 
518 | 
519 | function getCRUDprops(props)
520 | {
521 | 	return props.toString();
522 | }
523 | 
524 | function getCRUDheaders(props,jsonbody,me,xmethod)
525 | {
526 |     var hdrs = null;
527 |     var propsStr = getCRUDprops(props);
528 |     if (propsStr)
529 |     {
530 |     	return {'MAXAUTH': new Buffer(me.maximoRestUrl.auth).toString('base64'),
531 |     			   'content-type': 'application/json',
532 |     			   'x-method-override': xmethod,
533 |     			   'properties': propsStr,
534 |     			   'body':JSON.stringify(jsonbody)}
535 |     }
536 | 	return {'MAXAUTH': new Buffer(me.maximoRestUrl.auth).toString('base64'),
537 |     			   'content-type': 'application/json',
538 |     			   'x-method-override': xmethod,
539 |     			   'body':JSON.stringify(jsonbody)}
540 | }
541 | 
542 | 
543 | function getMaximoPath(maxpath)
544 | {
545 |     return (maxpath.indexOf("?") < 1) ? maxpath+"?" : maxpath+"&";
546 | }
547 | 
548 | 
549 | function getFetchConnector(me)  // Singleton
550 | {
551 | 	if(me.fconnect == null)
552 | 	{
553 | 		me.fconnect = new FetchConnector(me.maximoRestUrl, me.maximopath);
554 | 		me.fconnect.authType = me.authType;
555 | 		me.fconnect.cookie = me.cookie;
556 | 		me.fconnect.isCookieSet = me.cookie == null ? false : true;
557 | 	}
558 | 	return me.fconnect;
559 | }
560 | 
561 | function getSchemaConnector(me)  // Singleton
562 | {
563 | 	if(me.sconnect == null)
564 | 	{
565 | 		me.sconnect = new SchemaConnector(me.maximoRestUrl, me.schemapath+me.mbo);
566 | 		me.sconnect.authType = me.authType;
567 | 		me.sconnect.cookie = me.cookie;
568 | 		me.sconnect.isCookieSet = me.cookie == null ? false : true;
569 | 	}
570 | 	return me.sconnect;
571 | }
572 | 
573 | function getSchemaRelatedConnector(me)  // Singleton
574 | {
575 | 	if(me.sconnect == null)
576 | 	{
577 | 		me.sconnect = new SchemaConnector(me.maximoRestUrl, me.schemapath+me.mbo+"?oslc.select=*");
578 | 		me.sconnect.authType = me.authType;
579 | 		me.sconnect.cookie = me.cookie;
580 | 		me.sconnect.isCookieSet = me.cookie == null ? false : true;
581 | 	}
582 | 	return me.sconnect;
583 | }
584 | 
585 | function getCRUDConnector(me)  // Singleton
586 | {
587 | 	if(me.cconnect == null)
588 | 	{
589 | 		me.cconnect = new CRUDConnector(me.maximoRestUrl, me.maximopath);
590 | 		me.cconnect.authType = me.authType;
591 | 		me.cconnect.cookie = me.cookie;
592 | 		me.cconnect.isCookieSet = me.cookie == null ? false : true;
593 | 	}
594 | 	return me.cconnect;
595 | }
596 | 
597 |
598 |
599 | 600 | 601 | 602 | 603 |
604 | 605 | 608 | 609 |
610 | 611 | 614 | 615 | 616 | 617 | 618 | 619 | -------------------------------------------------------------------------------- /docs/scripts/linenumber.js: -------------------------------------------------------------------------------- 1 | /*global document */ 2 | (function() { 3 | var source = document.getElementsByClassName('prettyprint source linenums'); 4 | var i = 0; 5 | var lineNumber = 0; 6 | var lineId; 7 | var lines; 8 | var totalLines; 9 | var anchorHash; 10 | 11 | if (source && source[0]) { 12 | anchorHash = document.location.hash.substring(1); 13 | lines = source[0].getElementsByTagName('li'); 14 | totalLines = lines.length; 15 | 16 | for (; i < totalLines; i++) { 17 | lineNumber++; 18 | lineId = 'line' + lineNumber; 19 | lines[i].id = lineId; 20 | if (lineId === anchorHash) { 21 | lines[i].className += ' selected'; 22 | } 23 | } 24 | } 25 | })(); 26 | -------------------------------------------------------------------------------- /docs/scripts/prettify/Apache-License-2.0.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /docs/scripts/prettify/lang-css.js: -------------------------------------------------------------------------------- 1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n "]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com", 2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]); 3 | -------------------------------------------------------------------------------- /docs/scripts/prettify/prettify.js: -------------------------------------------------------------------------------- 1 | var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; 2 | (function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= 3 | [],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), 9 | l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, 10 | q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, 11 | q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, 12 | "");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), 13 | a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} 14 | for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], 18 | "catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], 19 | H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], 20 | J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ 21 | I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), 22 | ["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", 23 | /^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), 24 | ["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", 25 | hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= 26 | !k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p th:last-child { border-right: 1px solid #ddd; } 224 | 225 | .ancestors, .attribs { color: #999; } 226 | .ancestors a, .attribs a 227 | { 228 | color: #999 !important; 229 | text-decoration: none; 230 | } 231 | 232 | .clear 233 | { 234 | clear: both; 235 | } 236 | 237 | .important 238 | { 239 | font-weight: bold; 240 | color: #950B02; 241 | } 242 | 243 | .yes-def { 244 | text-indent: -1000px; 245 | } 246 | 247 | .type-signature { 248 | color: #aaa; 249 | } 250 | 251 | .name, .signature { 252 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 253 | } 254 | 255 | .details { margin-top: 14px; border-left: 2px solid #DDD; } 256 | .details dt { width: 120px; float: left; padding-left: 10px; padding-top: 6px; } 257 | .details dd { margin-left: 70px; } 258 | .details ul { margin: 0; } 259 | .details ul { list-style-type: none; } 260 | .details li { margin-left: 30px; padding-top: 6px; } 261 | .details pre.prettyprint { margin: 0 } 262 | .details .object-value { padding-top: 0; } 263 | 264 | .description { 265 | margin-bottom: 1em; 266 | margin-top: 1em; 267 | } 268 | 269 | .code-caption 270 | { 271 | font-style: italic; 272 | font-size: 107%; 273 | margin: 0; 274 | } 275 | 276 | .prettyprint 277 | { 278 | border: 1px solid #ddd; 279 | width: 80%; 280 | overflow: auto; 281 | } 282 | 283 | .prettyprint.source { 284 | width: inherit; 285 | } 286 | 287 | .prettyprint code 288 | { 289 | font-size: 100%; 290 | line-height: 18px; 291 | display: block; 292 | padding: 4px 12px; 293 | margin: 0; 294 | background-color: #fff; 295 | color: #4D4E53; 296 | } 297 | 298 | .prettyprint code span.line 299 | { 300 | display: inline-block; 301 | } 302 | 303 | .prettyprint.linenums 304 | { 305 | padding-left: 70px; 306 | -webkit-user-select: none; 307 | -moz-user-select: none; 308 | -ms-user-select: none; 309 | user-select: none; 310 | } 311 | 312 | .prettyprint.linenums ol 313 | { 314 | padding-left: 0; 315 | } 316 | 317 | .prettyprint.linenums li 318 | { 319 | border-left: 3px #ddd solid; 320 | } 321 | 322 | .prettyprint.linenums li.selected, 323 | .prettyprint.linenums li.selected * 324 | { 325 | background-color: lightyellow; 326 | } 327 | 328 | .prettyprint.linenums li * 329 | { 330 | -webkit-user-select: text; 331 | -moz-user-select: text; 332 | -ms-user-select: text; 333 | user-select: text; 334 | } 335 | 336 | .params .name, .props .name, .name code { 337 | color: #4D4E53; 338 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 339 | font-size: 100%; 340 | } 341 | 342 | .params td.description > p:first-child, 343 | .props td.description > p:first-child 344 | { 345 | margin-top: 0; 346 | padding-top: 0; 347 | } 348 | 349 | .params td.description > p:last-child, 350 | .props td.description > p:last-child 351 | { 352 | margin-bottom: 0; 353 | padding-bottom: 0; 354 | } 355 | 356 | .disabled { 357 | color: #454545; 358 | } 359 | -------------------------------------------------------------------------------- /docs/styles/prettify-jsdoc.css: -------------------------------------------------------------------------------- 1 | /* JSDoc prettify.js theme */ 2 | 3 | /* plain text */ 4 | .pln { 5 | color: #000000; 6 | font-weight: normal; 7 | font-style: normal; 8 | } 9 | 10 | /* string content */ 11 | .str { 12 | color: #006400; 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | 17 | /* a keyword */ 18 | .kwd { 19 | color: #000000; 20 | font-weight: bold; 21 | font-style: normal; 22 | } 23 | 24 | /* a comment */ 25 | .com { 26 | font-weight: normal; 27 | font-style: italic; 28 | } 29 | 30 | /* a type name */ 31 | .typ { 32 | color: #000000; 33 | font-weight: normal; 34 | font-style: normal; 35 | } 36 | 37 | /* a literal value */ 38 | .lit { 39 | color: #006400; 40 | font-weight: normal; 41 | font-style: normal; 42 | } 43 | 44 | /* punctuation */ 45 | .pun { 46 | color: #000000; 47 | font-weight: bold; 48 | font-style: normal; 49 | } 50 | 51 | /* lisp open bracket */ 52 | .opn { 53 | color: #000000; 54 | font-weight: bold; 55 | font-style: normal; 56 | } 57 | 58 | /* lisp close bracket */ 59 | .clo { 60 | color: #000000; 61 | font-weight: bold; 62 | font-style: normal; 63 | } 64 | 65 | /* a markup tag name */ 66 | .tag { 67 | color: #006400; 68 | font-weight: normal; 69 | font-style: normal; 70 | } 71 | 72 | /* a markup attribute name */ 73 | .atn { 74 | color: #006400; 75 | font-weight: normal; 76 | font-style: normal; 77 | } 78 | 79 | /* a markup attribute value */ 80 | .atv { 81 | color: #006400; 82 | font-weight: normal; 83 | font-style: normal; 84 | } 85 | 86 | /* a declaration */ 87 | .dec { 88 | color: #000000; 89 | font-weight: bold; 90 | font-style: normal; 91 | } 92 | 93 | /* a variable name */ 94 | .var { 95 | color: #000000; 96 | font-weight: normal; 97 | font-style: normal; 98 | } 99 | 100 | /* a function name */ 101 | .fun { 102 | color: #000000; 103 | font-weight: bold; 104 | font-style: normal; 105 | } 106 | 107 | /* Specify class=linenums on a pre to get line numbering */ 108 | ol.linenums { 109 | margin-top: 0; 110 | margin-bottom: 0; 111 | } 112 | -------------------------------------------------------------------------------- /docs/styles/prettify-tomorrow.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Theme */ 2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 3 | /* Pretty printing styles. Used with prettify.js. */ 4 | /* SPAN elements with the classes below are added by prettyprint. */ 5 | /* plain text */ 6 | .pln { 7 | color: #4d4d4c; } 8 | 9 | @media screen { 10 | /* string content */ 11 | .str { 12 | color: #718c00; } 13 | 14 | /* a keyword */ 15 | .kwd { 16 | color: #8959a8; } 17 | 18 | /* a comment */ 19 | .com { 20 | color: #8e908c; } 21 | 22 | /* a type name */ 23 | .typ { 24 | color: #4271ae; } 25 | 26 | /* a literal value */ 27 | .lit { 28 | color: #f5871f; } 29 | 30 | /* punctuation */ 31 | .pun { 32 | color: #4d4d4c; } 33 | 34 | /* lisp open bracket */ 35 | .opn { 36 | color: #4d4d4c; } 37 | 38 | /* lisp close bracket */ 39 | .clo { 40 | color: #4d4d4c; } 41 | 42 | /* a markup tag name */ 43 | .tag { 44 | color: #c82829; } 45 | 46 | /* a markup attribute name */ 47 | .atn { 48 | color: #f5871f; } 49 | 50 | /* a markup attribute value */ 51 | .atv { 52 | color: #3e999f; } 53 | 54 | /* a declaration */ 55 | .dec { 56 | color: #f5871f; } 57 | 58 | /* a variable name */ 59 | .var { 60 | color: #c82829; } 61 | 62 | /* a function name */ 63 | .fun { 64 | color: #4271ae; } } 65 | /* Use higher contrast and text-weight for printable form. */ 66 | @media print, projection { 67 | .str { 68 | color: #060; } 69 | 70 | .kwd { 71 | color: #006; 72 | font-weight: bold; } 73 | 74 | .com { 75 | color: #600; 76 | font-style: italic; } 77 | 78 | .typ { 79 | color: #404; 80 | font-weight: bold; } 81 | 82 | .lit { 83 | color: #044; } 84 | 85 | .pun, .opn, .clo { 86 | color: #440; } 87 | 88 | .tag { 89 | color: #006; 90 | font-weight: bold; } 91 | 92 | .atn { 93 | color: #404; } 94 | 95 | .atv { 96 | color: #060; } } 97 | /* Style */ 98 | /* 99 | pre.prettyprint { 100 | background: white; 101 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 102 | font-size: 12px; 103 | line-height: 1.5; 104 | border: 1px solid #ccc; 105 | padding: 10px; } 106 | */ 107 | 108 | /* Specify class=linenums on a pre to get line numbering */ 109 | ol.linenums { 110 | margin-top: 0; 111 | margin-bottom: 0; } 112 | 113 | /* IE indents via margin-left */ 114 | li.L0, 115 | li.L1, 116 | li.L2, 117 | li.L3, 118 | li.L4, 119 | li.L5, 120 | li.L6, 121 | li.L7, 122 | li.L8, 123 | li.L9 { 124 | /* */ } 125 | 126 | /* Alternate shading for lines */ 127 | li.L1, 128 | li.L3, 129 | li.L5, 130 | li.L7, 131 | li.L9 { 132 | /* */ } 133 | -------------------------------------------------------------------------------- /error/error.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var util = require('util'); 3 | //var Error = require('error'); 4 | 5 | function InvalidArgumentError(message) { 6 | // Error.call(this); 7 | // this.message = message; 8 | } 9 | 10 | util.inherits(InvalidArgumentError, Error); 11 | 12 | //assert(error.message); 13 | //assert(error instanceof InvalidArgumentError); 14 | //assert(error instanceof Error); -------------------------------------------------------------------------------- /maximofactory.js: -------------------------------------------------------------------------------- 1 | 2 | 'use strict'; 3 | 4 | module.exports = MaximoFactory; 5 | 6 | var ResourceObject = require('./resources/resourceobject'); 7 | 8 | var InvalidArgumentError = require('./error/error'); 9 | var events = require('events'); 10 | var url = require('url'); 11 | var AuthConnector = require('./resources/connectors/authconnector'); 12 | 13 | /** 14 | @typedef MaximoProperties 15 | @type {object} 16 | @property {string} protocol 17 | @property {string} hostname 18 | @property {number} port 19 | @property {string} user 20 | @property {string} password 21 | @property {string} tenantcode 22 | @property {string} auth_scheme 23 | @property {string} authtype 24 | @property {boolean} islean 25 | */ 26 | 27 | 28 | /** 29 | * 30 | * Creates an object for exposing Maximo OSLC API 31 | * 32 | * @param {MaximoProperties} options 33 | * @param cookie 34 | * @param callback 35 | * @returns {MaximoFactory} 36 | * @constructor 37 | */ 38 | function MaximoFactory(options,cookie,callback) 39 | { 40 | this.protocol = options.protocol; 41 | this.hostname = options.hostname; 42 | this.port = options.port; 43 | this.user = options.user; 44 | this.password = options.password; 45 | this.islean = 0; 46 | this.tenantcode = options.tenantcode; 47 | this.auth_scheme = options.auth_scheme; 48 | this.authType = options.authtype; 49 | this.cookie = cookie; 50 | this.isCookieSet = this.cookie ? true : false; 51 | 52 | if(this.authType && this.authType == "form") 53 | { 54 | this.authPath = this.auth_scheme+"/j_security_check"; 55 | } 56 | 57 | 58 | if(options.islean != null) 59 | { 60 | this.islean = options.islean; 61 | } 62 | 63 | console.log("### islean "+this.islean); 64 | 65 | this.resturl = url.parse(this.protocol+"://"+this.user+":"+this.password+"@"+this.hostname+":"+this.port); 66 | 67 | this.resturl.auth_scheme = this.auth_scheme; 68 | 69 | if(callback != null) 70 | { 71 | if(this.hostname === "" || this.user === "" || this.password === "") 72 | { 73 | callback(new Error("Invalid null arguments.","")); 74 | } 75 | } 76 | return this; 77 | } 78 | 79 | /** 80 | * 81 | * @returns {*} 82 | */ 83 | MaximoFactory.prototype.authenticate = function() 84 | { 85 | this.authC = new AuthConnector(this.resturl); 86 | this.authC.authType = this.authType; 87 | return this.authC.authenticate(this.authC); 88 | }; 89 | 90 | /** 91 | * 92 | * @param mbo 93 | * @returns {ResourceObject} 94 | */ 95 | MaximoFactory.prototype.resourceobject = function(mbo) 96 | { 97 | //return new ResourceSet(this.resturl,this.user,this.password,mbo); 98 | return new ResourceObject(this,mbo); 99 | }; 100 | 101 | /** 102 | * 103 | * @returns {string|*} 104 | */ 105 | MaximoFactory.prototype.publicuri = function() 106 | { 107 | return this.hostname; 108 | }; 109 | 110 | /** 111 | * 112 | * @returns {MaximoFactory.user|*} 113 | */ 114 | MaximoFactory.prototype.user = function() 115 | { 116 | return this.user; 117 | }; 118 | 119 | /** 120 | * 121 | */ 122 | MaximoFactory.prototype.isCookieSet; 123 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ibm-maximo-api", 3 | "version": "1.0.15", 4 | "description": "A high level API to access Maximo REST services", 5 | "repository": { 6 | "type": "git", 7 | "url": "git://github.com/sachbalag/ibm-maximo-api.git" 8 | }, 9 | "main": "maximofactory.js", 10 | "scripts": { 11 | "test": "echo \"Error: no test specified\" && exit 1", 12 | "start": "node server.js", 13 | "jsdoc": "node node_modules/.bin/jsdoc -R README.md -d docs/ maximofactory.js resources/*.js" 14 | }, 15 | "author": { 16 | "name": "Sachin Balagopalan", 17 | "email": "sachin.balagopalan@us.ibm.com" 18 | }, 19 | "license": "MIT", 20 | "keywords": [ 21 | "ibm-maximo-api", 22 | "ibm", 23 | "cloud", 24 | "bluemix", 25 | "api", 26 | "maximo", 27 | "REST", 28 | "node" 29 | ], 30 | "dependencies": { 31 | "buffer": "^3.1.2", 32 | "http": "0.0.0", 33 | "install": "^0.1.8", 34 | "npm": "^2.13.5", 35 | "q": "^1.2.0", 36 | "url": "^0.10.3" 37 | }, 38 | "devDependencies": { 39 | "express": "latest", 40 | "express-session": "latest", 41 | "cookie-parser": "latest", 42 | "ibm-maximo-api": "file:.", 43 | "jsdoc": "latest" 44 | }, 45 | "gitHead": "3898abc4cf3d95890b191424a9e7cc6dc5415715", 46 | "readme": "# IBM-Maximo-API\r\n\r\n## Introduction\r\n\r\nThis module includes a set of fluent API's for interfacing with Maximo by providing a high level abstraction for the\r\nMaximo REST API's. The intent is to shield developers from low level details and help them focus on their own implementation \r\nlogic.\r\n\r\n## Installing\r\n\r\nAssumes [Node](https://nodejs.org/en/) and [Express](http://expressjs.com/) are installed.\r\n\r\n$ npm install --save ibm-maximo-api\r\n\r\n## Usage\r\n\r\nThere are three main components ....\r\n\r\n\r\n\r\n#### Requiring Maximo\r\n\r\nLike any other Node.js module the \"maximo\" module has to be loaded and assigned a local reference in your code. The easiest\r\nway to do this is using the built-in require() function.\r\n\r\n var Maximo = require('ibm-maximo-api');\r\n\r\nThe require() function returns a prototype (class) and assigns it to the local variable Maximo in the example above. \r\n\r\n\r\n#### Constructor and Authentication\r\n\r\nAfter a local reference has been assigned using the require() function you can easily instantiate an object like this:\r\n\r\n var maximo = new Maximo(options,[authcookie]);\r\n\r\n\r\nThe constructor accepts two parameters:\r\n\r\n options: This parameter is REQUIRED and is represented by an object like this:\r\n {\r\n protocol: 'http',\r\n hostname: 'qawin03.swg.usma.ibm.com',\r\n port: '9080',\r\n user: 'wilson',\r\n password: 'wilson',\r\n auth_scheme: '/maximo',\r\n authtype:'maxauth',\r\n islean:1\r\n }\r\n \r\n authcookie: This parameter is OPTIONAL.\r\n If this parameter is null the Create, Read, Update and Delete (CRUD) api's will attempt to \r\n authenticate with Maximo everytime a CRUD operation is invoked.\r\n\r\nIf CRUD's are invoked multiple times it is recommended to authenticate first via the authenticate() function. If the \r\nauthentication is sucessful a token(jsessionID) will be returned. Save the token in the request session so it can be\r\nread and passed into the constructor for subsequent requests. The following code snippet illustrates a GET route that\r\nauthenticates with maximo and stores the token inside the session.\r\n\r\n app.get('/authenticate', function(req, res)\r\n {\r\n var maximo = new Maximo(options);\r\n maximo.authenticate()\r\n .then(function(jsessionid)\r\n {\r\n req.session.authcookie = jsessionid; // Set the token in the session so we can use it for future requests\r\n res.json(jsessionid); // Handle the response after setting the token in the session.\r\n })\r\n .fail(function (error)\r\n {\r\n console.log('****** Error Code = '+error);\r\n });\r\n }\r\n\r\nThe authenticate() function is asynchronous therefore it returns a defered [Promise](https://www.npmjs.com/package/q) \r\nwhich is fulfilled inside the then() function or the fail() function if the promise is rejected. \r\nIn either case the response is handled inside the callback as illustrated in the code snippet above.\r\n\r\n\r\n#### Fetch\r\n\r\nThe following code snippet illustrates how to use the fetch API. This example returns a ResourceSet and uses all the basic\r\nexpressions available.\r\n\r\n router.get('/test_resource_set', function(req, res)\r\n {\r\n var maximo = new Maximo(options);\r\n maximo.resourceobject(\"MXWODETAIL\")\r\n .select([\"wonum\",\"description\",\"location\",\"status\",\"assetnum.description\"])\r\n .where(\"status\").in([\"WAPPR\",\"APPR\"])\r\n .and(\"worktype\").equal('CM')\r\n .orderby('wonum','desc')\r\n .pagesize(20)\r\n .fetch()\r\n .then(function(resourceset)\r\n {\r\n jsondata = resourceset.thisResourceSet();\r\n res.json(jsondata);\r\n })\r\n .fail(function (error)\r\n {\r\n console.log('****** Error Code = '+error);\r\n });\r\n });\r\n\r\n#### Next Page\r\n\r\nThe following code snippet illustrates the Paging api. In this example we are assuming that the initial set is fetched\r\nwith the pagesize() set to a low number like 20 and stored in the session (req.session.resourcesetjson).\r\n\r\n router.get('/test_nextpage', function(req, res)\r\n {\r\n var authcookie = req.session.authcookie;\r\n var maximo = new Maximo(options,authcookie);\r\n maximo.resourceobject(\"MXWODETAIL\")\r\n .nextpage(req.session.resourcesetjson) // The paged resource is stored in session\r\n .then(function(resourceset)\r\n {\r\n if(resourceset)\r\n {\r\n jsondata = resourceset.JSON();\r\n req.session.resourcesetjson = jsondata; /// Store it in the session\r\n res.json(jsondata);\r\n }\r\n res.json({\"status\":\"End of page\"})\r\n })\r\n .fail(function (error)\r\n {\r\n console.log('****** Error Code = '+error);\r\n });\r\n });\r\n\r\n#### Create\r\n\r\nThe following code snippet illustrates the Create api. In this example we are creating a new Workorder.\r\n\r\n router.get('/test_create', function(req, res)\r\n {\r\n var wo = '';\r\n var required =\r\n {\r\n \"spi:description\":\"Created from API\",\r\n \"spi:siteid\":\"BEDFORD\"\r\n }\r\n var authcookie = req.session.authcookie;\r\n var maximo = new Maximo(options,authcookie);\r\n \r\n maximo.resourceobject(\"MXWODETAIL\")\r\n .create(required,[\"spi:wonum\",\"spi:description\"])\r\n .then(function(resource)\r\n {\r\n jsondata = resource.JSON();\r\n res.json(jsondata);\r\n })\r\n .fail(function (error)\r\n {\r\n console.log('****** Error Code = '+error);\r\n });\r\n });\r\n\r\n#### Update\r\n\r\nThe following code snippet illustrates the Update api. In this example we are assuming the resourceset is saved\r\nin the session (req.session.myresourceset) and we are updating the first record in the set by passing \r\nthe resource URL (req.session.myresourceset[0][\"rdf:about\"]). The resource URL for the update is contained in \"rdf:about\".\r\n\r\n router.get('/test_update', function(req, res)\r\n {\r\n var wo = '';\r\n var updates =\r\n {\r\n \"spi:description\":\"Updated from Node API - test crudconnector\",\r\n \"spi:siteid\":\"BEDFORD\"\r\n }\r\n // Assuming myresourceset was previously placed in session\r\n var authcookie = req.session.authcookie;\r\n var maximo = new Maximo(options,authcookie);\r\n maximo.resourceobject(\"MXWODETAIL\")\r\n .resource(req.session.myresourceset[0][\"rdf:about\"]) //Pass the URI\r\n .update(updates,[\"spi:wonum\",\"spi:description\"])\r\n .then(function(resource)\r\n {\r\n var jsondata = resource.JSON();\r\n res.json(jsondata);\r\n })\r\n .fail(function (error)\r\n {\r\n console.log('****** Error Code = '+error);\r\n });\r\n });\r\n\r\n#### Delete\r\n\r\nThe following code snippet illustrates the Delete api. In this example we are assuming the resourceset is saved\r\nin the session (req.session.myresourceset) and we are updating the first record in the set by passing \r\nthe resource URL (req.session.myresourceset[0][\"rdf:about\"]). The resource URL for the update is contained in \"rdf:about\".\r\n\r\n router.get('/test_update', function(req, res)\r\n {\r\n // Assuming myresourceset was previously placed in session\r\n var authcookie = req.session.authcookie;\r\n var maximo = new Maximo(options,authcookie);\r\n maximo.resourceobject(\"MXWODETAIL\")\r\n .resource(req.session.myresourceset[0][\"rdf:about\"]) //Pass the URI\r\n .delete([\"spi:wonum\",\"spi:description\"])\r\n .then(function(resource)\r\n {\r\n var jsondata = resource.JSON();\r\n res.json(jsondata);\r\n })\r\n .fail(function (error)\r\n {\r\n console.log('****** Error Code = '+error);\r\n });\r\n });\r\n\r\n#### Attachments\r\n\r\nThe following code snippet illustrates the Attachments api.\r\n\r\n router.get('/test_attachments', function(req, res)\r\n {\r\n getFileBytes('attachtestt.doc')\r\n .then(function(fileBuffer)\r\n {\r\n console.log(\"fileBuffer \"+fileBuffer.length);\r\n var authcookie = req.session.authcookie;\r\n console.log(\"********* AuthCookie \"+authcookie);\r\n var maximo = new Maximo(options,authcookie);\r\n //var maximo = new Maximo(options);\r\n maximo.resourceobject(\"MXWODETAIL\")\r\n .select([\"wonum\",\"description\",\"reportedby\",\"location\",\"status\",\"assetnum.assetnum\"])\r\n .where(\"wonum\").equal('1459')\r\n .pagesize(20)\r\n .fetch()\r\n .then(function(resourceset)\r\n {\r\n req.session.myresourceset = resourceset.thisResourceSet();\r\n var rsrc = resourceset.resource(0);\r\n var meta = {\r\n name: 'pmr.doc',\r\n description: 'PMR Recreation Steps',\r\n type: 'FILE',\r\n storeas: 'Attachment',\r\n contentype: 'application/msword'\r\n\r\n };\r\n var attch = rsrc.attachment(meta);\r\n attch.create(fileBuffer)\r\n .then(function(resc)\r\n {\r\n console.log(\"Writing Attachment response \");\r\n //jsondata = rsrc.JSON();\r\n //res.json(jsondata);\r\n });\r\n\r\n })\r\n .fail(function (error)\r\n {\r\n console.log('****** Error Code = '+error);\r\n });\r\n });\r\n });\r\n\r\n## Contact\r\n\r\n - [Sachin Balagopalan](sachin.balagopalan@us.ibm.com)\r\n\r\n## License\r\n\r\n(C) Copyright IBM Corp. 2015 All Rights Reserved\r\n", 47 | "readmeFilename": "README.md", 48 | "bugs": { 49 | "url": "https://github.com/sachbalag/ibm-maximo-api/issues" 50 | }, 51 | "homepage": "https://github.com/sachbalag/ibm-maximo-api", 52 | "_id": "ibm-maximo-api@1.0.4", 53 | "_shasum": "0bfd8784d9cee95fae57a762b6ebc1079d9b0300", 54 | "_from": "ibm-maximo-api@" 55 | } 56 | -------------------------------------------------------------------------------- /resources/attachment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = Attachment; 3 | var url = require('url'); 4 | var buffer = require('buffer'); 5 | var http = require('http'); 6 | var REST_PATH = '/maximo/oslc/os/'; 7 | var X_PUB_PATH = '/maximo/oslc/'; 8 | var Q = require('q'); 9 | var ResourceSet = require('./resourceset'); 10 | var Resource = require('./resource'); 11 | 12 | /** 13 | * Attachment (doclinks) object for Maximo OSLC API 14 | * @param member 15 | * @param meta 16 | * @param cookie 17 | * @returns {Attachment} 18 | * @constructor 19 | */ 20 | function Attachment(member,meta,cookie) 21 | { 22 | this.member = member; 23 | //this.currentResourceSet = collection["rdfs:member"]; 24 | this.resourceURI = (typeof(member)==="object")? getMyResourceURI(this.member) : member; 25 | this.cookie = cookie; 26 | this.name = meta.name; 27 | this.description = meta.description; 28 | this.type = meta.type; 29 | this.contenttype = meta.contentype; 30 | this.storeas = meta.storeas; 31 | return this; 32 | }; 33 | 34 | /** 35 | * 36 | * @returns {*} 37 | */ 38 | Attachment.prototype.JSON= function() 39 | { 40 | //return this.idx < 0 ? this.currentResourceSet : this.currentResourceSet[this.idx]; 41 | return this.member; 42 | }; 43 | 44 | 45 | /** 46 | * 47 | * @param buffer 48 | * @param datacallback 49 | * @returns {*} 50 | */ 51 | Attachment.prototype.create = function(buffer,datacallback) 52 | { 53 | return createAttachment(buffer,this,datacallback); 54 | }; 55 | 56 | 57 | 58 | // Private methods 59 | 60 | function getMyResourceURI(member) 61 | { 62 | // if rdf:resource is not available use rdf:about or href - one of them should definitely be available. 63 | var urltype = (typeof(member["rdf:about"] != "undefined") && member["rdf:about"] != null) 64 | ? "rdf:about" 65 | : (typeof(member["rdf:resource"] != "undefined") && member["rdf:resource"] != null) 66 | ? "rdf:resource" 67 | : "href" ; 68 | return member[urltype]; 69 | } 70 | 71 | 72 | function getHeaders(buffer,me) 73 | { 74 | console.log("Content_Type **** "+me.contenttype); 75 | console.log("cookie **** "+me.cookie); 76 | return {/*'MAXAUTH': new Buffer(me.resourceURI.auth).toString('base64')*/ 77 | 'Cookie' : me.cookie, 78 | 'content-type': me.contenttype, 79 | 'slug': me.name, 80 | 'x-method-override': 'PATCH', 81 | 'x-document-description': me.description, 82 | 'x-document-meta':me.type+"/"+me.storeas 83 | } 84 | } 85 | 86 | function createAttachment(buffer,current,datacallback) 87 | { 88 | var method = 'POST'; 89 | var deferred = Q.defer(); 90 | var returndata = ''; 91 | var client = require(current.resourceURI.split(':')[0]); 92 | var host = current.resourceURI.split(':')[1].split("//")[1]; 93 | var port = current.resourceURI.split(':')[2].split("/")[0]; 94 | var path = current.resourceURI.split(host)[1].split(port)[1]; 95 | // If this.cookie type === object it means it's a URL so we need to login 96 | /*var hdr = (typeof(current.cookie) === "object") 97 | ? 98 | {'MAXAUTH': new Buffer(current.cookie.auth).toString('base64'), 99 | 'x-public-uri':xpublicuri.toString()} 100 | : 101 | {'Cookie' : current.cookie};*/ 102 | var statusCode = ""; 103 | var resourceset = ""; 104 | var options = { 105 | hostname: host, 106 | port: port, 107 | headers: getHeaders(buffer,current), 108 | path: path, 109 | method: method 110 | }; 111 | 112 | var req = client.request(options, function(res) 113 | { 114 | res.setEncoding('utf8'); 115 | var resdata = ''; 116 | res.on('data', function (chunk) 117 | { 118 | resdata += chunk; 119 | }); 120 | res.on('error', function(err) 121 | { 122 | console.log('Error retrieving data... ' + err.message); 123 | deferred.reject("Error retrieving data...."+ err.message); 124 | }); 125 | res.on('end', function() 126 | { 127 | var data = null; 128 | data = {"error code":res.statusCode,"description":"Required headers may not be set e.g. properties"}; 129 | console.log("STATUS CODE: "+res.statusCode); 130 | var resourcemem = new Resource(data,current.cookie); 131 | statusCode = res.statusCode; 132 | if (datacallback) 133 | { 134 | deferred.promise.nodeify(datacallback(statusCode,resourcemem,current)); 135 | } else 136 | { 137 | deferred.resolve(resourcemem); 138 | } 139 | }); 140 | }); 141 | 142 | req.on('error', function(e) 143 | { 144 | console.log('problem with request: ' + e.message); 145 | }); 146 | 147 | 148 | req.write(buffer); 149 | req.end(); 150 | //return this; 151 | return deferred.promise; 152 | }; 153 | -------------------------------------------------------------------------------- /resources/connectors/authconnector.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = AuthConnector; 3 | var url = require('url'); 4 | var buffer = require('buffer'); 5 | var http = require('http'); 6 | var Q = require('q'); 7 | var querystring = require("querystring"); 8 | var REST_PATH = '/maximo/oslc/os/'; 9 | var X_PUB_PATH = '/maximo/oslc/'; 10 | var REST_PATH = '/maximo/oslc/os/'; 11 | var AUTH_PATH = '/maximo/oslc/'; 12 | 13 | /** 14 | * Asynchronous Http connector to service provider (Maximo etc.) 15 | * 16 | * @constructor 17 | * @param {Object} 18 | */ 19 | 20 | function AuthConnector(maximoRestUrl,maximopath) 21 | { 22 | X_PUB_PATH = maximoRestUrl.auth_scheme + '/oslc/'; 23 | AUTH_PATH = X_PUB_PATH; 24 | 25 | this.maximoRestUrl = maximoRestUrl; 26 | this.client = require(this.maximoRestUrl.protocol.split(':')[0]); 27 | this.xpublicuri = this.maximoRestUrl.protocol+"//"+this.maximoRestUrl.hostname+":"+this.maximoRestUrl.port+X_PUB_PATH; 28 | this.maximopath = maximopath; 29 | this.cookie = null; 30 | this.isCookieSet = "false"; 31 | 32 | }; 33 | 34 | // Expose these properties 35 | AuthConnector.prototype.cookie; 36 | 37 | AuthConnector.prototype.isCookieSet; 38 | 39 | AuthConnector.prototype.auth_scheme; 40 | 41 | AuthConnector.prototype.authType; 42 | 43 | 44 | AuthConnector.prototype.authenticate = function(myconnector,datacallback) 45 | { 46 | var deferred = Q.defer(); 47 | var returndata = ''; 48 | //var client = require(this.maximoRestUrl.protocol.split(':')[0]); 49 | var statusCode = ""; 50 | var resourceset = ""; 51 | var options = { 52 | hostname: this.maximoRestUrl.hostname, 53 | port: this.maximoRestUrl.port, 54 | headers: getAuthTypeHeader(this,myconnector), 55 | path: AUTH_PATH, 56 | }; 57 | 58 | var restcallback = function(response) 59 | { 60 | var resdata = ''; 61 | response.on("data", function(chunked) 62 | { 63 | resdata += chunked; 64 | }); 65 | 66 | response.on('error', function(err) 67 | { 68 | console.log('Error retrieving data... ' + err.message); 69 | deferred.reject("Error retrieving data...."+ err.message); 70 | }); 71 | 72 | response.on('end', function() 73 | { 74 | // Save the cookie (jsessionid, ltpa token etc.. etc..) for future use so we can participate 75 | // in any authentication strategy the client provides. 76 | var setCookieValue = response.headers['set-cookie']; 77 | this.cookie = {"set-cookie":setCookieValue}; 78 | this.isCookieSet = "true"; 79 | myconnector.cookie = this.cookie //response.headers['set-cookie']; 80 | myconnector.isCookieSet = "true"; 81 | statusCode = response.statusCode; 82 | if (datacallback) 83 | { 84 | deferred.promise.nodeify(datacallback(statusCode,this.cookie,this)); 85 | } else 86 | { 87 | deferred.resolve(this.cookie); 88 | } 89 | //datacallback(response.statusCode,resourceset,this); //Invoke the callback and pass the data back. 90 | }); 91 | } 92 | 93 | // Request the data (Asynch) from Maximo and handle the response in the callback above ... Ideally Maximo should give us a Promise so we don't 94 | // have to handle the Asynch in a callback. 95 | this.client.request(options, restcallback).end(); 96 | //return this; 97 | return deferred.promise; 98 | }; 99 | 100 | 101 | AuthConnector.prototype.getAuthTypeHeader = function(my,fconnect) 102 | { 103 | return getAuthTypeHeader(my,fconnect); 104 | } 105 | 106 | 107 | // Private Methods 108 | 109 | function getAuthTypeHeader(my,fconnect) 110 | { 111 | var hdr = ""; 112 | if(my.cookie == null) 113 | { 114 | console.log("Auth header type = "+fconnect.authType); 115 | switch (fconnect.authType) 116 | { 117 | case "basic": 118 | hdr = {'Authorization': 'Basic '+new Buffer(fconnect.maximoRestUrl.auth).toString('base64'), 119 | 'x-public-uri':fconnect.xpublicuri.toString()}; 120 | 121 | case "form": 122 | hdr = {'Accept': 'text/html,application/xhtml+xml,application/xml', 123 | 'Content-Type':'application/x-www-form-urlencoded', 124 | 'Connection':'keep-alive'}; 125 | break; 126 | 127 | case "maxauth": 128 | hdr = {'maxauth': new Buffer(fconnect.maximoRestUrl.auth).toString('base64'), 129 | 'x-public-uri':fconnect.xpublicuri.toString()}; 130 | break; 131 | 132 | // Default it to MaxAuth for now. 133 | default: 134 | hdr = {'maxauth': new Buffer(fconnect.maximoRestUrl.auth).toString('base64'), 135 | 'x-public-uri':fconnect.xpublicuri.toString()}; 136 | break; 137 | } 138 | } else 139 | { 140 | console.log("Auth header type = cookie"); 141 | hdr = {'Cookie' : my.cookie}; 142 | } 143 | return hdr; 144 | } 145 | -------------------------------------------------------------------------------- /resources/connectors/crudconnector.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = CRUDConnector; 3 | var url = require('url'); 4 | var buffer = require('buffer'); 5 | var http = require('http'); 6 | var Q = require('q'); 7 | var querystring = require("querystring"); 8 | var REST_PATH = '/maximo/oslc/os/'; 9 | var X_PUB_PATH = '/maximo/oslc/'; 10 | var REST_PATH = '/maximo/oslc/os/'; 11 | var AUTH_PATH = '/maximo/oslc/'; 12 | 13 | var Resource = require('../resource'); 14 | //var ResourceSet = require('../resourceset'); 15 | 16 | /** 17 | * Asynchronous Http connector to service provider (Maximo etc.) 18 | * 19 | * @constructor 20 | * @param {Object} 21 | */ 22 | 23 | 24 | function CRUDConnector(maximoRestUrl,maximopath) 25 | { 26 | if(maximoRestUrl) 27 | { 28 | X_PUB_PATH = maximoRestUrl.auth_scheme + '/oslc/'; 29 | 30 | this.maximoRestUrl = maximoRestUrl; 31 | if(typeof(this.maximoRestUrl) === "string") 32 | { 33 | var urlarray = this.maximoRestUrl.split(':'); 34 | var port = urlarray[2].split("/")[0]; 35 | this.client = require(urlarray[0]); 36 | this.xpublicuri = urlarray[0]+":"+urlarray[1]+":"+port+X_PUB_PATH; 37 | console.log("***** this.xpublicuri "+this.xpublicuri) 38 | } else 39 | { 40 | this.client = require(this.maximoRestUrl.protocol.split(':')[0]); 41 | this.xpublicuri = this.maximoRestUrl.protocol+"//"+this.maximoRestUrl.hostname+":"+this.maximoRestUrl.port+X_PUB_PATH; 42 | } 43 | } 44 | this.maximopath = maximopath? maximopath : null; 45 | this.connection = maximoRestUrl; // this.connection is exposed and may be overridden later. 46 | this.isCookieSet = "false"; 47 | 48 | }; 49 | 50 | // Expose these properties 51 | CRUDConnector.prototype.connection; 52 | 53 | CRUDConnector.prototype.isCookieSet; 54 | 55 | 56 | CRUDConnector.prototype.__create = function(jsonbody,props,attachments,datacallback) 57 | { 58 | 59 | var deferred = Q.defer(); 60 | var returndata = ''; 61 | var client = require(this.maximoRestUrl.protocol.split(':')[0]); 62 | var statusCode = ""; 63 | var resourceset = ""; 64 | 65 | var propsStr = null; 66 | if (props && props.constructor === Array) 67 | { 68 | var arrayLength = props.length; 69 | for (var i = 0; i < arrayLength; i++) 70 | { 71 | var prop = props[i]; 72 | propsStr += prop+","; 73 | propsStr = ((arrayLength - i) > 1) ? propsStr+prop+"," : propsStr+prop; 74 | } 75 | } 76 | 77 | var options = { 78 | hostname: this.maximoRestUrl.hostname, 79 | port: this.maximoRestUrl.port, 80 | headers: getAuthTypeHeader(props,jsonbody,this, null, null), 81 | path: this.maximopath, 82 | method: 'POST' 83 | }; 84 | 85 | var req = client.request(options, function(res) 86 | { 87 | res.setEncoding('utf8'); 88 | var resdata = ''; 89 | res.on('data', function (chunk) 90 | { 91 | resdata += chunk; 92 | }); 93 | res.on('error', function(err) 94 | { 95 | console.log('Error retrieving data... ' + err.message); 96 | deferred.reject("Error retrieving data...."+ err.message); 97 | }); 98 | res.on('end', function() 99 | { 100 | var data = null; 101 | if(res.statusCode == 201 && resdata == "") 102 | { 103 | data = {"error code":"201","description":"Properties are required for Create API"}; 104 | } else 105 | { 106 | console.log("***** RESPONSE "+res.statusCode); 107 | data = JSON.parse(resdata) 108 | } 109 | var resourcemem = new Resource(data,this.connection); 110 | statusCode = res.statusCode; 111 | if (datacallback) 112 | { 113 | deferred.promise.nodeify(datacallback(statusCode,resourcemem,this)); 114 | } else 115 | { 116 | deferred.resolve(resourcemem); 117 | } 118 | }); 119 | }); 120 | 121 | req.on('error', function(e) 122 | { 123 | console.log('problem with request: ' + e.message); 124 | }); 125 | 126 | 127 | req.write(JSON.stringify(jsonbody)); 128 | req.end(); 129 | //return this;*/ 130 | return deferred.promise; 131 | } 132 | 133 | CRUDConnector.prototype.__crud = function(jsonbody,props,current,method,xmethod,patchtype,datacallback) 134 | { 135 | var deferred = Q.defer(); 136 | var returndata = ''; 137 | var client = require(current.resourceURI.split(':')[0]); 138 | var host = current.resourceURI.split(':')[1].split("//")[1]; 139 | var port = current.resourceURI.split(':')[2].split("/")[0]; 140 | var path = current.resourceURI.split(host)[1].split(port)[1]; 141 | if(! current.isCookieSet) 142 | { 143 | var xpublicuri = current.connection.protocol+"//"+current.connection.hostname+":"+current.connection.port+X_PUB_PATH; 144 | } 145 | // If this.cookie type === object it means it's a URL so we need to login 146 | /*var hdr = (typeof(current.cookie) === "object") 147 | ? 148 | {'MAXAUTH': new Buffer(current.cookie.auth).toString('base64'), 149 | 'x-public-uri':xpublicuri.toString()} 150 | : 151 | {'Cookie' : current.cookie};*/ 152 | var statusCode = ""; 153 | var resourceset = ""; 154 | var options = { 155 | hostname: host, 156 | port: port, 157 | headers: getAuthTypeHeader(props,jsonbody,current,xmethod,patchtype), 158 | path: path, 159 | method: method 160 | }; 161 | 162 | var req = client.request(options, function(res) 163 | { 164 | res.setEncoding('utf8'); 165 | var resdata = ''; 166 | res.on('data', function (chunk) 167 | { 168 | resdata += chunk; 169 | }); 170 | res.on('error', function(err) 171 | { 172 | console.log('Error retrieving data... ' + err.message); 173 | deferred.reject("Error retrieving data...."+ err.message); 174 | }); 175 | res.on('end', function() 176 | { 177 | var data = null; 178 | if(res.statusCode == 201 && resdata == "") 179 | { 180 | data = {"error code":"201","description":"Required headers may not be set e.g. properties"}; 181 | } else 182 | { 183 | var scode = res.statusCode; 184 | data = (method === 'DELETE') ? {"status code":scode,"description":"Delete successful"} : JSON.parse(resdata); 185 | } 186 | var resourcemem = new Resource(data,current.connection); 187 | statusCode = res.statusCode; 188 | if (datacallback) 189 | { 190 | deferred.promise.nodeify(datacallback(statusCode,resourcemem,current)); 191 | } else 192 | { 193 | deferred.resolve(resourcemem); 194 | } 195 | }); 196 | }); 197 | 198 | req.on('error', function(e) 199 | { 200 | console.log('problem with request: ' + e.message); 201 | }); 202 | 203 | 204 | req.write(JSON.stringify(jsonbody)); 205 | req.end(); 206 | //return this; 207 | return deferred.promise; 208 | }; 209 | 210 | // Private Methods 211 | 212 | function getCRUDprops(props) 213 | { 214 | return props.toString(); 215 | } 216 | 217 | function getAuthTypeHeader(props,jsonbody,my,xmethod,patchtype) 218 | { 219 | var hdr = null; 220 | var propsStr = getCRUDprops(props); 221 | if(! my.isCookieSet) 222 | { 223 | console.log("Auth header type = MaxAuth "+JSON.stringify(my.connection)); 224 | hdr = (propsStr) ? 225 | {'MAXAUTH': new Buffer(my.connection.auth).toString('base64'), 226 | 'content-type': 'application/json', 227 | 'x-method-override': xmethod, 228 | 'PATCHTYPE':patchtype, 229 | 'properties': propsStr, 230 | 'body':JSON.stringify(jsonbody)} 231 | : 232 | {'MAXAUTH': new Buffer(my.connection.auth).toString('base64'), 233 | 'content-type': 'application/json', 234 | 'x-method-override': xmethod, 235 | 'PATCHTYPE':patchtype, 236 | 'body':JSON.stringify(jsonbody)} 237 | } else 238 | { 239 | //console.log("Auth header type = cookie"+JSON.stringify(my.cookie)); 240 | hdr = (propsStr) ? 241 | {'Cookie' : my.cookie, 242 | 'content-type': 'application/json', 243 | 'x-method-override': xmethod, 244 | 'PATCHTYPE':patchtype, 245 | 'properties': propsStr, 246 | 'body':JSON.stringify(jsonbody)} 247 | : 248 | {'Cookie' : my.cookie, 249 | 'content-type': 'application/json', 250 | 'x-method-override': xmethod, 251 | 'PATCHTYPE':patchtype, 252 | 'body':JSON.stringify(jsonbody)} 253 | } 254 | return hdr; 255 | } 256 | -------------------------------------------------------------------------------- /resources/connectors/externalconnector.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = ExternalConnector; 3 | var url = require('url'); 4 | var buffer = require('buffer'); 5 | var http = require('http'); 6 | var https = require('https'); 7 | var Q = require('q'); 8 | var querystring = require("querystring"); 9 | 10 | /** 11 | * Asynchronous Http connector to service provider (Maximo etc.) 12 | * 13 | * @constructor 14 | * @param {Object} 15 | */ 16 | 17 | 18 | function ExternalConnector(options,resourceset) 19 | { 20 | this.options = options; 21 | this.resourceset = resourceset; 22 | this.protocol = (options.protocol == null)? "http": options.protocol; 23 | this.client = require(this.protocol); 24 | this.host = options.host; 25 | this.port = options.port; 26 | this.endpoint = options.endpoint; 27 | this.headers = options.headers; 28 | this.template = options.template; 29 | this.path = options.path; 30 | this.originalpath = options.path; 31 | //initialize some instance variables 32 | this.promises = []; 33 | }; 34 | 35 | ExternalConnector.prototype.path = function(path) 36 | { 37 | this.path = path; 38 | } 39 | 40 | ExternalConnector.prototype.push = function(i) 41 | { 42 | if(this.template != null && this.template["prependtopath"] != null) 43 | { 44 | var substitute = this.template["prependtopath"]["substitute"]; 45 | var text = this.template["prependtopath"]["text"]; 46 | if (substitute != null) 47 | { 48 | var token = substitute.split("."); 49 | var related = this.resourceset[i][token[0]]; 50 | if(related != null) 51 | { 52 | var value = related[0][token[1]]; 53 | this.path = this.endpoint+value+text+this.originalpath; 54 | this.promises.push(asynch(this)); 55 | } 56 | } 57 | } 58 | } 59 | 60 | ExternalConnector.prototype.resolve = function(datacallback) 61 | { 62 | var deferred = Q.defer(); 63 | Q.all(this.promises).then(function(data) 64 | { 65 | if (datacallback) 66 | { 67 | deferred.promise.nodeify(datacallback(data)); 68 | } else 69 | { 70 | deferred.resolve(data); 71 | } 72 | }) 73 | .fail(function (error) 74 | { 75 | console.log('****** Error Code = '+error); 76 | }); 77 | return deferred.promise; 78 | } 79 | 80 | function asynch(my,datacallback) 81 | { 82 | var deferred = Q.defer(); 83 | var returndata = ''; 84 | //var client = require(this.maximoRestUrl.protocol.split(':')[0]); 85 | var statusCode = ""; 86 | var resourceset = ""; 87 | console.log("***** "+my.host+" **** "+my.path); 88 | var options = { 89 | hostname: my.host, 90 | port: my.port, 91 | path: my.path 92 | //path: "v1/location/02375:4:US/forecast/daily/10day.json?apiKey=34b54a2413263374bdace07052e0fdf3" 93 | }; 94 | var restcallback = function(response) 95 | { 96 | var resdata = ''; 97 | response.on("data", function(chunked) 98 | { 99 | resdata += chunked; 100 | }); 101 | 102 | response.on('error', function(err) 103 | { 104 | console.log('Error retrieving data... ' + err.message); 105 | deferred.reject("Error retrieving data...."+ err.message); 106 | }); 107 | 108 | response.on('end', function() 109 | { 110 | console.log("%%%%Status code "+response.statusCode); 111 | var data = JSON.parse(resdata); 112 | statusCode = response.statusCode; 113 | if (datacallback) 114 | { 115 | deferred.promise.nodeify(datacallback(statusCode,data,my)); 116 | } else 117 | { 118 | deferred.resolve(data); 119 | } 120 | //datacallback(response.statusCode,resourceset,this); //Invoke the callback and pass the data back. 121 | }); 122 | } 123 | // Request the data (Asynch) from Maximo and handle the response in the callback above ... Ideally Maximo should give us a Promise so we don't 124 | // have to handle the Asynch in a callback. 125 | my.client.request(options, restcallback).end(); 126 | //return this; 127 | return deferred.promise; 128 | }; 129 | -------------------------------------------------------------------------------- /resources/connectors/fetchconnector.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = FetchConnector; 3 | var url = require('url'); 4 | var buffer = require('buffer'); 5 | var http = require('http'); 6 | var Q = require('q'); 7 | var querystring = require("querystring"); 8 | var REST_PATH = '/maximo/oslc/os/'; 9 | var X_PUB_PATH = '/maximo/oslc/'; 10 | var REST_PATH = '/maximo/oslc/os/'; 11 | var AUTH_PATH = '/maximo/oslc/'; 12 | 13 | var Resource = require('../resource'); 14 | var ResourceSet = require('../resourceset'); 15 | 16 | /** 17 | * Asynchronous Http connector to service provider (Maximo etc.) 18 | * 19 | * @constructor 20 | * @param {Object} 21 | */ 22 | 23 | 24 | function FetchConnector(maximoRestUrl,maximopath) 25 | { 26 | X_PUB_PATH = maximoRestUrl.auth_scheme + '/oslc/'; 27 | 28 | this.maximoRestUrl = maximoRestUrl; 29 | this.client = require(this.maximoRestUrl.protocol.split(':')[0]); 30 | this.xpublicuri = this.maximoRestUrl.protocol+"//"+this.maximoRestUrl.hostname+":"+this.maximoRestUrl.port+X_PUB_PATH; 31 | this.maximopath = maximopath; 32 | this.cookie = null; 33 | this.isCookieSet = "false"; 34 | 35 | }; 36 | 37 | // Expose these properties 38 | FetchConnector.prototype.cookie; 39 | 40 | FetchConnector.prototype.isCookieSet; 41 | 42 | 43 | FetchConnector.prototype.__fetch = function(myconnector,datacallback) 44 | { 45 | var deferred = Q.defer(); 46 | var returndata = ''; 47 | //var client = require(this.maximoRestUrl.protocol.split(':')[0]); 48 | var statusCode = ""; 49 | var resourceset = ""; 50 | console.log(this.maximopath); 51 | var options = { 52 | hostname: this.maximoRestUrl.hostname, 53 | port: this.maximoRestUrl.port, 54 | headers: getAuthTypeHeader(this,myconnector), 55 | path: this.maximopath 56 | }; 57 | var ac = this.cookie; // make a local copy so it's in context for the callback 58 | var restcallback = function(response) 59 | { 60 | var resdata = ''; 61 | response.on("data", function(chunked) 62 | { 63 | resdata += chunked; 64 | }); 65 | 66 | response.on('error', function(err) 67 | { 68 | console.log('Error retrieving data... ' + err.message); 69 | deferred.reject("Error retrieving data...."+ err.message); 70 | }); 71 | 72 | response.on('end', function() 73 | { 74 | //console.log("***** AC ***"+ac); 75 | //If ac is null that means the user did not pass in an auth token. 76 | 77 | ac = (ac === null) ? response.headers['set-cookie'] : ac 78 | 79 | var data = JSON.parse(resdata); 80 | //resourceset = new ResourceSet(data["rdfs:member"],this.cookie); // send back the data wrapped inside ResourceSet 81 | resourceset = new ResourceSet(data,ac); // send back the data wrapped inside ResourceSet 82 | statusCode = response.statusCode; 83 | if (datacallback) 84 | { 85 | deferred.promise.nodeify(datacallback(statusCode,resourceset,this)); 86 | } else 87 | { 88 | deferred.resolve(resourceset); 89 | } 90 | //datacallback(response.statusCode,resourceset,this); //Invoke the callback and pass the data back. 91 | }); 92 | } 93 | // Request the data (Asynch) from Maximo and handle the response in the callback above ... Ideally Maximo should give us a Promise so we don't 94 | // have to handle the Asynch in a callback. 95 | this.client.request(options, restcallback).end(); 96 | //return this; 97 | return deferred.promise; 98 | }; 99 | 100 | 101 | 102 | FetchConnector.prototype.__fetchnext = function(np,myconnector,datacallback) 103 | { 104 | var deferred = Q.defer(); 105 | 106 | // If the type is Object we assume this is the ResourceSet JSON so let's get the nextpage URI 107 | //var np_uri = (typeof(np) === 'object') ? np["oslc:responseInfo"]["oslc:nextPage"]["rdf:resource"] 108 | // : np; 109 | var np_uri = nextPage(np); 110 | if(np_uri) 111 | { 112 | var nextpath = np_uri.substr( np_uri.indexOf(this.maximoRestUrl.port)+this.maximoRestUrl.port.length); 113 | var returndata = ''; 114 | var client = require(this.maximoRestUrl.protocol.split(':')[0]); 115 | var statusCode = ""; 116 | var resourceset = ""; 117 | var xpublicuri = this.maximoRestUrl.protocol+"//"+this.maximoRestUrl.hostname+":"+this.maximoRestUrl.port+X_PUB_PATH; 118 | var options = { 119 | hostname: this.maximoRestUrl.hostname, 120 | port: this.maximoRestUrl.port, 121 | headers: getAuthTypeHeader(this,myconnector), 122 | path: nextpath 123 | }; 124 | var restcallback = function(response) 125 | { 126 | var resdata = ''; 127 | response.on("data", function(chunked) 128 | { 129 | resdata += chunked; 130 | }); 131 | 132 | response.on('error', function(err) 133 | { 134 | console.log('Error retrieving data... ' + err.message); 135 | deferred.reject("Error retrieving data...."+ err.message); 136 | }); 137 | 138 | response.on('end', function() 139 | { 140 | // Save the jsessionid for future use.... 141 | this.cookie = response.headers['set-cookie']; 142 | if(this.cookie) 143 | { 144 | this.cookie = (this.cookie + '').split(";")[0]; 145 | } 146 | var data = JSON.parse(resdata); 147 | //resourceset = new ResourceSet(data["rdfs:member"],this.cookie); // send back the data wrapped inside ResourceSet 148 | resourceset = new ResourceSet(data,this.cookie); // send back the data wrapped inside ResourceSet 149 | statusCode = response.statusCode; 150 | if (datacallback) 151 | { 152 | deferred.promise.nodeify(datacallback(statusCode,resourceset,this)); 153 | } else 154 | { 155 | deferred.resolve(resourceset); 156 | } 157 | //datacallback(response.statusCode,resourceset,this); //Invoke the callback and pass the data back. 158 | }); 159 | } 160 | 161 | // Request the data (Asynch) from Maximo and handle the response in the callback above ... Ideally Maximo should give us a Promise so we don't 162 | // have to handle the Asynch in a callback. 163 | client.request(options, restcallback).end(); 164 | //return this; 165 | return deferred.promise; 166 | } 167 | console.log("********* NOT Set **** "+np); 168 | //deferred.resolve({"status":"End of Page"}); 169 | return np; 170 | } 171 | 172 | // Private Methods 173 | 174 | function getAuthTypeHeader(my,fconnect) 175 | { 176 | var hdr = ""; 177 | if(my.cookie == null) 178 | { 179 | console.log("Auth header type = "+fconnect.authType); 180 | switch (fconnect.authType) 181 | { 182 | case "basic": 183 | hdr = {'Authorization': 'Basic '+new Buffer(fconnect.maximoRestUrl.auth).toString('base64'), 184 | 'x-public-uri':fconnect.xpublicuri.toString()}; 185 | 186 | case "form": 187 | hdr = {'Accept': 'text/html,application/xhtml+xml,application/xml', 188 | 'Content-Type':'application/x-www-form-urlencoded', 189 | 'Connection':'keep-alive'}; 190 | break; 191 | 192 | case "maxauth": 193 | hdr = {'maxauth': new Buffer(fconnect.maximoRestUrl.auth).toString('base64'), 194 | 'x-public-uri':fconnect.xpublicuri.toString()}; 195 | break; 196 | 197 | // Default it to MaxAuth for now. 198 | default: 199 | hdr = {'maxauth': new Buffer(fconnect.maximoRestUrl.auth).toString('base64'), 200 | 'x-public-uri':fconnect.xpublicuri.toString()}; 201 | break; 202 | } 203 | } else 204 | { 205 | console.log("Auth header type = cookie"+my.cookie); 206 | hdr = {'Cookie' : my.cookie}; 207 | } 208 | return hdr; 209 | } 210 | 211 | function nextPage(np) 212 | { 213 | if(typeof(np) === 'object' && (np["oslc:responseInfo"] && np["oslc:responseInfo"]["oslc:nextPage"])) 214 | { 215 | return np["oslc:responseInfo"]["oslc:nextPage"]["rdf:resource"] 216 | } 217 | return np["rdf:about"]; 218 | } 219 | -------------------------------------------------------------------------------- /resources/connectors/relatedconnector.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = RelatedConnector; 3 | var url = require('url'); 4 | var buffer = require('buffer'); 5 | var http = require('http'); 6 | var Q = require('q'); 7 | var querystring = require("querystring"); 8 | var REST_PATH = '/maximo/oslc/os/'; 9 | var X_PUB_PATH = '/maximo/oslc/'; 10 | var REST_PATH = '/maximo/oslc/os/'; 11 | var AUTH_PATH = '/maximo/oslc/'; 12 | 13 | var Resource = require('../resource'); 14 | var ResourceSet = require('../resourceset'); 15 | 16 | /** 17 | * Asynchronous Http connector to service provider (Maximo etc.) 18 | * 19 | * @constructor 20 | * @param {Object} 21 | */ 22 | 23 | 24 | function RelatedConnector(maximoRestUrl,maximopath) 25 | { 26 | if(maximoRestUrl) 27 | { 28 | X_PUB_PATH = maximoRestUrl.auth_scheme + '/oslc/'; 29 | 30 | this.maximoRestUrl = maximoRestUrl; 31 | if(typeof(this.maximoRestUrl) === "string") 32 | { 33 | var urlarray = this.maximoRestUrl.split(':'); 34 | var port = urlarray[2].split("/")[0]; 35 | this.client = require(urlarray[0]); 36 | this.xpublicuri = urlarray[0]+":"+urlarray[1]+":"+port+X_PUB_PATH; 37 | console.log("***** this.xpublicuri "+this.xpublicuri) 38 | } else 39 | { 40 | this.client = require(this.maximoRestUrl.protocol.split(':')[0]); 41 | this.xpublicuri = this.maximoRestUrl.protocol+"//"+this.maximoRestUrl.hostname+":"+this.maximoRestUrl.port+X_PUB_PATH; 42 | } 43 | } 44 | this.maximopath = maximopath? maximopath : null; 45 | this.connection = maximoRestUrl; // this.connection is exposed and may be overridden later. 46 | this.isCookieSet = "false"; 47 | 48 | }; 49 | 50 | // Expose these properties 51 | RelatedConnector.prototype.cookie; 52 | 53 | RelatedConnector.prototype.isCookieSet; 54 | 55 | 56 | RelatedConnector.prototype.__fetch = function(current,myconnector,datacallback) 57 | { 58 | var deferred = Q.defer(); 59 | var returndata = ''; 60 | //var client = require(this.maximoRestUrl.protocol.split(':')[0]); 61 | var statusCode = ""; 62 | var resourceset = ""; 63 | var host = current.resourceURI.split(':')[1].split("//")[1]; 64 | var port = current.resourceURI.split(':')[2].split("/")[0]; 65 | var path = current.resourceURI.split(host)[1].split(port)[1]; 66 | this.connection = current.connection; 67 | var options = { 68 | hostname: host, 69 | port: port, 70 | headers: getAuthTypeHeader(this,myconnector), 71 | path: path 72 | }; 73 | var ac = this.cookie; // make a local copy so it's in context for the callback 74 | var restcallback = function(response) 75 | { 76 | var resdata = ''; 77 | response.on("data", function(chunked) 78 | { 79 | resdata += chunked; 80 | }); 81 | 82 | response.on('error', function(err) 83 | { 84 | console.log('Error retrieving data... ' + err.message); 85 | deferred.reject("Error retrieving data...."+ err.message); 86 | }); 87 | 88 | response.on('end', function() 89 | { 90 | //console.log("***** AC ***"+ac); 91 | //If ac is null that means the user did not pass in an auth token. 92 | 93 | ac = (ac === null) ? response.headers['set-cookie'] : ac 94 | 95 | var data = JSON.parse(resdata); 96 | //resourceset = new ResourceSet(data["rdfs:member"],this.cookie); // send back the data wrapped inside ResourceSet 97 | resourceset = new ResourceSet(data,ac); // send back the data wrapped inside ResourceSet 98 | statusCode = response.statusCode; 99 | if (datacallback) 100 | { 101 | deferred.promise.nodeify(datacallback(statusCode,resourceset,this)); 102 | } else 103 | { 104 | deferred.resolve(resourceset); 105 | } 106 | //datacallback(response.statusCode,resourceset,this); //Invoke the callback and pass the data back. 107 | }); 108 | } 109 | // Request the data (Asynch) from Maximo and handle the response in the callback above ... Ideally Maximo should give us a Promise so we don't 110 | // have to handle the Asynch in a callback. 111 | this.client.request(options, restcallback).end(); 112 | //return this; 113 | return deferred.promise; 114 | }; 115 | 116 | 117 | 118 | RelatedConnector.prototype.__fetchnext = function(np,myconnector,datacallback) 119 | { 120 | var deferred = Q.defer(); 121 | 122 | // If the type is Object we assume this is the ResourceSet JSON so let's get the nextpage URI 123 | //var np_uri = (typeof(np) === 'object') ? np["oslc:responseInfo"]["oslc:nextPage"]["rdf:resource"] 124 | // : np; 125 | var np_uri = nextPage(np); 126 | if(np_uri) 127 | { 128 | var nextpath = np_uri.substr( np_uri.indexOf(this.maximoRestUrl.port)+this.maximoRestUrl.port.length); 129 | var returndata = ''; 130 | var client = require(this.maximoRestUrl.protocol.split(':')[0]); 131 | var statusCode = ""; 132 | var resourceset = ""; 133 | var xpublicuri = this.maximoRestUrl.protocol+"//"+this.maximoRestUrl.hostname+":"+this.maximoRestUrl.port+X_PUB_PATH; 134 | var options = { 135 | hostname: this.maximoRestUrl.hostname, 136 | port: this.maximoRestUrl.port, 137 | headers: getAuthTypeHeader(this,myconnector), 138 | path: nextpath 139 | }; 140 | var restcallback = function(response) 141 | { 142 | var resdata = ''; 143 | response.on("data", function(chunked) 144 | { 145 | resdata += chunked; 146 | }); 147 | 148 | response.on('error', function(err) 149 | { 150 | console.log('Error retrieving data... ' + err.message); 151 | deferred.reject("Error retrieving data...."+ err.message); 152 | }); 153 | 154 | response.on('end', function() 155 | { 156 | // Save the jsessionid for future use.... 157 | this.cookie = response.headers['set-cookie']; 158 | if(this.cookie) 159 | { 160 | this.cookie = (this.cookie + '').split(";")[0]; 161 | } 162 | var data = JSON.parse(resdata); 163 | //resourceset = new ResourceSet(data["rdfs:member"],this.cookie); // send back the data wrapped inside ResourceSet 164 | resourceset = new ResourceSet(data,this.cookie); // send back the data wrapped inside ResourceSet 165 | statusCode = response.statusCode; 166 | if (datacallback) 167 | { 168 | deferred.promise.nodeify(datacallback(statusCode,resourceset,this)); 169 | } else 170 | { 171 | deferred.resolve(resourceset); 172 | } 173 | //datacallback(response.statusCode,resourceset,this); //Invoke the callback and pass the data back. 174 | }); 175 | } 176 | 177 | // Request the data (Asynch) from Maximo and handle the response in the callback above ... Ideally Maximo should give us a Promise so we don't 178 | // have to handle the Asynch in a callback. 179 | client.request(options, restcallback).end(); 180 | //return this; 181 | return deferred.promise; 182 | } 183 | console.log("********* NOT Set **** "+np); 184 | //deferred.resolve({"status":"End of Page"}); 185 | return np; 186 | } 187 | 188 | // Private Methods 189 | 190 | function getAuthTypeHeader(my,fconnect) 191 | { 192 | var hdr = ""; 193 | if(my.connection == null) 194 | { 195 | console.log("Auth header type = "+fconnect.authType); 196 | switch (fconnect.authType) 197 | { 198 | case "basic": 199 | hdr = {'Authorization': 'Basic '+new Buffer(fconnect.maximoRestUrl.auth).toString('base64'), 200 | 'x-public-uri':fconnect.xpublicuri.toString()}; 201 | 202 | case "form": 203 | hdr = {'Accept': 'text/html,application/xhtml+xml,application/xml', 204 | 'Content-Type':'application/x-www-form-urlencoded', 205 | 'Connection':'keep-alive'}; 206 | break; 207 | 208 | case "maxauth": 209 | hdr = {'maxauth': new Buffer(fconnect.maximoRestUrl.auth).toString('base64'), 210 | 'x-public-uri':fconnect.xpublicuri.toString()}; 211 | break; 212 | 213 | // Default it to MaxAuth for now. 214 | default: 215 | hdr = {'maxauth': new Buffer(fconnect.maximoRestUrl.auth).toString('base64'), 216 | 'x-public-uri':fconnect.xpublicuri.toString()}; 217 | break; 218 | } 219 | } else 220 | { 221 | console.log("Auth header type = cookie"+my.connection); 222 | hdr = {'Cookie' : my.connection}; 223 | } 224 | return hdr; 225 | } 226 | 227 | function nextPage(np) 228 | { 229 | if(typeof(np) === 'object' && (np["oslc:responseInfo"] && np["oslc:responseInfo"]["oslc:nextPage"])) 230 | { 231 | return np["oslc:responseInfo"]["oslc:nextPage"]["rdf:resource"] 232 | } 233 | return np["rdf:about"]; 234 | } 235 | -------------------------------------------------------------------------------- /resources/connectors/schemaconnector.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = SchemaConnector; 3 | var url = require('url'); 4 | var buffer = require('buffer'); 5 | var http = require('http'); 6 | var Q = require('q'); 7 | var querystring = require("querystring"); 8 | var REST_PATH = '/maximo/oslc/os/'; 9 | var X_PUB_PATH = '/maximo/oslc/'; 10 | var REST_PATH = '/maximo/oslc/os/'; 11 | var AUTH_PATH = '/maximo/oslc/'; 12 | 13 | var Resource = require('../resource'); 14 | var ResourceSet = require('../resourceset'); 15 | 16 | /** 17 | * Asynchronous Http connector to service provider (Maximo etc.) 18 | * 19 | * @constructor 20 | * @param {Object} 21 | */ 22 | 23 | 24 | function SchemaConnector(maximoRestUrl,maximopath) 25 | { 26 | X_PUB_PATH = maximoRestUrl.auth_scheme + '/oslc/'; 27 | 28 | this.maximoRestUrl = maximoRestUrl; 29 | this.client = require(this.maximoRestUrl.protocol.split(':')[0]); 30 | this.xpublicuri = this.maximoRestUrl.protocol+"//"+this.maximoRestUrl.hostname+":"+this.maximoRestUrl.port+X_PUB_PATH; 31 | this.maximopath = maximopath; 32 | this.cookie = null; 33 | this.isCookieSet = "false"; 34 | 35 | }; 36 | 37 | // Expose these properties 38 | SchemaConnector.prototype.cookie; 39 | 40 | SchemaConnector.prototype.isCookieSet; 41 | 42 | 43 | SchemaConnector.prototype.__fetch = function(myconnector,datacallback) 44 | { 45 | var deferred = Q.defer(); 46 | var returndata = ''; 47 | //var client = require(this.maximoRestUrl.protocol.split(':')[0]); 48 | var statusCode = ""; 49 | var resourceset = ""; 50 | console.log(this.maximopath); 51 | var options = { 52 | hostname: this.maximoRestUrl.hostname, 53 | port: this.maximoRestUrl.port, 54 | headers: getAuthTypeHeader(this,myconnector), 55 | path: this.maximopath 56 | }; 57 | var ac = this.cookie; // make a local copy so it's in context for the callback 58 | var restcallback = function(response) 59 | { 60 | var resdata = ''; 61 | response.on("data", function(chunked) 62 | { 63 | resdata += chunked; 64 | }); 65 | 66 | response.on('error', function(err) 67 | { 68 | console.log('Error retrieving data... ' + err.message); 69 | deferred.reject("Error retrieving data...."+ err.message); 70 | }); 71 | 72 | response.on('end', function() 73 | { 74 | //console.log("***** AC ***"+ac); 75 | //If ac is null that means the user did not pass in an auth token. 76 | 77 | ac = (ac === null) ? response.headers['set-cookie'] : ac 78 | 79 | var data = JSON.parse(resdata); 80 | statusCode = response.statusCode; 81 | if (datacallback) 82 | { 83 | deferred.promise.nodeify(datacallback(statusCode,data,this)); 84 | } else 85 | { 86 | deferred.resolve(data); 87 | } 88 | //datacallback(response.statusCode,resourceset,this); //Invoke the callback and pass the data back. 89 | }); 90 | } 91 | // Request the data (Asynch) from Maximo and handle the response in the callback above ... Ideally Maximo should give us a Promise so we don't 92 | // have to handle the Asynch in a callback. 93 | this.client.request(options, restcallback).end(); 94 | //return this; 95 | return deferred.promise; 96 | }; 97 | 98 | 99 | 100 | // Private Methods 101 | 102 | function getAuthTypeHeader(my,fconnect) 103 | { 104 | var hdr = ""; 105 | if(my.cookie == null) 106 | { 107 | console.log("Auth header type = "+fconnect.authType); 108 | switch (fconnect.authType) 109 | { 110 | case "basic": 111 | hdr = {'Authorization': 'Basic '+new Buffer(fconnect.maximoRestUrl.auth).toString('base64'), 112 | 'x-public-uri':fconnect.xpublicuri.toString()}; 113 | 114 | case "form": 115 | hdr = {'Accept': 'text/html,application/xhtml+xml,application/xml', 116 | 'Content-Type':'application/x-www-form-urlencoded', 117 | 'Connection':'keep-alive'}; 118 | break; 119 | 120 | case "maxauth": 121 | hdr = {'maxauth': new Buffer(fconnect.maximoRestUrl.auth).toString('base64'), 122 | 'x-public-uri':fconnect.xpublicuri.toString()}; 123 | break; 124 | 125 | // Default it to MaxAuth for now. 126 | default: 127 | hdr = {'maxauth': new Buffer(fconnect.maximoRestUrl.auth).toString('base64'), 128 | 'x-public-uri':fconnect.xpublicuri.toString()}; 129 | break; 130 | } 131 | } else 132 | { 133 | console.log("Auth header type = cookie"+my.cookie); 134 | hdr = {'Cookie' : my.cookie}; 135 | } 136 | return hdr; 137 | } -------------------------------------------------------------------------------- /resources/resource.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = Resource; 3 | var url = require('url'); 4 | var buffer = require('buffer'); 5 | var http = require('http'); 6 | var REST_PATH = '/maximo/oslc/os/'; 7 | var X_PUB_PATH = '/maximo/oslc/'; 8 | var Q = require('q'); 9 | var ResourceSet = require('./resourceset'); 10 | var Attachment = require('./attachment'); 11 | var CRUDConnector = require('./connectors/crudconnector'); 12 | var RelatedConnector = require('./connectors/relatedconnector'); 13 | 14 | /** 15 | * Business object for Maximo OSLC API 16 | * 17 | * @param member 18 | * @param connection 19 | * @returns {Resource} 20 | * @constructor 21 | */ 22 | function Resource(member,connection) 23 | { 24 | this.member = member; 25 | //this.currentResourceSet = collection["rdfs:member"]; 26 | this.resourceURI = (typeof(member)==="object")? getMyResourceURI(this.member) : member; 27 | //this.currentResourceSet = (typeof(collection["rdfs:member"]) == "undefined") ? collection: collection["rdfs:member"]; 28 | this.isCookieSet = false; 29 | //fyi... if this.isCookieSet = true (set by the client) then the connection will be a cookie 30 | // otherwise it's a URL 31 | this.connection = connection; 32 | return this; 33 | }; 34 | 35 | /** 36 | * 37 | */ 38 | Resource.prototype.isCookieSet; 39 | 40 | /** 41 | * 42 | * @param cookie 43 | */ 44 | Resource.prototype.setcookie= function(cookie) 45 | { 46 | this.cookie = cookie; 47 | this.isCookieSet = true; 48 | } 49 | 50 | /** 51 | * 52 | * @returns {*} 53 | */ 54 | Resource.prototype.JSON= function() 55 | { 56 | //return this.idx < 0 ? this.currentResourceSet : this.currentResourceSet[this.idx]; 57 | return this.member; 58 | }; 59 | 60 | /** 61 | * 62 | * @param relation 63 | * @returns {Resource} 64 | */ 65 | Resource.prototype.relatedResource = function(relation) 66 | { 67 | this.relation = relation; 68 | this.resourceURI = getMyResourceURI(this.member[relation]); 69 | return this; 70 | }; 71 | 72 | /** 73 | * 74 | * @param props 75 | * @returns {Resource} 76 | */ 77 | Resource.prototype.properties = function(props) 78 | { 79 | this.resourceURI += "?oslc.properties="+props.toString(); 80 | return this; 81 | }; 82 | 83 | /** 84 | * 85 | * @param meta 86 | * @param datacallback 87 | * @returns {Attachment} 88 | */ 89 | Resource.prototype.attachment = function(meta,datacallback) 90 | { 91 | return new Attachment(this.member,meta,this.connection); 92 | }; 93 | 94 | 95 | /** 96 | * 97 | * @param jsonbody 98 | * @param props 99 | * @param datacallback 100 | * @returns {*} 101 | */ 102 | Resource.prototype.update = function(jsonbody,props,datacallback) 103 | { 104 | return getCRUDConnector(this).__crud(jsonbody,props,this,'POST','PATCH','MERGE',datacallback); 105 | //return crud(jsonbody,props,this,'POST',null,datacallback); 106 | }; 107 | 108 | /** 109 | * 110 | * @param datacallback 111 | * @returns {*} 112 | */ 113 | Resource.prototype.fetch = function(datacallback) 114 | { 115 | return getRelatedConnector(this).__fetch(this,this.fconnect); // Pass this.fconnect so it's state is updated. 116 | } 117 | 118 | /** 119 | * 120 | * @param jsonbody 121 | * @param props 122 | * @param datacallback 123 | * @returns {*} 124 | */ 125 | Resource.prototype.merge = function(jsonbody,props,datacallback) 126 | { 127 | var patchtype = "MERGE"; 128 | return crud(jsonbody,props,this,'POST',patchtype,datacallback); 129 | }; 130 | 131 | /** 132 | * 133 | * @param jsonbody 134 | * @param props 135 | * @param datacallback 136 | * @returns {*} 137 | */ 138 | Resource.prototype.delete = function(jsonbody,props,datacallback) 139 | { 140 | var patchtype = "MERGE"; 141 | return getCRUDConnector(this).__crud(jsonbody,props,this,'DELETE',null,null,datacallback); 142 | //return crud(jsonbody,props,this,'DELETE',null,datacallback); 143 | }; 144 | 145 | 146 | 147 | // Private methods 148 | 149 | function getMyResourceURI(member) 150 | { 151 | // if rdf:resource is not available use rdf:about or href - one of them should definitely be available. 152 | var urltype = (typeof(member["rdf:about"] != "undefined") && member["rdf:about"] != null) 153 | ? "rdf:about" 154 | : (typeof(member["rdf:resource"] != "undefined") && member["rdf:resource"] != null) 155 | ? "rdf:resource" 156 | : "href" ; 157 | return member[urltype]; 158 | } 159 | 160 | function getCRUDConnector(me) // Singleton 161 | { 162 | if(me.cconnect == null) 163 | { 164 | me.cconnect = new CRUDConnector(me.resourceURI, me.maximopath); 165 | me.cconnect.authType = me.authType; 166 | me.cconnect.cookie = me.cookie; 167 | me.cconnect.isCookieSet = me.cookie == null ? false : true; 168 | } 169 | return me.cconnect; 170 | } 171 | 172 | function getRelatedConnector(cur) // Singleton 173 | { 174 | if(cur.fconnect == null) 175 | { 176 | cur.fconnect = new RelatedConnector(cur.resourceURI, cur.maximopath); 177 | cur.fconnect.authType = cur.authType; 178 | cur.fconnect.cookie = cur.cookie; 179 | cur.fconnect.isCookieSet = cur.cookie == null ? false : true; 180 | } 181 | return cur.fconnect; 182 | } 183 | -------------------------------------------------------------------------------- /resources/resourceobject.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = ResourceObject; 3 | 4 | var ResourceSet = require('./resourceset'); 5 | 6 | 7 | 8 | /** 9 | * Business object for Maximo OSLC API 10 | * @param maxfactory 11 | * @param mbo 12 | * @returns {ResourceSet} 13 | * @constructor 14 | */ 15 | function ResourceObject(maxfactory,mbo) 16 | { 17 | //Return a Zombie set. 18 | var cookie = maxfactory.isCookieSet ? maxfactory.cookie["set-cookie"] : null; 19 | return new ResourceSet(null,cookie,maxfactory,mbo); 20 | }; 21 | 22 | /** 23 | * 24 | * @returns {*} 25 | */ 26 | ResourceObject.prototype.name = function() 27 | { 28 | return this.mbo; 29 | }; 30 | -------------------------------------------------------------------------------- /resources/resourceset.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = ResourceSet; 3 | var url = require('url'); 4 | var buffer = require('buffer'); 5 | var http = require('http'); 6 | var Q = require('q'); 7 | var querystring = require("querystring"); 8 | var REST_PATH = '/maximo/oslc/os/'; 9 | var X_PUB_PATH = '/maximo/oslc/'; 10 | var REST_PATH = '/maximo/oslc/os/'; 11 | 12 | var Resource = require('./resource'); 13 | var FetchConnector = require('./connectors/fetchconnector'); 14 | var CRUDConnector = require('./connectors/crudconnector'); 15 | var ExternalConnector = require('./connectors/externalconnector'); 16 | var SchemaConnector = require('./connectors/schemaconnector'); 17 | 18 | /** 19 | * 20 | * @param resourcemboset 21 | * @param cookie 22 | * @param maxfactory 23 | * @param mbo 24 | * @returns {ResourceSet} 25 | * @constructor 26 | */ 27 | function ResourceSet(resourcemboset,cookie,maxfactory,mbo) 28 | { 29 | this.cookie = cookie; 30 | // Since JavaScript does not support method/constructor overloading we have 31 | // to handle multiple constructors by sniffing them out manually. 32 | 33 | // Constructor 1 34 | if(resourcemboset != null && cookie !== null) 35 | { 36 | //console.log("Instanciating Zombie Mbo Set - Constructor 1 "); 37 | this.resourcemboset = resourcemboset; 38 | return this; 39 | } 40 | // Constructor 2 41 | if(maxfactory != "undefined" && mbo != "undefined") 42 | { 43 | X_PUB_PATH = maxfactory.auth_scheme + '/oslc/'; 44 | REST_PATH = X_PUB_PATH + 'os/'; 45 | 46 | this.maximoRestUrl = maxfactory.resturl; 47 | this.password = maxfactory.password; 48 | this.mbo = mbo; 49 | this.islean = maxfactory.islean; 50 | console.log("this.islean ****** "+this.islean); 51 | this.namespace = this.islean == 1 ? "" : "spi:"; 52 | this.tenantcode = maxfactory.tenantcode; 53 | this.maximopath = REST_PATH+this.mbo+"?lean="+this.islean; 54 | this.maximopath = this.tenantcode ? this.maximopath+"&_tenantcode="+this.tenantcode : this.maximopath; 55 | this.schemapath = X_PUB_PATH + 'jsonschemas/' 56 | this.nextpageurl = ""; 57 | this.authType = maxfactory.authType 58 | if(this.authType == "form") 59 | { 60 | this.fconnect = new FetchConnector(this.maximoRestUrl, this.maximopath); 61 | this.fconnect.authType = this.authType; 62 | this.fconnect.authenticate(this.fconnect); 63 | } 64 | 65 | return this; 66 | } 67 | }; 68 | 69 | /** 70 | * 71 | */ 72 | ResourceSet.prototype.cookie; 73 | 74 | 75 | /** 76 | * 77 | */ 78 | ResourceSet.prototype.fconnect; 79 | 80 | 81 | /** 82 | * Returns the rdfs member only 83 | * @returns {*} 84 | */ 85 | ResourceSet.prototype.thisResourceSet = function() 86 | { 87 | return this.resourcemboset["member"]; 88 | }; 89 | 90 | /** 91 | * Returns the complete JSON i.e all top level OR sets this set and returns the new set. 92 | * @param resourcemboset 93 | * @returns {*} 94 | */ 95 | ResourceSet.prototype.JSON = function(resourcemboset) 96 | { 97 | if (resourcemboset != null) 98 | { 99 | this.resourcemboset = resourcemboset; 100 | } 101 | return this.resourcemboset; 102 | }; 103 | 104 | 105 | /** 106 | * 107 | * @param datacallback 108 | * @returns {*} 109 | */ 110 | ResourceSet.prototype.fetch = function(datacallback) 111 | { 112 | return getFetchConnector(this).__fetch(this.fconnect); // Pass this.fconnect so the it's state is updated. 113 | } 114 | 115 | /** 116 | * 117 | * @param datacallback 118 | * @returns {*} 119 | */ 120 | ResourceSet.prototype.schema = function(datacallback) 121 | { 122 | return getSchemaConnector(this).__fetch(this.sconnect); // Pass this.sconnect so the it's state is updated. 123 | } 124 | 125 | /** 126 | * 127 | * @param datacallback 128 | * @returns {*} 129 | */ 130 | ResourceSet.prototype.schemarelated = function(datacallback) 131 | { 132 | return getSchemaRelatedConnector(this).__fetch(this.sconnect); // Pass this.sconnect so the it's state is updated. 133 | } 134 | 135 | /** 136 | * 137 | * @param np 138 | * @param datacallback 139 | * @returns {*} 140 | */ 141 | ResourceSet.prototype.nextpage = function(np,datacallback) 142 | { 143 | return getFetchConnector(this).__fetchnext(np,this.fconnect); // Pass this.fconnect so the it's state is updated. 144 | } 145 | 146 | /** 147 | * 148 | * @param i 149 | * @returns {Resource} 150 | */ 151 | ResourceSet.prototype.resource = function(i) 152 | { 153 | //console.log("Index type "+typeof(i)); 154 | 155 | var connex = (this.cookie ? this.cookie : this.maximoRestUrl); 156 | if(typeof(i) === "number") //Strictly a number type and we assume this set contains members 157 | { 158 | return new Resource(this.resourcemboset["rdfs:member"][i],this.cookie); 159 | } 160 | //console.log("THIS COOKIE "+this.maximoRestUrl); 161 | //console.log("THIS COOKIE "+i); 162 | //console.log("CONNEX: "+connex); 163 | //console.log("CONNEX: "+typeof(connex)); 164 | // Most likely a URL so we will have to fetch/update/delete/invoke 165 | var res = new Resource(i,connex); 166 | if(this.cookie) 167 | { 168 | res.setcookie(this.cookie); 169 | } 170 | return res; 171 | 172 | }; 173 | 174 | /** 175 | * 176 | */ 177 | ResourceSet.prototype.size = function() 178 | { 179 | return this.resourcemboset["rdfs:member"].length; 180 | }; 181 | 182 | /** 183 | * 184 | * @param selects 185 | * @returns {ResourceSet} 186 | */ 187 | ResourceSet.prototype.select = function(selects) 188 | { 189 | if (selects && selects.constructor === Array) 190 | { 191 | var arrayLength = selects.length; 192 | var selectStr = ''; 193 | var relationships = {}; 194 | for (var i = 0; i < arrayLength; i++) { 195 | var wh = selects[i]; 196 | wh = (wh.indexOf(":") < 1) ? this.namespace+wh : wh //prepend the name spaces 197 | /*if(wh.indexOf(".") > 1) // check if this attribute is a relationship and construct expression 198 | { 199 | var wharray = wh.split("."); 200 | //wh = wharray[0]+"{"+this.namespace+wharray[1]+"}"; 201 | 202 | relatedset(wharray[0],this.namespace+wharray[1],relationships); 203 | }*/ 204 | selectStr = ((arrayLength - i) > 1) ? selectStr+wh+"," : selectStr+wh; 205 | } 206 | } 207 | this.select = selectStr+relationshipString(relationships); 208 | if(this.select != null && this.select != "") 209 | { 210 | this.maximopath = getMaximoPath(this.maximopath)+"oslc.select="+encodeURIComponent(this.select); 211 | } 212 | return this; 213 | } 214 | 215 | /** 216 | * 217 | * @param prop 218 | * @returns {ResourceSet} 219 | */ 220 | ResourceSet.prototype.where = function(prop) 221 | { 222 | this.where = (prop.indexOf(":") < 1) ? this.namespace+prop : prop 223 | //this.where = prop; 224 | if(this.where != null && this.where != "") 225 | { 226 | this.maximopath = (this.maximopath.indexOf("oslc.where=") > -1) 227 | ? getMaximoPath(this.maximopath)+"and"+encodeURIComponent(this.where) 228 | : getMaximoPath(this.maximopath)+"oslc.where="+encodeURIComponent(this.where); 229 | } 230 | return this; 231 | } 232 | 233 | /** 234 | * 235 | * @param str 236 | * @returns {ResourceSet} 237 | */ 238 | ResourceSet.prototype.and = function(str) 239 | { 240 | str = (str.indexOf(":") < 1) ? this.namespace+str : str 241 | this.maximopath = this.maximopath+encodeURIComponent(" and ")+encodeURIComponent(str); 242 | 243 | return this; 244 | } 245 | 246 | /** 247 | * 248 | * @param inarr 249 | * @param isint 250 | * @returns {ResourceSet} 251 | */ 252 | ResourceSet.prototype.in = function(inarr,isint) 253 | { 254 | if (inarr && inarr.constructor === Array) 255 | { 256 | var arrayLength = inarr.length; 257 | var inarrStr = ''; 258 | for (var i = 0; i < arrayLength; i++) { 259 | var inElement = inarr[i]; 260 | //inarrStr = ((arrayLength - i) > 1) ? inarrStr+'"'+inElement+'",' : inarrStr+'"'+inElement+'"'; 261 | inarrStr = isint ? (((arrayLength - i) > 1) ? inarrStr+inElement+',' : inarrStr+inElement) 262 | : (((arrayLength - i) > 1) ? inarrStr+'"'+inElement+'",' : inarrStr+'"'+inElement+'"'); 263 | } 264 | } 265 | this.maximopath = this.maximopath+encodeURIComponent(" in["+inarrStr+"]"); 266 | return this; 267 | } 268 | 269 | /** 270 | * 271 | * @param eq 272 | * @returns {ResourceSet} 273 | */ 274 | ResourceSet.prototype.equal = function(eq) 275 | { 276 | if(this.where != null && this.where != "") 277 | { 278 | //.where("spi:status").equal('"APPR"') 279 | eq = (typeof(eq) === "string") ? '"'+eq+'"' : eq; 280 | this.maximopath = this.maximopath+"="+encodeURIComponent(eq); 281 | } 282 | return this; 283 | } 284 | 285 | /** 286 | * 287 | * @param eq 288 | * @returns {ResourceSet} 289 | */ 290 | ResourceSet.prototype.notnull = function(eq) 291 | { 292 | if(this.where != null && this.where != "") 293 | { 294 | var eq = '*'; 295 | eq = (typeof(eq) === "string") ? '"'+eq+'"' : eq; 296 | this.maximopath = this.maximopath+"="+encodeURIComponent(eq); 297 | } 298 | return this; 299 | } 300 | 301 | /** 302 | * 303 | * @param oby 304 | * @param direction 305 | * @returns {ResourceSet} 306 | */ 307 | ResourceSet.prototype.orderby = function(oby,direction) 308 | { 309 | if(this.where != null && this.where != "") 310 | { 311 | oby = (oby.indexOf(":") < 1) ? this.namespace+oby : oby 312 | var ascending = direction == 'desc'? 0 : 1 313 | oby = ascending ? "+"+oby : "-"+oby; 314 | this.maximopath = this.maximopath+"&oslc.orderBy="+encodeURIComponent(oby); 315 | } 316 | return this; 317 | } 318 | 319 | /** 320 | * 321 | * @param pagesize 322 | * @returns {ResourceSet} 323 | */ 324 | ResourceSet.prototype.pagesize = function(pagesize) 325 | { 326 | this.pagesize = pagesize; 327 | if(this.pagesize != null && this.pagesize != "") 328 | { 329 | this.maximopath = getMaximoPath(this.maximopath)+"oslc.pageSize="+encodeURIComponent(this.pagesize); 330 | } 331 | return this; 332 | } 333 | 334 | /** 335 | * 336 | * @param action 337 | * @returns {ResourceSet} 338 | */ 339 | ResourceSet.prototype.action = function(action) 340 | { 341 | this.action = action; 342 | return this; 343 | } 344 | 345 | // TODO: Refactor invoke to Resource 346 | /** 347 | * 348 | * @param resource 349 | * @param datacallback 350 | * @returns {*|PromiseLike} 351 | */ 352 | ResourceSet.prototype.invoke = function(resource,datacallback) 353 | { 354 | var myurl = resource["url"]; 355 | var status = resource["status"]; 356 | var memo = resource["memo"]; 357 | var action = resource["action"]; 358 | 359 | myurl = myurl+"?action=wsmethod:"+this.action; 360 | var purl = url.parse(myurl); 361 | 362 | console.log("URL: "+purl.hostname); 363 | console.log("URL: "+purl.port); 364 | console.log("URL: "+purl.path); 365 | 366 | var deferred = Q.defer(); 367 | var returndata = ''; 368 | var client = require(this.maximoRestUrl.protocol.split(':')[0]); 369 | var statusCode = ""; 370 | var resourceset = ""; 371 | var xpublicuri = this.maximoRestUrl.protocol+"//"+this.maximoRestUrl.hostname+":"+this.maximoRestUrl.port+X_PUB_PATH; 372 | 373 | var options = { 374 | hostname: purl.hostname, 375 | port: purl.port, 376 | headers: {'MAXAUTH': new Buffer(this.maximoRestUrl.auth).toString('base64'), 377 | 'x-public-uri':xpublicuri.toString(), 378 | 'x-method-override': 'PATCH', 379 | 'content-type': 'application/json'}, 380 | path: purl.path, 381 | method: 'POST' 382 | }; 383 | 384 | var req = client.request(options, function(res) 385 | { 386 | res.setEncoding('utf8'); 387 | var resdata = ''; 388 | res.on('data', function (chunk) 389 | { 390 | resdata += chunk; 391 | }); 392 | res.on('error', function(err) 393 | { 394 | console.log('Error retrieving data... ' + err.message); 395 | deferred.reject("Error retrieving data...."+ err.message); 396 | }); 397 | res.on('end', function() 398 | { 399 | console.log("RESDATA "+resdata); 400 | //var data = JSON.parse(resdata); 401 | statusCode = res.statusCode; 402 | if (datacallback) 403 | { 404 | deferred.promise.nodeify(datacallback(statusCode,resdata,this)); 405 | } else 406 | { 407 | deferred.resolve(resdata); 408 | } 409 | //datacallback(response.statusCode,resourceset,this); //Invoke the callback and pass the data back. 410 | }); 411 | }); 412 | 413 | req.on('error', function(e) 414 | { 415 | console.log('problem with request: ' + e.message); 416 | }); 417 | 418 | 419 | req.write(JSON.stringify(resource)); 420 | req.end(); 421 | //return this;*/ 422 | return deferred.promise; 423 | } 424 | 425 | /** 426 | * 427 | * @param ops 428 | * @returns {ExternalConnector} 429 | */ 430 | ResourceSet.prototype.externalConnector = function(ops) 431 | { 432 | return new ExternalConnector(ops,this.resourcemboset["member"]); 433 | } 434 | 435 | 436 | // CRUD starts here ... 437 | 438 | /** 439 | * 440 | * @param jsonbody 441 | * @param props 442 | * @param attachments 443 | * @param datacallback 444 | * @returns {*} 445 | */ 446 | ResourceSet.prototype.create = function(jsonbody,props,attachments,datacallback) 447 | { 448 | return getCRUDConnector(this).__create(jsonbody,props,attachments,datacallback); // Pass this.fconnect so the it's state is updated. 449 | } 450 | 451 | 452 | //Private Methods 453 | 454 | 455 | // Populates the JSON (relationships) with relationships and attributes 456 | function relatedset(relname,attribute,relationships) 457 | { 458 | var length = Object.keys(relationships).length; 459 | var attrs = null; 460 | if(length > 0) // the json is not empty 461 | { 462 | attrs = relationships[relname]; 463 | } 464 | if(attrs == null) // the json is empty so pop in the first one. 465 | { 466 | relationships[relname] = [attribute]; 467 | }else 468 | { 469 | attrs.push(attribute); 470 | relationships[relname] = attrs; 471 | } 472 | //console.log("******* "+JSON.stringify(relationships)); 473 | } 474 | 475 | // Creates the relationship string 476 | function relationshipString(relationships) 477 | { 478 | var length = Object.keys(relationships).length; 479 | 480 | //spi:temeda{spi:event_description,spi:enginerpm,spi:idle_time_count} 481 | var relstr = ""; 482 | 483 | for(var attribute in relationships) 484 | { 485 | relstr = relstr+","+attribute+"{"+relationships[attribute]+"}"; 486 | } 487 | return relstr; 488 | } 489 | 490 | 491 | function getCRUDprops(props) 492 | { 493 | return props.toString(); 494 | } 495 | 496 | function getCRUDheaders(props,jsonbody,me,xmethod) 497 | { 498 | var hdrs = null; 499 | var propsStr = getCRUDprops(props); 500 | if (propsStr) 501 | { 502 | return {'MAXAUTH': new Buffer(me.maximoRestUrl.auth).toString('base64'), 503 | 'content-type': 'application/json', 504 | 'x-method-override': xmethod, 505 | 'properties': propsStr, 506 | 'body':JSON.stringify(jsonbody)} 507 | } 508 | return {'MAXAUTH': new Buffer(me.maximoRestUrl.auth).toString('base64'), 509 | 'content-type': 'application/json', 510 | 'x-method-override': xmethod, 511 | 'body':JSON.stringify(jsonbody)} 512 | } 513 | 514 | 515 | function getMaximoPath(maxpath) 516 | { 517 | return (maxpath.indexOf("?") < 1) ? maxpath+"?" : maxpath+"&"; 518 | } 519 | 520 | 521 | function getFetchConnector(me) // Singleton 522 | { 523 | if(me.fconnect == null) 524 | { 525 | me.fconnect = new FetchConnector(me.maximoRestUrl, me.maximopath); 526 | me.fconnect.authType = me.authType; 527 | me.fconnect.cookie = me.cookie; 528 | me.fconnect.isCookieSet = me.cookie == null ? false : true; 529 | } 530 | return me.fconnect; 531 | } 532 | 533 | function getSchemaConnector(me) // Singleton 534 | { 535 | if(me.sconnect == null) 536 | { 537 | me.sconnect = new SchemaConnector(me.maximoRestUrl, me.schemapath+me.mbo); 538 | me.sconnect.authType = me.authType; 539 | me.sconnect.cookie = me.cookie; 540 | me.sconnect.isCookieSet = me.cookie == null ? false : true; 541 | } 542 | return me.sconnect; 543 | } 544 | 545 | function getSchemaRelatedConnector(me) // Singleton 546 | { 547 | if(me.sconnect == null) 548 | { 549 | me.sconnect = new SchemaConnector(me.maximoRestUrl, me.schemapath+me.mbo+"?oslc.select=*"); 550 | me.sconnect.authType = me.authType; 551 | me.sconnect.cookie = me.cookie; 552 | me.sconnect.isCookieSet = me.cookie == null ? false : true; 553 | } 554 | return me.sconnect; 555 | } 556 | 557 | function getCRUDConnector(me) // Singleton 558 | { 559 | if(me.cconnect == null) 560 | { 561 | me.cconnect = new CRUDConnector(me.maximoRestUrl, me.maximopath); 562 | me.cconnect.authType = me.authType; 563 | me.cconnect.cookie = me.cookie; 564 | me.cconnect.isCookieSet = me.cookie == null ? false : true; 565 | } 566 | return me.cconnect; 567 | } 568 | --------------------------------------------------------------------------------