Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

...

This

...

page

...

originally

...

from

...

content

...

posted

...

on

...

the

...

uportal

...

website

...

.

Introduction

A group is a collection of individual things that together form a unit. Groups have a formal mathematical definition, but to most of us, a group is simply a list of objects that share some attribute, category or role. The Groups service provides an API for maintaining groups of portal entities like users (IPersons) and channels (ChannelDefinitions). The API does not address the entities themselves but only their group memberships. The groups API is used by portal frameworks like authorization, layout management and channel management.

This document describes the groups model and API, which depend on the related idea of a portal entity. It is directed primarily at developers who are working with groups, for example, implementing a custom group store. For information about how to configure the composite groups system, see The Composite Group Service Guide.

Portal Entities

IBasicEntity

An entity is a persistent object whose key and type uniquely identify it. The most obvious portal entity is the user or IPerson, with a type of org.jasig.portal.security.IPerson.

...

The

...

key

...

of

...

an

...

IPerson

...

is

...

usually

...

something

...

like

...

"kweiner"

...

or

...

"ab123"

...

and

...

is

...

typically

...

the

...

user's

...

handle

...

in

...

a

...

central

...

directory.

...

An

...

IBasicEntity

...

must

...

be

...

able

...

to

...

return

...

an

...

EntityIdentifier

...

which,

...

in

...

turn,

...

answers

...

a

...

key

...

and

...

a

...

type.

...

}
Code Block
public interface IBasicEntity {
    public EntityIdentifier getEntityIdentifier();
}
{code}

h3. Entity Types  

Besides implementing IBasicEntity, a portal entity must have its type added to 

Entity Types

Besides implementing IBasicEntity, a portal entity must have its type added to org.jasig.portal.EntityTypes.

...

This

...

is

...

accomplished

...

by

...

inserting

...

a

...

row

...

into

...

the

...

UP_ENTITY_TYPE

...

table

...

in

...

the

...

portal

...

database,

...

a

...

reference

...

table

...

that

...

maps

...

the

...

class

...

name

...

of

...

an

...

IBasicEntity

...

to

...

an

...

integer.

...

The

...

EntityTypes

...

class

...

has

...

a

...

convenience

...

method

...

to

...

do

...

this:

...

}
Code Block
// Add a new EntityType for Thing:
Class newType = Class.forName("org.jasig.portal.Thing");
String description = "An all-purpose object";
EntityTypes.addEntityType(newType, description);
{code}

The

...

concurrency

...

and

...

group

...

services

...

operate

...

on

...

IBasicEntities,

...

so

...

once

...

an

...

IBasicEntity

...

has

...

been

...

added

...

to

...

EntityTypes,

...

it

...

can

...

be

...

cached,

...

locked

...

and

...

grouped.

...

{For

...

more

...

information

...

on

...

caching

...

and

...

locking

...

portal

...

entities,

...

see

...

uPortal

...

Concurrency

...

Services

...

.

...

)

...

The

...

org.jasig.portal.ChannelDefinition

...

and

...

org.jasig.portal.security.IPerson

...

types

...

come

...

pre-loaded

...

in

...

EntityTypes.

...

The Groups Model

The groups framework does not operate on IBasicEntities like IPersons or ChannelDefinitions, but manipulates stub objects whose keys and types point to underlying entities. The stubs are implementations of org.jasig.portal.groups.IEntity,

...

and

...

their

...

only

...

concern

...

is

...

their

...

group

...

memberships.

...

The

...

groups

...

an

...

IEntity

...

belongs

...

to

...

are

...

implementations

...

of

...

org.jasig.portal.groups.IEntityGroup.

...

Both

...

IEntity

...

and

...

IEntityGroup

...

are

...

also

...

IBasicEntities,

...

and

...

as

...

a

...

result,

...

they

...

can

...

be

...

cached

...

and

...

locked.

...

IEntityGroups

...

are

...

composites;

...

they

...

can

...

contain

...

other

...

IEntityGroups

...

as

...

well

...

as

...

IEntities.

...

This

...

structure

...

is

...

represented

...

by

...

the

...

following

...

interfaces:

...

}
No Format
IBasicEntity
    IGroupMember extends IBasicEntity
        IEntity extends IGroupMember
        IEntityGroup extends IGroupMember    
{noformat}

IEntityGroups

...

are

...

homogeneous

...

;

...

an

...

IEntityGroup's

...

IEntities

...

must

...

have

...

underlying

...

entities

...

that

...

are,

...

implement

...

or

...

extend

...

a

...

single

...

type.

...

An

...

IEntityGroup

...

that

...

contains

...

IEntities

...

of

...

type

...

of

...

IPerson

...

can

...

contain

...

memberships

...

for

...

IPersons,

...

subtypes

...

of

...

IPerson,

...

and

...

other

...

IPerson

...

groups.

...

An

...

IEntityGroup

...

that

...

contains

...

entities

...

of

...

type

...

Object

...

can

...

contain

...

memberships

...

for

...

entities

...

of

...

any

...

type,

...

as

...

long

...

as

...

their

...

keys

...

do

...

not

...

collide.

...

Groups

...

form

...

acyclic

...

graphs;

...

a

...

group

...

can

...

belong

...

to

...

0

...

or

...

more

...

parent

...

groups,

...

can

...

contain

...

0

...

or

...

more

...

child

...

groups,

...

and

...

cannot

...

contain

...

a

...

circular

...

reference.

...

An

...

actual

...

group

...

service

...

implementation,

...

like

...

the

...

Person

...

Attributes

...

Group

...

Service,

...

may

...

impose

...

further

...

constraints.

...

Using the Groups Service

Clients of the groups service use its façade, org.jasig.portal.services.GroupService

...

to

...

obtain

...

an

...

IGroupMember,

...

which

...

acts

...

as

...

a

...

starting

...

point

...

in

...

the

...

groups

...

system,

...

much

...

like

...

a

...

javax.naming.InitialContext

...

obtained

...

from

...

a

...

jndi

...

service

...

acts

...

as

...

an

...

entry

...

point

...

into

...

a

...

directory.

...

Once

...

you

...

have

...

a

...

reference

...

to

...

a

...

new

...

or

...

pre-existing

...

IGroupMember,

...

you

...

make

...

subsequent

...

requests

...

to

...

the

...

group

...

member

...

itself,

...

to

...

navigate

...

the

...

system,

...

retrieve

...

other

...

group

...

members,

...

and

...

update

...

groups.

...

The

...

groups

...

service

...

facade

...

lets

...

you

...

get

...

an

...

IGroupMember

...

in

...

1

...

of

...

3

...

ways:

...

by

...

finding

...

it

...

with

...

a

...

key,

...

by

...

searching

...

for

...

it

...

by

...

name

...

or

...

by

...

creating

...

a

...

new

...

instance.

...

Each

...

of

...

these

...

techniques

...

has

...

a

...

different

...

meaning

...

for

...

IEntities

...

and

...

IEntityGroups.

...

Group

...

and

...

Entity

...

Keys

...

The

...

groups

...

service

...

is

...

itself

...

a

...

group,

...

a

...

group

...

of

...

group

...

services.

...

Each

...

individual

...

service

...

is

...

a

...

component,

...

and

...

the

...

service

...

as

...

a

...

whole

...

is

...

a

...

composite.

...

Most

...

of

...

the

...

time

...

– except

...

when

...

you

...

have

...

to

...

configure

...

a

...

composite

...

service

...

or

...

write

...

a

...

component

...

– the

...

composite

...

service

...

and

...

its

...

facade

...

shield

...

you

...

from

...

this

...

knowledge.

...

However

...

you

...

do

...

need

...

to

...

be

...

aware

...

of

...

component

...

services

...

when

...

you

...

use

...

a

...

group

...

key.

...

The

...

key

...

is

...

a

...

compound

...

key

...

composed

...

of

...

a

...

component

...

service

...

name

...

concatenated

...

to

...

the

...

key

...

of

...

the

...

group

...

in

...

the

...

component

...

service,

...

separated

...

by

...

a

...

separator

...

character,

...

typically

...

a

...

period.

...

For

...

example,

...

the

...

key

...

of

...

group

...

"chem101"

...

in

...

the

...

component

...

service

...

"ldap"

...

would

...

be

...

"ldap.chem101".

...

The

...

key

...

of

...

group

...

"chem101"

...

in

...

the

...

"local"

...

service

...

would

...

be

...

"local.chem101".

...

An

...

entity

...

key

...

is

...

not

...

compound.

...

It

...

has

...

a

...

single

...

node

...

containing

...

the

...

key

...

that

...

all

...

component

...

group

...

services

...

must

...

use

...

to

...

identify

...

the

...

underlying

...

entity.

...

The

...

assumption

...

here

...

is

...

that

...

in

...

the

...

portal,

...

an

...

entity

...

key

...

like

...

a

...

userid

...

will

...

transcend

...

an

...

individual

...

source,

...

service

...

or

...

application.

...

The

...

userid

...

will

...

be

...

understood

...

by

...

ldap,

...

ERP

...

systems,

...

the

...

portal

...

database,

...

etc.

...

In

...

many,

...

perhaps

...

most

...

installations,

...

this

...

will

...

be

...

the

...

case.

...

But

...

suppose

...

for

...

a

...

minute

...

that

...

it

...

isn't.

...

Assume

...

that

...

a

...

person,

...

say

...

Mick

...

Jagger,

...

is

...

known

...

in

...

ldap

...

as

...

"mjagger",

...

in

...

People

...

Soft

...

as

...

"mj1"

...

and

...

in

...

a

...

third

...

system

...

as

...

"J.J.Flash".

...

In

...

this

...

portal,

...

the

...

deployer

...

would

...

have

...

to

...

select

...

one

...

system

...

to

...

be

...

the

...

base

...

source

...

of

...

person

...

entities

...

(perhaps

...

ldap)

...

and

...

provide

...

translations

...

for

...

the

...

other

...

sources.

...

If

...

ldap

...

were

...

chosen,

...

then

...

a

...

request

...

to

...

find

...

groups

...

that

...

contain

...

"mjagger"

...

would

...

have

...

to

...

be

...

understood

...

by

...

the

...

People

...

Soft

...

component

...

as

...

meaning

...

"find

...

groups

...

that

...

contain

...

"mj1",

...

and

...

other

...

systems

...

would

...

have

...

to

...

perform

...

their

...

own

...

translations.

...

Regardless

...

of

...

whether

...

it

...

is

...

necessary

...

to

...

do

...

these

...

translations,

...

a

...

groups

...

client

...

should

...

see

...

an

...

entity

...

as

...

having

...

a

...

single,

...

untranslated

...

key.

...

In

...

fact,

...

an

...

IEntity

...

has

...

2

...

keys,

...

one

...

for

...

its

...

underlying

...

entity

...

and

...

one

...

for

...

itself

...

as

...

an

...

IBasicEntity,

...

which

...

allows

...

it

...

to

...

be

...

cached

...

with

...

other

...

IEntities.

...

This

...

duality

...

is

...

reflected

...

in

...

the

...

IGroupMember

...

interface,

...

which

...

has

...

getters

...

for

...

the

...

basic

...

EntityIdentifier

...

(inherited

...

from

...

IBasicEntity)

...

and

...

the

...

underlying

...

EntityIdentifier:

...

}
Code Block
public EntityIdentifier getUnderlyingEntityIdentifier();
public EntityIdentifier getEntityIdentifier();
{code}

In

...

the

...

case

...

of

...

an

...

IEntityGroup,

...

the

...

underlying

...

EntityIdentifier

...

will

...

be

...

the

...

same

...

as

...

the

...

basic

...

EntityIdentifier.

...

In

...

the

...

case

...

of

...

an

...

IEntity,

...

it

...

will

...

be

...

the

...

EntityIdentifier

...

for

...

the

...

underlying

...

entity,

...

the

...

IPerson,

...

ChannelDefinition,

...

etc.,

...

as

...

shown

...

below:

...

}
Code Block
IPerson person = new PersonImpl();
person.setID(1);
person.setAttribute(IPerson.USERNAME,"guest");
IGroupMember gm = GroupSevice.getGroupMember(person.getEntityIdentifier());

EntityIdentifier basicEI = gm.getEntityIdentifier();
EntityIdentifier underlyingEI = gm.getUnderlyingEntityIdentifier();

// Key and type used by clients to get the IEntity:
System.out.println(underlyingEI.getKey());  // guest
System.out.println(underlyingEI.getType()); // interface org.jasig.portal.security.IPerson

// Key and type used by groups system to cache the IEntity:
System.out.println(basicEI.getKey());       // 5.guest
System.out.println(basicEI.getType());      // interface org.jasig.portal.Groups.IEntity
{code}

For

...

more

...

information

...

on

...

keys

...

in

...

the

...

group

...

system,

...

see

...

the

...

section

...

on

...

group

...

and

...

entity

...

keys

...

in

...

The

...

Composite

...

Group

...

Service

...

Guide

...

.

Finding a Group Member by Key

A key uniquely identifies a group member, therefore an attempt to find one by key will return at most 1 instance. The service attempts to find an IEntityGroup by searching for an existing group. If it doesn't find the group, it returns null:

Code Block
// Find a group by key:
String key = "local.123";
IEntityGroup myGroup = GroupSevice.findGroup(key); // could be null
{code}

On

...

the

...

other

...

hand,

...

when

...

you

...

ask

...

the

...

group

...

service

...

to

...

get

...

an

...

IEntity

...

corresponding

...

to

...

a

...

given

...

key

...

and

...

type,

...

the

...

service

...

is

...

not

...

obligated

...

to

...

verify

...

that

...

the

...

underlying

...

entity

...

actually

...

exists

...

in

...

some

...

external

...

system.

...

The

...

behavior

...

of

...

the

...

local

...

service,

...

the

...

default

...

source

...

of

...

IEntities

...

is

...

to

...

return

...

an

...

IEntity

...

for

...

any

...

key

...

so

...

long

...

as

...

the

...

type

...

exists

...

in

...

EntityTypes.

...

A

...

non-null

...

result

...

does

...

not

...

mean

...

that

...

the

...

underlying

...

entity

...

actually

...

exists

...

or

...

that

...

it

...

has

...

memberships.

...

Code Block
// Get an entity by key (should never be null):
String key = "dan";
Class personType = Class.forName("org.jasig.portal.security.IPerson");
IEntity myEntity = GroupService.getEntity(key, personType);
{code}

You

...

can

...

override

...

this

...

behavior

...

by

...

asking

...

for

...

an

...

IEntity

...

from

...

a

...

non-default

...

source

...

by

...

passing

...

in

...

the

...

name

...

of

...

the

...

component

...

group

...

service,

...

and

...

reimplementing

...

the

...

entity

...

factory,

...

IEntityStore.

...

Code Block
// Get an entity by key (could be null):
String service = "myService";
String key = "dan";
Class personType = Class.forName("org.jasig.portal.security.IPerson");
IEntity myEntity = GroupService.getEntity(key, personType, service);
{code}

The

...

service

...

will

...

use

...

the

...

appropriate

...

method

...

if

...

you

...

call

...

one

...

of

...

the

...

getGroupMember()

...

methods:

...

}
Code Block
// Get a group member by key and type:
String key = "100";
Class channelDefType = Class.forName("org.jasig.portal.ChannelDefinition");
IGroupMember chanGroupMember = GroupService.getGroupMember(key, channelDefType);
{code}

or:

...

}
Code Block
// Get a group member by EntityIdentifier:
String key = "local.101";
Class groupType = Class.forName("org.jasig.portal.groups.IEntityGroup");
EntityIdentifier eid = new EntityIdentifier(key, groupType);
IGroupMember chanGroupMember = GroupService.getGroupMember(eid);
{code}

There

...

are

...

2

...

other

...

kinds

...

of

...

groups

...

that

...

can

...

be

...

found

...

by

...

key,

...

albeit

...

indirectly,

...

via

...

entries

...

in

...

portal.properties.

...

A

...

distinguished

...

group

...

has

...

an

...

entry

...

in

...

portal.properties

...

that

...

associates

...

a

...

name

...

with

...

a

...

group

...

key.

...

A

...

root

...

group

...

is

...

a

...

group

...

that

...

you

...

can

...

optionally

...

designate

...

as

...

the

...

group

...

from

...

which

...

all

...

groups

...

of

...

the

...

same

...

entity

...

type

...

descend.

...

The

...

entry

...

in

...

portal.properties

...

for

...

a

...

root

...

group

...

associates

...

a

...

type

...

name

...

with

...

a

...

group

...

key.

...

This

...

designation

...

is

...

informal

...

only

...

and

...

is

...

not

...

enforced

...

by

...

the

...

group

...

system.

...

It

...

exists

...

for

...

the

...

convenience

...

of

...

groups

...

clients

...

like

...

the

...

Groups

...

Manager

...

channel

...

that

...

display

...

the

...

group

...

system

...

as

...

a

...

forest

...

in

...

which

...

all

...

groups

...

of

...

the

...

same

...

type

...

descend

...

from

...

a

...

single

...

tree.

...

Code Block
// Find a distinguished group:
String distinguishedName = "administrators";
IEntityGroup administrators = GroupService.findDistinguishedGroup(distinguishedName);

// Find a root group:
Class thingType = Class.forName("org.jasig.portal.Thing");
IEntityGroup rootOfAllThings = GroupService.findRootGroup(thingType);
{code}

h2. Searching for Group Members by Name

There are times when you do not know the key of the group member, but instead want to search for it by name.  A search can turn up 0 or more instances, and the 4 search methods return an EntityIdentifier[], each element of which can be turned into an IGroupMember via 

Searching for Group Members by Name

There are times when you do not know the key of the group member, but instead want to search for it by name. A search can turn up 0 or more instances, and the 4 search methods return an EntityIdentifier[], each element of which can be turned into an IGroupMember via GroupService.getGroupMember():

...

}
Code Block
searchForEntities(String query, int method, Class type)
searchForEntities(String query, int method, Class type, IEntityGroup ancestor)
searchForGroups(String query, int method, Class leaftype)
searchForGroups(String query, int method, Class leaftype, IEntityGroup ancestor)
{code}


Two of the search methods take 3 arguments, a search String, (the name of the group member), a search method (see 

Two of the search methods take 3 arguments, a search String, (the name of the group member), a search method (see org.jasig.portal.groups.IGroupConstants

...

for

...

a

...

list

...

of

...

the

...

search

...

methods),

...

and

...

a

...

Class

...

(the

...

entity

...

type).

...

The

...

other

...

2

...

methods

...

take

...

an

...

additional

...

argument,

...

ancestor

...

group,

...

which

...

confines

...

the

...

search

...

to

...

(recursive)

...

members

...

of

...

the

...

group.

...

Each

...

component

...

group

...

service

...

is

...

obligated

...

to

...

implement

...

the

...

4

...

search

...

methods.

...

In

...

a

...

search

...

for

...

groups,

...

a

...

component

...

service

...

examines

...

its

...

group

...

store

...

and

...

returns

...

results

...

that

...

match

...

the

...

query.

...

The

...

results

...

are

...

EntityIdentifiers

...

for

...

groups

...

that

...

already

...

exist

...

in

...

the

...

groups

...

system.

...

A

...

search

...

for

...

entities,

...

on

...

the

...

other

...

hand,

...

may

...

be

...

conducted

...

to

...

locate

...

an

...

entity

...

that

...

is

...

not

...

yet

...

represented

...

in

...

the

...

group

...

system,

...

for

...

example,

...

a

...

new

...

employee.

...

Here,

...

the

...

search

...

is

...

conducted

...

on

...

one

...

or

...

more

...

stores

...

that

...

constitute

...

entity

...

sources

...

for

...

the

...

component

...

service.

...

}
Code Block
// search for IPersons whose names start with "Khar"
String query = "Khar";
int method = IGroupConstants.STARTS_WITH;
Class type = Class.forName("org.jasig.portal.security.IPerson");
EntityIdentifier[] ents = GroupService.searchForEntities(query,method,type);
{code}

h2. Creating a New Group Member

There are 2 methods for creating a new group.  In one, you designate the group type and the component service name.  In the other, you designate only the type and the default service creates the group.   (The default service is designated in the composite group service configuration, compositeGroupServices.xml.) 

{code}

Creating a New Group Member

There are 2 methods for creating a new group. In one, you designate the group type and the component service name. In the other, you designate only the type and the default service creates the group. (The default service is designated in the composite group service configuration, compositeGroupServices.xml.)

Code Block
IEntityGroup newGroup(Class type)
IEntityGroup newGroup(Class type, String serviceName)
{code}

Once

...

you

...

have

...

created

...

a

...

new

...

group,

...

you

...

can

...

set

...

its

...

name,

...

add

...

members,

...

make

...

it

...

a

...

member

...

of

...

other

...

groups,

...

etc.,

...

but

...

until

...

you

...

update

...

the

...

group,

...

it

...

is

...

not

...

saved

...

in

...

the

...

store.

...

Code Block
// Create a new IPerson group in the default service
Class type = Class.forName("org.jasig.portal.security.IPerson");
IEntityGroup newGroup = GroupService.newGroup(type);
newGroup.setName("Test Group");
...
newGroup.update();

{code}

A

...

new

...

IEntity

...

is

...

created

...

with

...

the

...

getEntity()

...

and

...

getGroupMember()

...

methods.

...

New

...

instances

...

of

...

IEntity

...

are

...

routinely

...

created

...

and

...

destroyed,

...

but

...

they

...

are

...

not

...

saved

...

persistently

...

in

...

the

...

groups

...

system.

...

An

...

IEntity

...

represents

...

and

...

points

...

to

...

an

...

underlying

...

entity

...

that

...

may

...

exist

...

in

...

some

...

external

...

source.

...

The

...

only

...

way

...

to

...

create

...

the

...

underlying

...

entity

...

is

...

to

...

create

...

it

...

in

...

the

...

external

...

source.

...


Working

...

With

...

Group

...

Members

...


Once

...

you

...

get

...

a

...

group

...

member

...

from

...

the

...

service,

...

you

...

can

...

use

...

it

...

to

...

retrieve

...

related

...

group

...

members:

...

}
Code Block
IGroupMember student = GroupService.getEntity("student");

// Find groups that the entity belongs to:
Iterator studentGroups = student.getContainingGroups();
...

// (Recursively) find groups the entity belongs to:
Iterator allStudentGroups = student.getAllContainingGroups();
...

// Find if an entity is a member of a group:
IGroupMember gradStudents = GroupService.findGroup("local.8");
if ( gradStudents != null && student.isMemberOf(gradStudents) )
{
    ...
}

{code}

IEntities

...

are

...

not

...

updatable.

...

An

...

IEntityGroup

...

may

...

or

...

may

...

not

...

be,

...

depending

...

on

...

whether

...

its

...

component

...

group

...

service

...

implements

...

update

...

methods

...

and

...

is

...

declared

...

to

...

be

...

updatable.

...

(For

...

information

...

on

...

configuring

...

component

...

group

...

services,

...

see

...

The

...

Composite

...

Group

...

Service

...

Guide.)

...

Changes

...

to

...

an

...

IEntityGroup

...

are

...

only

...

committed

...

to

...

the

...

store

...

when

...

the

...

group

...

is

...

explicitly

...

updated:

...

}
Code Block
IEntityGroup faculty = GroupService.findGroup("local.2");
if ( faculty != null && faculty.hasMembers() )
{
    // Find members of a group:
    for (Iterator itr = faculty.getMembers(); itr.hasNext();)
    {
        IGroupMember facultyMember = (IGroupMember) itr.next();
        faculty.removeMember(facultyMember);
    }
}
faculty.setDescription("Has no members");
faculty.update();

{code}

The

...

Group

...

Service

...

also

...

provides

...

a

...

lockable

...

group,

...

a

...

group

...

whose

...

key

...

has

...

been

...

exclusively

...

locked

...

by

...

the

...

Entity

...

Locking

...

Service

...

(see

...

uPortal

...

Concurrency

...

Services

...

for

...

locking

...

service

...

details.)

...

Getting

...

a

...

lockable

...

group

...

doesn't

...

literally

...

guarantee

...

exclusive

...

write

...

access,

...

it

...

guarantees

...

that

...

no

...

other

...

process

...

can

...

get

...

a

...

lockable

...

group

...

for

...

the

...

same

...

key,

...

so

...

as

...

long

...

as

...

all

...

group

...

clients

...

cooperate,

...

lockable

...

groups

...

work.

...

public

...

static

...

ILockableEntityGroup

...

findLockableGroup(String

...

key,

...

String

...

lockOwner)

...

If

...

the

...

group

...

is

...

already

...

locked,

...

the

...

group

...

service

...

throws

...

a

...

GroupsException,

...

so

...

you

...

must

...

catch

...

the

...

Exception

...

and

...

decide

...

whether

...

to

...

abandon

...

the

...

attempt

...

or

...

perhaps

...

wait

...

and

...

try

...

again.

...

Lock

...

management

...

for

...

the

...

group

...

is

...

handled

...

by

...

the

...

component

...

service,

...

including

...

checking

...

that

...

the

...

lock

...

is

...

still

...

valid

...

and

...

releasing

...

it

...

after

...

update.

...

Code Block
String studentGroupKey = "local.1";
String owner = "dan";
ILockableEntityGroup leg = null;
try
{
    leg = GroupService.findLockableGroup(studentGroupKey, owner);
}
catch (GroupsException gre)
{
    // group is already locked.
}

if ( leg == null )
{
    // group could not be found.
}
else
{
    leg.setDescription("Edited student group");
    ...
    leg.update();
}

{code}

The

...

complete

...

IGroupMember

...

interface

...

is

...

listed

...

below.

...

The

...

IGroupMember

...

Interface

...

IGroupMember

...

defines

...

the

...

common

...

(component)

...

behavior

...

for

...

both

...

its

...

leaf

...

(IEntity)

...

and

...

composite

...

(IEntityGroup)

...

sub-types.

...

An

...

IGroupMember

...

can

...

answer

...

both

...

its

...

parents

...

and

...

its

...

children

...

but

...

has

...

no

...

api

...

for

...

adding

...

or

...

removing

...

them.

...

These

...

methods,

...

along

...

with

...

methods

...

to

...

update

...

the

...

persistent

...

store,

...

are

...

defined

...

on

...

the

...

group

...

type

...

because

...

you

...

add

...

a

...

member

...

to

...

a

...

group,

...

not

...

vice

...

versa.

...

All

...

methods

...

that

...

maintain

...

the

...

groups

...

structure

...

or

...

return

...

IGroupMembers

...

throw

...

GroupsExceptions.

...

These

...

Exceptions

...

are

...

thrown

...

for

...

two

...

reasons,

...

an

...

attempt

...

to

...

violate

...

the

...

groups

...

structure,

...

for

...

example

...

by

...

trying

...

to

...

add

...

a

...

group

...

with

...

a

...

duplicate

...

name,

...

or

...

some

...

error

...

accessing

...

the

...

persistent

...

store.

...

In

...

the

...

latter

...

case,

...

the

...

GroupsException

...

wraps

...

an

...

Exception

...

specific

...

to

...

the

...

store,

...

like

...

a

...

SQLException

...

or

...

a

...

NamingException.

...

Code Block
public interface IGroupMember extends IBasicEntity {
  public boolean equals(Object o);
  public Class getEntityType();
  public String getKey();
  public Class getLeafType();
  public Class getType();
  public EntityIdentifier getUnderlyingEntityIdentifier();
  public int hashCode();
  public boolean isEntity();
  public boolean isGroup();

  // shallow:
  public boolean contains(IGroupMember gm) throws GroupsException;
  public Iterator getContainingGroups() throws GroupsException;
  public Iterator getEntities() throws GroupsException;
  public IEntityGroup getMemberGroupNamed(String name) throws GroupsException;
  public Iterator getMembers() throws GroupsException;
  public boolean isMemberOf(IGroupMember gm) throws GroupsException;
  public boolean hasMembers() throws GroupsException;

  // deep:
  public boolean deepContains(IGroupMember gm) throws GroupsException;
  public Iterator getAllContainingGroups() throws GroupsException;
  public Iterator getAllEntities() throws GroupsException;
  public Iterator getAllMembers() throws GroupsException;
  public boolean isDeepMemberOf(IGroupMember gm) throws GroupsException;
}
{code}

IEntity

...

is

...

the

...

leaf

...

sub-type

...

of

...

IGroupMember.

...

It

...

inherits

...

component

...

and

...

entity

...

behavior

...

from

...

IGroupMember.

...

At

...

present

...

this

...

is

...

just

...

a

...

marker

...

interface.

...

Code Block
public interface IEntity extends IGroupMember
{

  // marker interface

}
{code}
 
{code}
Code Block
public interface IEntityGroup extends IGroupMember
{
  // getters and setters:
  public String getCreatorID();
  public String getDescription();
  public String getLocalKey();
  public String getName();
  public Name getServiceName();
  public void setCreatorID(String userID);
  public void setDescription(String name);
  public void setName(String name) throws GroupsException;
  public void setLocalGroupService(IIndividualGroupService groupService)
    throws GroupsException;

  // composite methods:
  public void addMember(IGroupMember gm) throws GroupsException;
  public void delete() throws GroupsException;
  public boolean isEditable() throws GroupsException;
  public void removeMember(IGroupMember gm);
  public void update() throws GroupsException;
  public void updateMembers() throws GroupsException;
}
{code}

ILockableEntityGroup

...

extends

...

IEntityGroup

...

and

...

defines

...

a

...

few

...

methods

...

that

...

support

...

exclusive

...

updates:

...

}
Code Block
public interface ILockableEntityGroup extends IEntityGroup {
  public IEntityLock getLock();
  public void setLock(IEntityLock lock);
  public void updateAndRenewLock() throws GroupsException;
  public void updateMembersAndRenewLock() throws GroupsException;
}
{code}