Skip to content
Browse files

Using log4js framework for Logging.

New tests pass
  • Loading branch information...
1 parent c389c91 commit 43c012758faa78acdc3434d2f4de958d8f6902c7 @nka11 nka11 committed Jul 6, 2011
Showing with 246 additions and 92 deletions.
  1. +2 −1 README.md
  2. +9 −0 conf/log4js.json
  3. +1 −1 node_modules/NoCR
  4. +3 −1 src/Item.js
  5. +131 −24 src/Node.js
  6. +9 −7 src/Repository.js
  7. +9 −5 src/Session.js
  8. +79 −51 src/Workspace.js
  9. +1 −1 src/types/NodeType.js
  10. +2 −1 test/testSuite.js
View
3 README.md
@@ -7,9 +7,10 @@ KaraCos-NoCR-MongoDB is a content repository implementing the NoCR API, a JCR c
### Requirements
* mongodb
+* log4js
```
-npm install mongodb
+npm install mongodb log4js
```
### Grab submodules
View
9 conf/log4js.json
@@ -0,0 +1,9 @@
+{ "appenders": [
+ {
+ "type": "console"
+ }
+ ],
+ "levels": {
+ "nocr-mongo.*": "INFO"
+ }
+}
2 node_modules/NoCR
@@ -1 +1 @@
-Subproject commit eaaf5f611e2ddacfa7c7448b149f94b8ca06818a
+Subproject commit df315d8e167d84ac82f47cd40ff2ef3bbbe24f52
View
4 src/Item.js
@@ -1,5 +1,6 @@
var nocr = require("NoCR"),
_ = require('util'),
+ log4js = require('log4js')(),
wrapper = require('./wrapper.js'),
assert = require('assert'),
Item, itemproto;
@@ -12,7 +13,7 @@ itemproto = {
}
};
function Item(data, session) {
- var k;
+ var k, self = this;
assert.ok((session instanceof nocr.Session), "Missing argument, session is not specified");
this.getPath = function() {
return this.data.path;
@@ -26,6 +27,7 @@ function Item(data, session) {
this.isnew = true;
this.ismodified = true;
}
+ self.logger = log4js.getLogger("nocr-mongo.Workspace." + data._id);
//_.debug(_.inspect(session));
//_.debug(_.inspect(nocr.Session));
for (k in itemproto) {
View
155 src/Node.js
@@ -1,26 +1,31 @@
var nocr = require("NoCR"),
_ = require('util'),
assert = require('assert'),
+ log4js = require('log4js')(),
wrapper = require('./wrapper.js'),
Item = require('./Item.js'),
itemslookup = require('./utils/itemslookup.js'),
Node, nodeproto,
Property = require('./Property.js'),
+ nodeTypeManager = require('./types/nodeTypeManager.js'),
Value = require('./Value.js');
/**
-
* @param data
*/
nodeproto = {
getIdentifier: function() {
return this.data._id.toString();
},
+ /**
+ * Can accept callback func or not, as operations are performed in-memory, there is no async
+ */
getProperty: function(name, callback) {
var self = this, errmsg;
if (name in self['properties']) {
- _.debug('[getProperty]: found in instances');
+ _.debug('[getProperty]: found in instances'); // memory cache L1
if (typeof callback !== "undefined") {
+ //_.debug(_.inspect(self['properties'][name]));
callback(null, self['properties'][name]);
} else {
return self['properties'][name];
@@ -45,9 +50,12 @@ nodeproto = {
}
}
},
+ /**
+ * Can accept callback func or not, as operations are performed in-memory, there is no async
+ */
setProperty: function(name, value, type, callback) {
//_.debug("[setProperty]: " + _.inspect(arguments));
- var self = this, type,error;
+ var self = this, type,error, prop;
if (arguments.length === 0) {
throw new Error("at least name should be specified");
}
@@ -63,6 +71,9 @@ nodeproto = {
type = undefined;
}
}
+ if (callback === undefined ) {
+ callback = function(){};
+ }
//
// TODO: ACL check for writing
//
@@ -73,28 +84,30 @@ nodeproto = {
}
if (self.type.canSetProperty(name, value)) {
self.ismodified = true;
+ //_.debug(_.inspect(self));
if (name in self['node:properties'] || name in self['properties']) { //such property already exist ethier persisted or in session scope
self.getProperty(name, function(err, prop) {//gets the property instance and sets the value
if (err === null) {
- if (callback !== undefined ) {
- callback(err);
- }
+ callback(err);
} else {
prop.setValue(value);
- if (callback !== undefined ) {
callback(null, prop);
- }
}
});
} else { // probe property type and create new property
- self['properties'][name] = new Property(value, self.session);
- if (callback !== undefined ) {
- callback(null, self['properties'][name]);
- }
+ prop = new Property(value, self.session);
+ prop['data']['path'] = self.getPath() + name; //Node names always ends with /
+ //_.debug("Session scope property object " + _.inspect(prop));
+
+ // node local cache name reference
+ self['properties'][name] = prop;
+
+ // Session cache reference and path index
+ self.session.items.setItem(prop['data']['path'], prop, callback);
}
} else { // property can't be set
error = "Integrity error, can't set such propertie at such value";
- if (callback !== undefined ) {
+ if (callback !== function(){} ) {
callback(error);
} else {
throw new Error();
@@ -115,36 +128,130 @@ nodeproto = {
delete self['properties'][name];
self.ismodified = true;
} // deleting a nonexitent property have no effect
- if (callback !== undefined ) {
callback(null,undefined);
- }
}
}, // Node.setPropertypropertytest
- addNode: function(path, typename) {
- var self = this;
- if (self.type.canAddChildNode(path,typename)) {
-
+ /**
+ *
+ */
+ addNode: function(path, typename, callback) {
+ var self = this,
+ data,
+ node,
+ parent,
+ pathcheck = path.split('/'), pchecklen, pchkid,
+ pabspath; // supposed parent relative path (if not self)
+ /**
+ * Throws an error if either no child type is applicable or
+ * more than on type match.
+ */
+ function guessChildType(parent, path) {
+ var childNodesDef = parent.type.getChildNodeDefinitions(),
+ childTypeNames = [];
+ childNodesDef.forEach(function(propdef) {
+ var
+ restr = "^" + propdef['jcr:name'] + "$",
+ re = new RegExp(restr);
+ if (re.test(childName)) {
+ propdef['jcr:requiredPrimaryTypes'].forEach(function(typename, i) {
+ if (!nodeTypeManager.getNodeType(typename).isAbstract()) {
+ childTypeName.push(typename);
+ }
+ });
+ }
+ });
+ if (childTypeNames.length === 1) {
+ return childTypeNames[0];
+ } else {
+ throw new Error("Definiton problem, childNode type cannot be determined");
+ }
+ } // ---------------------- /function --------------------
+
+ function processAddNode(childName, parent) {
+ if (parent.type.canAddChildNode(path,typename)) {
+ if (typename === undefined) {
+ typename = guessChildType(path);
+ }
+ node = new Node({
+ 'path': parent.getPath() + childName + '/', // Implementation data, Index
+ 'node:type': 'nt:unstructured' // implementation reference
+ }, self.session);
+ //_.debug(_.inspect(node));
+
+ // parent node by name index
+ parent['childrens'][childName] = node;
+ // Session cache reference and path index
+ parent.session.items.setItem(node['data']['path'], node, callback);
+ node.setProperty('nt:primaryType', // Setting this default property which will be required all times
+ new Value({
+ 'property:value':typename,
+ 'property:type': 'NAME'
+ })
+ );
+ //_.debug(_.inspect(node));
+ } else {
+ throw new Error("Integrity problem, Operation addNode can't be performed");
+ }
+ } // ---------------------- /function --------------------
+
+ pchecklen = pathcheck.length;
+ if (pchecklen === 0){
+ throw new Error("Invalid path");
+ } else if (pchecklen === 1) {
+ processAddNode(pathcheck[0], self);
} else {
- throw new Error("Operation addNode can't be performed");
+
+ pabspath = "";
+ for (pcheckid = 0; pchkid++ < pchecklen -1; pcheckid++) {
+ pabspath = pabspath + pathcheck[pcheckid] + '/';
+ }
+ self.getNode(pabspath, function(err, node) {
+ if (err !== null) {
+ callback(err);
+ } else {
+ processAddNode(pathcheck[pchecklen -1], node);
+ }
+ });
}
+ },
+ getNode: function(path, callback) {
+ var pabspath,
+ self = this;
+ pabspath = self.getPath() + path;
+ if (pabspath[pabspath.length-1] !== "/") {
+ pabspath = pabspath + "/";
+ }
+ self.session.getNode(pabspath, function(err, node) {
+ self.logger.trace("Item at " + pabspath + ' : ' + _.inspect(node));
+ if (err !== null) {
+ self.logger.error(err);
+ callback(err);
+ }else {
+ if (node instanceof nocr.Node) {
+ callback(err, node);
+ } else {
+ callback("Invalid parent found");
+ }
+ }
+ });
+
}
};
function Node(data, session) {
var self = this,
workspace = session.getWorkspace();
- Item.call(self, data, session);
//_.debug("Initializing Node :" + _.inspect(data));
self['properties'] = {}; // data structure for properties instance (lazy load)
self['childrens'] = {}; //data structure for nodes instances (lazy load)
- if (!'node:properties' in data) {
+ if (!'node:properties' in data || data['node:properties'] === undefined) {
data['node:properties'] = {}; //data reference map
}
- if (!'node:childrens' in data) {
+ if (!'node:childrens' in data || data['node:childrens'] === undefined) {
data['node:childrens'] = {};
}
-
self['node:properties'] = data['node:properties'];
self['node:childrens'] = data['node:childrens'];
+ Item.call(self, data, session);
if (data['node:properties:' + workspace.getName()] !== undefined) {
for (k in data['node:properties:' + workspace.getName()]) {
self['node:properties'][k] = data['node:properties:' + workspace.getName()][k];
View
16 src/Repository.js
@@ -1,5 +1,6 @@
var nocr = require("NoCR"),
_ = require('util'),
+ log4js = require('log4js')(),
wrapper = require('./wrapper.js'),
Session = require('./Session.js'),
Node = require('./Node.js'),
@@ -66,11 +67,11 @@ function Repository(config, callback) {
this.drop = function(callback) {
self.client.dropDatabase(function(err, done) {
if (err !== null) {
- _.debug('fail removing database');
+ self.logger.debug('fail removing database');
callback(err,done);
} else {
console.log(done);
- _.debug('database removed successfully');
+ self.logger.debug('database removed successfully');
self.client.close();
callback(null,"Database drop command successful, repository deleted");
}
@@ -89,7 +90,7 @@ function Repository(config, callback) {
'property:type':'NAME',
'property:value': 'nt:unstructured'
}, {safe: true}, function(err, property) {
- _.debug(_.inspect(property));
+ self.logger.debug(_.inspect(property));
collection.insert({
'item:type': 'Node',
'node:type': 'nt:unstructured', //implementation specific shortcut to primaryNodeType property
@@ -127,10 +128,11 @@ function Repository(config, callback) {
objectId = dataId;
}
- _.debug("Searching for id : " + objectId);
+ self.logger.debug("Searching for id : " + objectId);
getItemsCollection(function(err, itemsCollection){
itemsCollection.find({"_id":objectId}).limit(1).toArray(function(err, item){
- _.debug("Search for id : " + objectId + " found data :" + _.inspect(item[0]));
+ self.logger.debug("Search for id : " + objectId);
+ self.logger.trace(" found data :" + _.inspect(item[0]));
callback(err, item[0]);
});
@@ -141,13 +143,13 @@ function Repository(config, callback) {
wrapper.getClient(config.db, function(err, client){
if (err === null) {
self.client = client;
- //console.log(self);
callback(null, self);
} else {
- _.error(err);
+ self.logger.error(err);
callback(err);
}
});
+ self.logger = log4js.getLogger("nocr-mongo.Repository." + config.db.dbname);
}
Repository.prototype = {
View
14 src/Session.js
@@ -1,5 +1,6 @@
var nocr = require("NoCR"),
_ = require('util'),
+ log4js = require('log4js')(),
wrapper = require('./wrapper.js'),
Node = require('./Node.js'),
Workspace = require('./Workspace.js'),
@@ -27,6 +28,7 @@ Session = function(repository, credentials, callback) {
});
}
function setUserContext(){
+ self.logger = log4js.getLogger("nocr-mongo.Session." + self.user.username);
client.collection('repository.workspaces', function(err, collection) {
workspaces = collection;
workspaces.count(function(err, count) {
@@ -59,11 +61,12 @@ Session = function(repository, credentials, callback) {
if(err) {
callback(err, null);
} else if(user) {
- _.debug("user found :" + _.inspect(users));
+ self.logger.debug("user found :" + _.inspect(users));
if (user.password === credentials.password) {
self.user = {username:user.username, id: user.userid, workspace:user.workspace};
setUserContext();
} else {
+ self.logger = log4js.getLogger("nocr-mongo.Session.INVALID");
callback("User not found in Domain");
}
@@ -79,13 +82,13 @@ Session = function(repository, credentials, callback) {
*/
function validateAuth() {
if (credentials === null) {
- _.debug('No credentials provided, providing anonymous user');
+ self.logger.debug('No credentials provided, providing anonymous user');
setAnonymous();
callback(null, self);
} else {
- _.debug("credentials != null :" + _.inspect(credentials));
+ self.logger.debug("credentials != null :" + _.inspect(credentials));
if (credentials.username !== undefined || credentials.username !== null) {
- _.debug("credentials provided :" + _.inspect(credentials));
+ self.logger.debug("credentials provided :" + _.inspect(credentials));
usersCollection.find({username: credentials.username}).limit(1).
toArray(checkUserAuth);
} else {
@@ -98,13 +101,14 @@ Session = function(repository, credentials, callback) {
* session initialization
*/
function initSession() {
+ self.logger = log4js.getLogger("nocr-mongo.Session.INITIALIZE");
if (credentials === undefined) {credentials = null;}
self.repository = repository;
function processUsersCollection(err, collection) {
collection.count(function(err, count) {
usersCollection = collection;
if (count === 0) {
- _.debug('No user found in db, creating defaults: anonymous and admin');
+ self.logger.debug('No user found in db, creating defaults: anonymous and admin');
collection.createIndex([['username', 1]], true, function(err, result) {
collection.save(
[{'username':'admin','password': 'demo', userid: 0,workspace:'admin'},
View
130 src/Workspace.js
@@ -1,5 +1,6 @@
var nocr = require("NoCR"),
_ = require('util'),
+ log4js = require('log4js')(),
wrapper = require('./wrapper.js'),
Node = require('./Node.js'),
Workspace, populateWorkspace, wsproto;
@@ -28,6 +29,7 @@ function Workspace(session, data, callback) {
data = {name: 'default'};
}
self.name = data.name;
+ self.logger = log4js.getLogger("nocr-mongo.Workspace." + self.name);
self.session = session;
callback(null, self);
for (k in wsproto) {
@@ -87,7 +89,7 @@ function Workspace(session, data, callback) {
function populateWorkspace(itemsIndex, callback) {
function indexRootNode(err, rootNodeData) {
var rootNode = new Node(rootNodeData, session);
- _.debug("Indexing rootNode");
+ self.logger.debug("Indexing rootNode");
//_.log(_.inspect(rootNode));
itemsIndex.insert({
'item:id': rootNode.data._id.toString(),
@@ -109,74 +111,100 @@ function Workspace(session, data, callback) {
}
/**
* Cache object for nodes instances
- //TODO: this is a raw in-memory cache.
+ //TODO: this is a raw in-memory cache. for current session
// It may use some library dependency and/or allow a shared cache (if it make sense ?).
// anyway, it can be overridden by top-level caller for the most flexible use.
*/
- self.nodes = {
+ session.items = {
data: {},
+ setItem: function(abspath, item, callback) {
+ this.data[item.getPath()] = item;
+ if (typeof callback === "function")
+ callback(null, item);
+ },
+ getItem: function(abspath,callback) {
+ self.logger.debug("getting " + abspath);
+ //self.logger.trace(_.inspect(this.data));
+ if (abspath in this.data && this.data[abspath] !== undefined) {
+ callback(null, this.data[abspath]);
+ } else {
+ callback("Item not found in cache");
+ }
+ }
+ };
+ self.nodes = {
setNode: function(abspath, node, callback) {
- this.data[node.getPath()] = node;
- callback(null, node);
+ session.items.setItem(node.getPath(), node,callback);
},
getNode: function(abspath,callback) {
- callback(null, this.data[abspath]);
+ session.items.getItem(abspath, callback);
}
};
self.properties = {
- data: {},
setProperty: function(abspath, property, callback) {
- this.data[property.getPath()] = property;
- callback(null, node);
+ session.items.setItem(property.getPath(),callback);
},
getProperty: function(abspath,callback) {
- callback(null, this.data[abspath]);
+ session.items.getItem(abspath, callback);
}
};
+ // Defining session access methods here..
session.getItem = function(abspath,callback) {
- getItemsIndex(function(err, itemsIndex){
- itemsIndex.find({'item:path': abspath}).toArray(function(err, items){
- if (err !== null) {
- callback(err);
- }
- if (items.length === 1) {
- _.debug('Found Index : ' + _.inspect(items[0]));
- if (items[0]['item:type'] === 'Node') {
- self.nodes.getNode(abspath, function(err, node) {
- if (node !== undefined) {
- callback(null,node);
- } else {
- repository.getDataById(items[0]['item:id'], getInstanciateNode(abspath, callback));
+ session.items.getItem(abspath, function(err, item) {
+ if (item !== undefined) {
+ callback(err, item);
+ } else {
+ getItemsIndex(function(err, itemsIndex){
+ itemsIndex.find({'item:path': abspath}).toArray(function(err, items){
+ if (err !== null) {
+ callback(err);
+ }
+ if (items.length === 1) {
+ self.logger.debug('Found Index : ' + _.inspect(items[0]));
+ if (items[0]['item:type'] === 'Node') {
+ self.nodes.getNode(abspath, function(err, node) {
+ if (node !== undefined) {
+ callback(null,node);
+ } else {
+ repository.getDataById(items[0]['item:id'], getInstanciateNode(abspath, callback));
+ }
+ });
+ } else if (items[0]['item:type'] === 'Property') { // This is an Property
+ self.properties.getProperty(abspath, function(err, property) {
+ if (property !== undefined) {
+ callback(null,property);
+ } else {
+ repository.getDataById(items[0]['item:id'], getInstanciateProperty(abspath, callback));
+ }
+ });
}
- });
- } else if (items[0]['item:type'] === 'Property') { // This is an Property
- self.properties.getProperty(abspath, function(err, property) {
- if (property !== undefined) {
- callback(null,property);
- } else {
- repository.getDataById(items[0]['item:id'], getInstanciateProperty(abspath, callback));
- }
- });
- }
- } else if (items.length === 0) {
- callback("No Item found at path " + abspath,undefined);
- } else {
- callback("More than one item with the same abspath");
- }
- });
+ } else if (items.length === 0) {
+ callback("No Item found at path " + abspath,undefined);
+ } else {
+ callback("More than one item with the same abspath");
+ }
+ });
+ });
+ }
});
};
session.itemExists = function(abspath, callback) {
- getItemsIndex(function(err, itemsIndex){
- itemsIndex.find({'item:path': abspath, 'item:type':'Node'}).toArray(function(err, items){
- if (items.length === 1) {
- callback(null, true);
- } else if (items.length === 0) {
- callback(null, false);
- } else {
- callback("Integrity problem");
- }
- });
+ session.items.getItem(abspath, function(err, item) {
+ if (item !== undefined) {
+ callback(null, true);
+ } else {
+ getItemsIndex(function(err, itemsIndex){
+ itemsIndex.find({'item:path': abspath, 'item:type':'Node'}).toArray(function(err, items){
+ if (items.length === 1) {
+ callback(null, true);
+ } else if (items.length === 0) {
+ callback(null, false);
+ } else {
+ callback("Integrity problem");
+ }
+ });
+ });
+ }
});
};
session.getNode = function(abspath,callback) {
@@ -190,7 +218,7 @@ function Workspace(session, data, callback) {
callback(err);
}
if (items.length === 1) {
- _.debug('Found Index : ' + _.inspect(items[0]));
+ self.logger.debug('Found Index : ' + _.inspect(items[0]));
repository.getDataById(items[0]['item:id'], getInstanciateNode(abspath, callback));
} else if (items.length === 0) {
callback("No Node found at path " + abspath,undefined);
@@ -218,7 +246,7 @@ function Workspace(session, data, callback) {
session.getNodeByIdentifier = function(nodeId, callback) {
getItemsIndex(function(err, itemsIndex){
itemsIndex.find({'item:id': nodeId, 'item:type': 'Node'}).toArray(function(err, items){
- _.debug("found item :" + _.inspect(items));
+ self.logger.debug("found item :" + _.inspect(items));
if (items.length === 1) {
repository.getDataById(nodeId, getInstanciateNode(items[0]['path'], callback));
} else if (items.length === 0) {
View
2 src/types/NodeType.js
@@ -143,7 +143,7 @@ ntproto = {
return result;
},
getChildNodeDefinitions: function() {
-
+ return self['data']['jcr:childNodeDefinition'];
},
getDeclaredSubtypes: function() {
View
3 test/testSuite.js
@@ -1,12 +1,13 @@
var Repository = require('../src/Repository.js'),
nocr = require("NoCR"),
vows = require('vows'),
+ log4js = require('log4js')(),
assert = require('assert'),
testSuite, testrepository,
_ = require('util')
// This is the coffee test compiled in js
,nocrTests = nocr.test.ImplTest;
-
+log4js.configure('./conf/log4js.json');
testSuite = vows.describe('KaraCos Nu-Q test Suite');
testSuite.addBatch({
"Clearing Database": {

0 comments on commit 43c0127

Please sign in to comment.
Something went wrong with that request. Please try again.