This was a great experiment, but I think I'm going to use the
InheritanceMap instead--it has access to the omClass without
the Village mumbo-jumbo.
pseudocode (without Exceptions, null-checks, etc):
if (getTableMap().isUseInheritance)
for (ColumnMap column : getTableMap().getColumns())
if (column.isUseInheritance()
return Class.forName(
column.getTable().getOMClass().getPackage().getName() +
"." +
column.getInheritanceMap(serviceType).getClassName())
.newInstance();
Brendan
On Thu, Feb 19, 2009 at 10:38:33AM -0800, Brendan Miller wrote:
>
> I have a table in my schema that uses an inheritance map for one of the
> columns:
>
> <column name="SERVICE_TYPE" javaName="ServiceType"
> size="50" type="VARCHAR" inheritance="single">
> <inheritance key="CUSTOM" class="CustomService"
> extends="foo.service.Service"/>
> <inheritance key="SPECIAL" class="SpecialService"
> extends="foo.service.Service"/>
> </column>
>
> There may be other inheritance keys, but this gives a concrete example.
>
> I understand that when you ServicePeer.retrieveByPK(id) the magic of
> ServicePeer.getOMClass and ServicePeer.row2Object will construct the
> proper type (either CustomService or SpecialService) depending on the
> value of the service_type column. (I also know that if your database
> contains values for that column that are not listed as inheritance keys,
> you have major fail.)
>
> It would be nice to have a method to construct a new Service object
> based on the value for the service_type column. I cannot create a
> Service as in
>
> Service service = new Service();
> service.setServiceType("CUSTOM");
>
> because Service is abstract. (I know I could change this, but that's
> not the point.) I'd really like a method that used the getOMClass
> logic to instantiate the right object class. Unfortunately, getOMClass
> is too tied to com.workingdogs.village.Record.
>
> To get around this, I wrote my own peer method:
>
> public static Service createFromServiceType(final String serviceType)
> throws TorqueException
> {
> try {
> Record record = new Record()
> {
> public Value getValue(int i) throws DataSetException
> {
> try {
> return new Value(null, 0, 0)
> {
> public String asString()
> {
> return serviceType;
> }
> };
> }
> catch (SQLException e) {
> throw new DataSetException("Couldn't return service
> type: "+
> serviceType);
> }
> }
> };
>
> Class omClass = getOMClass(record, 1);
>
> return (Service) omClass.newInstance();
> }
> catch (InstantiationException e) {
> throw new TorqueException("Couldn't create Service from
> "+serviceType, e);
> }
> catch (IllegalAccessException e) {
> throw new TorqueException("Couldn't create Service from
> "+serviceType, e);
> }
> }
>
> Now I can write
>
> Service service = ServicePeer.createFromServiceType(serviceType);
>
> and have the correct type of Service object instantiated. This is
> useful when serviceType is passed into my application via XML, user
> input, some form, etc.
>
> It's a little brutal to create the anonymous Record class to provide the
> hook to Record.getValue so that getOMClass continues to work, but it's
> all I could come up with short of duplicating the getOMClass code. I
> suppose this could be decoupled in Peer.vm to provide two methods:
>
> public static Class getOMClass(Record record, int offset)
>
> and
>
> public static Class getOMClass(String classKey)
>
> Something to think about, especially as the Village removal is
> considered. I'm guessing that getOMClass gets reworked in a VillageFree
> age anyway?
>
> Any other thoughts?
>
> Brendan
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]