Developer Area

AJAX API for TelHosting Software

This reference describes the new JavaScript-format AJAX interface that the TelHosting software exports. The web interface for the .tel control pane uses the same API.

This interface closely follows the web interface layout, and is divided into the following groups of functions:

  • login - logging into the !telhosting software system
  • wizard - preferences
  • settings - password and related settings
  • folder management - subdomains
  • profile management - profiles and associated records
  • text header management - txt record contents
  • node information management - ninfo records for status
  • location management - loc record contents
  • record management - naptr (naming authority pointer) record(s) content
  • group management - groups of readers for privacy settings
  • friend management - friends making up friend groups
  • keyword management - keywords for search indexing
  • export / import - operations to store/retrieve a copy of the data in xml
  • design - operations to adjust colour and other display settings for the proxy

The document assumes that the reader is familiar with basics of the .tel technology. For introductory materials, please read the whitepapers.

  1. AJAX API for TelHosting Software
    1. Method Call Format
  2. Login
    1. login (inputlogin, processresult, processerror)
    2. logout (null, processresult, processerror)
    3. passwordretrieval (inputlogin, processresult, processerror)
  3. wizard
    1. setdashboardpreferences (inputpreferences, processresult, processerror)
    2. getdashboardpreferences (null, processresult, processerror)
  4. Settings
    1. changepassword (inputpassword, processresult, processerror)
    2. getemail (null, processresult, processerror)
    3. changeemail (inputemail, processresult, processerror)
    4. clearrecentlocations (null, processresult, processerror)
    5. setlocallanguage (input, processresult, processerror)
    6. getproxysearchsetting (inputfolder, processresult, processerror)
    7. changeproxysearchsetting (inputsetting, processresult, processerror)
  5. Zone management
    1. checkzone (zone, processresult, processerror)
  6. Folder management
    1. getsubfolderlist (inputfolder, processresult, processerror)
    2. storefolder (inputfolder, processresult, processerror)
    3. renamefolder (inputfolder, processresult, processerror)
    4. deletefolder (inputfolder, processresult, processerror)
    5. setdisplaystring (inputfolder, processresult, processerror)
    6. getdisplaystring (inputfolder, processresult, processerror)
    7. getexpireinfo (domainname, processresult, processerror)
  7. Profile management
    1. getprofilelist (inputprofile, processresult, processerror)
    2. activateprofile (inputprofile, processresult, processerror)
    3. deleteprofile (inputprofile, processresult, processerror)
    4. storeprofile (inputprofile, processresult, processerror)
  8. Text header management
    1. gettextheader (inputtextheader, processresult, processerror)
    2. storetextheader (inputtextheader, processresult, processerror)
    3. deletetextheader (inputtextheader, processresult, processerror)
  9. Node information management
    1. getnodeinfo (inputnodeinfo, processresult, processerror)
    2. storenodeinfo (inputnodeinfo, processresult, processerror)
    3. deletenodeinfo (inputtextheader, processresult, processerror)
  10. Location management
    1. getlocrecord (inputlocrecord, processresult, processerror)
    2. storelocation (inputlocation, processresult, processerror)
    3. deletelocation (inputlocation, processresult, processerror)
    4. savelocationsearchstring (inputsearchstring, processresult, processerror)
    5. getlocationsearchstring (inputsearchstring, processresult, processerror)
  11. Record management
    1. getrecord (inputrecord, processresult, processerror)
    2. getrecordlist (inputrecord, processresult, processerror)
    3. storerecord (inputrecord, processresult, processerror)
    4. getservicekeys (null, processresult, processerror)
    5. getlocations (null, processresult, processerror)
    6. orderrecords (inputrecords, processresult, processerror)
    7. enablerecords (inputrecords, processresult, processerror)
    8. disablerecords (inputrecords, processresult, processerror)
    9. deleterecords (inputrecords, processresult, processerror)
    10. copyrecords (inputrecords, processresult, processerror)
    11. moverecords (inputrecords, processresult, processerror)
    12. getntnaptrrecordlist (inputrecord, processresult, processerror)
    13. storentnaptrrecord (inputrecord, processresult, processerror)
    14. deletentnaptrrecords (inputrecord, processresult, processerror)
    15. getmxrecordlist (inputrecord, processresult, processerror)
    16. getmxrecord (inputrecord, processresult, processerror)
    17. storemxrecord (inputrecord, processresult, processerror)
    18. deletemxrecord (inputrecord, processresult, processerror)
    19. replacemxrecords (inputrecord, processresult, processerror)
  12. Group management
    1. getgrouplist (inputgroup, processresult, processerror)
    2. getgrouprecords (inputgroup, processresult, processerror)
    3. getgroupfriends (inputgroup, processresult, processerror)
    4. addrecordstogroup (inputgroup, processresult, processerror)
    5. removerecordsfromgroup (inputgroup, processresult, processerror)
    6. addrecordstogroups (inputgroup, processresult, processerror)
    7. removerecordsfromgroups (inputgroup, processresult, processerror)
    8. addfriendstogroup (inputgroup, processresult, processerror)
    9. removefriendsfromgroup (inputgroup, processresult, processerror)
    10. storegroup (inputgroup, processresult, processerror)
    11. deletegroup (inputgroup, processresult, processerror)
  13. Friending
    1. checkdomainstate (domain, processresult, processerror)
    2. getsousername (domain, processresult, processerror)
    3. disconnectfromso (domain, processresult, processerror)
    4. getchallenge (credentials, processresult, processerror)
    5. sendchallengeanswer (challengeanswer, processresult, processerror)
    6. pollfromso (inputfolder, processresult, processerror)
    7. getmessagelist (inputfolder, processresult, processerror)
    8. getmessages (messageidlist, processresult, processerror)
    9. acceptrequestmessage (message, processresult, processerror)
    10. acceptrequestmessages (message, processresult, processerror)
    11. acceptinvitationmessages (message, processresult, processerror)
    12. rejectmessages (message, processresult, processerror)
    13. sendfriendingrequest (newreqmessage, processresult, processerror)
    14. sendfriendinginvitation (newinvmessage, processresult, processresult)
    15. getfriendlist (friendinput, processresult, processerror)
    16. deletefriends (friendinput, processresult, processerror)
    17. renamefriend (friendinput, processresult, processerror)
    18. addtoblacklist (messages, processresult, processerror)
  14. Keyword management
    1. getvalidkeywords (null, processresult, processerror)
    2. getkeywords (domain, processresult, processerror)
    3. getsuggestions (inputkeyword, processresult, processerror)
    4. addkeyword (newkeyword, processresult, processerror)
    5. addsecondarykeywords (newkeywords, processresult, processerror)
    6. addkeywordstructure (keyworddata, processresult, processerror)
    7. updatekeyword (keyworddata, processresult, processerror)
    8. deletekeywords (keywords, processresult, processerror)
    9. copykeywords (keywords, processresult, processerror)
    10. movekeywords (keywords, processresult, processerror)
    11. reordersubkeywords (subkeywordorder, processresult, processerror)
  15. Export/import
    1. getvaliddomainstoimport (null, processresult, processerror)
    2. importdomains (domains, processresult, processerror)
    3. exportdomains (http post, no ajax function)
  16. Design
    1. getdesignproperties (domainname, processresult, processerror)
    2. changecolours (inputcolours, processresult, processerror)
    3. changecsstemplate (inputtemplate, processresult, processerror)

Method Call Format

to call a method from this interface, use the namespace for the method's group and the method itself, e.g.:

/g2/json/domain/record/gettextheader.action - this calls method gettextheader to retrieve the txt record for the given domain.

Login

the namespace for this group is: namespace=/g2/json/

login (inputlogin, processresult, processerror)

/**
 * this method is used to login a user;
 * depending on the type of user logging in, a url is returned, which can
 * be used by the dashboard to forward the user;
 * the flag usedtemppassword tells, whether the user is logging in with
 * a temporary password; in this case, the user should prompted to change
 * his password immediately, since he won't be able to log in using this
 * password another time
 */

inputpreferences = {
	username: "johnsmith",
	password: "secret"
};

successresult = {
	success: true,
	usedtemppassword: false,
	urlforward: "http://localhost:8080/ps-server/g2/dashboard.action",
	actionmessages: ["user logged in successfully",
                     	 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["invalid user name or password",
               	       "more errors here..."]
}; 

validation: login (inputlogin, processresult, processerror)

valuenamedescriptionvalidation
usernamelogin allowedcheck login permission based on "allow web login" permissionajax api
usernamelogincheck of combination username and passwordbackend
passwordlogincheck of combination username and passwordbackend

for security reasons, any errors in the combination of username and password or a non existing username will lead to the same error.

logout (null, processresult, processerror)

/**
 * this method is used to logout a user
 */

/** no input needed */

successresult = {
	success: true,
	actionmessages: ["user logged out successfully",
                     	 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["an unexecpted problem occurred",
               	       "more errors here..."]
}; 

validation: logout (null, processresult, processerror)

no validation required as the method does not have any input values

passwordretrieval (inputlogin, processresult, processerror)

/**
 * this method allows the user to reset his password; a valid
 * e-mail address has to be supplied and an an e-mail is sent to this
 * containing new temporary passwords for every user having this
 * address
 */

inputlogin = {
	email: "johnsmith@smith.th"
};

successresult = {
	actionmessages: ["e-mail sent",
                     	 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["e-mail address does not exist",
               	       "more errors here..."]
}; 

validation: passwordretrieval (inputlogin, processresult, processerror)

the input is not validated

wizard

the namespace for this group is: namespace=/g2/json/preferences

setdashboardpreferences (inputpreferences, processresult, processerror)

/**
 * this method sets the four flags for the dashboard preferences; these
 * preferences can be different for each second-level domain
 */

inputpreferences = {
	domainname: "cartman.tel",
	enableprivacy: true,
	enableprofiles: false,
	enablefolders: true,
	displayfriending: true
};

successresult = {
	success: true,
	actionmessages: ["preferences successfully set",
                     	 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot set preferences",
               	       "more errors here..."]
}; 

getdashboardpreferences (null, processresult, processerror)

/**
 * this method returns the four flags for the dashboard preferences
 * of the given (second-level) domain; if a subdomain is submitted, the
 * preferences of its second-level domain are returned
 */

inputpreferences = {
	domainname: "cartman.tel"
};


successresult = {
	success: true,
	enableprivacy: true,
	enableprofiles: false,
	enablefolders: true,
	displayfriending: true
	actionmessages: ["request successful",
                     	 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot get preferences",
               	       "more errors here..."]
}; 

Settings

the namespace for this group is: namespace=/g2/json/settings

changepassword (inputpassword, processresult, processerror)

/**
 * method to change the user's password
 */

inputpassword = {
	newpassword: "secret"
};

successresult = {
	success: true,
	actionmessages: ["password changed successfully",
                     	 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot change password",
               	       "more errors here..."],
	fielderrors: ["newpassword", "invalid password"]
};

validation: changepassword (inputpassword, processresult, processerror)

valuenamedescriptionimplemented
newpasswordpresencechecks if input value is not empty or _null_ajax api

getemail (null, processresult, processerror)

/**
 * method to obtain the user's e-mail address
 */

/** no input needed */

successresult = {
	success: true,
	email: john@smith.org,
	actionmessages: ["email obtained successfully",
                     	 "2nd message here",
                     	 "3rd message here"]
};

errorresult = {
	success: false,
	actionerrors: ["cannot obtain email",
               	       "more errors here..."]
};

changeemail (inputemail, processresult, processerror)

/**
 * method to change the user's e-mail address
 */

inputemail = {
	newemail: "tel@telinc.nic"
};

successresult = {
	success: true,
	actionmessages: ["email changed successfully",
                     	 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot change email",
               	       "more errors here..."],
	fielderrors: ["email", "invalid password"]
};

validation: changeemail (inputemail, processresult, processerror)

valuenamedescriptionimplemented
newemailpresencechecks if input value is not empty or _null_ajax api
newemailemailchecks if input is a valid emailajax api

clearrecentlocations (null, processresult, processerror)

/**
 * method to reset the recent location strings
 */

/** no input needed */

successresult = {
	success: true,
	actionmessages: ["recent location list cleared",
                     	 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot clear recent location list",
               	       "more errors here..."]
};

validation: clearrecentlocations (null, processresult, processerror)

no validation required as method has no input values

setlocallanguage (input, processresult, processerror)

/**
 * set the user's local language, tries to rename some objects (the
 * default profile, the "all friends" group) of the given domain, thus
 * should be called upon initial loading of the dashboard and upon
 * domain change;
 * renaming only occurs if the current name is the name of the object in
 * a supported language (different from the requested one, of course);
 * if the locallanguage parameter is omitted, the browser's
 * language is used as fallback
 * errors occurring during renaming (because an object of the same name
 * already exists) are reported but do not lead to abortion of the
 * operation, i.e. other objects may have been renamed anyway;
 * the returned actionmessages can be used to differentiate between
 * success without any renaming done and success with at least one
 * object name change (s. examples below)
 */

input = {
	domainname: "cartman.tel",
	locallanguage: "de"
};

successresult = {
	success: true,
	actionmessages: ["default object names successfully updated with local language.",
			 "default object names do not need to be updated.",
			 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["please specify a domain name.",
		       "more errors here..."]
};

validation: setlocallanguage (input, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is not empty or _null_ajax api
locallanguagevalidchecks whether the given language is supported by the systemajax api

getproxysearchsetting (inputfolder, processresult, processerror)

/**
* method to obtain the domain's proxy search setting
*/
inputfolder = {
domainname: "cartman.tel"
};
successresult = {
success: true,
searchdomainonly: false,
actionmessages: [""]
};
errorresult = {
success: false,
actionerrors: ["cannot obtain proxy search setting",
"more errors here..."]
};

validation: getproxysearchsetting (inputfolder, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if domain is not empty or nullajax api
domainnameexistencechecks if domain is existing (domain does not exist, if not belonging to user)backend

changeproxysearchsetting (inputsetting, processresult, processerror)

/**
* method to change the user's e-mail address
*/
inputsetting = {
domainname: "cartman.tel",
searchdomainonly: true
};
successresult = {
success: true,
actionmessages: ["the search flag has been updated. it has been limited to your domain."]
};
errorresult = {
success: false,
actionerrors: ["cannot change proxy search setting",
"more errors here..."]
};

!validation: changeproxysearchsetting (inputsetting, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if domain is not empty or nullajax api
domainnameexistencechecks if domain is existing (domain does not exist, if not belonging to user)backend

Zone management

checkzone (zone, processresult, processerror)

/**
 * this method returns information about the existence of a zone with the given name;
 * it may be called to give the user a visual indication regarding whether the zone
 * for the domain he's looking at exists (i.e., whether the domain is "active" and
 * published in dns); in case of a successful call, the "exists" property of the
 * successresult contains true if the zone exists and false otherwise
 */

zone = {
	zonename: "cartman.tel"
};

successresult = {
        success: true,
        actionmessages: ["zone checked successfully."],
        exists: true
};

errorresult = {
        success: false,
        actionerrors: ["some error",
		       "more errors here..."]
};

validation: checkzone (zone, processresult, processerror)

valuenamedescriptionimplemented
zonenamepresencechecks if input value is present and not _null_ajax api

Folder management

the namespace for this group is: namespace=/g2/json/domain/

getsubfolderlist (inputfolder, processresult, processerror)

/** 
 * retrieve the list of subfolders for the given folder (i.e. domain) name;
 * if the domainname is "tel", a list of all folders of the current user is
 * returned;
 * the input domain name is never returned, so the resulting list may be empty
 * the boolean parameter recursive determines whether all subdomains are
 * returned (true) or only the direct subdomains (false)
 */


input = {
	domainname: "tel",  /** gets a list of all folders */
	recursive: true
};

successresult = {
	success: true,
	folderlist: [{id: 12, name: "cartman.tel", soconnection: "active"},
		     {id: 23, name: "stan.cartman.tel", soconnection: "uninitialised"},
		     {id: 14, name: "henry.tel", soconnection: "incomplete"}],
	actionmessages: ["request successful",


                     	 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot get folder list",
               	       "more errors here..."]
}; 

validation: getsubfolderlist (inputfolder, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
recursivetype cast checkchecks if value is a boolean valuejson framework

storefolder (inputfolder, processresult, processerror)

/** 
 * add a new folder;
 * the complete domain name of the new folder has to be provided;
 * the id of the new folder will be supplied in case of success 
 */

inputfolder = {
	domainname: "stan.cartman.tel"
};

successresult = {
	success: true,
	domainid: 25,
	actionmessages: ["folder added",
                     	 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot add folder",
               	       "more errors here..."],
	fielderrors: ["domainname", "invalid domain name"]
}; 

validation: storefolder (inputfolder, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnamevalidationchecks if domain name is validajax api
domainnameexistencechecks if domain has not been created beforebackend
domainnamedomain create permissioncheck for permission to create domain based on secondary user rightsbackend
domainnamedomain quotacheck for permission to create domain based on "max. number of domains" permission for sec. usersbackend
domainnamedomain quotacheck for permission to create domain based on "max. number of domains" permission for primary usersbackend
domainnamelabel quotacheck for permission to create domain based on "max. number of etrecords" permissionbackend
domainnamezone existencecheck if zone must exist based on user permissionsbackend
domainnamezone quotacheck for permission to create domain based on "max. number of labels" zone permissionbackend
domainnamedomain quotacheck for permission to create domain based on "max. number of domains" zone permissionbackend

renamefolder (inputfolder, processresult, processerror)

/** 
 * rename a folder;
 * the complete domain name of the old and new folder name has to be provided;
 * the id of the new folder will stay the same; both domain names must be a
 * direct sub-domain of the same domain and they may not be apex domains;
 * all sub-domains of the domain to be renamed are renamed as well; furthermore
 * all non-terminal naptrs (domain links) of the current user are checked if they
 * point to the old domain name or one of its sub-domains, if so the naptrs will be
 * renamed accordingly; all other domain properties (records, profiles, groups,
 * etc.) remain as they are;
 */

inputfolder = {
	domainname: "stan.cartman.tel"
	newdomainname: "john.cartman.tel"
};

successresult = {
	success: true,
	actionmessages: ["folder renamed",
                     	 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot rename folder",
               	       "more errors here..."],
	fielderrors: ["newdomainname", "invalid domain name"]
}; 

validation: renamefolder (inputfolder, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain the domain exists and is not a root domainbackend
newdomainnamepresencechecks if input value is present and not _null_ajax api
newdomainnameexistencechecks if domain has not been created beforebackend
newdomainnamevalidationchecks if domain name is validajax api

deletefolder (inputfolder, processresult, processerror)

/** 
 * delete a folder;
* the complete domain name of the folder has to be provided; the folder
* including all subdomains will be deleted; the folder must not be a
* root domain
 */

inputfolder = {
	domainname: "test.cartman.tel"
};

successresult = {
	success: true,
	actionmessages: ["folder deleted"
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot delete root domain",
               	       "more errors here..."]
}; 

validation: deletefolder (inputfolder, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain existsbackend

setdisplaystring (inputfolder, processresult, processerror)

/** 
 * set the domain display string for this domain; if the display string is
 * missing or set to the empty string, the domain display string is removed
 */

inputfolder = {
	domainname: "stan.cartman.tel",
	displaystring "stan cartman: my domain"
};

successresult = {
	success: true,
	actionmessages: ["domain display string set",
                     	 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot set domain display string",
               	       "more errors here..."],
	fielderrors: ["newdomainname", "invalid domain name"]
}; 

validation: setdisplaystring (inputfolder, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain the domain existsbackend
displaystringlengthchecks if the byte representation is more than 255 bytesbackend

getdisplaystring (inputfolder, processresult, processerror)

/** 
 * get the domain display string for this domain; if the display string is
 * not set the method returns null as the display string
 */

inputfolder = {
	domainname: "stan.cartman.tel"
};

successresult = {
	success: true,
	displaystring: "stan's domain",
	actionmessages: ["domain display string retrieved",
                     	 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot get domain display string",
               	       "more errors here..."],
	fielderrors: ["newdomainname", "invalid domain name"]
}; 

validation: setdisplaystring (inputfolder, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain the domain existsbackend

getexpireinfo (domainname, processresult, processerror)

/**
* get expire information for domainname
*
* returns "this domain is due to expire on ..." if domain expires within the next 30 days
* returns "this domain expired ..." if domain expired within the last 45 days
* returns null in any other case
*/
domainname = {
domainname: "cartman.tel"
};
successresult = {
success: true,
date : null,
actionmessages: null,
displaystring: "this domain is due to expire on tuesday 23 mar 2010 27 2332800000!. to avoid losing this name please contact your domain provider and request a renewal."
};

validation: getexpireinfo (domainname, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_backend
domainnameexistencechecks if domain has a dns entrybackend

Profile management

the namespace for this group is: namespace=/g2/json/domain/profile

getprofilelist (inputprofile, processresult, processerror)

/** 
 * retrieve the list of profiles for the specified domain;
 * the successresult contains the profilelist, consisting of id and name
 * of the profile as well as flags whether it is the default and/or
 * active profile and a list of ids of the records belonging to this
 * profile;
 * an optional parameter simpleversion may be added; if missing it is set
 * to false with no change; if set to true, the request will not return
 * the recordids, this list will always be null;
 */

inputprofile = {
	domainname: "cartman.tel"
};

successresult = {
	success: true,
	profilelist: [{id: 12, name: "paris", isdefault: false,
		       isactive: true, recordids: [12,34,1,4]},
		      {id: 23, name: "london", isdefault: true,
		       isactive: false, recordids: [12,1,2]}],
	actionmessages: ["request successful",
                     	 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot get profile list",
               	       "more errors here..."]
}; 

validation: getprofilelist (inputprofile, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain is existingbackend

activateprofile (inputprofile, processresult, processerror)

/** 
 * activate a profile (defined by its id) for a given domain
 */

inputprofile = {
	domainname: "cartman.tel",
	profileid: 23
};

successresult = {
	success: true,
	actionmessages: ["profile activated",
                     	 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot activate profile",
               	       "more errors here..."]
}; 

validation: activateprofile (inputprofile, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain is existingbackend
profileidpresencechecks if input value is present and not _null_ajax api & backend

deleteprofile (inputprofile, processresult, processerror)

/** 
 * delete a profile (defined by its id) for a given domain
 */

inputprofile = {
	domainname: "cartman.tel",
	profileid: 23
};

successresult = {
	success: true,
	actionmessages: ["profile deleted"
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot delete profile",
               	       "more errors here..."]
};

validation: deleteprofile (inputprofile, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain is existingbackend
profileidpresencechecks if input value is present and not _null_ajax api & backend
profileiddeleteablecheck if profile is not the default profile (which is not allowed to delete)backend

storeprofile (inputprofile, processresult, processerror)

/** 
 * stores a profile of the given name in the given domain;
 * in case the profile id is set to 0, a new profile will be created (and
 * its id will be returned on success); for non-zero profile ids an
 * existing profile will be renamed (in this case the returned
 * id is the same as the one input)
 */

inputprofile = {
	domainname: "cartman.tel",
	profileid: 13,
	newprofilename: "holiday"
};

successresult = {
	success: true,
	profileid: 13,
	actionmessages: ["profile stored"
			 "2nd message here",
			 "3rd message here"]
};

errorresult = {
	success: false,
	actionerrors: ["cannot store profile",
               	       "more errors here..."],
	fielderrors: ["profilename", "invalid profile name"]
};

validation: storeprofile (inputprofile, processresult, processerror)

valuenamedescriptionimplemented
profileidpresencechecks if input value is present and not _null_ajax api & backend
profileidprofile quotain case of a new profile (id=0) check if the profile can be created based on "max. number of profiles" domain permissionbackend
domainnameexistencecheck if the domain is existingbackend
domainnamepresencechecks if input value is present and not _null_ajax api
newprofilenameuniquenesscheck if profile name is only used oncebackend

Text header management

the namespace for this group is: namespace=/g2/json/domain/record

gettextheader (inputtextheader, processresult, processerror)

/** 
 * retrieve the text header of a profile (defined by its id) for the given
 * domain; if there is more than one text header in the profile, the text
 * header with the lowest api id is returned
 */

inputtextheader = {
	domainname: "cartman.tel",
	profileid: 23
};

successresult = {
	success: true,
	text: "this is my text header",
        apiid: 12,
	actionmessages: "request successful",
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot get text header",
               	       "more errors here..."]
}; 

validation: gettextheader (inputtextheader, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencecheck if the domain existsbackend
profileidexistencechecks if porfile existsbackend

storetextheader (inputtextheader, processresult, processerror)

/** 
 * create or edit the text header of a profile (defined by its id) for the
 * given domain if the apiid is 0, a new text header will be created for the
 * given profileid, if it is non-zero, the text record of the given apiid
 * will be changed and the profileid will simply be ignored;
 * note: due to the uniqueness constraint of the text header for each
 * profile it may  be the case that even though a specific record (defined
 * by its api id) is given to store, it may obtain a new api id; hence the
 * returned api id must always be checked and updated if necessary;
 *
 * as background information: the text header record has to be unique for
 * its profile; therefore, saving a text record can lead to several (maybe
 * unexpected) side effects, which are listed here for clarification:
 * in order to have just one text record in the profile, all other text
 * records will be removed from the profile by calling this method; if
 * removing a text record from the profile will make it abandoned
 * (i.e., not belonging to any profile any more), it will be deleted; this
 * is to make sure this method does not produce data garbage;
 * a second use case to consider is that this message edits a text record,
 * which belongs not only to this profile, but also to other profiles; just
 * editing it, would display the edited version also for the other profiles,
 * which is not something the user would expect; therefore the text record
 * itself will be removed from this profile, but otherwise left untouched;
 * a new text record will then be created for this profile and stored;
 * again, all other records in this profile will be removed and if
 * abandoned deleted
 */

inputtextheader = {
	domainname: "cartman.tel",
	apiid: 23, /** may be 0 if text header is not yet set */
	profileid: 2, /** only needed if apiid is 0, else ignored */
	text: "lorem ipsum dolor sit amet consectateur..."
};

successresult = {
	success: true,
	actionmessages: ["text header changed"
			 "2nd message here",
                     	 "3rd message here"],
	apiid: 23, /** warning: can be different from the supplied one==  */
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot change text header",
               	       "more errors here..."]
};

validation: storetextheader (inputtextheader, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencecheck if the domain existsbackend
textpresencechecks if input is not _null_ajax api
profileidexistencechecks if porfile existsbackend
apiidexistencechecks if apiid exists, if id = 0backend

deletetextheader (inputtextheader, processresult, processerror)

/** 
 * deletes the text record with the given apiid
 */

inputtextheader = {
	domainname: "cartman.tel",
	apiid: 23
};

successresult = {
	success: true,
	actionmessages: ["text header deleted"
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot delete text header",
               	       "more errors here..."]
};

validation: deletetextheader (inputtextheader, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
apiidexistencechecks if apiid existsbackend

Node information management

getnodeinfo (inputnodeinfo, processresult, processerror)

/** 
 * this has the same functionality as gettextheader
 */

storenodeinfo (inputnodeinfo, processresult, processerror)

/** 
 * this has the same functionality as storetextheader
 */

deletenodeinfo (inputtextheader, processresult, processerror)

/** 
 * this has the same functionality as deletetextheader
 */

Location management

the namespace for this group is: namespace=/g2/json/domain/record

getlocrecord (inputlocrecord, processresult, processerror)

/** 
 * retrieve the (only) location record for the given domain;
 * only the apiid, latitude and longitude associated with the
 * location record are returned
 */

inputlocrecord = {
	domainname: "cartman.tel"
};

successresult = {
	success: true,
	apiid: 23,
	latitude: 1.0001,
	longitude: 0.1110,
	actionmessages: "request successful",
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot get location record",
               	       "more errors here..."]
};

validation: getlocrecord (inputlocrecord, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain existsbackend

storelocation (inputlocation, processresult, processerror)

/**
 * create or edit the location record of a domain;
 * if the apiid is 0 (and no other location record exists), a new
 * location record will be created, if it is non-zero,
 * the location record of the given id will be changed;
 * note that only the latitude and longitude of the location are changed,
 * since these are the only values googlemap can handle; all other
 * values (i.e., altitude, size, horizontal precision, and vertical
 * precision) which are visible in the dns are set to a default value
 * (when creating a new location record) or left unchanged (when editing a
 * location record); in case of success, the (new) api id of the location
 * record will be returned; if the record was only edited, the api id will
 * stay the same
 */


inputlocation = {
	domainname: "cartman.tel",
	apiid: 23, /** may be 0 if location is not yet set */
	latitude: 1.0001,
	longitude: 0.1110
};

successresult = {
	success: true,
	apiid: 23,
	actionmessages: ["location changed"
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot change location",
               	       "more errors here..."],
	fielderrors: ["latitude", "latitude invalid",
		      "longitude", "longitude invalid"]
};

validation: storelocation (inputlocation, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain existsbackend
apiidexistencechecks if id / record exists, if id = 0backend
groupidsexistencechecks if group ids are existingbackend
latitudepresencechecks if input value is present and not _null_ajax api
longitudepresencechecks if input value is present and not _null_ajax api

deletelocation (inputlocation, processresult, processerror)

/**
 * deletes a location record defined by its api id
 */

inputlocation = {
	domainname: "cartman.tel",
	apiid: 23
};

successresult = {
	success: true,
	actionmessages: ["location deleted"
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot delete location",
               	       "the record is not a location record.",
               	       "more errors here..."]
};

validation: deletelocation (inputlocation, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain existsbackend
apiidexistencechecks if id / record existsbackend
apiidtype checkchecks if record for given id is a loc recordajax api

savelocationsearchstring (inputsearchstring, processresult, processerror)

/** 
 * save a location search string (as entered in the text field) for
 * display in the "recent locations" select box;
 * search strings are user-specific, so no domain name needs to be specified;
 * in case of success, the current list of recent location search strings
 * will be returned; this list always contains the last ten entered search
 * strings
 */

inputsearchstring = {
	searchstring: "21 oxford street, london"
};

successresult = {
	success: true,
	list: ["21 oxford street, london", 
               "another location", 
               "yet another one"],
	actionmessages: ["search string saved"
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot save search string",
               	       "more errors here..."],
	fielderrors: ["searchstring", "search string invalid"]
};

validation: savelocationsearchstring (inputsearchstring, processresult, processerror)

no validation is required as the input can be arbitrary strings

getlocationsearchstring (inputsearchstring, processresult, processerror)

/** 
 * returns the current list of recent location search strings;


 * search strings are user-specific, so no domain name needs to be specified;
 * the list always contains the last ten entered search strings;
 * no input is needed for the method
 */


successresult = {
	success: true,
	list: ["21 oxford street, london", 
               "another location", 
               "yet another one"],
	actionmessages: ["search string saved"
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot save search string",
               	       "more errors here..."],
	fielderrors: ["searchstring", "search string invalid"]
};

validation: savelocationsearchstring (inputsearchstring, processresult, processerror)

no validation is required as the method has not input values

Record management

the group manages terminal and non-terminal naptr records.

the namespace for this group is: namespace=/g2/json/domain/record

getrecord (inputrecord, processresult, processerror)

/**
* gets a contact (naptr) record for the given domain;
* the returned data contains a map, consisting of the api id, a flag
* saying whether it is a terminal or non-terminal naptr, its value,
* the list of group ids the record belongs to, the
* list of profile ids the record belongs to, the global flag to tell
* whether the record is global for this domain, i.e., belonging to
* all profiles, and the list of locations; in case of a terminal naptr
* the list of service keys, its label, and an additional flag are also
* returned to determine whether the record is editable or not
*/
inputrecord = {
	domainname: "cartman.tel",
	apiid: 42
};

successresult = {
	success: true,
	domainid: 123,
	recorddata: {apiid: 23, terminal: true,
		     servicekeys: ["voice", "fax"], value: "+34.34343443",
		     label: "my home number", groups: [1, 3],
		     profiles: [12, 23], global: false,
		     locations: ["x-home", "x-mobile"], editable: true,
		     longlabel: "this is my home number."},
	actionmessages: ["request successful",
			 "2nd message here",
                     	 "3rd message here"]
};

errorresult = {
	success: false,
	actionerrors: ["profile id does not exist",
		       "cannot get record list",
               	       "more errors here..."]
}; 

validation: getrecord (inputrecord, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
domainnameexistencechecks if domain is existingbackend

getrecordlist (inputrecord, processresult, processerror)

/**
 * gets the list of contact (naptr) records for the given domain and
 * profile; in order to get a complete list of records for a given domain,
 * the profile id can be set to -1; the flag includenonterminals determines
 * whether only terminal naptrs or also non-terminal naptrs should be listed;
 * the returned list contains a map for each record, consisting of its api
 * id, a flag saying whether it is a terminal or non-terminal naptr, its
 * value, the list of group ids the record belongs to, the
 * list of profile ids the record belongs to, the global flag to tell
 * whether the record is global for this domain, i.e., belonging to all
 * profiles, and the list of locations; in case of a terminal naptr also
 * the list of service keys, its label, and an additional flag is
 * returned to determine whether the record is editable or not
 */

inputrecord = {
	domainname: "stan.cartman.tel",
	profileid: 12, /** use -1 to get all records of the domain */
        includenonterminals: true
};

successresult = {
	success: true,
	domainid: 12,
	recordlist: [{apiid: 23, terminal: true,
		      servicekeys: ["voice", "fax"], value: "+34.34343443",
		      label: "my home number", groups: [1, 3],
		      profiles: [12, 23], global: false,
		      locations: ["x-home", "x-mobile"], editable: true,
		      longlabel: "some text to describe my home number"},
		     {apiid: 12, terminal: true, servicekeys: ["web"],
		      value: "www.telnic.org", label: "my homepage",
		      groups: [3], profiles: [], global: true,
		      locations: ["x-home"], editable: true},
		     {apiid: 12, terminal: false, value: "stan.cartman.tel.",
		      groups: [3], profiles: [], global: true,
		      longlabel: "see my infos for stan"}],
	actionmessages: ["request successful",
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["profile id does not exist",
		       "cannot get record list",
               	       "more errors here..."]
}; 

validation: getrecordlist (inputrecord, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
domainnameexistencechecks if domain existsbackend
profileidexistenceif profileid = -1, check if profile existscombination of ajax api & backend

storerecord (inputrecord, processresult, processerror)

/**
 * stores a single record for the given domain name; in case the api id is
 * set to 0, a new record will be created (and its new api id will be
 * returned on success); for non-zero api ids an existing record will be
 * changed
 * apart from the necessary service keys and the value, there are also the
 * optional parameters label, longlabel, groups, profiles, and locations; these
 * may be set to the empty string or empty list respectively;
 * in case of success, the (new) api id of the record will be returned; if
 * the record was only edited, the api id will stay the same
 */

inputrecord = {
	domainname: "cartman.tel",
	apiid: 0,
	servicekeys: ["voice", "fax"],
	value: "+34.34343443",
	label: "my home number",
	groups: [1, 2, 3],
	profiles: [12, 23, 47],
	locations: ["x-home"],
	longlabel: "some more details about my home number"
};

successresult = {
	success: "true",
	actionmessages: ["record stored successfully",
			 "2nd message here",
			 "3dmessage here"],
	apiid: 17
};

errorresult = {
	success: "false",
	actionerrors: ["cannot store record",
		       "record data invalid",
		       "more errors here..."],
	fielderrors: ["value", "value invalid== "]
}; 

validation: storerecord (inputrecord, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain existsbackend
apiidexistenceif apiid = 0, check if a domain with the given apiid existsbackend
servicekeysprivilegeschecks, if the user is allowed to use the given services based on "allowed record types" permissionbackend
servicekeysallow generic checks, if user is allowed to use generic record types based on permission "allowed generic record types"backend
groupsexistencechecks, if groups with given ids exist (for logged in user)backend
profilesexistencechecks, if profiles with given ids exist (for logged in user)backend
servicekeys, value, labelnaptr limitchecks if record does not exceed encrytable naptr limitsbackend
longlabellengthchecks that the long label does not exceed 255 charactersbackend

getservicekeys (null, processresult, processerror)

/**
 * this method does not need any input; it returns the list of possible
 * service keys, their internationalized display version, and their id;
 * the id will only be used for universal naptrs set up in this partition,
 * all other service keys will have an id of -1
 */

/** no input needed */

successresult = {
	success: true,
	servicekeys: [{key: "voice", label: "voice call", id: -1},
	{key: "fax", label: "fax", id: -1},
	{key: "x-c2c", label: "click2communicate", id: 21}],
	actionmessages: "request successful",
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot get service keys",
               	       "more errors here..."]
}; 

validation:getservicekeys (null, processresult, processerror)

no validation is required as the method has not input values

getlocations (null, processresult, processerror)

/**
 * this method does not need any input; it returns the list of possible
 * location keys (and their internationalized display version) for
 * resource records, e.g., x-home, x-work, x-main; the result is a list of
 * strings, such that the key is followed by the
 * internationalized version
 */

/** no input needed */

successresult = {
	success: true,
	locations: ["x-home", "home", "x-work", "work", "x-main",
		      "main contact"],
	actionmessages: "request successful",
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot get locations",
               	       "more errors here..."]
}; 

validation:getlocations (null, processresult, processerror)

no validation is required as the method has not input values

orderrecords (inputrecords, processresult, processerror)

/**
 * this method defines a new order on the record list for a given domain;
 * the new order is submitted as a list of api ids; in case of success the
 * records are altered at the backend such that they reflect the new order;
 * in case of failure the current order of the records from the backend is
 * returned such that the frontend can update its list accordingly;
 * this request will fail if the list of api ids is incomplete or if there
 * is an api id, which does not exist at the backend; note that the list
 * has to contain all terminal and non-terminal records of the specified
 * domain if includenonterminals is set to true; the function should be
 * used with the same flag value as  getrecordlist
 */

inputrecords = {
	domainname: "cartman.tel",
        includenonterminals: true
	apiids: [23, 31, 1, 45, 2, 22]
};

successresult = {
	success: true,
	actionmessages: ["records reordered"
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	oldapiids: [1, 2, 22, 23, 31, 45],
	actionerrors: ["cannot reorder records",
               	       "more errors here..."]
};

validation: orderrecords (inputrecords, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain existsbackend
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
apiidsmissingchecks, if all records in list are belonging to given domainajax
apiidscompletenesschecks, if given list has not more or less elements as currently stored for given domainajax

enablerecords (inputrecords, processresult, processerror)

/**
* this method enables the given list of records for the given list of profiles;
* the list of profiles may be empty (no changes done) or contain the
* single entry -1 to enable the records in all profiles;
 * the method will be lenient in such a way that it will not produce an
 * error if one ore more of the input records are already enabled in the
 * given profiles;
 *
 * as background information: enabling a record for a profile means that
 * this record will be added to the profile
 */

inputrecords = {
	domainname: "cartman.tel",
	profiles: [23, 35],
	apiids: [23, 2, 22]
};

successresult = {
	success: true,
	actionmessages: ["records enabled"
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot enable records",
               	       "more errors here..."]
};

validation: enablerecords (inputrecords, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks whether domain existsbackend
domainnamepresencechecks whether input value is present and not _null_ajax api
domainnameprivilegeschecks whether the logged in user has the rights to access the domain based on usertype and domain delegationbackend
profilesspecial valueif special value -1 is present, checks whether it is the only id in the listajax api
profilesexistencechecks whether profiles with given ids exist (if -1 is not present)backend
apiidscompletenesschecks whether given list of ids does only contain records belonging to domainnameajax api

disablerecords (inputrecords, processresult, processerror)

/**
* this method disables the given list of records for the given list of profiles;
* the list of profiles may be empty (no changes done) or contain the
* single entry -1 to disable the records in all profiles;
 * the method will be lenient in such a way that it will not produce an
 * error if one ore more of the input records are already disabled in the
 * given profiles;
 *
 * as background information: disabling a record for a profile means that
 * this record will be removed from the profile
 */

inputrecords = {
	domainname: "cartman.tel",
        profiles: [-1],
	apiids: [23, 2, 22]
};

successresult = {
	success: true,
	actionmessages: ["records disabled"
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot disable records",
               	       "more errors here..."]
};

validation: disablerecords (inputrecords, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks whether domain existsbackend
domainnamepresence|checks whether input value is present and not _null_ajax api
domainnameprivilegeschecks whether the logged in user has the rights to access the domain based on usertype and domain delegationbackend
profilesspecial valueif special value -1 is present, checks whether it is the only id in the listajax api
profilesexistencechecks whether profiles with given ids exist (if -1 is not present)backend
apiidscompletenesschecks whether given list of ids does only contain records belonging to domainnameajax api

deleterecords (inputrecords, processresult, processerror)

/**
 * this method deletes the given list of records;
 *
 * as background information: deleting a record has an effect on all 
 * profiles of the given domain;
 */

inputrecords = {
	domainname: "cartman.tel",
	apiids: [23, 2, 22]
};

successresult = {
	success: true,
	actionmessages: ["records deleted"
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot delete records",
               	       "more errors here..."]
};

validation: deleterecords (inputrecords, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain existsbackend
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
apiidsexistencechecks if records with given ids existbackend

copyrecords (inputrecords, processresult, processerror)

/**
 * this method creates copies of the records whose api ids are given;
 * each copy will be added as a new record to the given destination domain
 * name; the ids of the newly created records will be returned as a list;
 * the new records will retain their service keys, values, labels, and 
 * locations, but their groups and profiles will be reset to empty lists,
 * since the destination domain will not have the same groups and profiles;
 * however, records will be assigned to the destination
 * domain's default profile if they belonged to the source domain's
 * default profile
 */

inputrecords = {
	domainname: "cartman.tel",
	apiids: [23, 2, 22],
	destinationdomainname: "stan.tel"
};

successresult = {
	success: true,
	newapiids: [27, 28, 29],
	actionmessages: ["records copied"
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot copy records",
               	       "more errors here..."],
	fielderrors: ["destinationdomainname", "domain does not exist"]
};

validation: copyrecords (inputrecords, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain existsbackend
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
apiidsexistencechecks if ids exist and accessible for logged in userbackend
destinationdomainnameexistencechecks, destination with given id exists and accessible for userbackend

moverecords (inputrecords, processresult, processerror)

/**
 * this method works similarly to copyrecords; it 'moves' the records
 * whose api ids are given to the destination domain; the records will not
 * be able to retain their api ids and will be assigned new ones; they will
 * retain the service keys, values, labels, and locations,
 * but their groups and profiles will be reset to empty lists,
 * since the destination domain will not have the same groups and profiles;
 * however, records will be assigned to the destination
 * domain's default profile if they belonged to the source domain's
 * default profile
 * the ids of the moved records will be returned as a list
 */

inputrecords = {
	domainname: "cartman.tel",
	apiids: [23, 2, 22],
	destinationdomainname: "stan.tel"
};

successresult = {
	success: true,
	newapiids: [27, 28, 29],
	actionmessages: ["records moved"
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot move records",
               	       "more errors here..."],
	fielderrors: ["destinationdomainname", "domain does not exist"]
};

validation: moverecords (inputrecords, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain existsbackend
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
apiidsexistencechecks if ids exist and accessible for logged in userbackend
destinationdomainnameexistencechecks, destination with given id exists and accessible for userbackend

getntnaptrrecordlist (inputrecord, processresult, processerror)

/**
 * gets the list of link (non-terminal naptr) records for the given
 * domain and profile; in order to get a complete list of link records
 * for a given domain, the profile id can be set to -1; the returned
 * list contains map for each record, consisting of its api id, the
 * value (i.e., the link itself), the list of group ids the record
 * belongs to, the list of profile ids the record belongs to, and
 * the global flag to tell whether the record is global for this domain,
 * i.e., belonging to all profiles;
 */

inputrecord = {
	domainname: "cartman.tel",
	profileid: 12   /** use -1 to get all links of the domain */
};

successresult = {
	success: true,
	domainid: 12,
	recordlist: [{apiid: 23, value: "test.cartman.tel.",
		      groups: [1, 3], profiles: [12, 23],
		      global: false, longlabel: null},
		      {apiid: 12, value: "stan.cartman.tel.",
		      groups: [3], profiles: [], global: true,
		      longlabel: "some text"}],
	actionmessages: ["request successful",
			 "2nd message here",
                     	 "3rd message here"]
};

errorresult = {
	success: false,
	actionerrors: ["profile id does not exist",
		       "cannot get record list",
               	       "more errors here..."]
};

validation: getntnaptrrecord (inputrecord, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain existsbackend
profileidexistenceif profileid != -1, check if a profile with the given id existsbackend

storentnaptrrecord (inputrecord, processresult, processerror)

/**
 * stores a single non-terminal naptr record for the given domain name;
 * in case the api id is set to 0, a new record will be created (and its
 * new api id will be returned on success); for non-zero api ids an
 * existing record will be changed;
 * apart from domain name and apiid the value has to be provided; this
 * is the link the record points to; if the value is not ended with a
 * dot, the value is taken as relative to the given domain name, e.g.,
 * domainname="cartman.tel" and value="test.tel" will result in a link
 * to "test.tel.cartman.tel.", whereas "value.tel." will result in a
 * link to "value.tel.";
 * in case of success, the (new) api id of the record will be returned;
 * if the record was only edited, the api id will stay the same
 */

inputrecord = {
	domainname: "cartman.tel",
	apiid: 0,
	value: "test",
	groups: [],
	profiles: [],
	globalprofile: true,
	longlabel: "some text"

};

successresult = {
	success: true,
	actionmessages: ["record stored successfully",
			 "2nd message here",
			 "3dmessage here"],
	apiid: 17
};

errorresult = {
	success: false,
	actionerrors: ["cannot store record",
		       "record data invalid",
		       "more errors here..."]
};

validation: storentnaptrrecord (inputrecord, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain is existingbackend
apiidexistenceif apiid != 0, check if a non-terminal naptr with the given apiid is existingbackend
groupsexistencechecks, if groups with given ids are existing (for logged in user)backend
profilesexistencechecks, if profiles with given ids are existing (for logged in user)backend
longlabellengthchecks that the long label does not exceed 255 charactersbackend
valuevalidationchecks that the value is a valid domain namebackend

deletentnaptrrecords (inputrecord, processresult, processerror)

/**
 * deletes all non-terminal naptr records having the same value as the
 * given value, i.e., all records that link to the given value; if the
 * value is not an absolute domain name, it is taken relative to the
 * given domainname, e.g., domainname = "cartman.tel" and value = "test"
 * will delete all non-terminal naptr records having "test.cartman.tel" 
 * as their link target;
 * the message will return no error if there is no matching non-terminal
 * naptr record;
 *
 * note, that it is also possible to use the deleterecors method to
 * delete non-terminal naptr records by their api id
 */

inputrecord = {
	domainname: "cartman.tel",
	value: "test.cartman.tel."
};

successresult = {
	success: true,
	actionmessages: ["record(s) deleted successfully",
			 "2nd message here",
			 "3dmessage here"]
};

errorresult = {
	success: false,
	actionerrors: ["cannot delete record",
		       "more errors here..."]
};

validation: deletentnaptrrecords (inputrecord, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain is existingbackend
apiidexistenceif apiid != 0, check if a non-terminal naptr with the given apiid is existingbackend
groupsexistencechecks, if groups with given ids are existing (for logged in user)backend
profilesexistencechecks, if profiles with given ids are existing (for logged in user)backend
longlabellengthchecks that the long label does not exceed 255 charactersbackend
valuevalidationchecks that the value is a valid domain namebackend

getmxrecordlist (inputrecord, processresult, processerror)

/**
 * gets the list of mx records for the given domain;
 * the returned list contains a map for each record, consisting of
 * its api id, the exchange value, the priority value, the list of
 * profile ids the record belongs to, and the global flag to tell
 * whether the record is global for this domain, i.e., belonging to
 * all profiles
 */

inputrecord = {
  domainname: "cartman.tel"
};

successresult = {
  success: true,
  domainid: 1,
  recordlist: [{
    "apiid": 53,
    "exchange": "neues.beispiel.de.",
    "global": false,
    "priority": 0,
    "profiles": [2]
  },
  {
    "apiid": 33,
    "exchange": "beispiel.de.",
    "global": true,
    "priority": 0,
    "profiles": []
  }],
  actionmessages: ["request successful",
                   "2nd message here",
                   "3rd message here"]
};

errorresult = {
  success: false,
  actionerrors: ["domain does not exist",
                 "cannot get record list",
                 "more errors here..."]
};

validation: getmxrecordlist (inputrecord, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain is existingbackend

getmxrecord (inputrecord, processresult, processerror)

/**
 * gets an mx record for the given domain;
 * the returned data contains a map, consisting of the api id, its
 * exchange value, its priority value, the list of profile ids the
 * record belongs to and the global flag to tell whether the record
 * is global for this domain, i.e., belonging to all profiles
 */

inputrecord = {
  domainname: "cartman.tel",
  apiid: 42
};

successresult = {
  success: true,
  domainid: 1,
  recorddata: {
    "apiid": 33,
    "exchange": "beispiel.de.",
    "global": true,
    "priority": 10,
    "profiles": []
  },
  actionmessages: ["request successful",
                   "2nd message here",
                   "3rd message here"]
};

errorresult = {
  success: false,
  actionerrors: ["domain does not exist",
                 "record does not exist",
                 "more errors here..."]
}; 

validation: getmxrecord (inputrecord, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
domainnameexistencechecks if domain is existingbackend

storemxrecord (inputrecord, processresult, processerror)

/**
 * stores a single mx record for the given domain name;
 * in case the api id is set to 0, a new record will be created (and its
 * new api id will be returned on success); for non-zero api ids an
 * existing record will be changed;
 * apart from domain name and apiid the exchange and priority values have
 * to be provided; if the exchange value does not end with a dot, it is
 * taken as relative to the given domain name, e.g.,
 * domainname="cartman.tel" and value="mail" will result in a link
 * to "mail.cartman.tel.", whereas "value.tel." will result in a
 * link to "value.tel.";
 * in case of success, the (possibly new) api id of the record will be
 * returned, if the record was only edited, the api id will stay the same
 */

inputrecord = {
  domainname: "cartman.tel",
  apiid: 0,
  exchange: "beispiel.de.",
  priority: 42,
  profiles: [],
  globalprofile: true
};

successresult = {
  success: true,
  apiid: 17,
  actionmessages: ["record stored successfully",
                   "2nd message here",
                   "3dmessage here"]
};

errorresult = {
  success: false,
  actionerrors: ["cannot store record",
                 "record data invalid",
                 "more errors here..."]
};

validation: storemxrecord (inputrecord, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain is existingbackend
apiidexistenceif apiid != 0, check if an mx with the given apiid is existingbackend
exchangevalidchecks whether value is a valid domain nameajax api
priorityrangechecks whether 0 <= priority <= 65535ajax api

deletemxrecord (inputrecord, processresult, processerror)

/**
 * deletes an mx record specified by its api id;
 * the message will return no error if there is no matching mx record
 */

inputrecord = {
  domainname: "cartman.tel",
  apiid: 26
};

successresult = {
  success: true,
  actionmessages: ["record deleted successfully",
                   "2nd message here",
                   "3dmessage here"]
};

errorresult = {
  success: false,
  actionerrors: ["cannot delete record",
                 "more errors here..."]
};

validation: deletemxrecord (inputrecord, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain is existingbackend
apiidexistencechecks that a record of the given api id existsbackend

replacemxrecords (inputrecord, processresult, processerror)

/**
 * replaces all exisintg mx records of the given domain;
 * mx records with api ids not specified in the request will be deleted,
 * those with api ids specified will be updated, records in the request
 * that have an api id of 0 will be created;
 * the data provided for each mx record is the same as for storemxrecord;
 * in case of success, the (possibly new) api ids of the records will be
 * returned
 */

inputrecord = {
  domainname: "cartman.tel",
  recordlist: [
    { apiid: 0, exchange: "mail", priority: 21,
      profiles: [], globalprofile: true },
    { apiid: 33, exchange: "another.mail", priority: 10,
      profiles: [1, 2], globalprofile: false },
    { apiid: 0, exchange: "absolute.mail.example.org.", priority: 21,
      profiles: [3, 4, 2], globalprofile: false }
  ]
};

successresult = {
  success: true,
  apiids: [101, 33, 102],
  actionmessages: ["records stored successfully",
                   "2nd message here",
                   "3dmessage here"]
};

errorresult = {
  success: false,
  actionerrors: ["cannot store record",
                 "record data invalid",
                 "more errors here..."]
};

validation: replacemxrecords (inputrecord, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain is existingbackend
apiidsexistenceif apiid != 0, check if an mx with the given apiid is existingbackend
exchangevalidchecks whether value is a valid domain nameajax api
priorityrangechecks whether 0 <= priority <= 65535ajax api

Group management

the namespace for this group is: namespace=/g2/json/domain/group

getgrouplist (inputgroup, processresult, processerror)

/**
 * this methods gets the list of groups for the given domain; if successful,
 * it returns the group's id, its name, and the flag whether the group is
 * the special undeletable all-friends group
 */

inputgroup = {
	domainname: "cartman.tel"
};

successresult = {
	success: true,
	grouplist: [{id: 12, name: "friends", allfriends: true},
		    {id: 23, name: "family", allfriends: false}],
	actionmessages: "request successful",
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot get group list",
               	       "more errors here..."]
}; 

validation: getgrouplist (inputgroup, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain existsbackend
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend

getgrouprecords (inputgroup, processresult, processerror)

/**
 * this method gets the list of records for a given group; it
 * returns the full set of information for each record, i.e.,
 * its id, the service key(s), the value, the label, the list
 * of groups it belongs to, the list of profiles it belongs to,
 * the global flag to tell whether the record is global for this
 * domain, i.e., belonging to all profiles, and its location
 * identifiers; additionally for each record a flag will be
 * returned to determine whether the record is 
 * editable or not; also the domain id will be returned
 */


inputgroup = {
	domainname: "cartman.tel",
	groupid: 23
};

successresult = {
	success: true,
	domainid: 12,
	recordlist: [{apiid: 23, terminal: true, 
		      servicekeys: ["voice", "fax"],
		      value: "+34.34343443", label: "my home number",
		      groups: [1, 23], profiles: [12, 23],
		      global: false, locations: ["x-home", "x-mobile"],
		      editable: true, longlabel: null},
		     {apiid: 12, terminal: true, servicekeys: ["web"],
		      value: "www.telnic.org", label: "my homepage",
		      groups: [23], profiles: [], global: true,
		      locations: ["x-home"], editable: true,
		      longlabel: "some text"},
		     {apiid: 12, terminal: false, value: "stan.cartman.tel.",
		      groups: [3], profiles: [], global: true,
		      longlabel: null}],
	actionmessages: "request successful",
			 "2nd message here",
                     	 "3rd message here"]
}; 
errorresult = {
	success: false,
	actionerrors: ["cannot get record list",
               	       "more errors here..."]
}; 

validation: getgrouplist (inputgroup, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain existsbackend
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
groupidexistencechecks if group existsbackend

getgroupfriends (inputgroup, processresult, processerror)

/**
 * this method gets the list of friends for a given group; it
 * returns the ids and names of the friends/readers
 */

inputgroup = {
	domainname: "cartman.tel",
	groupid: 23
};

successresult = {
	success: true,
	friendlist: [{id: 12, name: "michael palin"},
		     {id: 23, name: "eric idle"}],
	actionmessages: "request successful",
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot get list of friends",
               	       "more errors here..."]
}; 

validation: getgroupfriends (inputgroup, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain existsbackend
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
groupidexistencechecks if group existsbackend

addrecordstogroup (inputgroup, processresult, processerror)

/**
 * this method adds a list of records (by their apiids) to a given
 * group; the method is lenient in such a way that no exception is
 * thrown if a record already belonging to the group is added
 */

inputgroup = {
	domainname: "cartman.tel",
	groupid: 23,
	apiids: [12, 1, 2]
};

successresult = {
	success: true,
	actionmessages: "records added",
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot add records to group",
               	       "more errors here..."]
}; 

validation: addrecordstogroup (inputgroup, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain existsbackend
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
groupidexistencechecks if group existsbackend
apiidsexistencechecks if records exist and accessible for logged in userbackend
apiidsnaptr limitchecks if record does not exceed encrytable naptr limitsbackend

removerecordsfromgroup (inputgroup, processresult, processerror)

/**
 * this method removes a list of records (by their apiids) from a given
 * group; the method is lenient in such a way that no exception is
 * thrown if a record not belonging to the group is removed
 */

inputgroup = {
	domainname: "cartman.tel",
	groupid: 23,
	apiids: [12, 1, 2]
};


successresult = {
	success: true,
	actionmessages: "records removed",
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot remove records to group",
               	       "more errors here..."]
}; 

validation: removerecordsfromgroup (inputgroup, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain existsbackend
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
groupidexistencechecks if group existsbackend
apiidsexistencechecks if records exist and accessible for logged in userbackend

addrecordstogroups (inputgroup, processresult, processerror)

/**
 * this method adds a list of records (by their apiids) to a given
 * list of groups (by their ids); the method is lenient in such a way
 * that no exception is thrown if a record already belonging to a
 * group is added; if the single group id of -1 is used, the given
 * records will be added to all groups; if reset is set to true,
 * the records will only belong to the given groups after this
 * operation (i.e., they will be removed from all groups that are
 * not given)
 */

inputgroup = {
	domainname: "cartman.tel",
	groupids: [23, 1],
	apiids: [12, 1, 2],
	reset: false
};

successresult = {
	success: true,
	actionmessages: "records added",
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot add records to group",
               	       "more errors here..."]
}; 

validation: addrecordstogroups (inputgroup, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain is existingbackend
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
groupidsexistencechecks if groups are existingbackend
apiidsexistencechecks if records are existing and accessible for logged in userbackende
apiidsnaptr limitchecks if record does not exceed encrytable naptr limitsbackend

removerecordsfromgroups (inputgroup, processresult, processerror)

/**
 * this method removes a list of records (by their apiids) from a given
 * list of groups (by their ids); the method is lenient in such a way that
 * no exception is thrown if a record not belonging to a group is removed;
 * note that if a record is removed from its last group, it will lose its
 * private status and will be publicly visible; contrary to
 * removerecordsfromgroup, the record is not taken from all profiles, but
 * keeps its profile association;  if the single group id of -1 is used,
 * the given records will be removed from all groups
 */

inputgroup = {
	domainname: "cartman.tel",
	groupids: [-1],
	apiids: [12, 1, 2]
};

successresult = {
	success: true,
	actionmessages: "records removed",
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot remove records from group",
               	       "more errors here..."]
}; 

validation: removerecordsfromgroups (inputgroup, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain is existingbackend
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
groupidsexistencechecks if groups are existingbackend
apiidsexistencechecks if records are existing and accessible for logged in userbackend

addfriendstogroup (inputgroup, processresult, processerror)

/**
 * this method adds a list of readers (by their ids) to a given
 * group; the method is lenient in such a way that no exception is
 * thrown if a reader already belonging to the group is added
 */

inputgroup = {
	domainname: "cartman.tel",
	groupid: 23,
	readerids: [12, 1, 2]
};

successresult = {
	success: true,
	actionmessages: "friends added",
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot add friends to group",
               	       "more errors here..."]
}; 

validation: addfriendstogroup (inputgroup, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain existsbackend
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
groupidexistencechecks if group existsbackend
readeridsexistencechecks if records exist and accessible for logged in userbackend

removefriendsfromgroup (inputgroup, processresult, processerror)

/**
 * this method removes a list of readers (by their ids) from a given


 * group; the method is lenient in such a way that no exception is
 * thrown if a reader not belonging to the group is removed
 */

inputgroup = {
	domainname: "cartman.tel",

	groupid: 23,
	readerids: [12, 1, 2]
};

successresult = {
	success: true,
	actionmessages: "friends removed",
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot remove friends from group",
               	       "more errors here..."]
}; 



validation: removefriendsfromgroup (inputgroup, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain existsbackend
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
groupidexistencechecks if group existsbackend
readeridsexistencechecks if records exist and accessible for logged in userbackend

storegroup (inputgroup, processresult, processerror)

/**
 * this method creates a new group or edits an existing group;
 * if groupid is set to 0, a new group will be created and its
 * new id will be returned; for a groupid greater than 0 the



 * given group will be edited, this can also be used to change a
 * group's name
 */

inputgroup = {
	domainname: "cartman.tel",
	groupid: 0,
	groupname: "friends",
	readerids: [12, 1, 2]
};

successresult = {
	success: true,
	groupid: 24,
	actionmessages: "group stored",
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot store group",
               	       "more errors here..."]
}; 

validation: storegroup (inputgroup, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain existsbackend
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
groupidgroup limitif groupid = null, check if use is allowed to create a new group based on "max. * of groups" permissionbackend
readeridsexistencechecks if records exist and accessible for logged in userbackend
groupnameuniquenesschecks if given group name is unique (for logged in user)backend

deletegroup (inputgroup, processresult, processerror)

/**
 * this method deletes an existing group;
 */

inputgroup = {
	domainname: "cartman.tel",
	groupid: 45
};

successresult = {
	success: true,
	actionmessages: "group deleted",
			 "2nd message here",
                     	 "3rd message here"]
}; 

errorresult = {
	success: false,
	actionerrors: ["cannot delete group",
               	       "more errors here..."]
}; 

validation: deletegroup (inputgroup, processresult, processerror)

valuenamedescriptionimplemented
domainnameexistencechecks if domain existsbackend
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameprivilegeschecks if the logged in user has the rights to access the domain based on usertype and domain delegationbackend
groupidexistencechecks if group exists and accessible for logged in userbackend
groupidremoveablechecks if group is not the non removeable "all friends" groupbackend

Friending

the namespace for this group is: namespace=/g2/json/friending

checkdomainstate (domain, processresult, processerror)

/**
 * this method should be called directly after a user's login to get the
 * updated information of the soconnection state and also the so user name;
 * at login the soconnection state of the getsubfolderlist should not be
 * used, since the information might be outdated; this method should not be
 * called for every page (re)load or change of domain;
 * it contacts the so (telfriends) to find out the current state and user
 * name for this domain;
 * it returns a the soconnection state and the sousername; note, that the
 * sousername may be null in case it is not known (i.e., soconnection is
 * unitialised)
 * the method directly stores all changes to the database so that the next
 * page re-load will show the correct information
 */

domain = {
	domainname: "cartman.tel"
};

successresult = {
	success: true,
	soconnection: "incomplete",
	sousername: "cartman",
	actionmessages: null
};

errorresult = {
	success: false,
	actionerrors: ["some error",
		       "more errors here..."]
};

validation: checkdomainstate (domain, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain is existingbackend

getsousername (domain, processresult, processerror)

/**
 * this method should only be called for a domain which soconnection is 
 * 'active', 'incomplete', or 'broken'; if the value is 'unitialised'
 * the method will return an error saying so; 
 * in case of success the method will return the so user name to whose so
 * account the domain belongs;
 * this method should be used to ease a user's cold boot process by
 * telling him already with which user name he has to log in
 */

domain = {
	domainname: "cartman.tel"
};

successresult = {
	success: true,

	sousername: "cartman",

	actionmessages: ["user name retrieved",
			 "2nd message here"]
};

errorresult = {
	success: false,
	actionerrors: ["domain unititialised",
		       "more errors here..."]
};

validation: getsousername (domain, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain existsbackend

disconnectfromso (domain, processresult, processerror)

/**
* this method should only be called for a domain which soconnection is
* 'active', 'incomplete', or 'broken'; if the value is 'unitialised'
* the method will return an error saying so;
* the method will remove the so credentials corresponding to the
* given domain; as a result this domain (and all other domains using the
* same so credentials) will be put into the state uninitialised;
*/
domain = {
domainname: "cartman.tel"
};
successresult = {
success: true,
actionmessages: []
};
errorresult = {
success: false,
actionerrors: ["domain unititialised",
"more errors here..."]
};

validation: disconnectfromso (domain, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain existsbackend

getchallenge (credentials, processresult, processerror)

/**
 * for the user to be able to use the friending functionality, he needs to
 * initialise his embedded friending client; the initialisation process has 
 * two steps; in this first step the user enters the domain name, his so user
 * name and so web password to get his challenge question; if the authentication was
 * successful the challenge question is returned and can be displayed to the
 * user, which leads to step two;
 */

credentials = {
        domainname: "cartman.tel",	
        sowebusername: "cartman",
	sowebpassword: "secret"
};

successresult = {
	success: true,
	actionmessages: ["challenge retrieved",
			 "2nd message here"],
	challengequestion: "you talkin' to me?"
};

errorresult = {
	success: false,
	actionerrors: ["username or password incorrect",
		       "more errors here..."]
};

validation: getchallenge (credentials, processresult, processerror)

valuenamedescriptionimplemented
sowebusernamelogincheck of combination username and passwordajax api (backend)
sowebpasswordlogincheck of combination username and passwordajax api (backend)

sendchallengeanswer (challengeanswer, processresult, processerror)

/**
 * this function is for the second step of the initialisation process
 * (compare getchallenge); the user has to supply the answer to the
 * previously received challenge question; since the backend does not save
 * the domain name, so web user name or password, these three strings have to
 * be provided again; if the authentication was successful, the user
 * is connected with the so and can henceforth use the friending functionality
 *
 * as background information: the so credentials needed for further
 * communication with the so are stored at the backend, the frontend does
 * not need to care about this
 */

challengeanswer = {
	sowebusername: "cartman",
	sowebpassword: "secret",
	answer: "hugo"
        domainname: "cartman.tel",
};

successresult = {
	success: true,
	actionmessages: ["answer accepted",
			 "2nd message here"]
};

errorresult = {
	success: false,
	actionerrors: ["wrong answer",
		       "more errors here..."]
};

validation: sendchallengeanswer (challengeanswer, processresult, processerror)

valuenamedescriptionimplemented
sowebusernamelogincheck of combination username, password and answerajax api (backend)
sowebpasswordlogincheck of combination username, password and answerajax api (backend)
answerlogincheck of combination username, password and answerajax api (backend)

pollfromso (inputfolder, processresult, processerror)

/**
 * only possible after initialisation of the friending functionality;
 * this method needs the current domain name to determine which member
 * info should be used; it returns the current list of
 * message (i.e., friending requests, (solicited) friending responses,
 * and unsolicited friending responses) ids; the frontend can compare
 * this list with its current list of ids; for all new ids the messages
 * can be obtained from the backend via the getmessages method;
 * contrary to the getmessagelist function, this function first
 * contacts the so and polls for new messages; since this might be a 
 * time consuming task, this method should not be called too often,
 * maybe only if the user clicks on a 'check for new messages' button
 */

inputfolder = {
	domainname: "cartman.tel"
};

successresult = {
	success: true,
	actionmessages: ["messages retrieved",
			 "2nd message here"],
	idlist: [13, 14, 16, 19, 20, 21]  /** messages at the nsp */
};

errorresult = {
	success: false,
	actionerrors: ["user does not exist",
		       "more errors here..."]
};

validation: pollfromso (inputfolder, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencecheck if domain existsbackend

getmessagelist (inputfolder, processresult, processerror)

/**
 * only possible after initialisation of the friending functionality;
 * this method needs the current domain name to determine which member
 * info should be used; it returns the current list of
 * message (i.e., friending requests, (solicited) friending responses,
 * and unsolicited friending responses) ids; the frontend can compare
 * this list with its current list of ids; for all new ids the messages
 * can be obtained from the backend via the getmessages method
 *
 * as background information: it might be useful to call this message
 * regularly, since new messages may arrive at any point of time; also
 * a button to 'check for new message' might be useful
 */

inputfolder= {
	domainname: "cartman.tel"
};

successresult = {
	success: true,
	actionmessages: ["messages retrieved",
			 "2nd message here"],
	idlist: [13, 14, 16, 19, 20, 21]  /** messages at the nsp */
};

errorresult = {
	success: false,
	actionerrors: ["user does not exist",
		       "more errors here..."]
};

validation: getmessagelist (inputfolder, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain existsbackend

getmessages (messageidlist, processresult, processerror)

/**
 * only possible after initialisation of the friending functionality;
 * this method needs the current domain name to determine which member
 * info should be used; it also takes a list of message ids as input
 * and returns the
 * complete messages for these ids; all messages contain the sender,
 * the receiver, the sent date, and an optional cover note; furthermore
 * the messages have to flags to determine the message type:
 * - friending request (isrequest = true, isrejectable = true), friending
 *     requests are messages sent from an so user to a specific .tel
 *     domain, asking to be put onto the list of friends for this domain;
 *     this message should have the buttons 'reject' and 'accept';
 * - (solicited) friending repsonse (isrequest = false, isrejectable =
 *     false), these messages are purely for informational purposes; the
 *     receiver is informed that an former friending request has been
 *     accepted and he is now on the list of friends of that .tel domain;
 *     this message should only have the button 'delete';
 * - unsolicited friending response (isrequest = false, isrejectable =
 *     true), these messages are also called 'friending invitation',
 *     because they  are sent by a .tel domain owner, who wants to put an
 *     so user onto his list of friends; to avoid misuse of this feature,
 *     the receiver of an unsolicited friending response can either accept or
 *     reject it this message should have the buttons 'reject' and
 *     'accept'
 */

messageidlist = {
	domainname: "cartman.tel",
	idlist: [20, 21]  /** ids of messages to be retrieved */
};

successresult = {
	success: true,
	actionmessages: ["messages retrieved",
			 "2nd message here"],
	messagelist: [ {id: 20, isrequest: true, isrejectable: true,
			from: "henri", to: "cartman.tel",
			received: "2008-06-13 23:59",
			covernote: "blabla"},

		       {id: 21, isrequest: false,
			isrejectable: true, from: "henri.tel", to: "cartman",
			received: "2008-06-15 04:20",
			covernote: "duh== "} ]
};

errorresult = {
	success: false,
	actionerrors: ["message does not exist",
		       "more errors here..."]
};

validation: getmessages (null, processresult, processerror)

valuenamedescriptionimplemented
idlistexistencechecks if the ids in list existajax api (backend)
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain existsbackend

acceptrequestmessage (message, processresult, processerror)

/**
 * only possible after initialisation of the friending functionality;
 * this method is used to accept a received friending request; thus
 * the supplied message id must be of a friending request message;
 * this method also needs the current domain name to determine which
 * member info should be used; 
 * accepting a friending request means that a friend (sometimes also
 * called reader) will be added to the .tel domain; the name of the new
 * friend may be chosen by the user and is supplied as the readername to
 * this method;
 * if the call was successful a new reader has been created and its id is
 * returned; the id of the original message is also returned;
 *
 * as background information: accepting a friending request will initiate a
 * (solicited) friending response to be sent to the sender of the friending
 * request
 */

message = {
	domainname: "cartman.tel",
	id: 42
	readername: "dummi"  /** the name of new reader as shown to this user */
};

successresult = {
	success: true,
	actionmessages: ["message accepted",
			 "2nd message here"],
	id: 14,        /** the id of the created reader */
	readername: "dummi",
	messageid: 42  /** the id of the accepted message */
};



errorresult = {
	success: false,
	actionerrors: ["no message with given id found",
		       "more errors here..."],
	fielderrors: ["readername": "illegal reader name"]
};

validation: acceptrequestmessage (message, processresult, processerror)

valuenamedescriptionimplemented
idexistencechecks if the ids in list existajax api (backend)
iddouble entrieschecks if reader sending the request is uniqueajax api (backend)
readernamedouble entrieschecks if readername is uniquebackend
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain existsbackend

acceptrequestmessages (message, processresult, processerror)

/**
 * only possible after initialisation of the friending functionality;
 * this method is used to accept several received friending request at
 * the same time; thus the supplied message ids must be of friending
 * request messages; this method also needs the current domain name to
 * determine which member info should be used; 
 * accepting a friending request means that a friend
 * (sometimes also called reader) will be added to the .tel domain; the
 * name of the new friends are automatically determined by their sender
 * names, but can always be changed later through the renamefriend
 * method; if the call was successful a new reader has been created for
 * each of the selected friending requests; the returned response in the
 * success case will contain a list of pairs of id and name for each reader;
 * the ids of the original messages are also returned;
 *
 * as background information: accepting a friending request will initiate a
 * (solicited) friending response to be sent to the sender of the friending
 * request
 */

message = {
	domainname: "cartman.tel",
	idlist: [1, 4, 42]
};

successresult = {
	success: true,
	actionmessages: ["message accepted",
			 "2nd message here"],
	readerlist: [{id: 14, readername: "stan"},
		     {id: 11, readername: "sam"},

		     {id: 23, readername: "john"}],
	messageidlist: [1, 4, 42]  /** the ids of the accepted messages */
 };

errorresult = {
	success: false,
	actionerrors: ["no message with given id found",
		       "reader with name xyz already exists"]
};

validation: acceptrequestmessages (message, processresult, processerror)

valuenamedescriptionimplemented
idexistencechecks if the ids in list existajax api (backend)
iddouble entrieschecks if reader sending the request is uniqueajax api (backend)
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain existsbackend

acceptinvitationmessages (message, processresult, processerror)

/**
 * only possible after initialisation of the friending functionality;
 * this method is used to accept one or several received unsolicited
 * friending requests (also called friending invitations); thus the
 * supplied message ids must be of unsolicited friending response messages;
 * this method also needs the current domain name to determine which member
 * info should be used; 
 * accepting an unsolicited friending response means that the user agrees
 * to be put onto the sender's list of friends; the ids of the original
 * messages are also returned;
 *
 * as background information: the sender of an unsolicited friending
 * response has put the receiver onto his list of friends; accepting or
 * rejecting this message does not make any difference; however,
 * accepting this message means that a publisher will be added for the
 * receiver at the so; only if such a publisher exists, the user can
 * actually read any private data (otherwise he would not know where to
 * look for this private data)
 */

message = {
	domainname: "cartman.tel",
	idlist: [42,13,1]
};

successresult = {


	success: true,
	actionmessages: ["messages accepted, you are now able to read private" +
                         " data provided for you at the domain",
			 "2nd message here"],
	messageidlist: [42, 13, 1]  /** the ids of the accepted messages */
};

errorresult = {
	success: false,
	actionerrors: ["no message with given id found",
		       "more errors here..."]

validation: acceptrequestmessages (message, processresult, processerror)

valuenamedescriptionimplemented
idexistencechecks if the ids in list existajax api (backend)
iddouble entrieschecks if reader sending the request is uniqueajax api (backend)
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain existsbackend

rejectmessages (message, processresult, processerror)

/**
 * only possible after initialisation of the friending functionality;
 * this method needs the current domain name to determine which member
 * info should be used; 
 * this method is the same for all kinds of friending messages,
 * because rejecting a message just means deleting it; no further action
 * will be taken;
 * the message ids will be returned in case of a successful deletion
 */

message = {
	domainname: "cartman.tel",
	idlist: [42, 12, 1]
};

successresult = {
	success: true,
	idlist: [42, 12, 1],
	actionmessages: ["messages rejected",
			 "2nd message here"]
};

errorresult = {
	success: false,
	actionerrors: ["no message with given id found",
		       "more errors here..."]
};

validation: rejectmessages (message, processresult, processerror)

valuenamedescriptionimplemented
idlistexistencechecks if field is not empty or nullajax api
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain existsbackend

sendfriendingrequest (newreqmessage, processresult, processerror)

/**
 * only possible after initialisation of the friending functionality;
 * if a user would like to read private data of a specific .tel domain,
 * he needs to send a friending request to this domain; optionally a
 * cover note may be added; this method needs the current domain name
 * to determine which member info should be used; 
 *
 * as background information: once the friending request has been

 * accepted by the receiver, a corresponding (solicited) friending
 * response will be sent back to the sender of the friending request;
 * if such a response is received, the process has been completed and
 * the sender of the request is able to read private data at the domain
 */

newreqmessage = {
	domainname: "cartman.tel",
	to: "henri.tel",
	covernote: "barbarbar"
};
  
successresult = {
	success: true,
	actionmessages: ["message sent",
			 "2nd message here"]
};

errorresult = {
	success: false,
	actionerrors: ["sending of message failed",
		       "more errors here..."],
	fielderrors: ["to": "target domain does not exist",
		      "covernote": "cover note too long"]
};

validation: sendfriendingrequest (newreqmessage, processresult, processerror)

valuenamedescriptionimplemented
toexistencechecks if field is not empty or nullajax api
tosending possiblechecks ifso can deliver message to domain and/or domain existsajax api (backend)
domainnamepresencechecks if input value is present and not _null_ajax api
domainnameexistencechecks if domain existsbackend

sendfriendinginvitation (newinvmessage, processresult, processresult)

/**
 * only possible after initialisation of the friending functionality;
 * this method directly adds a new person to the list of friends; the
 * name of the friend can be chosen by setting the readername parameter; the
 * from parameter determines to which domain the friend should be added;
 * to contains the so user name of the person to invite as a friend and
 * the cover note may be an arbitary message for the receiver;
 * the successful result contains the id of the newly created reader (friend)
 * 
 * as background information: this method initiates an unsolicted
 * friending response to be sent to the so user; only if that user accepts
 * the message, he is actually able to view the private data provided at
 * this domain; the sender of the friending invitation will not be notified
 * whether his invitation was accepted or rejected
 */

newinvmessage = {
	from: "cartman.tel",  /* specific subdomain the invited user shall be
                                 able to read */
	to: "henri",          /* so username of the person to invite */
	readername: "henri viii",  /* name of new reader as shown to this 
                                      user */
	covernote: "barbarbar",
};

successresult = {
	success: true,
	actionmessages: ["message sent",
			 "2nd message here"],
	id: 6    /** the id of the user added as a new reader */
};

errorresult = {
	success: false,
	actionerrors: ["sending of message failed",
		       "more errors here..."],
	fielderrors: ["from": "domain does not belong to you",
		      "to": "target user does not exist",
		      "readername": "illegal reader name",
		      "covernote": "cover note too long"]
};

validation: sendfriendinginvitation (newinvmessage, processresult, processresult)

valuenamedescriptionimplemented
fromexistencechecks if domain exists (domain does not exist, if not belonging to user)backend
toexistencechecks so can deliver message to domain and/or domain existsajax api (backend)
readernameuniquenesschecks if readername is uniquebackend
readernamereader limitchecks if user can create more readers based on permission "max. * of readers"backend

getfriendlist (friendinput, processresult, processerror)

/**
 * gets the list of all friends/readers for the given domain; 
 * note, that friends are only available for second level, but not third or
 * deeper level domains;
 * the friend's id and name will be returned
 */

friendinput = {
	domainname: "cartman.tel"
};

successresult = {
	success: true,
	friendlist: [{id: 12, name: "michael palin"},
		     {id: 23, name: "eric idle"}],

	actionmessages: ["request successful",
			 "2nd message here"]
};

errorresult = {
	success: false,
	actionerrors: ["list of friends could not be retrieved",
		       "domain name must be a second level domain",
		       "more errors here..."]
};

validation: getfriendlist (friendinput, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if domain is not empty or _null_ajax api
domainnameexistencechecks if domain exists (domain does not exist, if not belonging to user)backend

deletefriends (friendinput, processresult, processerror)

/**
 * deletes a list of friends determined by their ids
 */

friendinput = {
	domainname: "cartman.tel",
	idlist: [1,34]
}

successresult = {
	success: true,
	actionmessages: ["friends deleted",
			 "2nd message here"]
};

errorresult = {
	success: false,
	actionerrors: ["friends could not be deleted",
		       "more errors here..."]
};

validation: deletefriends (friendinput, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if domain is not empty or _null_ajax api
domainnameexistencechecks if domain exists (domain does not exist, if not belonging to user)backend
idlistexistencechecks if isd in list exist and accessible for logged in userbackend

renamefriend (friendinput, processresult, processerror)

/**
 * renames a friend/reader determined by the id; the new name of the
 * friend is supplied in the readername parameter
 */

friendinput = {
	domainname: "cartman.tel",
	id: 1,
	readername: "my best friend"
}

successresult = {
	success: true,
	actionmessages: ["friend renamed",
			 "2nd message here"]
};



errorresult = {
	success: false,
	actionerrors: ["friend could not be renamed",
		       "more errors here..."],
	fielderrors: ["readername", "friend xyz already exist"]
};

validation: renamefriend (friendinput, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if domain is not empty or _null_ajax api
domainnameexistencechecks if domain exists (domain does not exist, if not belonging to user)backend
idexistencechecks if isd in list exist and accessible for logged in userbackend
readernameuniquenesschecks if readername is uniquebackend

addtoblacklist (messages, processresult, processerror)

/**
 * only possible after initialisation of the friending functionality;
 * this method needs the current domain name to determine which member
 * info should be used; 
 * this method is the same for all kinds of friending messages and adds
 * all senders (i.e., so users) of the given messages to the current
 * user's blacklist;
 * the users, who have been added to the blacklist will be returned
 * in case of success
 */

messages = {
	domainname: "cartman.tel",
	idlist: [42, 12, 1]
};

successresult = {
	success: true,
	userlist: ["cartman", "johnsmith"],
	actionmessages: ["user blacklisted",
			 "2nd message here"]
};

errorresult = {
	success: false,
	actionerrors: ["no message with given id found",
		       "more errors here..."]
};

Keyword management

currently available keyword types (short forms): s, fn, ln, nn, dob, g, ms, pa, a1, a2, a3, tc, sp, pc, c, ll, o, d, jt, hi, ft, bpa, bn, bar, bsa, sa, aux

the namespace for this group is: namespace=/g2/json/searchdata

getvalidkeywords (null, processresult, processerror)

/**
 * retrieve the list of valid keyword types;
 * the returned list contains the short form of the keyword type, a
 * human-readable description, and two boolean flags:
 * - canhavesecondaries is true if the keyword type can have secondary
 *   keywords associated with it,
 * - canbesecondary is true if the keyword type can appear as a secondary
 *   keyword
 */

/** no input needed */

successresult = {
	success: true,
	actionmessages: ["valid keywords retrieved",
			 "2nd message here"],
	validkeywordlist = [ {shortform: "pa", displaytext: "postal address",
			      canhavesecondaries: true, canbesecondary: false},
			     {shortform: "a1", displaytext: "address line 1",

			      canhavesecondaries: false, canbesecondary: true}
			   ]

};

errorresult = {
	success: false,
	actionerrors: ["retrieval of valid keywords failed",
		       "more errors here..."]
};

validation: getvalidkeywords (null, processresult, processerror)

no validation required as the method does not have any input values

getkeywords (domain, processresult, processerror)

/**
 * retrieve the list of current keywords for the given domain;
 * the returned list contains the following information for each keyword:
 * - id;
 * - field: the short form of the keyword type;
 * - value: the user-defined value;
 * - secondarykewords: the list of secondary keywords (may be empty) of this
 *     keyword, has the same structure as the result of this request,
 *     except for the secondarykeywords part
 */

domain = {
	domain: "cartman.tel"
};

successresult = {
	success: true,
	actionmessages: ["keywords retrieved",
			 "2nd message here"],

	keywordlist = [ {id: 12, field: "pa", value: "my postal address",
			 secondarykewords: [ {id: 15, field: "a1", 
                                              value: "my street"} ]},
			{id: 13, field: "fn", value: "cart", 
                         secondarykewords: []} ]
};

errorresult = {
	success: false,
	actionerrors: ["retrieval of keywords failed",

		       "more errors here..."]
};

validation: getkeywords (domain, processresult, processerror)

valuenamedescriptionimplemented
domainnamepresencechecks if domain is not empty or nullajax api
domainnameexistencechecks if domain exists (domain does not exist, if not belonging to user)backend

getsuggestions (inputkeyword, processresult, processerror)

/**
 * retrieves a list of suggestions for the given keyword type and value;
 * the returned list contains keyword values starting with the given
 * value; note that the value has to contain at least two characters for
 * the suggestion to work;
 * the suggestions are generated via a request to the tel-pages index
 */

inputkeyword = {
	type: "tc",
	value: "do"
};

successresult = {
	success: true,
	type: "tc",
	prefix: "do",
	suggestions: ["donaueschingen", "dorsten", "dortmund", "dover"],
	actionmessages: ["suggestions retrieved",
			 "2nd message here"]
};

errorresult = {
	success: false,
	actionerrors: ["suggestions could not be retrieved",
		       "more errors here..."]
};

validation: getsuggestions (inputkeyword, processresult, processerror)

valuenamedescriptionimplemented
typepresencechecks if the type is not empty or nullajax api
typevalidchecks if input value is valid (in list of defined keyword types)backend
prefixemptychecks if the prefix is not empty or nullajax api

addkeyword (newkeyword, processresult, processerror)

/**
 * add a new (primary) keyword for the given domain;
 * the type is provided as the short form, the value specifies the
 * user's input;
 * upon success, the id of the created keyword is returned
 */

newkeyword = {
	domain: "cartman.tel",
	type: "tc",
	value: "dormtund"
};

successresult = {
	success: true,
	actionmessages: ["keyword added",
			 "2nd message here"],
	id: 27    /** the id assigned to the newly created keyword */
};


errorresult = {
	success: false,
	actionerrors: ["addition of keyword failed",
		       "more errors here..."],
	fielderrors: ["type": "unknown keyword type",
		      "value": "keyword value too long"]
};

validation: addkeyword (newkeyword, processresult, processerror)

valuenamedescriptionimplemented
domainpresencechecks if domain is not empty or _null_ajax api
domainexistencechecks if domain exists (domain does not exist, if not belonging to user)backend
typepresencechecks if the type is not empty or nullajax api
typevalidchecks if input value is valid (in list of defined keyword types)backend
typelimitchecks if the use is allowed to create a new search data entry based on "max. * of keywords" permissionbackend
typeallowedchecks if use is allowed to use the given type based "allowed keywords" permissionbackend

addsecondarykeywords (newkeywords, processresult, processerror)

/**
 * add new secondary keywords for the given domain;
 * the primary keyword to associated these new keywords with is specified
 * by its id, the list of secondary keywords contain the types given as
 * the short form and the values representing the user's input;
 * upon success, the ids of the created keywords are returned in given order
 */

newkeywords = {
	domain: "cartman.tel",
	primarykeywordid: 47,
	keywords: [{key: "sp", value: "nrw"}, {key: "sp", value: "d"}]
};


successresult = {
	success: true,
	actionmessages: ["message sent",
			 "2nd message here"],

	ids: [28, 29]  /** the ids assigned to the newly created keywords */
};

errorresult = {
	success: false,
	actionerrors: ["addition of keyword failed",
		       "more errors here..."],
	fielderrors: ["primarykeywordid": 
                        "primary keyword of given id does not exist",
		      "type": "unknown keyword type",
		      "value": "keyword value too long"]
};

validation: addsecondarykeywords (newkeywords, processresult, processerror)

valuenamedescriptionimplemented
domainpresencechecks if domain is not empty or nullajax api
domainexistencechecks if domain exists (domain does not exist, if not belonging to user)backend
primarykeywordidexistencechecks if keyword exists and accessible for logged in userbackend
primarykeywordidsecondary keywords allowedchecks if primary keyword is capabile for secondary keywordsbackend
keywords.spvalidchecks if input value is valid (in list of defined keyword types)backend
keywords.splimitchecks if the use is allowed to create a new search data entry based on "max. * of keywords" permissionbackend
keywords.spallowedchecks if use is allowed to use the given type based "allowed keywords" permissionbackend

addkeywordstructure (keyworddata, processresult, processerror)

/**
 * add a primary keyword to the given domain, specified by its id,
 * possibly along with secondary keywords; new keywords will be
 * created according to the data provided in the "keywords" list,
 * where the first element contains the data of the primary keyword,
 * all following elements will be added as secondary keywords;
 * upon success, the list of ids of the created keywords is
 * returned, with the first id being the one of the new primary,
 * followed by the ids of its secondary keywords
 */

keyworddata = {
	domain: "cartman.tel",
	keywords: [{key: "nl", value: "secret"},
		   {key: "s",  value: "mr"},
		   {key: "fn", value: "john"},
		   {key: "ln", value: "smith"},
		   {key: "nn", value: "marvin"}]
};

successresult = {
	success: true,
	actionmessages: ["new keyword structure added successfully.",
			 "2nd message here"],
	newidlist: [21, 22, 23, 24, 25]  /* the ids of the new keywords */
};

errorresult = {
	success: false,
	actionerrors: ["too many keywords specified (maximum is 16 keywords).",
		       "more errors here..."]
};

validation: addkeywordstructure (keyworddata, processresult, processerror)

valuenamedescriptionimplemented
domainpresencechecks if domain is not empty or _null_ajax api
domainexistencechecks if domain is existing (domain does not exist, if not belonging to user)backend
keywordspresencechecks if the keys is not empty or nullajax api
keywordsvalidchecks if they keys are valid (in list of defined keyword types)backend
keywordslimitchecks if the use is allowed to create a new search data entry based on "max. # of keywords" permissionbackend
keywordsallowedchecks if user is allowed to use the given keyword types "allowed keywords" permissionbackend

updatekeyword (keyworddata, processresult, processerror)

/**
 * updates a primary keyword of the given domain, specified by its id;
 * note that the primary keyword and all existing secondaries will be
 * deleted, new keywords will be created according to the data provided
 * in the "keywords" list, where the first element contains the new data

 * of the primary keyword, all following elements will be added as
 * secondary keywords;
 * upon success, the list of ids of the newly created keywords is
 * returned, with the first id being the one of the updated primary,
 * followed by the ids of its secondary keywords
 */

keyworddata = {
	domain: "cartman.tel",
	primarykeywordid: 42,
	keywords: [{key: "aux", value: "miscellaneous info"},
		   {key: "hi", value: "playing the mouse organ"},
		   {key: "sp", value: "nrw"}]
};


successresult = {
	success: true,
	actionmessages: ["keyword updated successfully.",
			 "2nd message here"],
	newidlist: [66, 67, 68]  /* the ids of the new keywords */
};

errorresult = {
	success: false,
	actionerrors: ["a keyword with id \"42\" does not exist.",
		       "more errors here..."]
};

validation: updatekeyword (keyworddata, processresult, processerror)

valuenamedescriptionimplemented
domainpresencechecks if domain is not empty or _null_ajax api
domainexistencechecks if domain is existing (domain does not exist, if not belonging to user)backend
primarykeywordidexistencechecks if the keyword is existing and a primary keywordbackend
keywordspresencechecks if the keys is not empty or nullajax api
keywordsvalidchecks if they keys are valid (in list of defined keyword types)backend
keywordslimitchecks if the use is allowed to create a new search data entry based on "max. # of keywords" permissionbackend
keywordsallowedchecks if user is allowed to use the given keyword types "allowed keywords" permissionbackend

at line 3729 changed 3 lines.

deletekeywords (keywords, processresult, processerror)

/**
 * deletes a number of keywords, provided as a list of ids; secondary keywords are 
 * deleted automatically with there primary keyword.
 */

keywords = {
	domain: "cartman.tel",
	idlist: [13, 15],
};

successresult = {
	success: true,
	actionmessages: ["keywords deleted",
			 "2nd message here"]
};

errorresult = {
	success: false,
	actionerrors: ["deletion of keywords failed",
		       "more errors here..."]
};

validation: deletekeywords (keywords, processresult, processerror)

valuenamedescriptionimplemented
domainpresencechecks if domain is not empty or _null_backend
domainexistencechecks if domain exists (domain does not exist, if not belonging to user)backend
idlistexistencechecks if keywords in id list exist and accessible for logged in userbackend

copykeywords (keywords, processresult, processerror)

/**
 * copies the given keywords (provided as a list of ids) from the given domain to
 * another domain/folder; dest specifies the destination domain where the
 * new keywords should be created;
 * to copy a primary keyword including the secondary keywords, all keywords should
 * be provided in the (linearized) list of ids in such an order that each list of 
 * secondary keywords is preceeded by its primary keyword. 
 * if the secondary keywords should be copied, too, please add "includesecondary: true"
 * to the request.
 * upon success, the list of ids of the newly created keywords is returned
 */

keywords = {
	domain: "henri.tel",
	idlist: [13, 15, 16],
	dest: "social.henri.tel",  /** the destination folder/domain */
        includesecondary: true   /** to copy secondary keywords for primary keywords */ 
};

successresult = {
	success: true,
	actionmessages: ["keywords copied",

			 "2nd message here"],
	newidlist: [21, 22, 23]  /* the ids of the new keywords in the
                                    destination folder */
};

errorresult = {
	success: false,
	actionerrors: ["copying of keywords failed",
		       "more errors here..."],
	fielderrors: ["dest": "destination folder not found"]
};

validation: copykeywords (keywords, processresult, processerror)

valuenamedescriptionimplemented
domainpresencechecks if domain is not empty or _null_ajax api
domainexistencechecks if domain exists (domain does not exist, if not belonging to user)backend
idlistexistencechecks if keywords in id list exist and accessible for logged in userbackend
idlistsecondarykeywordif includesecondary is set to true, no secondary keywords are allowed in idlistbackend
destemptychecks if domain is not empty or nullajax api
destexistencechecks if domain exists (domain does not exist, if not belonging to user)backend

movekeywords (keywords, processresult, processerror)

/**
 * moves keywords (provided as a list of ids) from the given domain to
 * another domain; dest specifies the destination domain where the
 * keywords should be moved to; since the ids of the moved keywords do not
 * change, no corresponding list is returned.
 * to move a primary keyword including the secondary keywords, all keywords should
 * be provided in the (linearized) list of ids in such an order that each list of 
 * secondary keywords is preceeded by its primary keyword or use the parameter
 * "includesecondary:true" for automatic move of secondary keywords
 */

keywords = {
	domain: "henri.tel",
	idlist: [13, 15, 16]
	dest: "social.henri.tel",  /** the destination folder/subdomain */
        includesecondary: true   /** to copy secondary keywords for primary keywords */ 
};

successresult = {
	success: true,
	actionmessages: ["keywords moved",
			 "2nd message here"]
};

errorresult = {
	success: false,
	actionerrors: ["moving of keywords failed",

		       "more errors here..."],
	fielderrors: ["dest": "destination folder not found"]
};

validation: movekeywords (keywords, processresult, processerror)

valuenamedescriptionimplemented
domainpresencechecks if domain is not empty or _null_ajax api
domainexistencechecks if domain exists (domain does not exist, if not belonging to user)backend
idlistexistencechecks if keywords in id list exist and accessible for logged in userbackend
idlistsecondarykeywordif includesecondary is set to true, no secondary keywords are allowed in idlistbackend
destemptychecks if domain is not empty or nullajax api
destexistencechecks if domain exists (domain does not exist, if not belonging to user)backend

reordersubkeywords (subkeywordorder, processresult, processerror)

/**
 * reorder the secondary keywords of a primary keyword (defined by its
 * id) for a given domain/folder;
 * the idlist is the (newly ordered) list of ids;
 * if an error occurs, the unaltered ordering is returned to enable
 * consistency and simplify the presentation of the current ordering to the
 * user
 */

subkeywordorder = {
	domain: "cartman.tel",
	primarykeywordid: 36,
	idlist: [2, 13, 7, 1, 10]
};

successresult = {
	success: true,
	actionmessages: ["subkeywords reordered",
			 "2nd message here"]
};

errorresult = {
	success: false,
	actionerrors: ["reordering of subkeywords failed",
		       "more errors here..."],
	oldidlist: [1, 2, 7, 10, 13]
};

validation: reordersubkeywords (subkeywordorder, processresult, processerror)

valuenamedescriptionimplemented
domainpresencechecks if domain is not empty or _null_ajax api
domainexistencechecks if domain exists (domain does not exist, if not belonging to user)backend
primarykeywordidexistencechecks if keywords in id list exist and accessible for logged in userbackend
idlistequalitychecks if the entries are matching to the stored onces (same number of records and ids)backend

Export/import

getvaliddomainstoimport (null, processresult, processerror)

/**
 * obtains a list of domains importable from
 * the most recent xml data upload
 */

/** no input needed */

successresult = {
    "success": true,
    "actionmessages": ["list of valid domains to import retrieved successfully."],
    "domainlist": ["cartman.tel", "kyle.tel", "smith.tel", "stan.tel"]
}; 

errorresult = {
    "success": false,
    "actionerrors": ["no import data available. please upload previously exported data before starting this operation."]
}; 

validation: getvaliddomainstoimport (null, processresult, processerror)

no validation required as the method does not have any input values; however, a valid xml export file must have been uploaded to the server (it is then stored in the session) before the method may be called, otherwise the error message above is returned. also, the file must be a valid export file, otherwise various xml parsing errors will occur.

the upload must be done by posting (http post) proper content to the relative url {{/g2/json/exchange/import_submit.action}}; proper content in this context is {{multipart/form-data}} encoded data in the input field "importdata". minimal example form:

<form namespace="/g2/json/exchange" id="import_submit" name="import_submit" onsubmit="return true;"
  action="/g2/json/exchange/import_submit.action" method="post" enctype="multipart/form-data">
  <input type="file" name="importdata" value="" accept="text/xml" id="import_submit_importdata"/>
</form>

importdomains (domains, processresult, processerror)

/**
 * this method is used to import a given list of
 * root ("apex") domains from a previously uploaded xml file
 */

domains = {
    "domainlist": ["kyle.tel", "cartman.tel"]
};

successresult = {
    "success": true,
    "actionmessages": ["the import operation has been completed successfully."]
};

errorresult = {
    "success": false,
    "actionerrors": ["no import data available. please upload previously exported data before starting this operation."]
}; 

validation: importdomains (domains, processresult, processerror)

valuenamedescriptionvalidation
domainlistdomain list missingdomain list must be specifiedajax api
domainlistdomain list emptydomain list may not be emptyajax api

exportdomains (http post, no ajax function)

to facilitate the download of xml export data from the browser, the export functionality was implemented as an http post of the list of selected domains to the url

/g2/json/exchange/exportdomains.action

this returns the stream of export xml to the browser with a content-disposition header bearing 'attachment;filename="export.xml"' and a content-type of "text/xml". this makes the browser open the "save as" dialogue.

the (optional) parameter for the http post is a list of selected domains; if missing or empty, all domains of the current user are exported. this minimal form demonstrates the usage:

<form namespace="g2/json/exchange"
  id="exportdomains"
  name="exportdomains"
  action="/g2/json/exchange/exportdomains.action"
  method="post" enctype="multipart/form-data">

  <select name="selecteddomains" id="exportdomains_selecteddomains" multiple="multiple">

    <option value="cartman.tel" selected="selected">cartman.tel</option>
    <option value="test122.cartman.tel" selected="selected">test122.cartman.tel</option>
    <option value="testomat.cartman.tel" selected="selected">testomat.cartman.tel</option>
    <option value="xxx.cartman.tel" selected="selected">xxx.cartman.tel</option>
    <option value="kyle.tel" selected="selected">kyle.tel</option>
    <option value="smith.tel" selected="selected">smith.tel</option>
    <option value="stan.tel" selected="selected">stan.tel</option>

  </select>

</form>

an example for the generation of this form via struts/freemarker can be found in the file {{project/apps/ps-server/web/domain/exchange/export.ftl}} within the nsp svn repository.

in case of an error during the export, the action currently forwards back to the dashboard. this may need to be changed for proper error handling.

Design

getdesignproperties (domainname, processresult, processerror)

/**
* retrieve the domain's proxy design properties
*/
domainname = {
domain: "cartman.tel"
};
successresult = {
success: true,
actionmessages: [""],
colour1: "0000ff",
colour2: "00ffff",
colour3: "aa00ff",
csstemplate: 2
};
errorresult = {
success: false,
actionerrors: ["retrieval of design properties failed",
"more errors here..."]
};

validation: getdesignproperties (domainname, processresult, processerror)

valuenamedescriptionvalidation
domainnamepresencechecks if domain is not empty or nullajax api
domainnameexistencechecks if domain is existing (domain is not existing, if not belonging to user)backend

changecolours (inputcolours, processresult, processerror)

/**
* change a domain's proxy colours
*/
domainname = {
domain: "cartman.tel",
colour1: "0000ff",
colour2: "00ffff",
colour3: "aa00ff"
};
successresult = {
success: true,
actionmessages: ["colour successfully updated."]
};
errorresult = {
success: false,
actionerrors: ["update of colour failed",
"more errors here..."]
};

validation: changecolours (inputcolours, processresult, processerror)

valuenamedescriptionvalidation
domainnamepresencechecks if domain is not empty or nullajax api
domainnameexistencechecks if domain is existing (domain is not existing, if not belonging to user)backend
colour1validchecks if the submitted string represents a valid colour hex codebackend
colour2validchecks if the submitted string represents a valid colour hex codebackend
colour3validchecks if the submitted string represents a valid colour hex codebackend

changecsstemplate (inputtemplate, processresult, processerror)

/**
* change a domain's proxy colours
*/
domainname = {
domain: "cartman.tel",
csstemplate: 2
};
successresult = {
success: true,
actionmessages: ["template successfully updated."]
};
errorresult = {
success: false,
actionerrors: ["update of template failed",
"more errors here..."]
};

validation: changecsstemplate (inputtemplate, processresult, processerror)

valuenamedescriptionvalidation
domainnamepresencechecks if domain is not empty or nullajax api
domainnameexistencechecks if domain is existing (domain is not existing, if not belonging to user)backend
csstemplatevalidchecks if the submitted integer value is validbackend
Telnic
Search This Site
Partners
Neustar
ICANN
Main site | WHOIS | Sell .tel | FAQ | Archived Site | About Telnic | Contact Us