001 /* 002 * Copyright 2011 The Kuali Foundation. 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.kfs.fp.dataaccess; 017 018 import java.util.Map; 019 020 import org.apache.ojb.broker.PersistenceBroker; 021 import org.apache.ojb.broker.PersistenceBrokerException; 022 import org.apache.ojb.broker.PersistenceBrokerFactory; 023 import org.apache.ojb.broker.accesslayer.RowReaderDefaultImpl; 024 import org.apache.ojb.broker.metadata.ClassDescriptor; 025 026 /** 027 * (Inspired by example posted at http://nagoya.apache.org/eyebrowse/ReadMsg?listName=ojb-user@db.apache.org&msgId=749837) This 028 * class enables mapping multiple (presumably similar) classes to a single database table. Subclasses must implement the 029 * getDiscriminatorColumns method, returning a String array of columns to consider when determining which class to return, as well 030 * as implement the corresponding chooseClass method that acts on received values for those columns. Sample OBJ config: 031 * <class-descriptor class="org.kuali.bo.ClassA" table="some_common_table" row-reader="org.kuali.dao.ojb.ClassADiscriminator"> ... 032 * </class-descriptor> <class-descriptor class="org.kuali.bo.ClassB" table="some_common_table" 033 * row-reader="org.kuali.dao.ojb.ClassBDiscriminator"> ... </class-descriptor> (where ClassADiscriminator and ClassBDiscriminator 034 * extend PolymorphicMultiColumnDiscriminator) 035 */ 036 public abstract class PolymorphicMultiColumnDiscriminator extends RowReaderDefaultImpl { 037 038 /** Column(s) that distinguish the parent class */ 039 private String[] column = null; 040 041 public PolymorphicMultiColumnDiscriminator(ClassDescriptor cld) { 042 super(cld); 043 column = getDiscriminatorColumns(); 044 } 045 046 /** 047 * This method should return the column(s) necessary to determine which class to cast to. 048 * 049 * @return one or more column names 050 */ 051 public abstract String[] getDiscriminatorColumns(); 052 053 /** 054 * Based on the received key values, this method determines the appropriate class. 055 * 056 * @param values 057 * @return an appropriately chosen class 058 */ 059 public abstract Class chooseClass(String[] values); 060 061 protected ClassDescriptor selectClassDescriptor(Map row) throws PersistenceBrokerException { 062 String[] key = new String[column.length]; 063 064 for (int i = 0; i < column.length; i++) { 065 key[i] = (String) row.get(column[i]); 066 } 067 068 Class clazz = null; 069 070 if (key != null) { 071 clazz = chooseClass(key); 072 } 073 if (clazz == null) { 074 return getClassDescriptor(); 075 } 076 077 PersistenceBroker broker = null; 078 try { 079 broker = PersistenceBrokerFactory.defaultPersistenceBroker(); 080 ClassDescriptor result = broker.getClassDescriptor(clazz); 081 broker.close(); 082 if (result == null) { 083 return getClassDescriptor(); 084 } 085 else { 086 return result; 087 } 088 } 089 catch (PersistenceBrokerException e) { 090 broker.close(); 091 throw e; 092 } 093 } 094 095 }