]> git.pond.sub.org Git - eow/blobdiff - static/dojo-release-1.1.1/dojox/data/AtomReadStore.js
add Dojo 1.1.1
[eow] / static / dojo-release-1.1.1 / dojox / data / AtomReadStore.js
diff --git a/static/dojo-release-1.1.1/dojox/data/AtomReadStore.js b/static/dojo-release-1.1.1/dojox/data/AtomReadStore.js
new file mode 100644 (file)
index 0000000..2bc6920
--- /dev/null
@@ -0,0 +1,543 @@
+if(!dojo._hasResource["dojox.data.AtomReadStore"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.data.AtomReadStore"] = true;
+dojo.provide("dojox.data.AtomReadStore");
+
+dojo.require("dojo.data.util.simpleFetch");
+dojo.require("dojo.data.util.filter");
+dojo.require("dojo.date.stamp");
+
+dojo.experimental("dojox.data.AtomReadStore");
+
+dojo.declare("dojox.data.AtomReadStore", null, {
+       //      summary:
+       //              A read only data store for Atom XML based services or documents
+       //      description:
+       //              A data store for Atom XML based services or documents.  This store is still under development
+       //              and doesn't support wildcard filtering yet.  Attribute filtering is limited to category or id.
+
+       constructor: function(/* object */ args) {
+               //      summary:
+               //              Constructor for the AtomRead store.
+               //      args:
+               //              An anonymous object to initialize properties.  It expects the following values:
+               //              url:                    The url to a service or an XML document that represents the store
+               //              unescapeHTML:   A boolean to specify whether or not to unescape HTML text
+               //              sendQuery:              A boolean indicate to add a query string to the service URL
+
+               if(args){
+                       this.url = args.url;
+                       this.rewriteUrl = args.rewriteUrl;
+                       this.label = args.label || this.label;
+                       this.sendQuery = (args.sendQuery || args.sendquery || this.sendQuery);
+                       this.unescapeHTML = args.unescapeHTML;
+               }
+               if(!this.url){
+                       throw new Error("AtomReadStore: a URL must be specified when creating the data store");
+               }
+       },
+
+       //Values that may be set by the parser.
+       //Ergo, have to be instantiated to something
+       //So the parser knows how to set them.
+       url: "",
+
+       label: "title",
+
+       sendQuery: false,
+
+       unescapeHTML: false,
+
+       /* dojo.data.api.Read */
+
+       getValue: function(/* item */ item, /* attribute || attribute-name-string */ attribute, /* value? */ defaultValue){
+               //      summary:
+               //              Return an attribute value
+               //      description:
+               //              'item' must be an instance of an object created by the AtomReadStore instance.
+               //              Accepted attributes are id, subtitle, title, summary, content, author, updated,
+               //              published, category, link and alternate
+               //      item:
+               //              An item returned by a call to the 'fetch' method.
+               //      attribute:
+               //              A attribute of the Atom Entry
+               //      defaultValue:
+               //              A default value
+               //      returns:
+               //              An attribute value found, otherwise 'defaultValue'
+               this._assertIsItem(item);
+               this._assertIsAttribute(attribute);
+               this._initItem(item);
+               attribute = attribute.toLowerCase();
+               //If the attribute has previously been retrieved, then return it
+               if(!item._attribs[attribute] && !item._parsed){
+                       this._parseItem(item);
+                       item._parsed = true;
+               }
+               var retVal = item._attribs[attribute];
+
+               if(!retVal && attribute=="summary") {
+                       var content = this.getValue(item, "content");
+                       var regexp = new RegExp("/(<([^>]+)>)/g", "i");
+                       var text = content.text.replace(regexp,"");
+                       retVal = {
+                               text: text.substring(0, Math.min(400, text.length)),
+                               type: "text"
+                       };
+                       item._attribs[attribute] = retVal;
+               }
+
+               if(retVal && this.unescapeHTML){
+                       if ((attribute == "content" || attribute == "summary" || attribute == "subtitle") && !item["_"+attribute+"Escaped"]) {
+                               retVal.text = this._unescapeHTML(retVal.text);
+                               item["_"+attribute+"Escaped"] = true;
+                       }
+               }
+               return retVal ? dojo.isArray(retVal) ? retVal[0]: retVal : undefined;
+       },
+
+       getValues: function(/* item */ item, /* attribute || attribute-name-string */ attribute){
+               //      summary:
+               //              Return an attribute value
+               //      description:
+               //              'item' must be an instance of an object created by the AtomReadStore instance.
+               //              Accepted attributes are id, subtitle, title, summary, content, author, updated,
+               //              published, category, link and alternate
+               //      item:
+               //              An item returned by a call to the 'fetch' method.
+               //      attribute:
+               //              A attribute of the Atom Entry
+               //      defaultValue:
+               //              A default value
+               //      returns:
+               //              An array of values for the attribute value found, otherwise 'defaultValue'
+               this._assertIsItem(item);
+               this._assertIsAttribute(attribute);
+               this._initItem(item);
+               attribute = attribute.toLowerCase();
+               //If the attribute has previously been retrieved, then return it
+               if(!item._attribs[attribute]){
+                       this._parseItem(item);
+               }
+               var retVal = item._attribs[attribute];
+               return retVal ? ((retVal.length !== undefined && typeof(retVal) !== "string") ? retVal : [retVal]) : undefined;
+       },
+
+       getAttributes: function(/* item */ item) {
+               //      summary:
+               //              Return an array of attribute names
+               //      description:
+               //              'item' must be have been created by the AtomReadStore instance.
+               //              tag names of child elements and XML attribute names of attributes
+               //              specified to the element are returned along with special attribute
+               //              names applicable to the element including "tagName", "childNodes"
+               //              if the element has child elements, "text()" if the element has
+               //              child text nodes, and attribute names in '_attributeMap' that match
+               //              the tag name of the element.
+               //      item:
+               //              An XML element
+               //      returns:
+               //              An array of attributes found
+               this._assertIsItem(item);
+               if(!item._attribs){
+                       this._initItem(item);
+                       this._parseItem(item);
+               }
+               var attrNames = [];
+               for(var x in item._attribs){
+                       attrNames.push(x);
+               }
+               return attrNames; //array
+       },
+
+       hasAttribute: function(/* item */ item, /* attribute || attribute-name-string */ attribute){
+               //      summary:
+               //              Check whether an element has the attribute
+               //      item:
+               //              'item' must be created by the AtomReadStore instance.
+               //      attribute:
+               //              An attribute of an Atom Entry item.
+               //      returns:
+               //              True if the element has the attribute, otherwise false
+               return (this.getValue(item, attribute) !== undefined); //boolean
+       },
+
+       containsValue: function(/* item */ item, /* attribute || attribute-name-string */ attribute, /* anything */ value){
+               //      summary:
+               //              Check whether the attribute values contain the value
+               //      item:
+               //              'item' must be an instance of a dojox.data.XmlItem from the store instance.
+               //      attribute:
+               //              A tag name of a child element, An XML attribute name or one of
+               //              special names
+               //      returns:
+               //              True if the attribute values contain the value, otherwise false
+               var values = this.getValues(item, attribute);
+               for(var i = 0; i < values.length; i++){
+                       if((typeof value === "string")){
+                               if(values[i].toString && values[i].toString() === value){
+                                       return true;
+                               }
+                       }else if (values[i] === value){
+                               return true; //boolean
+                       }
+               }
+               return false;//boolean
+       },
+
+       isItem: function(/* anything */ something){
+               //      summary:
+               //              Check whether the object is an item (XML element)
+               //      item:
+               //              An object to check
+               //      returns:
+               //              True if the object is an XML element, otherwise false
+               if(something && something.element && something.store && something.store === this){
+                       return true; //boolean
+               }
+               return false; //boolran
+       },
+
+       isItemLoaded: function(/* anything */ something){
+               //      summary:
+               //              Check whether the object is an item (XML element) and loaded
+               //      item:
+               //              An object to check
+               //      returns:
+               //              True if the object is an XML element, otherwise false
+               return this.isItem(something); //boolean
+       },
+
+       loadItem: function(/* object */ keywordArgs){
+               //      summary:
+               //              Load an item (XML element)
+               //      keywordArgs:
+               //              object containing the args for loadItem.  See dojo.data.api.Read.loadItem()
+       },
+
+       getFeatures: function() {
+               //      summary:
+               //              Return supported data APIs
+               //      returns:
+               //              "dojo.data.api.Read" and "dojo.data.api.Write"
+               var features = {
+                       "dojo.data.api.Read": true
+               };
+               return features; //array
+       },
+
+       getLabel: function(/* item */ item){
+               //      summary:
+               //              See dojo.data.api.Read.getLabel()
+               if((this.label !== "") && this.isItem(item)){
+                       var label = this.getValue(item,this.label);
+                       if(label && label.text){
+                               return label.text;
+                       }else if (label){
+                               return label.toString();
+                       }else{
+                               return undefined;
+                       }
+               }
+               return undefined; //undefined
+       },
+
+       getLabelAttributes: function(/* item */ item){
+               //      summary:
+               //              See dojo.data.api.Read.getLabelAttributes()
+               if(this.label !== ""){
+                       return [this.label]; //array
+               }
+               return null; //null
+       },
+
+       getFeedValue: function(attribute, defaultValue){
+               // summary:
+               //              Non-API method for retrieving values regarding the Atom feed,
+               //              rather than the Atom entries.
+               var values = this.getFeedValues(attribute, defaultValue);
+               if(dojo.isArray(values)){
+                       return values[0];
+               }
+               return values;
+       },
+
+       getFeedValues: function(attribute, defaultValue){
+               // summary:
+               //              Non-API method for retrieving values regarding the Atom feed,
+               //              rather than the Atom entries.
+               if(!this.doc){
+                       return defaultValue;
+               }
+               if(!this._feedMetaData){
+                       this._feedMetaData = {
+                               element: this.doc.getElementsByTagName("feed")[0],
+                               store: this,
+                               _attribs: {}
+                       };
+                       this._parseItem(this._feedMetaData);
+               }
+               return this._feedMetaData._attribs[attribute] || defaultValue;
+       },
+
+       _initItem: function(item){
+               // summary:
+               //              Initializes an item before it can be parsed.
+               if(!item._attribs){
+                       item._attribs = {};
+               }
+       },
+
+       _fetchItems: function(request, fetchHandler, errorHandler) {
+               // summary:
+               //              Retrieves the items from the Atom XML document.
+               var url = this._getFetchUrl(request);
+               if(!url){
+                       errorHandler(new Error("No URL specified."));
+                       return;
+               }
+               var localRequest = (!this.sendQuery ? request : null); // use request for _getItems()
+
+               var _this = this;
+               var docHandler = function(data){
+                       _this.doc = data;
+                       var items = _this._getItems(data, localRequest);
+                       var query = request.query;
+                       if(query) {
+                               if(query.id) {
+                                       items = dojo.filter(items, function(item){
+                                               return (_this.getValue(item, "id") == query.id);
+                                       });
+                               } else if(query.category){
+                                       items = dojo.filter(items, function(entry) {
+                                               var cats = _this.getValues(entry, "category");
+                                               if(!cats){
+                                                       return false;
+                                               }
+                                               return dojo.some(cats, "return item.term=='"+query.category+"'");
+                                       });
+                               }
+                       }
+
+                       if (items && items.length > 0) {
+                               fetchHandler(items, request);
+                       }
+                       else {
+                               fetchHandler([], request);
+                       }
+               };
+
+               if (this.doc) {
+                       docHandler(this.doc);
+               }else{
+                       var getArgs = {
+                               url: url,
+                               handleAs: "xml"//,
+                       //      preventCache: true
+                       };
+                       var getHandler = dojo.xhrGet(getArgs);
+                       getHandler.addCallback(docHandler);
+
+                       getHandler.addErrback(function(data){
+                               errorHandler(data, request);
+                       });
+               }
+       },
+
+       _getFetchUrl: function(request){
+               if(!this.sendQuery){
+                       return this.url;
+               }
+               var query = request.query;
+               if(!query){
+                       return this.url;
+               }
+               if(dojo.isString(query)){
+                       return this.url + query;
+               }
+               var queryString = "";
+               for(var name in query){
+                       var value = query[name];
+                       if(value){
+                               if(queryString){
+                                       queryString += "&";
+                               }
+                               queryString += (name + "=" + value);
+                       }
+               }
+               if(!queryString){
+                       return this.url;
+               }
+               //Check to see if the URL already has query params or not.
+               var fullUrl = this.url;
+               if(fullUrl.indexOf("?") < 0){
+                       fullUrl += "?";
+               }else{
+                       fullUrl += "&";
+               }
+               return fullUrl + queryString;
+       },
+
+       _getItems: function(document, request) {
+               // summary:
+               //              Parses the document in a first pass
+               if(this._items){
+                       return this._items;
+               }
+               var items = [];
+               var nodes = [];
+               
+               if(document.childNodes.length < 1){
+                       this._items = items;
+                       console.log("dojox.data.AtomReadStore: Received an invalid Atom document. Check the content type header");
+                       return items;
+               }
+               
+               var feedNodes = dojo.filter(document.childNodes, "return item.tagName && item.tagName.toLowerCase() == 'feed'");
+
+               var query = request.query;
+
+               if(!feedNodes || feedNodes.length != 1){
+                       console.log("dojox.data.AtomReadStore: Received an invalid Atom document, number of feed tags = " + (feedNodes? feedNodes.length : 0));
+                       return items;
+               }
+
+               nodes = dojo.filter(feedNodes[0].childNodes, "return item.tagName && item.tagName.toLowerCase() == 'entry'");
+
+               if(request.onBegin){
+                       request.onBegin(nodes.length);
+               }
+
+               for(var i = 0; i < nodes.length; i++){
+                       var node = nodes[i];
+                       if(node.nodeType != 1 /*ELEMENT_NODE*/){
+                               continue;
+                       }
+                       items.push(this._getItem(node));
+               }
+               this._items = items;
+               return items;
+       },
+
+       close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
+                //     summary:
+                //             See dojo.data.api.Read.close()
+       },
+
+/* internal API */
+
+       _getItem: function(element){
+               return {
+                       element: element,
+                       store: this
+               };
+       },
+
+       _parseItem: function(item) {
+               var attribs = item._attribs;
+               var _this = this;
+               var text, type;
+
+               function getNodeText(node){
+                       var txt = node.textContent || node.innerHTML || node.innerXML;                  
+                       if(!txt && node.childNodes[0]){
+                               var child = node.childNodes[0];
+                               if (child && (child.nodeType == 3 || child.nodeType == 4)) {
+                                       txt = node.childNodes[0].nodeValue;
+                               }
+                       }
+                       return txt;
+               }
+               function parseTextAndType(node) {
+                       return {text: getNodeText(node),type: node.getAttribute("type")};
+               }
+               dojo.forEach(item.element.childNodes, function(node){
+                       var tagName = node.tagName ? node.tagName.toLowerCase() : "";
+                       switch(tagName){
+                               case "title":
+                                       attribs[tagName] = {
+                                               text: getNodeText(node),
+                                               type: node.getAttribute("type")
+                                       }; break;
+                               case "subtitle":
+                               case "summary":
+                               case "content":
+                                       attribs[tagName] = parseTextAndType(node);
+                                       break;
+                               case "author":
+                                       var nameNode ,uriNode;
+                                       dojo.forEach(node.childNodes, function(child){
+                                               if(!child.tagName){
+                                                       return;
+                                               }
+                                               switch(child.tagName.toLowerCase()){
+                                                       case "name":nameNode = child;break;
+                                                       case "uri": uriNode = child; break;
+                                               }
+                                       });
+                                       var author = {};
+                                       if(nameNode && nameNode.length == 1){
+                                               author.name = getNodeText(nameNode[0]);
+                                       }
+                                       if(uriNode && uriNode.length == 1){
+                                               author.uri = getNodeText(uriNode[0]);
+                                       }
+                                       attribs[tagName] = author;
+                                       break;
+                               case "id": attribs[tagName] = getNodeText(node); break;
+                               case "updated": attribs[tagName] = dojo.date.stamp.fromISOString(getNodeText(node) );break;
+                               case "published": attribs[tagName] = dojo.date.stamp.fromISOString(getNodeText(node));break;
+                               case "category":
+                                       if(!attribs[tagName]){
+                                               attribs[tagName] = [];
+                                       }
+                                       attribs[tagName].push({scheme:node.getAttribute("scheme"), term: node.getAttribute("term")});
+                                       break;
+                               case "link":
+                                       if(!attribs[tagName]){
+                                               attribs[tagName] = [];
+                                       }
+                                       var link = {
+                                               rel: node.getAttribute("rel"),
+                                               href: node.getAttribute("href"),
+                                               type: node.getAttribute("type")};
+                                       attribs[tagName].push(link);
+
+                                       if(link.rel == "alternate") {
+                                               attribs["alternate"] = link;
+                                       }
+                                       break;
+                               default:
+                                       break;
+                       }
+               });
+       },
+
+       _unescapeHTML : function(text) {
+               //Replace HTML character codes with their unencoded equivalents, e.g. &#8217; with '
+               text = text.replace(/&#8217;/m , "'").replace(/&#8243;/m , "\"").replace(/&#60;/m,">").replace(/&#62;/m,"<").replace(/&#38;/m,"&");
+               return text;
+       },
+
+       _assertIsItem: function(/* item */ item){
+               //      summary:
+               //              This function tests whether the item passed in is indeed an item in the store.
+               //      item: 
+               //              The item to test for being contained by the store.
+               if(!this.isItem(item)){ 
+                       throw new Error("dojox.data.AtomReadStore: Invalid item argument.");
+               }
+       },
+
+       _assertIsAttribute: function(/* attribute-name-string */ attribute){
+               //      summary:
+               //              This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
+               //      attribute: 
+               //              The attribute to test for being contained by the store.
+               if(typeof attribute !== "string"){ 
+                       throw new Error("dojox.data.AtomReadStore: Invalid attribute argument.");
+               }
+       }
+});
+dojo.extend(dojox.data.AtomReadStore,dojo.data.util.simpleFetch);
+
+}