View Javadoc
1   /*
2    * Copyright 2005 The Kuali Foundation
3    * 
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    * http://www.opensource.org/licenses/ecl2.php
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.fp.dataaccess;
17  
18  import java.util.Map;
19  
20  import org.apache.ojb.broker.PersistenceBroker;
21  import org.apache.ojb.broker.PersistenceBrokerException;
22  import org.apache.ojb.broker.PersistenceBrokerFactory;
23  import org.apache.ojb.broker.accesslayer.RowReaderDefaultImpl;
24  import org.apache.ojb.broker.metadata.ClassDescriptor;
25  
26  /**
27   * (Inspired by example posted at http://nagoya.apache.org/eyebrowse/ReadMsg?listName=ojb-user@db.apache.org&msgId=749837) This
28   * class enables mapping multiple (presumably similar) classes to a single database table. Subclasses must implement the
29   * getDiscriminatorColumns method, returning a String array of columns to consider when determining which class to return, as well
30   * as implement the corresponding chooseClass method that acts on received values for those columns. Sample OBJ config:
31   * <class-descriptor class="org.kuali.bo.ClassA" table="some_common_table" row-reader="org.kuali.dao.ojb.ClassADiscriminator"> ...
32   * </class-descriptor> <class-descriptor class="org.kuali.bo.ClassB" table="some_common_table"
33   * row-reader="org.kuali.dao.ojb.ClassBDiscriminator"> ... </class-descriptor> (where ClassADiscriminator and ClassBDiscriminator
34   * extend PolymorphicMultiColumnDiscriminator)
35   */
36  public abstract class PolymorphicMultiColumnDiscriminator extends RowReaderDefaultImpl {
37  
38      /** Column(s) that distinguish the parent class */
39      private String[] column = null;
40  
41      public PolymorphicMultiColumnDiscriminator(ClassDescriptor cld) {
42          super(cld);
43          column = getDiscriminatorColumns();
44      }
45  
46      /**
47       * This method should return the column(s) necessary to determine which class to cast to.
48       * 
49       * @return one or more column names
50       */
51      public abstract String[] getDiscriminatorColumns();
52  
53      /**
54       * Based on the received key values, this method determines the appropriate class.
55       * 
56       * @param values
57       * @return an appropriately chosen class
58       */
59      public abstract Class chooseClass(String[] values);
60  
61      protected ClassDescriptor selectClassDescriptor(Map row) throws PersistenceBrokerException {
62          String[] key = new String[column.length];
63  
64          for (int i = 0; i < column.length; i++) {
65              key[i] = (String) row.get(column[i]);
66          }
67  
68          Class clazz = null;
69  
70          if (key != null) {
71              clazz = chooseClass(key);
72          }
73          if (clazz == null) {
74              return getClassDescriptor();
75          }
76  
77          PersistenceBroker broker = null;
78          try {
79              broker = PersistenceBrokerFactory.defaultPersistenceBroker();
80              ClassDescriptor result = broker.getClassDescriptor(clazz);
81              broker.close();
82              if (result == null) {
83                  return getClassDescriptor();
84              }
85              else {
86                  return result;
87              }
88          }
89          catch (PersistenceBrokerException e) {
90              broker.close();
91              throw e;
92          }
93      }
94  
95  }