Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "Org.eclipse.higgins.js.pds.client"

(setCredentials (domain, userid, password))
(setCredentials (domain, userid, password, neverRememberPassword))
Line 401: Line 401:
  
 
== setCredentials (domain, userid, password, neverRememberPassword) ==
 
== setCredentials (domain, userid, password, neverRememberPassword) ==
 +
Sets the (username, password, neverRememberPassword) triple in the Proxy object related to this site.
 +
 +
Parameters:
 +
* ''domain'': domain of the website (e.g. nytimes.com)
 +
* ''userid'': userid
 +
* ''password'': password
 +
* ''neverRememberPassword'': user's preference to never remember the password at this site
 +
 +
Implementation:
 +
* template := '''getConnectionTemplate''' (''domain'')
 +
* proxy := '''findProxy''' (''domain, proxy:WebLogin'')
 +
* If ''proxy'' is nil then  // dynamically create the proxy
 +
** proxyClass := get value of ''template:proxyClass'' of ''template'' 
 +
** If ''proxyClass'' is not ''proxy:WebLogin'' then return
 +
** proxy := a new instance of ''proxyClass''
 +
* EndIf
 +
* proxy.userid := ''userid''
 +
* proxy.password := ''password''
 +
* proxy.neverRememberPassword := ''neverRememberPassword''
  
 
== Common Functions ==
 
== Common Functions ==

Revision as of 16:38, 21 September 2011

{{#eclipseproject:technology.higgins|eclipse_custom_style.css}}

Files

Design Notes for API additions to this component

Objective

Create a general purpose API that JavaScript programs executed by HBX can use to get and set attributes about the user. The APIs are to support various kind of JavaScript apps executed by HBX. These HBX JavaScript apps can fill forms, scrape pages, auto-login to sites, as well as lots of other things with data that read using getAttributes() and write using setAttributes(). The goal of these three rather high-level API methods is to shield the developer from the complexities of the multi-contextual, multi-person persona data model.

Summary

General purpose:

  • getAttributes() - reads a set of attributes from the ADS
  • getSuggestions() - reads back all possible values of a given attribute. Useful for supporting interactive typeahead UI.
  • setAttributes() - writes a set of attributes to the ADS entirely replacing current values of specified attributes

Special:

  • getCredentials() - special method to get the user's username & password
  • setCredentials() - special method to set the user's username & password

Example

getAttributes (domain, attributes[], where[], future)

Searches for one or more suitable "source" p:Person nodes in one or more contexts to find the values of requested attributes, attributes[].

These attributes[] URIs are in a namespace that is either (i) the FlatPersona vocabulary or in some other vocabulary that is defined as a set of mapping rules stored within a template context or (ii) in a namespace for which no mapping rules can be found. In the latter case the attribute value will be directly read from the source person node(s).

Suitable source person nodes are found first by searching for ones that have a matching role attribute. Second, if more than one matching source person is found then the where[] expressions are evaluated to cull down the list of potential sources, and finally the source persons are scanned for the requested attributes. If for a given attribute, a, more than one value is found, then in the returned object, we (a) return a nil value and (b) return a flag that this was ambiguous.

This method is idempotent; it has no side effects of changing any data in the ADS).

Notes:

  • Depending on how the calling JavaScript is written, information about the user may remain local (i.e. within the browser and/or on the user's machine) or it may be transmitted to some external web service. The identity of the calling application and the identity of the "domain" are parameters to this call.
  • FUTURE: By setting the value of the authorities = the JavaScript developer's domain (i.e. the "issuer" id of the context associated with this JavaScript) it will only read attributes from this context.
  • FUTURE: If the attribute release is not part of (i) an explicit pre-existing connection/relationship with the domain or (ii) an implicit relationship (e.g. form filling when the user is viewing the page) then a UI should be implemented informing the user as to the identity of the agent, the identity of domain (the "next hop" destination if any) and the set of requested (required/optional) attributes and allowing them to give consent to this attribute disclosure.

Parameters:

  • domain: a string identifier of ultimate attribute data consumer as far as this is known.
  • attributes[]: a set of attribute URIs. The attribute may have one or more role param attached (e.g. ?r=Buyer).
    • NOTE: In the future this parameter will be a set of (attribute, optional, authorities) tuples where optional is a boolean (if true then this attribute is desired but not required)--for now this must be false. authorities is a list of domains that are considered by the caller as authoritative WRT this attribute and thus must be used as the source of the attribute, if this list is nil then self asserted values are acceptable. The value of a member of authorities is matched against the issuer of the containing context of the entity.
  • where[]: a set of (attribute, value-expression) pairs. attribute is the attribute URI of the form <namespace>#localAtt and namespace is the URL of a page (or a set of pages with a consistent schema). If the entire site uses the same schema then the site domain will suffice. value-expression (for now) may be an exact value (e.g. "Alice") or may be a regex that the value must match. In the short term the so-called "regex" is just a string of one or more characters followed by an asterisk (e.g. 2*, or 25*)--meaning that the value of the attribute must start with these characters (e.g. values "290" and "250" will match "2*" and "250" (only) will match "25*")
  • tokenTypes: A list of token types that are understood by the entity consuming the attributes requested. At present this must be a JSON document
  • future: (optional) a Futures object to handle asynchronous completion of this function

Parameters to be added in the future

  • audience: (string) Must match either the agent or the domain parameter value or be nil. If not nil, then indicates whether to encrypt tokens for the agent or the domain.

Returns:

  • A set of zero or more tokens (JSON documents at present). Each token encodes multiple (attribute, value(s), ambiguous) tuples where:
    • attribute is the attribute URI (note: this will be one of the attribute URIs passed in to this method)
    • value(s) are the value(s) of the attribute (may be nil, if no values could be found or ambiguous). Each value may be literal or object typed.
    • ambiguous is true if more than one possible value could have been returned. False otherwise.

Implementation:

We start with an empty list called rt[] of (attribute, value, ambiguous) tuples where attribute is the long (URI) form of the attribute; value is the value of the attribute or nil; ambiguous is a boolean that indicates that there were multiple alternative values found (and thus a nil value is returned). We are careful that we pull in a logically self-consistent manner. That is, we do not pull inter-related attributes from different entities (e.g. person nodes). For example we would never pull a vcard:street from a v:adr object and the vcard:postal-code from another v:adr object.

  • context := getConnectionContext(domain) // e.g. http://azigo.com/ptrevithick/nytimes.com
  • rolesAtts[] := findRoles (template, attributes[]) // rolesAtts[] is a set of (roles[], atts[]) pairs where atts is a set of attributes, and roles[] is a set of roles
  • sortByRole (rolesAtts[])

(1) We try to pull values starting at the :me person within context

  • person := context concatenated with "#me" // e.g. http://azigo.com/ptrevithick/nytimes.com#me
  • If context exists and person has at least one attribute then
    • template := getConnectionTemplate(domain)
    • findAttributeValues(template, person, rolesAtts[], where[], rt[])
  • Endif

(2) We try to pull values starting at the :me person in the root context

  • person := rootPerson // root node in root context
  • findAttributeValues(template, person, rolesAtts[], where[], rt[])

(3) Convert rt into JSON and return rt

sortByRole (rolesAtts[])

Combine together all pairs in rolesAtts[] that have the exact same roles[] component (thus increasing from exactly one to N>=1 the number of attribute-triples in each pair)

  • So e.g. we have these three pairs as input:
    • ((Buyer, eCommerce), firstname)
    • ((Buyer, eCommerce), lastname)
    • ((nil), postalcode)
  • We would return two pairs:
    • ((Buyer, eCommerce), (firstname, lastname))
    • ((nil), postalcode)

Parameters:

  • rolesAtts (by reference): a set of (roles[], atts[]) pairs where atts is a set of attributes, and roles[] is a set of roles

Implementation:

  • TODO

findAttributeValues (template, topPerson, rolesAtts[], where[], rt[])

Each of the N pairs of (roles[], atts[]) in rolesAtts, can be thought of as a request to (a) find person nodes whose roles match roles[] and (b) retrieve the values of the atts[] attributes from this/these persons making sure that if there are N>1 values for a given attribute that we return nil as the value for this attribute (and flag it as ambiguous).

Parameters:

  • template: first place to look to find mapping rules for the namespace of attributes in atts[]
  • topPerson: the topmost person node to search down from
  • rolesAtts[]: a list of (roles[], atts[]) pairs where roles[] is a set of roles and atts[] is a set of attributes
  • where[]: a set of (attribute, value-expression) pairs.
  • rt[]: set of (attribute, value, ambiguous) triples

Initialize rt[]:

  • Loop: For every pair ra in rolesAtts[]
    • Loop: For every attribute a in ra.atts[]
      • Add (a, nil, true) tuple into rt[]
    • EndLoop
  • EndLoop

Implementation:

  • Loop: For every pair ra in rolesAtts[]
    • sourcePersons[] := findPersonsByRole (topPerson, ra.roles[])
    • sourcePersons[] := cullByWhere (template, sourcePersons[], where[])
    • Loop: For every Person p in sourcePersons
      • extractValues (template, p, ra.atts[], rt[])
    • EndLoop
  • EndLoop

cullByWhere (template, persons[], where[])

Given a set of persons, persons all of which could be sources for attributes, return a set of persons that satisfy all where parameters, where.

Parameters:

  • template: first place to look to find mapping rules for the namespace of attributes mentioned in where[]
  • persons[]: a set of Persons
  • where[]: a set of (attribute, expression) pairs

Implementation:

  • Loop: For every person p in persons[]
    • if not hasAttributeAndMatchesExpression (template, p, where[]) then
      • remove p from the set persons[]
    • EndIf
  • EndLoop
hasAttributeAndMatchesExpression (template, person, attExp[])

Return true if person person has all attributes in attexp[] and for each attribute its value matches the corresponding expresssion in attexp[]

Parameters:

  • template: first place to look to find mapping rules for the namespace of attributes in attExp[]
  • person: a p:Person
  • attexp[]: a set of (attribute, expression) pairs

Implementation

  • Loop: For every pair ae in attExp[]
    • rule := findRule (template, ae.attribute)
    • value := pullEvalRule (rule, person) // pull within the scope of person
    • If value is nil then return nil
    • If value does not match expression then return nil
  • EndLoop
  • Return true

extractValues(template, person, attributes[], rt[])

Extract the values of all members of attributes from person node person. Parameters:

  • template: first place to look to find mapping rules for the namespace of attributes in atts[]
  • person: person node to extract attributes from
  • attributes[]: a set of attributes
  • rt[]: set of (attribute, value, ambiguous) triples

Implementation:

  • Loop: For every attribute att in attributes[]
    • rule := findRule (template, att)
    • value := pullEvalRule (rule, person) // pull within the scope of person
    • If value is not nil then
      • If rt[] contains a tuple whose attribute component matches att and that has a non-nil value then
        • Replace the value of value in that tuple with nil
        • Set the value of ambiguous in that tuple to true
      • Else
        • Add a new tuple (att, value, false) to rt[]
        • Remove attribute att from attributes[]
      • EndIf
    • EndIf
  • EndLoop

pullEvalRule (string rule, URI person)

We evaluate the rule in "pull" mode (we're pulling values from the PDS) and from person person. We dispatch functions by name.

  • mappingRule := getRuleField (rule, rdf:type) // e.g. "rolePathLiteral"
  • If mappingRule == "rolePathLiteral" then
    • value := pullRolePathLiteral(rule, person)
    • return value
  • If (mappingRule == ... ) then ...
pullRolePathLiteral(rule, person)

Pull value within scope of person

Parameters:

  • rule: a rule object. Has subfields:
    • rdf:type (e.g. map:rolePathLiteral) - the name of the mapping function (ignored here)
    • map:predicate (E.g. :bFirstName) - the attribute we are trying to get the value of (ignored here)
    • map:role (e.g. p:Buyer) - an optional field (ignored here because it has already played its part in helping to select person)
    • map:path (e.g. vcard:n) - object valued attribute of person
    • map:mappedAtt (e.g. vcard:given-name) - attribute of object to read
  • person: we begin the search at the person person

Implementation:

  • path := getRuleField (rule, map:path)
  • mappedAtt := getRuleField (rule, map:mappedAtt)
  • obj := value of path attribute of person
  • If obj is nil then return nil
  • Return the value of mappedAtt attribute of obj

getCredentials (domain)

Returns a (username, password, neverRememberPassword) triple that is the credentials necessary to login to this site.

Parameters:

  • domain: domain of the website (e.g. nytimes.com)

Implementation:

  • template := getConnectionTemplate (domain)
  • proxy := findProxy (domain, proxy:WebLogin)
  • If proxy is not nil then
    • Return (proxy.userid, proxy.password, proxy.neverRememberPassword) // i.e. the userid and password attribute of proxy
  • EndIf
  • Return nil

findProxy (domain, class)

Find a proxy:Proxy instance the domain of whose externalResource matches domain.

Parameters:

  • domain: website domain (e.g. nytimes.com)
  • class: subclass of Proxy (e.g. proxy:WebLogin)

Implementation:

  • Loop: For every Proxy p reachable by following the immediate h:correlation links from :me in the root context
    • If domain portion of externalResource of p == domain and if class of p == class then
      • Return p
    • EndIf
  • Return nil

getSuggestions (attribute, future)

This method is only needed for interactive form filling use cases.

Note: For privacy reasons this method may only be called by highly trusted JavaScript.

Parameters:

  • attribute: attribute URI of the form <namespace>#<localAtt>
  • future: (optional) a Futures object to handle asynchronous completion of this function

setAttributes (domain, attVals[])

Takes a set (i.e. no duplicates allowed) of (attribute, value[]) pairs, attVals[], and it attempts to find one or more suitable "target" p:Person nodes on which to set the values of these attributes. One or more attributes, objects, and/or p:Persons may be created in the process.

Unlike getAttributes(), setAttributes() is limited as to the context into which it writes. It only writes into (or creates as necessary) the context identified by the domain parameter.

Here is the simplest possible case. Consider a single attribute-value pair, (att, newVal[]), as the value of attVals[]. setAttributes finds an existing target person, :me, in the context identified by domain that has the required role (e.g. p:eCommerce) and that already has attribute att. It removes all current values of att and replaces them with newVal[].

More complex cases involve (i) attributes that must be fetched from a p:Person holding a role that is different from the value of the role of the :me person (ii) attributes that are on a sub-object of a person, such that the sub-object that doesn't yet exist (e.g. setting the value of vcard:given-name when the "container" vcard:Name object doesn't yet exist as an attribute of the person.

The attribute URIs passed in are in a namespace that is either (i) the FlatPersona vocabulary or in some other vocabulary that is defined as a set of mapping rules stored within a template context or (ii) in a namespace for which no mapping rules can be found. In the latter case the attribute and value will be directly added to the target person node.

These rules describe how to transform between the native vocabulary and the generic Persona data model. A attribute passed as a parameter may map to an attribute in that is reached via traversal path through the graph of objects linked to a p:Person object. For example, if one of the attributes passed in is fp:givenName then this attribute maps to a path that originates at a person node in a context whose identity is derived from domain, follows a vcard:n link (complex attribute) whose value is an instance of vcard:Name, and arrives at the vcard:given-name attribute of this vcard:Name object. If either the person object, the vcard:Name object or both did not exist prior to invoking this method then they would be constructed on-the-fly.

Parameters:

  • domain: domain of the party providing the attribute value
  • attVals: an array of (attribute, value[]) pairs. The attribute is a URI of the form <namespace>#<localAtt>. The value is a literal value or object (URI) value.

Implementation:

  • context := getConnectionContext (domain) // e.g. http://azigo.com/ptrevithick/nytimes.com
  • template := getConnectionTemplate (domain) // e.g. http://azigo.com/sys/template/nytimes.com
  • If context doesn't exist then
    • Create context from information (esp. Participant ContextPrototype) in template // class == ConnectionContext.
    • newPersonRole := value of role attribute of Participant ContextPrototype
  • Endif
  • attributes[] := extractAttributes (attVals[]) // attributes[] is a set of attributes
  • rolesAtts[] := findRoles (template, attributes[]) // rolesAtts[] is a set of (roles[], atts[]) pairs where atts[] is a set of attributes, and roles[] is a set of roles
  • sortByRole (rolesAtts[])
  • mePerson := context concatenated with "#me" // e.g. http://azigo.com/ptrevithick/nytimes.com#me
  • If mePerson doesn't exist then
    • Add these two statements to context: // thus creating a new Person
      • (subj=:me pred=rdf:type obj=persona:Person)
      • (subj=:me pred=p:role obj=newPersonRole)
    • If there is an existing proxy:Proxy object in root context with a nil proxy:resource attribute, then set the value of :resource to the URI of the new person. If there isn't an existing 1/2 created Proxy, then create a new one and have its :resource attribute point to the new person node //TODO: explain how to create a proxy:Proxy from info in template
  • EndIf
  • Loop: For every pair ra in rolesAtts[]
    • targetPersons[] := findPersonsByRole (person, ra.roles[])
    • If size of targetPersons[] == 0 then
      • person := create a new person and set the value of its role attribute to ra.roles[]
      • Add person to newPersons[]
    • ElseIf size of targetPersons[] == 1 then
      • person := targetPersons[0]
    • Else // size of targetPersons[] > 1
      • person := create a new person and set the value of its role attribute to ra.roles[]
      • Add person to newPersons[]
    • EndIf
    • partialAttVals[] := subsetAttVals (ra.atts[], attVals[])
    • Loop. For every (attribute, value[]) pair av in partialAttVals[]
      • rule := getRule (template, av.attribute)
      • pushEvalRule (person, rule, av.value[])
    • EndLoop
  • EndLoop
  • Loop: For every person np in newPersons[]
    • If duplicate (np, mePerson) then
      • Delete np
    • Else
      • If isOwner (newPerson) then
        • Add h:correlation link from :me to np
      • Else
        • Add h:indeterminate link from :me to np
      • EndIf
    • EndIf
  • EndLoop

boolean isOwner (person)

By comparing name information of person with other person's in the h:correlation graph down from root :me, see if person is the same as the Azigo user (aka owner). If so return true.

Implementation:

  • TODO

subsetAttVals (someAtts[], allAttVals[])

Return the subset of allAttVals[] such that the attribute component of every (attribute, value[]) pair in allAttVals[] is a member of someAtts[]

Implementation:

  • Create a new, empty set of (attribute, values[]) pairs, rtnAttVals[]
  • Loop: For every pair av in allAttVals[]
    • If av.attribute is a member of someAtts[] then
      • Add av to rtnAttVals[]
    • EndIf
  • EndLoop
  • Return rtnAttVals[]

extractAttributes (attVals[])

Return the set of attributes mentioned in attVals[].

Implementation

  • Create a new empty set of attributes, attributes[]
  • Loop: For every (attribute, value[]) pair av in attVals[]
    • Add av.attribute to attributes[]
  • EndLoop
  • Return attributes[]

pushEvalRule (template, person, rule, value[])

We evaluate the rule in "push" mode (we're pushing values in to the ADS). Within the rule string there is the name of the mapping rule to execute.

Parameters:

  • template: first place to look to find mapping rules for the namespace of attribute in rule
  • person: person on which to set attribute values
  • rule: a rule object containing a set of field attributes
  • value[]: one or more values to set as the value of the attribute mentioned in rule

Implementation:

  • mappingRule := getRuleField (rule, rdf:type) // e.g. "rolePathLiteral"
  • If mappingRule == "roleSameAs" then
    • pushRoleSameAs (template, person, rule, value[])
  • ElseIf mappingRule == "rolePathLiteral" then
    • pushRolePathLiteral (template, person, rule, value[])
  • ElseIf mappingRule == "roleLiteral" then
    • pushRoleLiteral (template, person, rule, value[])
  • ElseIf mappingRule == ...

pushRoleSameAs (template, person, rule, value[])

Parameters:

  • template: first place to look to find mapping rules for the namespace of attribute in rule
  • person: person on which to set attribute values
  • rule: a rule object containing a set of field attributes
  • value[]: one or more values to set as the value of the attribute mentioned in rule

This is a special rule. It involves indirection to another rule in another vocabulary.

  • equivAtt := getRuleField (rule, map:equivalentAttribute)
  • newRule := findRule (template, equivAtt)
  • pushEvalRule (person, newRule, value[]) // recurse

pushRolePathLiteral (template, person, rule, value[])

Push value[] into person.

Parameters:

  • template: first place to look to find mapping rules for the namespace of attribute in rule
  • person: person on which to set attribute values
  • rule: a rule object containing a set of field attributes
  • value[]: one or more values to set as the value of the attribute mentioned in rule

Implementation:

  • path := getRuleField (rule, map:path)
  • If person has path attribute then
    • obj := value of path attribute of person
  • Else
    • obj := create a new obj whose class is the value of the rdf:range property of the path property
  • EndIf
  • mappedAtt := getRuleField (rule, map:mappedAtt)
  • If obj has attribute mappedAtt then
    • Replace all of its current values with value[]
  • Else
    • Add new attribute mappedAtt to obj and set its value to value[]
  • EndIf

pushRoleLiteral (template, person, rule, value[])

Push value[] into person.

Parameters:

  • template: first place to look to find mapping rules for the namespace of attribute in rule
  • person: person on which to set attribute values
  • rule: a rule object containing a set of field attributes
  • value[]: one or more values to set as the value of the attribute mentioned in rule

Implementation:

  • mappedAtt := getRuleField (rule, map:mappedAtt)
  • If person has attribute mappedAtt then
    • Replace all of its current values with value[]
  • Else
    • Add new attribute mappedAtt to person and set its value to value[]
  • EndIf

setCredentials (domain, userid, password, neverRememberPassword)

Sets the (username, password, neverRememberPassword) triple in the Proxy object related to this site.

Parameters:

  • domain: domain of the website (e.g. nytimes.com)
  • userid: userid
  • password: password
  • neverRememberPassword: user's preference to never remember the password at this site

Implementation:

  • template := getConnectionTemplate (domain)
  • proxy := findProxy (domain, proxy:WebLogin)
  • If proxy is nil then // dynamically create the proxy
    • proxyClass := get value of template:proxyClass of template
    • If proxyClass is not proxy:WebLogin then return
    • proxy := a new instance of proxyClass
  • EndIf
  • proxy.userid := userid
  • proxy.password := password
  • proxy.neverRememberPassword := neverRememberPassword

Common Functions

findPersonsByRole (topPerson, roles[])

Return a list of p:Person nodes found that hold the required role value(s). Start the search at topPerson and follow h:correlation links (and tunneling through Proxy objects).

Parameters:

  • topPerson: topmost p:Person at which to begin search
  • roles[]: list of required roles to match

Implementation:

  • Initialize empty set rtn[]
  • Loop: For every person p reachable (by traversing h:correlation and h:indeterminate links) from topPerson (including topPerson)
    • If the set of values of the role attribute of p is the same set (or a super-set) as roles[] //we've found a role-matching person. Note that if roles[] is empty then the initial person (i.e. topPerson) will always match.
      • add p to rtn[]
    • EndIf
  • EndLoop
  • Return rtn[]

findRoles (template, inAtts[])

Determine roles for each attribute in attributes[] if any.

Parameters:

  • template: first place to look to find mapping rules for the namespace of attributes in atts[]
  • inAtts[]: a set of (attribute, optional, authorities[]) triples

Implementation:

  • Create a new empty set of pairs ra // ra is a set of (roles[], atts[]) pairs where roles[] is a set of roles and atts[] is a set of attributes
  • Loop: For every attribute att in inAtts[]
    • roles[] := getRoles(att) // extract role params from URI (if any)
    • rule := findRule (template, att')
    • If rule is not nil then
      • Add the value of map:param attribute of the rule to roles[]
    • EndIf
    • Create a new, empty set outAtts[]
    • Add att to outAtts[]
    • Add a new pair (roles[], outAtts[]) to ra[]
  • EndLoop
  • Return ra

URI getConnectionContext (string domain)

Return:

  • http://<servername>/<pdsuser>/domain

URI getConnectionTemplate (string domain)

Return:

  • http://<servername>/sys/template/domain

string getLocalAtt (URI attribute)

Return everything to the right of the #. (e.g. if the input was http://nytimes.com#bFirstName then return "bFirstName").

getRoles (URI attribute)

Return the value(s) of "r" (role) parameter on URI. (e.g. if the input was http://www.eclipse.org/higgins/ontologies/2010/6/fp#givenName?r=Buyer then return ("Buyer")).

URI getNamespace (URI attribute)

Return all but the # and beyond. (e.g. if the input was http:///nytimes.com#bFirstName then return http://nytimes.com).

rule findRule (URI template, URI attribute)

Given an attribute, find a mapping rule for it. These rules are attached to a higgins:Person subclass which by convention is named "#Person" (except for FlatPersonaPerson)). The question is where to find a context that contains this class. The first place to look is in the context template.

Once this context containing the Person class is found, we look through all the values of spin:rule attribute (or one of its sub-attributes, e.g. map:nameRule) to find one such that the value of attribute map:predicate matches the value of the local/relative segment of the attribute (e.g. bFirstName).

If the relative segment was "bFirstName" then this rule would be a match:

     map:nameRule
             [ rdf:type map:rolePathLiteral ;
               map:mappedAtt <http://www.w3.org/2006/vcard/ns#given-name> ;
               map:path <http://www.w3.org/2006/vcard/ns#n> ;
               map:predicate :bFirstName ;
               map:role p:Buyer
             ] ;

Parameters:

  • template: first place to look to find mapping rules for the namespace of attributes in atts[]
  • atttribute: attribute for which to find a rule

Implementation:

  • latt := getLocalAtt (attribute) // e.g. bFirstName
  • ns := getNamespace (attribute) // e.g. http://nytimes.com
  • class := ns concatenated with "#Person" // e.g. http://nytimes.com#Person
  • If class exists within template then
    • rule := the rule attached to class whose map:predicate matches latt
    • Return rule
  • Else
    • TODO: Need to discuss with Alex. At the very least we should rename fp:FlatPersonaPerson to fp:Person so that it is consistent. Also Google, Yahoo, Lotame.
    • Return rule if found
    • // We can't find mapping rule for this namespace/vocabulary.
    • // We assume the value is a literal TODO:
    • // We dynamically create the following rule
    • rule := [ rdf:type map:roleLiteral ; map:mappedAtt attribute ; map:predicate :latt ;]
  • Return rule
  • EndIf

getRuleField (rule, URI field)

Return the value of field attribute of rule object

URI getTemplate (URI context)

Returns value of template attribute of context.

Back to the top