...
This
...
page
...
originally
...
from
...
content
...
posted
...
...
...
...
...
.
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
...
...
...
...
.
...
)
...
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
...
...
...
...
...
...
.
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} |