Oberon || Library || Module Index || Search Engine || Definition || Module


Ulm's Oberon Library:
Names


NAME

Names - abstraction for name hierarchies

SYNOPSIS

TYPE Name = ConstStrings.String;
TYPE Node = POINTER TO NodeRec;
TYPE NodeRec = RECORD (Services.ObjectRec) END;
TYPE Lister = Iterators.Iterator;


CONST examine = 0; CONST change = 1; CONST read = 2; CONST search = 3; CONST insert = 4; CONST delete = 5; CONST destroy = 6; CONST accessmodes = 7; TYPE AccessMode = SHORTINT; (* [examine..destroy] *) TYPE Permissions = ARRAY accessmodes OF Shards.Pot; TYPE Status = POINTER TO StatusRec; TYPE StatusRec = RECORD (Objects.ObjectRec) perm: Permissions; END;

TYPE AccessProc = PROCEDURE (node: Node; mode: AccessMode; auth: Shards.Lid): BOOLEAN; TYPE GetStatusProc = PROCEDURE (node: Node; auth: Shards.Lid; VAR status: StatusRec): BOOLEAN; TYPE SetStatusProc = PROCEDURE (node: Node; status: Status; auth: Shards.Lid): BOOLEAN; TYPE GetMembersProc = PROCEDURE (node: Node; auth: Shards.Lid; VAR members: Lister): BOOLEAN; TYPE TakeInterestProc = PROCEDURE (node: Node; auth: Shards.Lid; VAR eventType: Events.EventType): BOOLEAN; TYPE GetNodeProc = PROCEDURE (node: Node; name: Name; auth: Shards.Lid; VAR subnode: Node): BOOLEAN; TYPE InsertProc = PROCEDURE (node, subnode: Node; name: Name; auth: Shards.Lid): BOOLEAN; TYPE MakeSubnodeProc = PROCEDURE (node: Node; name: Name; status: Status; caps: CapabilitySet; auth: Shards.Lid; VAR subnode: Node): BOOLEAN; TYPE DeleteProc = PROCEDURE (node: Node; name: Name; auth: Shards.Lid): BOOLEAN; TYPE DestroyProc = PROCEDURE (node: Node; auth: Shards.Lid): BOOLEAN;

TYPE Interface = POINTER TO InterfaceRec; TYPE InterfaceRec = RECORD (Objects.ObjectRec) access: AccessProc; getStatus: GetStatusProc; setStatus: SetStatusProc; getMembers: GetMembersProc; takeInterest: TakeInterestProc; getNode: GetNodeProc; insert: InsertProc; makeSubnode: MakeSubnodeProc; delete: DeleteProc; destroy: DestroyProc; END;

CONST accessCap = 0; CONST statusCap = 1; CONST domainCap = 2; CONST destroyCap = 3; CONST makeSubnodeCap = 4; CONST allCaps = {accessCap .. makeSubnodeCap}; CONST strictCaps = {statusCap, domainCap, makeSubnodeCap}; TYPE CapabilitySet = SET; (* of [accessCap..destroyCap] *)

CONST inserted = insert; CONST deleted = delete; TYPE State = SHORTINT; (* inserted or deleted *) TYPE MemberEvent = POINTER TO MemberEventRec; TYPE MemberEventRec = RECORD (Events.EventRec) state: State; name: Name; (* of inserted/deleted member *) node: Node; END;

VAR root: Node;

TYPE ErrorCode = SHORTINT; TYPE ErrorEvent = POINTER TO ErrorEventRec; TYPE ErrorEventRec = RECORD (Events.EventRec) errorcode: ErrorCode; END; VAR errormsg: ARRAY errorcodes OF Events.Message; VAR error: Events.EventType;

PROCEDURE InitNode(node: Node; if: Interface; caps: CapabilitySet); PROCEDURE CreateNode(VAR node: Node; status: Status; caps: CapabilitySet); PROCEDURE Error(errors: RelatedEvents.Object; code: ErrorCode); PROCEDURE Capabilities(node: Node): CapabilitySet; PROCEDURE Access(node: Node; mode: AccessMode; auth: Shards.Lid): BOOLEAN; PROCEDURE GetStatus(node: Node; auth: Shards.Lid; VAR status: StatusRec): BOOLEAN; PROCEDURE SetStatus(node: Node; status: Status; auth: Shards.Lid): BOOLEAN; PROCEDURE GetMembers(node: Node; auth: Shards.Lid; VAR members: Lister): BOOLEAN; PROCEDURE TakeInterest(node: Node; auth: Shards.Lid; VAR eventType: Events.EventType): BOOLEAN; PROCEDURE GetNode(node: Node; name: Name; auth: Shards.Lid; VAR subnode: Node): BOOLEAN; PROCEDURE Insert(node, subnode: Node; name: Name; auth: Shards.Lid): BOOLEAN; PROCEDURE MakeSubnode(node: Node; name: Name; status: Status; caps: CapabilitySet; auth: Shards.Lid; VAR subnode: Node): BOOLEAN; PROCEDURE Delete(node: Node; name: Name; auth: Shards.Lid): BOOLEAN; PROCEDURE Destroy(node: Node; auth: Shards.Lid): BOOLEAN;

DESCRIPTION

Names defines and basically implements an abstraction for globally distributable name spaces for objects. Name spaces are directed (and in general cycle-free) graphs. Nodes in the ``root'' hierarchy as defined in this module can belong to other processes (name servers). Access to individual nodes can be controlled by use of an authorization scheme.

Nodes can have a combination of following capabilities:

accessCap
indicates that an explicit access method is present, so that results of Access (see below) can be considered authoritative;
statusCap
indicates that status information is maintained;
domainCap
denotes a node's capability to manage subnodes (members);
destroyCap
indicates that an explicit destroy method is present.
makeSubnodeCap
indicates the support of the MakeSubnode operation.
For convenience, allCaps defines a set of all capabilities, and strictCaps defines a set of those capabilities that will cause failures of associated methods when missing.

A status, if maintained, contains authorization agents (of type Shards.Pot) controlling the use of following methods:

examine
GetStatus
change
SetStatus
read
GetMembers, TakeInterest
search
GetNode
insert
Insert
delete
Delete
destroy
Destroy

Procedures of general interest

Capabilities returns capabilities of node.

Access tries to guess whether node would allow a particular access mode mode. When in doubt, e.g. because node has no access capability, result is TRUE.

GetStatus examines the current status of node. SetStatus changes the status of node.

GetMembers reads from node all names of current subnodes.

TakeInterest returns an event type for events notifying changes (additions or deletions) of members. Different nodes will yield different event types. Notification events carry a reference to the domain node whose set of members has changed and the name of the member.

GetNode searches node for a direct subnode named name.

Insert inserts name name for subnode subnode into node.

MakeSubnode creates a subnode of the same type as node and inserts it into node. The initial status is defined by status. If set to NIL, subnode inherits its status from node. The set of supported capabilities of subnode is the intersection of caps and those of the corresponding implementation. The new subnode is returned in subnode.

Delete deletes name name for an existing subnode of node.

Destroy terminates node and deletes references to it wherever possible.

CreateNode can be used to create a node of standard behaviour. In that case, status may be NIL if no restrictions are required.

Example

This is an example of a procedure printing the names of all direct subnodes of a given node to a stream, supposed they are publicly visible:
PROCEDURE PrintMembers(node: Names.Node; s: Streams.Stream);
   VAR
      members: Iterators.Iterator;
      member: Names.Name;
BEGIN
   IF Names.domainCap in Names.Capabilities(node) THEN
      IF Names.GetMembers(node, NIL, members) THEN
         WHILE Iterators.Get(members, member) DO
            ConstStrings.Write(s, member); Write.LnS(s);
         END;
      ELSE
         Conclusions.Conclude(node, Errors.error, "PrintMembers");
      END;
   END;
END PrintMembers;

Procedures for implementors

Implementations other than the standard implementation must initialize new instances of nodes using InitNode, specifying a set of capabilities caps and an interface if containing following procedures:

If statusCap IN caps:

getStatus: PROCEDURE(node: Node; auth: Shards.Lid; VAR status: StatusRec) : BOOLEAN;
copy node's status information into status.

setStatus: PROCEDURE(node: Node; status: Status; auth: Shards.Lid) : BOOLEAN;
set node's status information to status.

If domainCap IN caps:

getMembers: PROCEDURE(node: Node; auth: Shards.Lid; VAR members: Lister) : BOOLEAN;
return in members an iterator that will supply all names of node's direct subnodes.

takeInterest: PROCEDURE(node: Node; auth: Shards.Lid; VAR eventType: Events.EventType) : BOOLEAN;
return in eventType a type for events notifying changes of members of node.

getNode: PROCEDURE(node: Node; name: Name; auth: Shards.Lid; VAR subnode: Node) : BOOLEAN;
return in subnode node's subnode named name.

insert: PROCEDURE(node: Node; subnode: Node; name: Name; auth: Shards.Lid) : BOOLEAN;
insert subnode subnode by name name into node.

delete: PROCEDURE(node: Node; name: Name; auth: Shards.Lid) : BOOLEAN;
delete name name from node.

If makeSubnodeCap IN caps:

makeSubnode: PROCEDURE(node: Node; name: Name; status: Status; caps: CapabilitySet; auth: Shards.Lid; VAR subnode: Node) : BOOLEAN;
create a subnode of the own implementation and insert it under the given name into node. The status is to be inherited from node unless a non-NIL status is given.

If destroyCap IN caps:

destroy: PROCEDURE(node: Node; auth: Shards.Lid) : BOOLEAN;
check authorization to destroy node; clean up if appropriate.

Trivial implementations (i.e. those with an empty set of capabilities) may pass a NIL value for if to InitNode.

Implementors are free to share the builtin Error procedure to raise error events as defined below.

DIAGNOSTICS

All procedures return TRUE on success, otherwise FALSE. Errors are related to nodes and queued by default; their priority is Priorities.liberrors.

Following error codes are currently implemented:

noPermission
operation was not permitted
badAccessMode
illegal access mode
noStatus
node does not maintain a status
noDomain
node is not a domain
nodeNotFound
node could not be found
nodeDestroyed
node has been destroyed
nameExists
name is already in use
nodeBusy
node busy, possible deadlock situation
cyclicLink
operation would cause a cyclic link (not detected by some implementations)
serverFailure
name server failure
noSubDomain
MakeSubnode is not supported by this node
unknownError
Error was called with unknown error code

SEE ALSO

ConstStrings
handling of arbitrarily long strings
Iterators
sequential access of data structures
NamedObjects
add Names functionality to arbitrary objects
Paths
resolving string constants into name paths
PathConditions
wait until a path of Names becomes valid
PersistentNodes
persistent directory nodes
Services
type-independent definition of extensions
RelatedEvents
error event handling
RemoteNames
support of RemoteObjects for Names
Resources
object termination handling
Shards
abstraction for authorization protocols
UniqueNames
supply unique names
UnixNames
imports the public root

AUTHOR

Martin Hasch, University of Ulm,
MakeSubnode was added by Andreas Borchert
Edited by: borchert, last change: 2004/09/13, revision: 1.7, converted to HTML: 2004/09/13

Oberon || Library || Module Index || Search Engine || Definition || Module