[OPENMRS-DEV] Current state of attributes

Couldn't help but notice that the openmrs team are also engaged in a
process of defining generic attributes. And making them the subject
of design calls :slight_smile:

It might be useful to compare. Two things i pick up from the below is
that there seems to be much effort put into attribute types (validated
strings, dates etc) though I don't see the coded attributes which we
have and (ii) they DO have an interface, Customizable, which applies
to all classes which can e extended.

Interesting to see these efforts happening at the same time.

Cheers
Bob

···

---------- Forwarded message ----------
From: Darius Jazayeri <djazayeri@gmail.com>
Date: 24 September 2011 21:03
Subject: [OPENMRS-DEV] Current state of attributes
To: openmrs-devel-l@listserv.iupui.edu

Hi All,
On our last few design calls we've been working through the generic
AttributeType mechanism that we're introducing in 1.9. (see ticket)
I wanted to summarize the current state of things. Some of this is in
trunk, but some is refactoring I'm doing. I'm especially interested in
thoughts about how these classes should be linked together with
parameterized types, since I'm not convinced I've gotten that right:
interface CustomDatatypeHandler<T>

Capable of converting T to/from a String that can be persisted in the
varchar column of a database. E.g. a date would be stored as
yyyy-mm-dd and an image might be stored as a uri pointing to a PACS
system. Also capable of validating T, e.g. so we can use a plain
java.util.Date to represent "date-in-past" but limit its possible
values.
Defines a String "datatypeHandled", e.g. "date", "regex-validated-string")
T fromPersistedString(String)
String toPersistedString(T)
void validate(T)
String render(String persistedValue, String view)
can be configured with setHandlerConfiguration(String)

interface CustomDatatyped

holds the definition of a custom datatype (which is handled by a
handler of the above interface). For example VisitAttributeType and
GlobalProperty (we're able to do typed GPs trivially now)
required: String getDatatype()
optional: String getPreferredHandlerClassname()

if specified, will be handled by this specific CustomDatatypeHandler,
otherwise it will be handled by the default handler for this thing's
datatype

optional: String getHandlerConfig()

interface AttributeType<OwningType extends Customizable> extends
CustomDatatyped, OpenmrsMetadata

for user-defined extensions to core domain objects, which would be
handled by adding custom database columns in a less generic system.
E.g. VisitAttributeType implements AttributeType<Visit>
datatype/handler specified via CustomDatatyped superinterface
Integer getMinOccurs()
Integer getMaxOccurs()

class VisitAttributeType, class LocationAttributeType, class
ProviderAttributeType

trivial implementations of AttributeType (via BaseAttributeType)

interface Customizable<AttrClass extends Attribute>

Implemented by domain classes that may be customized by the user via
custom attributes. E.g. Visit implements Customizable<VisitAttribute>,
Location implements Customizable<LocationAttribute>
Has convenience methods for dealing with a collection of attributes,
of different types:
Collection<AttrClass> getAttributes() //includes voided
Collection<AttrClass> getActiveAttributes() //non-voided
void addAttribute(AttrClass)
void setAttribute(AttrClass) //voids other attributes of the given type

interface CustomValue

holds a value managed by a CustomDatatypeHandler. E.g. VisitAttribute,
GlobalProperty. Any implementation of this has a corresponding
CustomDatatyped implementation. "persistedValue" is a String suitable
for persisting in a db varchar column; "objectValue" is what you'd
want to work with in the API.
String getPersistedValue()
void setPersistedValue()
Object getObjectValue() // don't remember why this isn't <T>
void setObjectValue(Object)

interface Attribute<OwningType extends Customizable> implements
CustomValue, OpenmrsData

value corresponding to an AttributeType (which defines its datatype,
whether it's required, whether it can repeat, etc), e.g.
VisitAttribute corresponds to VisitAttributeType
OwningType getOwner()
void setOwner(OwningType)
AttributeType<OwningType> getAttributeType()

class VisitAttribute, class LocationAttribute, class ProviderAttribute

trivial implementation of Attribute (via BaseAttribute)

class GlobalProperty implements CustomDatatyped, CustomValue

this is interesting in that it both defines a custom datatype and
stores its value

Thoughts welcome...
-Darius
________________________________
Click here to unsubscribe from OpenMRS Developers' mailing list

I like it. A lot.

I come back to this, which I have been ranting about for some time

https://blueprints.launchpad.net/dhis2/+spec/regex-validation

Seeing that they are more or less following this route to some degree
(it would at least seem from the discussion) with regex validation of
attributes, seems like a very wise move. Otherwise, I can imagine
chaos will result.

If we could do this with the new attributes, this would obviously add
a lot more control of what would get in an attribute, such as a
national identity number, which would make it a lot easier to do
something with, i.e. "getOrganisationUnitByAttribute(attribute,
value)"

Ergo, it would seem that an organisation unit code is also an
attribute, but a predefined one which can actually do something "e.g.
getOrganisationUnitByCode" (but which is lacking validation, which
seemingly would be useful).

Regards,
Jason

···

On Sun, Sep 25, 2011 at 5:25 PM, Bob Jolliffe <bobjolliffe@gmail.com> wrote:

Couldn't help but notice that the openmrs team are also engaged in a
process of defining generic attributes. And making them the subject
of design calls :slight_smile:

It might be useful to compare. Two things i pick up from the below is
that there seems to be much effort put into attribute types (validated
strings, dates etc) though I don't see the coded attributes which we
have and (ii) they DO have an interface, Customizable, which applies
to all classes which can e extended.

Interesting to see these efforts happening at the same time.

Cheers
Bob

---------- Forwarded message ----------
From: Darius Jazayeri <djazayeri@gmail.com>
Date: 24 September 2011 21:03
Subject: [OPENMRS-DEV] Current state of attributes
To: openmrs-devel-l@listserv.iupui.edu

Hi All,
On our last few design calls we've been working through the generic
AttributeType mechanism that we're introducing in 1.9. (see ticket)
I wanted to summarize the current state of things. Some of this is in
trunk, but some is refactoring I'm doing. I'm especially interested in
thoughts about how these classes should be linked together with
parameterized types, since I'm not convinced I've gotten that right:
interface CustomDatatypeHandler<T>

Capable of converting T to/from a String that can be persisted in the
varchar column of a database. E.g. a date would be stored as
yyyy-mm-dd and an image might be stored as a uri pointing to a PACS
system. Also capable of validating T, e.g. so we can use a plain
java.util.Date to represent "date-in-past" but limit its possible
values.
Defines a String "datatypeHandled", e.g. "date", "regex-validated-string")
T fromPersistedString(String)
String toPersistedString(T)
void validate(T)
String render(String persistedValue, String view)
can be configured with setHandlerConfiguration(String)

interface CustomDatatyped

holds the definition of a custom datatype (which is handled by a
handler of the above interface). For example VisitAttributeType and
GlobalProperty (we're able to do typed GPs trivially now)
required: String getDatatype()
optional: String getPreferredHandlerClassname()

if specified, will be handled by this specific CustomDatatypeHandler,
otherwise it will be handled by the default handler for this thing's
datatype

optional: String getHandlerConfig()

interface AttributeType<OwningType extends Customizable> extends
CustomDatatyped, OpenmrsMetadata

for user-defined extensions to core domain objects, which would be
handled by adding custom database columns in a less generic system.
E.g. VisitAttributeType implements AttributeType<Visit>
datatype/handler specified via CustomDatatyped superinterface
Integer getMinOccurs()
Integer getMaxOccurs()

class VisitAttributeType, class LocationAttributeType, class
ProviderAttributeType

trivial implementations of AttributeType (via BaseAttributeType)

interface Customizable<AttrClass extends Attribute>

Implemented by domain classes that may be customized by the user via
custom attributes. E.g. Visit implements Customizable<VisitAttribute>,
Location implements Customizable<LocationAttribute>
Has convenience methods for dealing with a collection of attributes,
of different types:
Collection<AttrClass> getAttributes() //includes voided
Collection<AttrClass> getActiveAttributes() //non-voided
void addAttribute(AttrClass)
void setAttribute(AttrClass) //voids other attributes of the given type

interface CustomValue

holds a value managed by a CustomDatatypeHandler. E.g. VisitAttribute,
GlobalProperty. Any implementation of this has a corresponding
CustomDatatyped implementation. "persistedValue" is a String suitable
for persisting in a db varchar column; "objectValue" is what you'd
want to work with in the API.
String getPersistedValue()
void setPersistedValue()
Object getObjectValue() // don't remember why this isn't <T>
void setObjectValue(Object)

interface Attribute<OwningType extends Customizable> implements
CustomValue, OpenmrsData

value corresponding to an AttributeType (which defines its datatype,
whether it's required, whether it can repeat, etc), e.g.
VisitAttribute corresponds to VisitAttributeType
OwningType getOwner()
void setOwner(OwningType)
AttributeType<OwningType> getAttributeType()

class VisitAttribute, class LocationAttribute, class ProviderAttribute

trivial implementation of Attribute (via BaseAttribute)

class GlobalProperty implements CustomDatatyped, CustomValue

this is interesting in that it both defines a custom datatype and
stores its value

Thoughts welcome...
-Darius
________________________________
Click here to unsubscribe from OpenMRS Developers' mailing list

_______________________________________________
Mailing list: DHIS 2 developers in Launchpad
Post to : dhis2-devs@lists.launchpad.net
Unsubscribe : DHIS 2 developers in Launchpad
More help : ListHelp - Launchpad Help

On coded attributes ...

How is a coded attribute different from a groupset? From a
dimensionality perspective they realy seem completely identical to me.
So should we drop groupsets? Or implement coded attributes as
groupsets?

···

On 25 September 2011 16:25, Bob Jolliffe <bobjolliffe@gmail.com> wrote:

Couldn't help but notice that the openmrs team are also engaged in a
process of defining generic attributes. And making them the subject
of design calls :slight_smile:

It might be useful to compare. Two things i pick up from the below is
that there seems to be much effort put into attribute types (validated
strings, dates etc) though I don't see the coded attributes which we
have and (ii) they DO have an interface, Customizable, which applies
to all classes which can e extended.

Interesting to see these efforts happening at the same time.

Cheers
Bob

---------- Forwarded message ----------
From: Darius Jazayeri <djazayeri@gmail.com>
Date: 24 September 2011 21:03
Subject: [OPENMRS-DEV] Current state of attributes
To: openmrs-devel-l@listserv.iupui.edu

Hi All,
On our last few design calls we've been working through the generic
AttributeType mechanism that we're introducing in 1.9. (see ticket)
I wanted to summarize the current state of things. Some of this is in
trunk, but some is refactoring I'm doing. I'm especially interested in
thoughts about how these classes should be linked together with
parameterized types, since I'm not convinced I've gotten that right:
interface CustomDatatypeHandler<T>

Capable of converting T to/from a String that can be persisted in the
varchar column of a database. E.g. a date would be stored as
yyyy-mm-dd and an image might be stored as a uri pointing to a PACS
system. Also capable of validating T, e.g. so we can use a plain
java.util.Date to represent "date-in-past" but limit its possible
values.
Defines a String "datatypeHandled", e.g. "date", "regex-validated-string")
T fromPersistedString(String)
String toPersistedString(T)
void validate(T)
String render(String persistedValue, String view)
can be configured with setHandlerConfiguration(String)

interface CustomDatatyped

holds the definition of a custom datatype (which is handled by a
handler of the above interface). For example VisitAttributeType and
GlobalProperty (we're able to do typed GPs trivially now)
required: String getDatatype()
optional: String getPreferredHandlerClassname()

if specified, will be handled by this specific CustomDatatypeHandler,
otherwise it will be handled by the default handler for this thing's
datatype

optional: String getHandlerConfig()

interface AttributeType<OwningType extends Customizable> extends
CustomDatatyped, OpenmrsMetadata

for user-defined extensions to core domain objects, which would be
handled by adding custom database columns in a less generic system.
E.g. VisitAttributeType implements AttributeType<Visit>
datatype/handler specified via CustomDatatyped superinterface
Integer getMinOccurs()
Integer getMaxOccurs()

class VisitAttributeType, class LocationAttributeType, class
ProviderAttributeType

trivial implementations of AttributeType (via BaseAttributeType)

interface Customizable<AttrClass extends Attribute>

Implemented by domain classes that may be customized by the user via
custom attributes. E.g. Visit implements Customizable<VisitAttribute>,
Location implements Customizable<LocationAttribute>
Has convenience methods for dealing with a collection of attributes,
of different types:
Collection<AttrClass> getAttributes() //includes voided
Collection<AttrClass> getActiveAttributes() //non-voided
void addAttribute(AttrClass)
void setAttribute(AttrClass) //voids other attributes of the given type

interface CustomValue

holds a value managed by a CustomDatatypeHandler. E.g. VisitAttribute,
GlobalProperty. Any implementation of this has a corresponding
CustomDatatyped implementation. "persistedValue" is a String suitable
for persisting in a db varchar column; "objectValue" is what you'd
want to work with in the API.
String getPersistedValue()
void setPersistedValue()
Object getObjectValue() // don't remember why this isn't <T>
void setObjectValue(Object)

interface Attribute<OwningType extends Customizable> implements
CustomValue, OpenmrsData

value corresponding to an AttributeType (which defines its datatype,
whether it's required, whether it can repeat, etc), e.g.
VisitAttribute corresponds to VisitAttributeType
OwningType getOwner()
void setOwner(OwningType)
AttributeType<OwningType> getAttributeType()

class VisitAttribute, class LocationAttribute, class ProviderAttribute

trivial implementation of Attribute (via BaseAttribute)

class GlobalProperty implements CustomDatatyped, CustomValue

this is interesting in that it both defines a custom datatype and
stores its value

Thoughts welcome...
-Darius
________________________________
Click here to unsubscribe from OpenMRS Developers' mailing list

How is a coded attribute different from a groupset? From a
dimensionality perspective they realy seem completely identical to me.
So should we drop groupsets? Or implement coded attributes as
groupsets?

Seems you are right. AttributeOption=Group and Attribute=GroupSet.
Don't think we want to remove group sets but it seems redundant to
have both.

I think maybe its really a UI paradigm twist ...

Currently we only add orgunits to groups in the orgunitgroup editor.
What we need, in the orgunit edit screen, is to show the
orgunitgroupsets (attributes) and their corresponding groups (values)
and have the means to change the value from there. This will then
have the same 'look and feel' as editing attributes.

This should also simplify the attribute code as dealing with the coded
attribute special case seemed a bit awkward.

···

On 26/09/2011, Lars Helge Øverland <larshelge@gmail.com> wrote:

How is a coded attribute different from a groupset? From a
dimensionality perspective they realy seem completely identical to me.
So should we drop groupsets? Or implement coded attributes as
groupsets?

Seems you are right. AttributeOption=Group and Attribute=GroupSet.
Don't think we want to remove group sets but it seems redundant to
have both.

Yup agree.

···

2011/9/26 Bob Jolliffe <bobjolliffe@gmail.com>:

I think maybe its really a UI paradigm twist ...

Currently we only add orgunits to groups in the orgunitgroup editor.
What we need, in the orgunit edit screen, is to show the
orgunitgroupsets (attributes) and their corresponding groups (values)
and have the means to change the value from there. This will then
have the same 'look and feel' as editing attributes.

This should also simplify the attribute code as dealing with the coded
attribute special case seemed a bit awkward.

We actually allow the users to select groups per group set in the edit orgunit window today, at least for the two standard group sets “Type” and “Ownership”, so this change is not so radical.

If we can add additional group sets in there dynamically, then I guess we have what you suggest.

What we still need is the ability to batch assign orgunits to groups like we have in the edit group today, since no one wants to add 8000 facilities to a type by opening the edit orgunit window for 8000 orgunits…

Ola

···

2011/9/26 Bob Jolliffe bobjolliffe@gmail.com

I think maybe its really a UI paradigm twist …

Currently we only add orgunits to groups in the orgunitgroup editor.

What we need, in the orgunit edit screen, is to show the

orgunitgroupsets (attributes) and their corresponding groups (values)

and have the means to change the value from there. This will then

have the same ‘look and feel’ as editing attributes.


This should also simplify the attribute code as dealing with the coded

attribute special case seemed a bit awkward.

On 26/09/2011, Lars Helge Øverland larshelge@gmail.com wrote:

How is a coded attribute different from a groupset? From a

dimensionality perspective they realy seem completely identical to me.

So should we drop groupsets? Or implement coded attributes as

groupsets?

Seems you are right. AttributeOption=Group and Attribute=GroupSet.

Don’t think we want to remove group sets but it seems redundant to

have both.


Mailing list: https://launchpad.net/~dhis2-devs

Post to : dhis2-devs@lists.launchpad.net

Unsubscribe : https://launchpad.net/~dhis2-devs

More help : https://help.launchpad.net/ListHelp

I think maybe its really a UI paradigm twist ...

Currently we only add orgunits to groups in the orgunitgroup editor.
What we need, in the orgunit edit screen, is to show the
orgunitgroupsets (attributes) and their corresponding groups (values)
and have the means to change the value from there. This will then
have the same 'look and feel' as editing attributes.

We actually allow the users to select groups per group set in the edit
orgunit window today, at least for the two standard group sets "Type" and
"Ownership", so this change is not so radical.
If we can add additional group sets in there dynamically, then I guess we
have what you suggest.

What we still need is the ability to batch assign orgunits to groups like we
have in the edit group today, since no one wants to add 8000 facilities to a
type by opening the edit orgunit window for 8000 orgunits....

Sure. Wasn't suggesting taking that away. Just observing that we can
also view the groupset as a coded attribute so we should avoid
implementing it twice. I think its a win-win situation :slight_smile:

···

On 26/09/2011, Ola Hodne Titlestad <olati@ifi.uio.no> wrote:

2011/9/26 Bob Jolliffe <bobjolliffe@gmail.com>

Ola
--------

This should also simplify the attribute code as dealing with the coded
attribute special case seemed a bit awkward.

On 26/09/2011, Lars Helge Øverland <larshelge@gmail.com> wrote:
>> How is a coded attribute different from a groupset? From a
>> dimensionality perspective they realy seem completely identical to me.
>> So should we drop groupsets? Or implement coded attributes as
>> groupsets?
>>
>
> Seems you are right. AttributeOption=Group and Attribute=GroupSet.
> Don't think we want to remove group sets but it seems redundant to
> have both.
>

_______________________________________________
Mailing list: DHIS 2 developers in Launchpad
Post to : dhis2-devs@lists.launchpad.net
Unsubscribe : DHIS 2 developers in Launchpad
More help : ListHelp - Launchpad Help