PDA

View Full Version : Data Reader for Jersey Web Services



krdavis
10 Jan 2008, 6:30 AM
I just started started experimenting with JSR-311 and the Jersey RI as a back end for Ext applications. The first step I stumbled on was Jersey produces Badgerfish JSON. This doesn't work with the standard Ext JSON reader. So I hacked up the following based on the original JSON reader source:


Ext.namespace('openEPRS', 'openEPRS.data');

openEPRS.data.BadgerfishReader = function(meta, recordType){
meta = meta || {};
openEPRS.data.BadgerfishReader.superclass.constructor.call(this, meta, recordType || meta.fields);
};

Ext.extend(openEPRS.data.BadgerfishReader, Ext.data.DataReader, {
read : function(response) {
var json = response.responseText;
var o = eval("("+json+")");
if(!o) {
throw {message: "BadgerfishReader.read: Json object not found"};
}
if(o.metaData) {
delete this.ef;
this.meta = o.metaData;
this.recordType = Ext.data.Record.create(o.metaData.fields);
this.onMetaChange(this.meta, this.recordType, o);
}
return this.readRecords(o);
},

onMetaChange : function(meta, recordType, o) {

},

simpleAccess: function(obj, subsc) {
return obj[subsc];
},

getJsonAccessor: function() {
var re = /[\[\.]/;
return function(expr) {
try {
return(re.test(expr))
? new Function("obj", "return obj." + expr)
: function(obj){
return obj[expr];
};
} catch(e) {}
return Ext.emptyFn;
};
}(),

readRecords : function(o) {
this.jsonData = o;
var s = this.meta, Record = this.recordType,
f = Record.prototype.fields, fi = f.items, fl = f.length;

if (!this.ef) {
if(s.totalProperty) {
this.getTotal = this.getJsonAccessor(s.totalProperty);
}
if(s.successProperty) {
this.getSuccess = this.getJsonAccessor(s.successProperty);
}
this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;};
if (s.id) {
var g = this.getJsonAccessor(s.id);
this.getId = function(rec) {
var r = g(rec);
return (r === undefined || r === "") ? null : r;
};
} else {
this.getId = function(){return null;};
}
this.ef = [];
for(var i = 0; i < fl; i++){
f = fi[i];
var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
this.ef[i] = this.getJsonAccessor(map);
}
}
var root = this.getRoot(o);
var c = (root.length == undefined) ? 1 : root.length;
var totalRecords = c;
var success = true;
if(s.totalProperty) {
var v = parseInt(this.getTotal(o), 10);
if(!isNaN(v)){
totalRecords = v;
}
}
if(s.successProperty) {
var v = this.getSuccess(o);
if(v === false || v === 'false') {
success = false;
}
}
var records = [];
for(var i = 0; i < c; i++) {
var n = (c == 1) ? root : root[i];
var values = {};
var id = this.findValue(null, this.getId(n));
var v;
for(var j = 0; j < fl; j++) {
f = fi[j];
if(f.name == '@uri' || f.mapping == '@uri' ) {
v = n['@uri'];
} else {
v = this.ef[j](n);
v = this.findValue(f.name, v);
}
values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue);
}
var record = new Record(values, id);
record.json = n;
records[i] = record;
}
return {
success : success,
records : records,
totalRecords : totalRecords
};
},

findValue : function(field, value) {
if(value == undefined)
return field;
if(value['$'] == undefined) {
var r = {};
for(var i in value) {
r[i] = value[i]['$'];
}
return r;
} else {
return value['$'];
}
}
});

I probably missed something, but it works for my needs. The Jersey developers plan to offer an option to disable Badgerfish in the future. You can visit my blog for more details here (http://www.zunisoft.com/?p=65). Enjoy or curse at your convenience!