Skip to content
This repository has been archived by the owner on Sep 23, 2020. It is now read-only.

Commit

Permalink
added first prototype of a simple object manager
Browse files Browse the repository at this point in the history
  • Loading branch information
flosse committed Jan 3, 2012
1 parent 5f55d2e commit f7c3eb7
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 6 deletions.
22 changes: 22 additions & 0 deletions README.markdown
Expand Up @@ -12,6 +12,28 @@ With package manager [npm](http://npmjs.org/):

## Usage

### Manager

```coffeescript
xmpp = require "node-xmpp"
joap = require "node-xmpp-joap"

comp = new xmpp.Component
jid : "mycomponent"
password : "secret"
host : "127.0.0.1"
port : "8888"

class User
constructor: (params) ->
{ @name, @age } = params

mgr = new joap.Manager comp
mgr.addClass "User", User, ["name"]
```

### Router

```coffeescript
xmpp = require "node-xmpp"
joap = require "node-xmpp-joap"
Expand Down
73 changes: 73 additions & 0 deletions lib/Manager.coffee
@@ -0,0 +1,73 @@
events = require "events"
joap = require "node-xmpp-joap"

YOUR_NOT_AUTH = "You are not authorized"

class Manager extends events.EventEmitter

constructor: (@xmpp) ->
@classes = {}
@objects = {}
@router = new joap.Router @xmpp
@router.on "add", @onAdd
@router.on "read", @onRead

hasPermission: (jid, action, clazz) -> true

addClass: (name, creator, required=[], notWritable=[]) ->
if typeof creator is "function" and not @classes[name]?
@classes[name] = {creator:creator, required:required, notWritable:notWritable}
@objects[name] = {}
true
else false

create: (clazzName, params) ->
clazz = @classes[clazzName]
if clazz?
for r in clazz.required
return false if not params[r]?
x = new clazz.creator params
if not x.id or @objects[clazzName][x.id]?
x.id = joap.uniqueId()
@objects[clazzName][x.id] = x
"#{clazzName}@#{@router.xmpp.jid}/#{x.id}"
else false

onRead: (action, clazz, instance, iq) =>

if not @hasPermission iq.attrs.from, action.type, clazz
@router.sendError action, 403, "#{YOUR_NOT_AUTH} to read", iq

else if not clazz? or not instance? or not @objects[clazz][instance]?
@router.sendError action, 404, "The object adressed does not exist", iq

else if @objects[clazz][instance]?

res = {}
inst = @objects[clazz][instance]

if action.limits
res[k] = v for k,v of inst when k in action.limits and typeof v isnt "function"
else
res[k] = v for k,v of inst when typeof v isnt "function"
@router.sendResponse joap.serialize(res, action), iq

onAdd: (action, clazz, instance, iq) =>

if not @hasPermission iq.attrs.from, action.type, clazz
@router.sendError action, 403, "#{YOUR_NOT_AUTH} to create an instance of the class #{clazz}", iq

else if not clazz? or instance?
@router.sendError action, 405, "#{iq.attrs.to} is not a class", iq

else if not @classes[clazz]?
@router.sendError action, 404, "The class '#{clazz}' does not exist.", iq

else
address = @create clazz, action.attributes
if address is false
@router.sendError action, 406, "Invalid constructor parameters", iq
else
@router.sendResponse joap.serialize(address, action), iq

exports.Manager = Manager
2 changes: 1 addition & 1 deletion lib/Parser.coffee
Expand Up @@ -24,7 +24,7 @@ class Parser
else if xml instanceof Array
(Parser.parse c for c in xml)

else if xml instanceof ltx.Element
else if typeof xml is "object"

if Parser.isJOAPStanza xml
action = {
Expand Down
9 changes: 5 additions & 4 deletions lib/Router.coffee
Expand Up @@ -11,16 +11,17 @@ class Router extends events.EventEmitter
constructor: (@xmpp) ->
@xmpp.on "stanza", (iq) =>

if iq.name is "iq" and (joap.isJOAPStanza xml or joap.isRPCStanza xml)
if iq.name is "iq"

child = iq.children?[0]
to = iq.attrs.to
clazz = to.split('@')[0]
instance = to.split('/')[1]
action = joap.parse child

action = joap.parse child
@emit action.type, action, clazz, instance, iq
@emit "action", action, clazz, instance, iq
if action.type?
@emit action.type, action, clazz, instance, iq
@emit "action", action, clazz, instance, iq

sendError: (action, code, msg, iq) ->

Expand Down
1 change: 1 addition & 0 deletions lib/Serializer.coffee
Expand Up @@ -55,5 +55,6 @@ class Serializer
new joap.Array val
else
new joap.Struct val
else ""

exports.Serializer = Serializer
6 changes: 6 additions & 0 deletions lib/node-xmpp-joap.coffee
@@ -1,6 +1,7 @@
stanza = require("./stanza")

exports.Router = require("./Router").Router
exports.Manager = require("./Manager").Manager

exports.Attribute = stanza.Attribute
exports.Member = stanza.Member
Expand All @@ -18,3 +19,8 @@ exports.isRPCStanza = Parser.isRPCStanza
Serializer = require("./Serializer").Serializer
exports.Serializer = Serializer
exports.serialize = Serializer.serialize

exports.uniqueId = (length=8) ->
id = ""
id += Math.random().toString(36).substr(2) while id.length < length
id.substr 0, length
4 changes: 3 additions & 1 deletion spec/Serializer.spec.coffee
Expand Up @@ -8,6 +8,8 @@ describe "Serializer", ->

it "serializes basic data types", ->

(expect Serializer.serialize null ).toEqual ""
(expect Serializer.serialize undefined ).toEqual ""
(expect Serializer.serialize "foo" ).toEqual ltx.parse "<string>foo</string>"
(expect Serializer.serialize 2 ).toEqual ltx.parse "<int>2</int>"
(expect Serializer.serialize -0.3 ).toEqual ltx.parse "<double>-0.3</double>"
Expand Down Expand Up @@ -43,7 +45,7 @@ describe "Serializer", ->
(expect Serializer.serialize null, editAct).toEqual ltx.parse "<edit xmlns='jabber:iq:joap' />"
(expect Serializer.serialize addr, editAct).toEqual ltx.parse "<edit xmlns='jabber:iq:joap' >" +
"<newAddress>#{addr}</newAddress></edit>"

(expect Serializer.serialize null, delAct).toEqual ltx.parse "<delete xmlns='jabber:iq:joap' />"

searchResults = ["a", "b", "c"]
Expand Down

0 comments on commit f7c3eb7

Please sign in to comment.