OpenLayers OpenLayers

Ticket #1366: format-atom.patch

File format-atom.patch, 36.9 kB (added by sgillies, 8 months ago)
  • a/lib/OpenLayers.js

    old new  
    217217            "OpenLayers/Format/GML/Base.js", 
    218218            "OpenLayers/Format/GML/v2.js", 
    219219            "OpenLayers/Format/GML/v3.js", 
     220            "OpenLayers/Format/Atom.js", 
    220221            "OpenLayers/Format/KML.js", 
    221222            "OpenLayers/Format/GeoRSS.js", 
    222223            "OpenLayers/Format/WFS.js", 
  • /dev/null

    old new  
     1// Copyright to be assigned to OpenLayers project 
     2 
     3/** 
     4 * @requires OpenLayers/Format/XML.js 
     5 * @requires OpenLayers/Format/GML/v3.js 
     6 * @requires OpenLayers/Feature/Vector.js 
     7 */ 
     8 
     9/** 
     10 * Class: OpenLayers.Format.Atom 
     11 * Read/write Atom feeds. Create a new instance with the 
     12 *     <OpenLayers.Format.AtomFeed> constructor. 
     13 * 
     14 * Inherits from: 
     15 *  - <OpenLayers.Format.XML> 
     16 */ 
     17OpenLayers.Format.Atom = OpenLayers.Class(OpenLayers.Format.XML, { 
     18     
     19    /** 
     20     * APIProperty: atomns 
     21     * {String} Atom namespace to use. 
     22     */ 
     23    atomns: "http://www.w3.org/2005/Atom", 
     24     
     25    /** 
     26     * APIProperty: georssns 
     27     * {String} GeoRSS namespace to use.  Defaults to 
     28     *     "http://www.georss.org/georss" 
     29     */ 
     30    georssns: "http://www.georss.org/georss", 
     31         
     32    /** 
     33     * Property: gmlParse 
     34     * {Object} GML Format object for parsing features 
     35     * Non-API and only created if necessary 
     36     */ 
     37    gmlParser: null, 
     38     
     39    /** 
     40     * APIProperty: xy 
     41     * {Boolean} Order of the GML coordinate: true:(x,y) or false:(y,x) 
     42     * For GeoRSS the default is (y,x), therefore: false 
     43     */ 
     44    xy: false, 
     45     
     46    /** 
     47     * Constructor: OpenLayers.Format.AtomEntry 
     48     * Create a new parser for Atom. 
     49     * 
     50     * Parameters: 
     51     * options - {Object} An optional object whose properties will be set on 
     52     *     this instance. 
     53     */ 
     54    initialize: function(options) { 
     55        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]); 
     56    }, 
     57     
     58    /** 
     59     * APIMethod: read 
     60     * Return a list of features from an Atom feed or entry document. 
     61      
     62     * Parameters: 
     63     * doc - {Element} or {String} 
     64     * 
     65     * Returns: 
     66     * An Array of <OpenLayers.Feature.Vector>s 
     67     */ 
     68    read: function(doc) { 
     69        if (typeof doc == "string") { 
     70            doc = OpenLayers.Format.XML.prototype.read.apply(this, [doc]); 
     71        } 
     72        return this.parseFeatures(doc); 
     73    }, 
     74     
     75    /** 
     76     * APIMethod: write 
     77     * Serialize or more feature nodes to Atom documents. 
     78     * 
     79     * Parameters: 
     80     * features - a single {<OpenLayers.Feature.Vector>} or an 
     81     * Array({<OpenLayers.Feature.Vector>}). 
     82     * 
     83     * Returns: 
     84     * {String} an Atom entry document if passed one feature node, or a feed 
     85     * document if passed an array of feature nodes. 
     86     */ 
     87    write: function(features) { 
     88        var doc; 
     89        if (features instanceof Array) { 
     90            doc = this.createElementNS(this.atomns, "feed"); 
     91            for (var i=0; i<features.length; i++) { 
     92                doc.appendChild(this.buildEntryNode(features[i])); 
     93            } 
     94        } 
     95        else { 
     96            doc = this.buildEntryNode(features); 
     97        } 
     98        return OpenLayers.Format.XML.prototype.write.apply(this, [doc]); 
     99    }, 
     100     
     101    /** 
     102     * Method: buildContentNode 
     103     * 
     104     * Parameters: 
     105     * content - {Object} 
     106     * 
     107     * Returns: 
     108     * {DOMElement} an Atom content node. 
     109     * 
     110     * TODO: types other than text. 
     111     */ 
     112     
     113    buildContentNode: function(content) { 
     114        var node = this.createElementNS(this.atomns, "content"); 
     115        if (content.type) { 
     116            node.setAttribute("type", content.type); 
     117        } 
     118        node.appendChild( 
     119            this.createTextNode(content.value) 
     120            ); 
     121        return node; 
     122    }, 
     123     
     124    /** 
     125     * Method: buildEntryNode 
     126     * Build an Atom entry node from a feature object. 
     127     * 
     128     * Parameters: 
     129     * feature - {<OpenLayers.Feature.Vector>} 
     130     * 
     131     * Returns: 
     132     * {DOMElement} an Atom entry node. 
     133     * 
     134     * These entries are geared for publication using AtomPub. 
     135     * 
     136     * TODO: support extension elements 
     137     */ 
     138    buildEntryNode: function(feature) { 
     139        var attrib = feature.attributes; 
     140        var atomAttrib = attrib.atom ? attrib.atom : {}; 
     141        var entryNode = this.createElementNS(this.atomns, "entry"); 
     142         
     143        // atom:author 
     144        if (atomAttrib.authors) { 
     145            var authors = atomAttrib.authors instanceof Array ? 
     146                atomAttrib.authors : new Array(atomAttrib.authors); 
     147            var authorNode; 
     148            for (var i=0; i<authors.length; i++) { 
     149                entryNode.appendChild( 
     150                    this.buildPersonConstructNode( 
     151                        "author", 
     152                        authors[i] 
     153                        ) 
     154                    ); 
     155            } 
     156        } 
     157         
     158        // atom:category 
     159        if (atomAttrib.categories) { 
     160            var categories = atomAttrib.categories instanceof Array ? 
     161                atomAttrib.categories : new Array(atomAttrib.categories); 
     162            var category; 
     163            var categoryNode; 
     164            for (var i=0; i<categories.length; i++) { 
     165                categoryNode = this.createElementNS(this.atomns, "category"); 
     166                category = categories[i]; 
     167                categoryNode.setAttribute("term", category.term); 
     168                if (category.scheme) { 
     169                    categoryNode.setAttribute("scheme", category.scheme); 
     170                } 
     171                if (category.label) { 
     172                    categoryNode.setAttribute("label", category.label); 
     173                } 
     174                entryNode.appendChild(categoryNode); 
     175            } 
     176        } 
     177         
     178        // atom:content 
     179        if (atomAttrib.content) { 
     180            entryNode.appendChild(this.buildContentNode(atomAttrib.content)); 
     181        } 
     182         
     183        // atom:contributor 
     184        if (atomAttrib.contributors) { 
     185            var contributors = atomAttrib.contributors instanceof Array ? 
     186                atomAttrib.contributors : new Array(atomAttrib.contributors); 
     187            var contributorNode; 
     188            for (var i=0; i<contributors.length; i++) { 
     189                entryNode.appendChild( 
     190                    this.buildPersonConstructNode( 
     191                        "contributor", 
     192                        contributors[i] 
     193                        ) 
     194                    ); 
     195            } 
     196        } 
     197         
     198        // atom:id 
     199        if (feature.fid) { 
     200            entryNode.appendChild( 
     201                this.buildTextConstructNode("id", feature.fid) 
     202                ); 
     203        } 
     204         
     205        // atom:link 
     206        if (atomAttrib.links) { 
     207            var links = atomAttrib.links instanceof Array ? 
     208                atomAttrib.links : new Array(atomAttrib.links); 
     209            var link; 
     210            var linkNode; 
     211            var oAtts = ["rel", "type", "hreflang", "title", "length"]; 
     212            for (var i=0; i<links.length; i++) { 
     213                link = links[i]; 
     214                linkNode = this.createElementNS(this.atomns, "link"); 
     215                linkNode.setAttribute("href", link.href); 
     216                for (var j=0; j<oAtts.length; j++) { 
     217                    if (link[oAtts[j]]) { 
     218                        linkNode.setAttribute(oAtts[j], link[oAtts[j]]); 
     219                    } 
     220                } 
     221                entryNode.appendChild(linkNode); 
     222            } 
     223        } 
     224         
     225        // atom:published 
     226        if (atomAttrib.published) { 
     227            entryNode.appendChild( 
     228                this.buildTextConstructNode("published", atomAttrib.published) 
     229                ); 
     230        } 
     231         
     232        // atom:rights 
     233        if (atomAttrib.rights) { 
     234            entryNode.appendChild( 
     235                this.buildTextConstructNode("rights", atomAttrib.rights) 
     236                ); 
     237        } 
     238         
     239        // atom:source not implemented 
     240         
     241        // atom:summary 
     242        if (atomAttrib.summary || attrib.description) { 
     243            entryNode.appendChild( 
     244                this.buildTextConstructNode( 
     245                    "summary", 
     246                    atomAttrib.summary || attrib.description 
     247                    ) 
     248                ); 
     249        } 
     250         
     251        // atom:title 
     252        entryNode.appendChild( 
     253            this.buildTextConstructNode( 
     254                "title",  
     255                atomAttrib.title || attrib.title 
     256                ) 
     257            ); 
     258         
     259        // atom:updated 
     260        if (atomAttrib.updated) { 
     261            entryNode.appendChild( 
     262                this.buildTextConstructNode("updated", atomAttrib.updated) 
     263                ); 
     264        } 
     265         
     266        // georss:where 
     267        if (feature.geometry) { 
     268            var whereNode = this.createElementNS( 
     269                this.georssns, "georss:where" 
     270                ); 
     271            var geometryNode = this.buildGeometryNode(feature.geometry); 
     272            whereNode.appendChild(geometryNode); 
     273            entryNode.appendChild(whereNode); 
     274        } 
     275         
     276        return entryNode; 
     277    }, 
     278     
     279    /** 
     280     * Method: buildGeometryNode 
     281     * builds a GeoRSS node with a given geometry 
     282     * 
     283     * Parameters: 
     284     * geometry - {<OpenLayers.Geometry>} 
     285     * 
     286     * Returns: 
     287     * {DOMElement} A gml node. 
     288     */ 
     289    buildGeometryNode: function(geometry) { 
     290        var gmlParser = new OpenLayers.Format.GML.v3({'xy': this.xy}); 
     291        var geomType = gmlParser.geometryTypes[geometry.CLASS_NAME]; 
     292        return gmlParser.writers["gml"][geomType].apply( 
     293                                                    gmlParser, [geometry] 
     294                                                    ); 
     295    }, 
     296     
     297    /** 
     298     * Method: buildPersonConstructNode 
     299     * 
     300     * Parameters: 
     301     * name - {String} 
     302     * value - {Object} 
     303     * 
     304     * Returns: 
     305     * {DOMElement} an Atom person construct node. 
     306     * 
     307     * Example: 
     308     * >>> buildPersonConstructNode("author", {name: "John Smith"}) 
     309     * {<author><name>John Smith</name></author>} 
     310     * 
     311     * TODO: how to specify extension elements? Add to the oNames array? 
     312     */ 
     313     
     314    buildPersonConstructNode: function(name, value) { 
     315        var oNode; 
     316        var oNames = ["uri", "email"]; 
     317        var personNode = this.createElementNS(this.atomns, name); 
     318        var nameNode = this.createElementNS(this.atomns, "name"); 
     319        nameNode.appendChild( 
     320            this.createTextNode(value.name) 
     321            ); 
     322        personNode.appendChild(nameNode); 
     323        for (var i=0; i<oNames.length; i++) { 
     324            if (value[oNames[i]]) { 
     325                oNode = this.createElementNS(this.atomns, oNames[i]); 
     326                oNode.appendChild( 
     327                    this.createTextNode(value[oNames[i]]) 
     328                    ); 
     329                personNode.appendChild(oNode); 
     330            } 
     331        } 
     332        return personNode; 
     333    }, 
     334     
     335    /** 
     336     * Method: buildTextConstructNode 
     337     * 
     338     * Parameters: 
     339     * name - {String} 
     340     * value - {String} 
     341     * 
     342     * Returns: 
     343     * {DOMElement} an Atom text construct node with tag=name containing the 
     344     * value as text. 
     345     * 
     346     * Example: 
     347     * >>> buildTextConstructNode("published", "2003-12-13T08:29:29-04:00") 
     348     * {<published>2003-12-13T08:29:29-04:00</published>} 
     349     */ 
     350     
     351    buildTextConstructNode: function(name, value) { 
     352        var node = this.createElementNS(this.atomns, name); 
     353        node.appendChild( 
     354            this.createTextNode(value) 
     355            ); 
     356        return node; 
     357    }, 
     358     
     359    /** 
     360     * Method: getChildValue 
     361     * 
     362     * Parameters: 
     363     * node - {DOMElement} 
     364     * nsuri - {String} Child node namespace uri ("*" for any). 
     365     * name - {String} Child node name. 
     366     * def - {String} Optional string default to return if no child found. 
     367     * 
     368     * Returns: 
     369     * {String} The value of the first child with the given tag name.  Returns 
     370     *     default value or empty string if none found. 
     371     */ 
     372    getChildValue: function(node, nsuri, name, def) { 
     373        var value; 
     374        try { 
     375            value = this.getElementsByTagNameNS(node, nsuri, name)[0].firstChild.nodeValue; 
     376        } catch(e) { 
     377            value = (def == undefined) ? "" : def; 
     378        } 
     379        return value; 
     380    }, 
     381     
     382    /** 
     383     * Method: parseFeature 
     384     * Parse feature from an Atom entry node.. 
     385     * 
     386     * Parameters: 
     387     * node - {DOMElement} An Atom entry or feed node. 
     388     * 
     389     * Returns: 
     390     * An <OpenLayers.Feature.Vector>. 
     391     */ 
     392     
     393    parseFeature: function(node) { 
     394        var atomAttrib = {}; 
     395        var value = null; 
     396        var nodes = null; 
     397        var attval = null; 
     398         
     399        // atomAuthor* 
     400        this.parsePersonConstructs(node, "author", atomAttrib); 
     401         
     402        // atomCategory* 
     403        nodes = this.getElementsByTagNameNS(node, this.atomns, 'category'); 
     404        if (nodes.length > 0) { 
     405            atomAttrib.categories = new Array(); 
     406        } 
     407        for (var i=0; i<nodes.length; i++) { 
     408            value = {}; 
     409            value.term = nodes[i].getAttribute("term"); 
     410            attval = nodes[i].getAttribute("scheme"); 
     411            if (attval) { value.scheme = attval; } 
     412            attval = nodes[i].getAttribute("label"); 
     413            if (attval) { value.label = attval; } 
     414            atomAttrib.categories.push(value); 
     415        } 
     416         
     417        // atomContent? 
     418        nodes = this.getElementsByTagNameNS(node, this.atomns, 'content'); 
     419        if (nodes.length > 0) { 
     420            value = {}; 
     421            attval = nodes[0].getAttribute("type") 
     422            if (attval) { value.type = attval; } 
     423            value.value = this.getChildValue( 
     424                            node, 
     425                            this.atomns, 
     426                            "content", 
     427                            null 
     428                            ); 
     429            atomAttrib.content = value; 
     430        } 
     431         
     432        // atomContributor* 
     433        this.parsePersonConstructs(node, "contributor", atomAttrib); 
     434         
     435        // atomId 
     436        atomAttrib.id = this.getChildValue(node, this.atomns, "id", null); 
     437         
     438        // atomLink* 
     439        nodes = this.getElementsByTagNameNS(node, this.atomns, 'link'); 
     440        if (nodes.length > 0) { 
     441            atomAttrib.links = new Array(nodes.length); 
     442        } 
     443        var oAtts = ["rel", "type", "hreflang", "title", "length"]; 
     444        for (var i=0; i<nodes.length; i++) { 
     445            value = {}; 
     446            value.href = nodes[i].getAttribute("href"); 
     447            for (var j=0; j<oAtts.length; j++) { 
     448                attval = nodes[i].getAttribute(oAtts[j]); 
     449                if (attval) { value[oAtts[j]] = attval; } 
     450            } 
     451            atomAttrib.links[i] = value; 
     452        } 
     453         
     454        // atomPublished? 
     455        value = this.getChildValue(node, this.atomns, "published", null); 
     456        if (value) { atomAttrib.published = value; } 
     457         
     458        // atomRights? 
     459        value = this.getChildValue(node, this.atomns, "rights", null); 
     460        if (value) { atomAttrib.rights = value; } 
     461         
     462        // atomSource? -- not implemented 
     463         
     464        // atomSummary? 
     465        value = this.getChildValue(node, this.atomns, "summary", null); 
     466        if (value) { atomAttrib.summary = value; } 
     467         
     468        // atomTitle 
     469        atomAttrib.title = this.getChildValue( 
     470                                node, this.atomns, "title", null 
     471                                ); 
     472         
     473        // atomUpdated 
     474        atomAttrib.updated = this.getChildValue( 
     475                                node, this.atomns, "updated", null 
     476                                ); 
     477         
     478        var featureAttrib = { 
     479            title: atomAttrib.title, 
     480            description: atomAttrib.summary 
     481            } 
     482        featureAttrib.atom = atomAttrib; 
     483        var geometry = this.parseLocations(node)[0]; 
     484        var feature = new OpenLayers.Feature.Vector(geometry, featureAttrib); 
     485        feature.fid = atomAttrib.id; 
     486        return feature; 
     487    }, 
     488     
     489    /** 
     490     * Method: parseFeatures 
     491     * Return features from an Atom entry or feed. 
     492     * 
     493     * Parameters: 
     494     * node - {DOMElement} An Atom entry or feed node. 
     495     * 
     496     * Returns: 
     497     * An Array of <OpenLayers.Feature.Vector>s. 
     498     */ 
     499     
     500    parseFeatures: function(node) { 
     501        var features = []; 
     502        var entries = null; 
     503        entries = this.getElementsByTagNameNS(node, this.atomns, 'entry'); 
     504        if (entries.length == 0) { 
     505            entries = new Array(node); 
     506        } 
     507        for (var i=0; i<entries.length; i++) { 
     508            features.push(this.parseFeature(entries[i])); 
     509        } 
     510        return features; 
     511    }, 
     512     
     513    /** 
     514     * Method: parseLocations 
     515     * Parse the locations from an Atom entry or feed. 
     516     * 
     517     * Parameters: 
     518     * node - {DOMElement} An Atom entry or feed node. 
     519     * 
     520     * Returns: 
     521     * An Array of <OpenLayers.Geometry>s. 
     522     */ 
     523    parseLocations: function(node) { 
     524        var locations = {components: []}; 
     525        var where = this.getElementsByTagNameNS( 
     526                        node, 
     527                        this.georssns, 
     528                        "where" 
     529                        ); 
     530        var point = this.getElementsByTagNameNS( 
     531                        node, 
     532                        this.georssns, 
     533                        "point" 
     534                        ); 
     535        var line = this.getElementsByTagNameNS( 
     536                        node, 
     537                        this.georssns, 
     538                        "line" 
     539                        ); 
     540        var polygon = this.getElementsByTagNameNS( 
     541                        node, 
     542                        this.georssns, 
     543                        "polygon" 
     544                        ); 
     545         
     546        if (where.length > 0) { 
     547            var gmlParser = new OpenLayers.Format.GML.v3({'xy': this.xy}); 
     548            for (var i=0; i<where.length; i++) { 
     549                gmlParser.readChildNodes(where[i], locations); 
     550            } 
     551        } 
     552         
     553        if (point.length > 0) { 
     554            for (var i=0; i<point.length; i++) { 
     555                var xy = OpenLayers.String.trim( 
     556                            point[i].firstChild.nodeValue 
     557                            ).split(/\s+/); 
     558                if (xy.length !=2) { 
     559                    xy = OpenLayers.String.trim( 
     560                                point[i].firstChild.nodeValue 
     561                                ).split(/\s*,\s*/); 
     562                } 
     563                locations.components.push( 
     564                    new OpenLayers.Geometry.Point( 
     565                            parseFloat(xy[1]), 
     566                            parseFloat(xy[0]) 
     567                            ) 
     568                    ); 
     569            } 
     570        } 
     571         
     572        if (line.length > 0) { 
     573            var coords; 
     574            var p; 
     575            var points; 
     576            for (var i=0; i<line.length; i++) { 
     577                coords = OpenLayers.String.trim( 
     578                                line[i].firstChild.nodeValue 
     579                                ).split(/\s+/); 
     580                points = new Array(); 
     581                for (var j=0; j<coords.length; j+=2) { 
     582                    p = new OpenLayers.Geometry.Point( 
     583                            parseFloat(coords[j+1]), 
     584                            parseFloat(coords[j]) 
     585                            ); 
     586                    points.push(p); 
     587                } 
     588                locations.components.push( 
     589                    new OpenLayers.Geometry.LineString(points) 
     590                    ); 
     591            } 
     592        } 
     593         
     594        if (polygon.length > 0) { 
     595            var coords; 
     596            var p; 
     597            var points; 
     598            for (var i=0; i<polygon.length; i++) { 
     599                coords = OpenLayers.String.trim( 
     600                            polygon[i].firstChild.nodeValue 
     601                            ).split(/\s+/); 
     602                points = new Array(); 
     603                for (var j=0; j<coords.length; j+=2) { 
     604                    p = new OpenLayers.Geometry.Point( 
     605                                parseFloat(coords[i+1]), 
     606                                parseFloat(coords[i]) 
     607                                ); 
     608                    points.push(p); 
     609                } 
     610                locations.components.push( 
     611                    new OpenLayers.Geometry.Polygon( 
     612                            [new OpenLayers.Geometry.LinearRing(components)] 
     613                            ) 
     614                    ); 
     615            } 
     616        } 
     617         
     618        if (this.internalProjection && this.externalProjection) { 
     619            for (var i=0; i<locations.components.length; i++) { 
     620                if (locations.components[i]) { 
     621                    locations.components[i].transform( 
     622                            this.externalProjection, 
     623                            this.internalProjection 
     624                            ); 
     625                } 
     626            } 
     627        } 
     628         
     629        return locations.components; 
     630    }, 
     631     
     632    /** 
     633     * Method: parsePersonConstruct 
     634     * Parse Atom person constructs from an Atom entry node. 
     635     * 
     636     * Parameters: 
     637     * node - {DOMElement} An Atom entry or feed node. 
     638     * name - {String} Construcy name ("author" or "contributor") 
     639     * data = {Object} Object in which to put parsed persons. 
     640     * 
     641     * Returns: 
     642     * An {Object}. 
     643     */ 
     644     
     645    parsePersonConstructs: function(node, name, data) { 
     646        var persons = new Array(); 
     647        nodes = this.getElementsByTagNameNS(node, this.atomns, name); 
     648        var oAtts = ["uri", "email"]; 
     649        for (var i=0; i<nodes.length; i++) { 
     650            value = {}; 
     651            value.name = this.getChildValue( 
     652                            nodes[i], 
     653                            this.atomns, 
     654                            "name", 
     655                            null 
     656                            ); 
     657            for (var j=0; j<oAtts.length; j++) { 
     658                attval = this.getChildValue( 
     659                            nodes[i], 
     660                            this.atomns, 
     661                            oAtts[j], 
     662                            null); 
     663                if (attval) { value[oAtts[j]] = attval; } 
     664            } 
     665            persons.push(value); 
     666        } 
     667        if (persons.length > 0) { 
     668            data[name + "s"] = persons; 
     669        } 
     670    }, 
     671 
     672    CLASS_NAME: "OpenLayers.Format.Atom" 
     673}); 
  • /dev/null

    old new  
     1<html>  
     2<head>  
     3    <script src="../../lib/OpenLayers.js"></script>  
     4    <script type="text/javascript"> 
     5 
     6    function test_Format_Atom_constructor(t) {  
     7        t.plan(4);  
     8        var options = {'foo': 'bar'};  
     9        var format = new OpenLayers.Format.Atom(options);  
     10        t.ok(format instanceof OpenLayers.Format.Atom,  
     11             "new OpenLayers.Format.GeoRSS returns object" );  
     12        t.eq(format.foo, "bar", "constructor sets options correctly");  
     13        t.eq(typeof format.read, "function", "format has a read function");  
     14        t.eq(typeof format.write, "function", "format has a write function");  
     15    } 
     16 
     17    /* Reading tests */ 
     18 
     19    function test_Format_Atom_reproject_null(t) {  
     20        t.plan(1); 
     21        var parser = new OpenLayers.Format.Atom({'internalProjection':new OpenLayers.Projection("EPSG:4326"), 'externalProjection': new OpenLayers.Projection("EPSG:4326")}); 
     22        var data = parser.read( 
     23          // begin document 
     24          '<feed xmlns="http://www.w3.org/2005/Atom">'  + 
     25          '<entry></entry>'                             + 
     26          '</feed>' 
     27          // end document 
     28          ); 
     29        t.eq( 
     30          data.length, 1,  
     31          "Parsing items with null geometry and reprojection doesn't fail" 
     32          ); 
     33    } 
     34 
     35    // read entry 1: basic entry, no categories or persons 
     36    function test_Format_Atom_readentry1(t) {  
     37        t.plan(10); 
     38        var parser = new OpenLayers.Format.Atom(); 
     39        var data = parser.read( 
     40          // begin document 
     41          '<entry xmlns="http://www.w3.org/2005/Atom">'                 + 
     42          '  <id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>'    + 
     43          '  <link href="http://example.com/blog/1" rel="alternate"/>'  + 
     44          '  <summary>An Atom testing entry</summary>'                  + 
     45          '  <title>Atom test</title>'                                  + 
     46          '  <updated>2009-06-02T10:00:00Z</updated>'                   + 
     47          '</entry>' 
     48          // end document 
     49          ); 
     50        t.ok(data instanceof Array, "Read features"); 
     51        var fx = data[0]; 
     52        t.ok(fx instanceof OpenLayers.Feature.Vector, "Read feature"); 
     53        t.eq(fx.geometry, null, "Geometry is null"); 
     54        t.eq( 
     55            fx.fid,  
     56            "urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed",  
     57            "Read fid" 
     58            ); 
     59        var attrib = fx.attributes; 
     60        t.eq(attrib.title, "Atom test", "Correct title attribute"); 
     61        t.eq( 
     62            attrib.description,  
     63            "An Atom testing entry",  
     64            "Correct description attribute" 
     65            ); 
     66        var atomAttrib = attrib.atom; 
     67        t.eq( 
     68            atomAttrib.links,  
     69            [{href: "http://example.com/blog/1", rel: "alternate"}],  
     70            "Correct links in atom namespace" 
     71            ); 
     72        t.eq( 
     73            atomAttrib.summary,  
     74            "An Atom testing entry",  
     75            "Correct summary in atom namespace" 
     76            ); 
     77        t.eq( 
     78            atomAttrib.title,  
     79            "Atom test",  
     80            "Correct title in atom namespace" 
     81            ); 
     82        t.eq( 
     83            atomAttrib.updated,  
     84            "2009-06-02T10:00:00Z",  
     85            "Correct timestamp in atom namespace" 
     86            ); 
     87    } 
     88 
     89    // read entry 2: with georss:where 
     90    function test_Format_Atom_readentry2(t) {  
     91        t.plan(5); 
     92        var parser = new OpenLayers.Format.Atom(); 
     93        var data = parser.read( 
     94          // begin document 
     95          '<entry xmlns="http://www.w3.org/2005/Atom">'                   + 
     96          '  <id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>'      + 
     97          '  <georss:where xmlns:georss="http://www.georss.org/georss">'  + 
     98          '    <gml:Point xmlns:gml="http://www.opengis.net/gml">'        + 
     99          '      <gml:pos>45.68 -111.04</gml:pos>'                        + 
     100          '    </gml:Point>'                                              + 
     101          '  </georss:where>'                                             + 
     102          '</entry>' 
     103          // end document 
     104          ); 
     105        t.ok(data instanceof Array, "Read features"); 
     106        var fx = data[0]; 
     107        t.ok(fx instanceof OpenLayers.Feature.Vector, "Read feature"); 
     108        t.ok(fx.geometry instanceof OpenLayers.Geometry.Point, "Read geometry"); 
     109        t.eq(fx.geometry.x, -111.04, "Read x"); 
     110        t.eq(fx.geometry.y, 45.68, "Read y"); 
     111    } 
     112 
     113    // read entry 3: with georss:point 
     114    function test_Format_Atom_readentry3(t) {  
     115        t.plan(5); 
     116        var parser = new OpenLayers.Format.Atom(); 
     117        var data = parser.read( 
     118          // begin document 
     119          '<entry xmlns="http://www.w3.org/2005/Atom">'                   + 
     120          '  <id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>'      + 
     121          '  <georss:point xmlns:georss="http://www.georss.org/georss">45.68 -111.04</georss:point>'                                                   + 
     122          '</entry>' 
     123          // end document 
     124          ); 
     125        t.ok(data instanceof Array, "Read features"); 
     126        var fx = data[0]; 
     127        t.ok(fx instanceof OpenLayers.Feature.Vector, "Read feature"); 
     128        t.ok(fx.geometry instanceof OpenLayers.Geometry.Point, "Read geometry"); 
     129        t.eq(fx.geometry.x, -111.04, "Read x"); 
     130        t.eq(fx.geometry.y, 45.68, "Read y"); 
     131    } 
     132 
     133    // read feed 1 
     134    function test_Format_Atom_readfeed1(t) {  
     135        t.plan(2); 
     136        var parser = new OpenLayers.Format.Atom(); 
     137        var data = parser.read( 
     138          // begin document 
     139          '<feed xmlns="http://www.w3.org/2005/Atom">'                  + 
     140          '  <entry>'                                                   + 
     141          '    <id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>'  + 
     142          '  </entry>'                                                  + 
     143          '</feed>' 
     144          // end document 
     145          ); 
     146        t.ok(data instanceof Array, "Read features"); 
     147        var fx = data[0]; 
     148        t.ok(fx instanceof OpenLayers.Feature.Vector, "Read feature"); 
     149    } 
     150     
     151    /* Writing tests */ 
     152   
     153    // write entry 1: null geometry, no attributes 
     154    function test_Format_Atom_writeentry1(t) {  
     155        t.plan(1); 
     156        var writer = new OpenLayers.Format.Atom(); 
     157        var feature = new OpenLayers.Feature.Vector(null, {}); 
     158        feature.fid = '1'; 
     159        var data = writer.write(feature); 
     160        t.xml_eq( 
     161          data, 
     162          // begin document 
     163          '<entry xmlns="http://www.w3.org/2005/Atom">' + 
     164          '<id>1</id>'                                  + 
     165          '<title>undefined</title>'                    + 
     166          '</entry>', 
     167          // end document  
     168          'Writes an entry doc with id, no attributes' 
     169          ); 
     170    } 
     171 
     172    // write entry 2: null geometry, well-known attributes 
     173    function test_Format_Atom_writeentry2(t) {  
     174        t.plan(1); 
     175        var writer = new OpenLayers.Format.Atom(); 
     176        var feature = new OpenLayers.Feature.Vector(null, {title: "Test", description: "A testing feature"}); 
     177        feature.fid = '1'; 
     178        var data = writer.write(feature); 
     179        t.xml_eq( 
     180          data, 
     181          // begin document 
     182          '<entry xmlns="http://www.w3.org/2005/Atom">' + 
     183          '<id>1</id>'                                  + 
     184          '<summary>A testing feature</summary>'        + 
     185          '<title>Test</title>'                         + 
     186          '</entry>', 
     187          // end document 
     188          'Writes an entry doc with id, well-known attributes' 
     189          ); 
     190    } 
     191 
     192    // write entry 3: null geometry, Atom constructs to override  
     193    // well-known attributes 
     194    function test_Format_Atom_writeentry3(t) {  
     195        t.plan(1); 
     196        var writer = new OpenLayers.Format.Atom(); 
     197        var feature = new OpenLayers.Feature.Vector(null, {title: "Test", description: "A testing feature", atom: {title: "Atom test", summary: "An Atom testing feature", updated: "2009-06-02T10:00:00Z"}}); 
     198        feature.fid = '1'; 
     199        var data = writer.write(feature); 
     200        t.xml_eq( 
     201          data, 
     202          // begin document 
     203          '<entry xmlns="http://www.w3.org/2005/Atom">' + 
     204          '<id>1</id>'                                  + 
     205          '<summary>An Atom testing feature</summary>'  + 
     206          '<title>Atom test</title>'                    + 
     207          '<updated>2009-06-02T10:00:00Z</updated>'     + 
     208          '</entry>', 
     209          // end document 
     210          'Writes an entry doc with Atom constructs overriding well-known atts' 
     211          ); 
     212    } 
     213 
     214    // write entry 4: Atom categories 
     215    function test_Format_Atom_writeentry4(t) {  
     216        t.plan(1); 
     217        var writer = new OpenLayers.Format.Atom(); 
     218        var feature = new OpenLayers.Feature.Vector(null, {title: "Test", description: "A testing feature", atom: {title: "Atom test", summary: "An Atom testing feature", updated: "2009-06-02T10:00:00Z", categories: [{term: "blog", scheme: "http://example.com/terms", label: "A blog post"}]}}); 
     219        feature.fid = '1'; 
     220        var data = writer.write(feature); 
     221        t.xml_eq( 
     222          data, 
     223          // begin document 
     224          '<entry xmlns="http://www.w3.org/2005/Atom">' + 
     225          '<category term="blog" scheme="http://example.com/terms" label="A blog post"/>'                                           + 
     226          '<id>1</id>'                                  + 
     227          '<summary>An Atom testing feature</summary>'  + 
     228          '<title>Atom test</title>'                    + 
     229          '<updated>2009-06-02T10:00:00Z</updated>'     + 
     230          '</entry>', 
     231          // end document 
     232          'Writes an entry doc with Atom constructs and categories' 
     233          ); 
     234    } 
     235 
     236    // write entry 5: Atom authors, contributors 
     237    function test_Format_Atom_writeentry5(t) {  
     238        t.plan(1); 
     239        var writer = new OpenLayers.Format.Atom(); 
     240        var feature = new OpenLayers.Feature.Vector(null, {title: "Test", description: "A testing feature", atom: {title: "Atom test", summary: "An Atom testing feature", updated: "2009-06-02T10:00:00Z", authors: [{name: "John Doe", uri: "http://example.com/people/jdoe", email: "jdoe@example.com"}], contributors: [{name: "Pikov Andropov", uri: "http://example.com/people/pandropov", email: "pandropov@example.com"}]}}); 
     241        feature.fid = '1'; 
     242        var data = writer.write(feature); 
     243        t.xml_eq( 
     244          data, 
     245          // begin document 
     246          '<entry xmlns="http://www.w3.org/2005/Atom">' + 
     247          '<author>'                                    + 
     248          '  <name>John Doe</name>'                     + 
     249          '  <uri>http://example.com/people/jdoe</uri>' + 
     250          '  <email>jdoe@example.com</email>'           + 
     251          '</author>'                                   + 
     252          '<contributor>'                               + 
     253          '  <name>Pikov Andropov</name>'               + 
     254          '  <uri>http://example.com/people/pandropov</uri>' + 
     255          '  <email>pandropov@example.com</email>'      + 
     256          '</contributor>'                              + 
     257          '<id>1</id>'                                  + 
     258          '<summary>An Atom testing feature</summary>'  + 
     259          '<title>Atom test</title>'                    + 
     260          '<updated>2009-06-02T10:00:00Z</updated>'     + 
     261          '</entry>', 
     262          // end document 
     263          'Writes an entry doc with Atom constructs and persons' 
     264          ); 
     265    } 
     266 
     267    // write entry 6: Atom links 
     268    function test_Format_Atom_writeentry6(t) {  
     269        t.plan(1); 
     270         
     271        // Feature attributes in Atom namespace 
     272        var atomAttrib = { 
     273              title: "Atom test",  
     274              summary: "An Atom testing feature",  
     275              updated: "2009-06-02T10:00:00Z",  
     276              links: [ 
     277                { href: "http://example.com/blog/1", rel: "alternate" } 
     278                ] 
     279              }; 
     280        var fx = new OpenLayers.Feature.Vector(null, {atom: atomAttrib}); 
     281        fx.fid = 'urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed'; 
     282         
     283        var writer = new OpenLayers.Format.Atom(); 
     284        var data = writer.write(fx); 
     285         
     286        t.xml_eq( 
     287          data, 
     288          // begin document 
     289          '<entry xmlns="http://www.w3.org/2005/Atom">'               + 
     290          '<id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>'    + 
     291          '<link href="http://example.com/blog/1" rel="alternate"/>'  + 
     292          '<summary>An Atom testing feature</summary>'                + 
     293          '<title>Atom test</title>'                                  + 
     294          '<updated>2009-06-02T10:00:00Z</updated>'                   + 
     295          '</entry>', 
     296          // end document 
     297          'Writes an entry doc with Atom constructs and links' 
     298          ); 
     299    } 
     300 
     301    // write out point -- just enough to see that we're getting the 
     302    // georss:where element with a Point. We'll trust GML.v3 to get the 
     303    // details right. 
     304    function test_Format_Atom_writepoint(t) {  
     305        t.plan(1); 
     306 
     307        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);   
     308        var fx = new OpenLayers.Feature.Vector(point, {}); 
     309        fx.fid = 'urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed'; 
     310         
     311        var writer = new OpenLayers.Format.Atom(); 
     312        var data = writer.write(fx); 
     313         
     314        t.xml_eq( 
     315          data, 
     316          // begin document 
     317          '<entry xmlns="http://www.w3.org/2005/Atom">'                 + 
     318          '<id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>'      + 
     319          '<title>undefined</title>'                                    + 
     320          '<georss:where xmlns:georss="http://www.georss.org/georss">'  + 
     321          '  <gml:Point xmlns:gml="http://www.opengis.net/gml">'        + 
     322          '    <gml:pos>45.68 -111.04</gml:pos>'                        + 
     323          '  </gml:Point>'                                              + 
     324          '</georss:where>'                                             + 
     325          '</entry>', 
     326          // end document 
     327          'Writes an entry doc with a point location' 
     328          ); 
     329    } 
     330     
     331    </script>  
     332</head>  
     333<body>  
     334</body>  
     335</html>  
  • a/tests/list-tests.html

    old new  
    4545    <li>Filter/Logical.html</li> 
    4646    <li>Filter/Spatial.html</li> 
    4747    <li>Format.html</li> 
     48    <li>Format/Atom.html</li> 
    4849    <li>Format/ArcXML.html</li> 
    4950    <li>Format/ArcXML/Features.html</li> 
    5051    <li>Format/GeoJSON.html</li>