Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: nectar/data/DataAdapterService.java


1   /*
2       Copyright (C) 2003  Kai Schutte
3    
4       This program is free software; you can redistribute it and/or modify
5       it under the terms of the GNU General Public License as published by
6       the Free Software Foundation; either version 2 of the License, or
7       (at your option) any later version.
8    
9       This program is distributed in the hope that it will be useful,
10      but WITHOUT ANY WARRANTY; without even the implied warranty of
11      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12      GNU General Public License for more details.
13   
14      You should have received a copy of the GNU General Public License
15      along with this program; if not, write to the Free Software
16      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17   
18   * SqlAdapter.java
19   *
20   * Created on March 13, 2003, 11:31 AM
21   */
22  
23  package nectar.data;
24  
25  import java.util.HashMap;
26  import java.util.Collection;
27  import java.util.Vector;
28  import java.util.List;
29  import java.util.Iterator;
30  import nectar.Service;
31  import nectar.ServiceException;
32  import nectar.configuration.ConfigurationException;
33  import nectar.record.Record;
34  import nectar.record.IdTree;
35  
36  /** The DataAdapterService allows access to the DataSource configured in the struts_config.xml file.
37   *
38   * @author  Kai Schutte skander@skander.com
39   */
40  public abstract class DataAdapterService extends Service {
41      
42      /** Signal the beggining of a Transaction. The returned ConnectionHandle holds an active Connection to the DataSource, and will buffer data updates sent to the DataAdapter until {@link commitTransaction } is called.<p>
43       *
44       * You <B>MUST</B> absolutely liberate this connection with {@link commitTransaction } or {@link rollbackTransaction}, since the ConnectionHandle reserves a DataSource connection for exclusive use.
45       * @throws DataException Any Data IO related exceptions.
46       * @return The ConnectionHandle to the transaction locked connection.
47       */    
48      public abstract ConnectionHandle beginTransaction() throws DataException;
49      
50      public abstract void commitTransaction(ConnectionHandle ch) throws DataException;
51      
52      public abstract void rollbackTransaction(ConnectionHandle cd) throws DataException;
53      
54      /** Perfoms the query defined by the Query parameter Object, and returns the results
55       *  as the [(Object) value].
56       */
57      public abstract Object readSingleFieldSingleRow(Query q) throws DataException;
58      
59      /** Perfoms the query defined by the Query parameter Object, and returns the results
60       *  as a [field] => [(Object) value] HashMap.
61       */
62      public abstract HashMap readMultipleFieldSingleRow(Query q) throws DataException;
63      /** Perfoms the query defined by the Query parameter Object, and returns the results
64       *  as a List of [field] => [(Object) value] HashMap's.
65       */
66      public abstract List readMultipleFieldMultipleRow(Query q) throws DataException;
67      /** Perfoms the query defined by the Query parameter Object, and returns the results
68       *  as a List of [(Object) value]'s.
69       */
70      public abstract List readSingleFieldMultipleRow(Query q) throws DataException;
71      
72      /** Performs a query, retrieving the given <i>fields</i> from the given <i>tables</i> for the given record <i>id </i> and
73       *  returns a [field] => [(Object) value] HashMap.
74       */
75      public HashMap getFieldsById(Collection fields, Collection tables, Long project, Long id) throws DataException {
76          Query q = new Query(fields, tables);
77          q.addDataCondition(DataConditions.AND, new OperatorCondition( new FieldElement(Record.TABLE, Record.FIELD_PROJECT), OperatorCondition.EQUAL, new ValueElement(project.toString())));
78          q.addDataCondition(DataConditions.AND, new OperatorCondition( new FieldElement(Record.TABLE, Record.FIELD_RECORD_ID), OperatorCondition.EQUAL, new ValueElement(id.toString())));
79          for (Iterator iter = tables.iterator(); iter.hasNext(); ) {
80              String table = (String)iter.next();
81              if (table.compareTo(Record.TABLE) != 0) {
82                  q.addDataCondition(DataConditions.AND, new OperatorCondition( new FieldElement(table, "id"), OperatorCondition.EQUAL, new ValueElement(id.toString())));
83              }
84          }
85          q.addPostElement(new LimitPostElement(1));
86          return readMultipleFieldSingleRow(q);
87      }
88      
89      public List getFieldsByIds(Collection fields, Collection tables, Collection ids) throws DataException {
90          Query q = new Query(fields, tables);
91          for (Iterator tableIter = tables.iterator(); tableIter.hasNext();) {
92              String table = (String)tableIter.next();
93              if (table.compareTo(Record.TABLE) != 0) {
94                  q.addDataCondition(DataConditions.AND, new OperatorCondition( new FieldElement(Record.TABLE, Record.FIELD_RECORD_ID), OperatorCondition.EQUAL, new FieldElement(table, "id")));
95              }
96          }
97          
98          DataConditions idDcs = new DataConditions();
99          for (Iterator i = ids.iterator(); i.hasNext(); ) {
100             Long id = (Long)i.next();
101             idDcs.append(DataConditions.OR, new OperatorCondition( new FieldElement(Record.TABLE, Record.FIELD_RECORD_ID), OperatorCondition.EQUAL, new ValueElement(id.toString())));
102         }
103         q.addDataCondition(DataConditions.AND, idDcs);
104         return readMultipleFieldMultipleRow(q);
105     }
106     
107     /** Fetches the ID numbers of the children of the root record defined in the given IdTree.
108      * The ID numbers may refer to any record type -- the restrictions are to be
109      * defined in the Query parameter.<p>
110      *
111      * The root ID defined in the IdTree instance may be null, in which case the top level records of the tree will
112      * be retrieved, and the ID property at the top of the resulting IdTree will be
113      * null. <p>
114      *
115      * If the root ID defined in the IdTree instance is not null, it's ID number will appear as the ID property in the
116      * top level of the tree. <p>
117      *
118      * depth is the number of recursions to perform into the tree, so the tree depth.<p>
119      * @param q The Query restricting the contents of the resulting tree.
120      * @param tree An IdTree whose root ID number is the owner of the tree to fetch.
121      * @param depth The recursion depth into the tree.
122      * @throws DataException Any of the usual Data IO Exceptions.
123      * @return The resulting IdTree.
124      * @see nectar.record.RecordTree
125      * @see nectar.services.RecordService#loadTree
126      * @see nectar.record.IdTree
127      */
128     public IdTree getIdTree(Query q, IdTree tree, int depth) throws DataException {
129         Long topOwner = tree.getId();
130         if (depth > 0) {
131             Query tempQ = (Query)q.clone();
132             if (topOwner != null) {
133                 tempQ.addDataCondition(DataConditions.AND, new OperatorCondition( new FieldElement(Record.TABLE, Record.FIELD_OWNER), OperatorCondition.EQUAL, new ValueElement( topOwner.toString())));
134             } else {
135                 tempQ.addDataCondition(DataConditions.AND, new FunctionCondition( FunctionCondition.ISNULL, new FieldElement(Record.TABLE, Record.FIELD_OWNER)));
136             }
137             List ids = readMultipleFieldMultipleRow(tempQ);
138             for (Iterator i=ids.iterator(); i.hasNext();) {
139                 java.util.Map map = (java.util.Map)i.next();
140                 Long tmpId = (Long)map.get(Record.FIELD_RECORD_ID);
141                 
142                 if (map.containsKey(Record.FIELD_TYPE)) {
143                     String type = (String)map.get(Record.FIELD_TYPE);
144                     if (depth > 1) {
145                         IdTree it = new IdTree(tmpId, type);
146                         tree.addChild( getIdTree(q, it, depth-1) );
147                     } else {
148                         tree.addChild(new IdTree(tmpId, type));
149                     }
150                 } else {
151                     if (depth > 1) {
152                         IdTree it = new IdTree(tmpId);
153                         tree.addChild( getIdTree(q, it, depth-1) );
154                     } else {
155                         tree.addChild(new IdTree(tmpId));
156                     }
157                 }
158             }
159         }
160         return tree;
161     }
162     
163     public abstract void insert(Insert i) throws DataException;
164     
165     public abstract void insert(ConnectionHandle ch, Insert i) throws DataException;
166     
167     public abstract void insert(ConnectionHandle ch, Insert i, boolean returnLastInsertId) throws DataException;
168     
169     public abstract void update(Update update) throws DataException;
170 
171     public abstract void update(ConnectionHandle ch, Update update) throws DataException;
172     
173     public abstract void delete(ConnectionHandle ch, Delete delete) throws DataException;
174 
175     public abstract void delete(Delete delete) throws DataException;
176     
177     public void initService() throws ConfigurationException, ServiceException {
178     }
179     
180     public void killService() {
181         killDependants();
182     }
183 }