e0ab7be5694d42a75c1b22bf726ccf4e6184f617
[mir.git] / source / mir / entity / adapter / EntityAdapter.java
1 /*
2  * Copyright (C) 2001, 2002 The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with  any library licensed under the Apache Software License,
22  * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
23  * (or with modified versions of the above that use the same license as the above),
24  * and distribute linked combinations including the two.  You must obey the
25  * GNU General Public License in all respects for all of the code used other than
26  * the above mentioned libraries.  If you modify this file, you may extend this
27  * exception to your version of the file, but you are not obligated to do so.
28  * If you do not wish to do so, delete this exception statement from your version.
29  */
30 package mir.entity.adapter;
31
32 import mir.entity.Entity;
33 import mir.util.CachingRewindableIterator;
34 import mir.util.RewindableIterator;
35
36 import java.util.*;
37
38 /** An EntityAdapter is a wrapper around an Entity meant to add
39  * missing functionality. It provides "calculated fields" 
40  * which mir installations can extend reasonably easilly.
41  * "calculated fields" compute values that are not directly present
42  * in the db table. For example:  
43  * a field to have the number of comments associated with an article;
44  * a field to get the list of hidden comments associated with an article;
45  * etc.
46  * <p>This whole framework is meant to be replaced by hibernate</p>
47  */
48 public class EntityAdapter {
49   private Entity entity;
50   private EntityAdapterDefinition definition;
51   private Map calculatedFieldsCache;
52   private EntityAdapterModel model;
53
54   public EntityAdapter(Entity anEntity, EntityAdapterDefinition aDefinition, EntityAdapterModel aModel) {
55     entity = anEntity;
56     definition = aDefinition;
57     calculatedFieldsCache = new HashMap();
58     model = aModel;
59   }
60
61   public boolean equals(Object anObject) {
62     return        anObject instanceof EntityAdapter
63            && ((EntityAdapter) anObject).entity.equals(entity);
64   }
65
66   public int hashCode() {
67     if (entity!=null) {
68       return entity.hashCode();
69     }
70     else {
71       return 0;
72     }
73   }
74
75   public Entity getEntity() {
76     return entity;
77   }
78
79   public EntityAdapterModel getModel() {
80     return model;
81   }
82
83   public Object get(String aKey) {
84     Object result;
85
86     if (calculatedFieldsCache.containsKey(aKey)) {
87       return calculatedFieldsCache.get(aKey);
88     }
89     else if (aKey instanceof String && definition.hasCalculatedField((String) aKey)) {
90       result = definition.getCalculatedField((String) aKey).getValue(this);
91       calculatedFieldsCache.put(aKey, result);
92
93       return result;
94     }
95     else {
96       return entity.getFieldValue((String) aKey);
97     }
98   }
99
100   public Iterator getIterator(String aKey) {
101     Object result = get(aKey);
102
103     if (result instanceof RewindableIterator) {
104       ((RewindableIterator) result).rewind();
105       return (RewindableIterator) result;
106     }
107     else if (result instanceof Iterator) {
108       return (Iterator) result;
109     }
110     else if (result instanceof Collection) {
111       return ((Collection) result).iterator();
112     }
113     else if (result!=null) {
114       return Collections.singletonList(result).iterator();
115     }
116     else {
117       return null;
118     }
119   }
120
121   public Object getComplexRelation(String aMainTablePrefix, List someExtraTables,
122     String aWhereClause, String anOrderByClause, String aDefinition) {
123     try {
124       return
125           new CachingRewindableIterator(
126             new EntityIteratorAdapter(aMainTablePrefix, someExtraTables,
127                 aWhereClause, anOrderByClause,
128                 -1, getModel(), aDefinition, -1, 0)
129             );
130     }
131     catch (Throwable t) {
132       throw new RuntimeException(t.getMessage());
133     }
134   }
135
136
137   public List getRelation(String aWhereClause, String anOrderByClause, String aDefinition) {
138     try {
139       return EntityAdapterEngine.retrieveAdapterList(model, aDefinition, aWhereClause, anOrderByClause, -1, 0);
140     }
141     catch (Throwable t) {
142       throw new RuntimeException(t.getMessage());
143     }
144   }
145
146   public EntityAdapter getToOneRelation(String aWhereClause, String anOrderByClause, String aDefinition) {
147     try {
148       Iterator i = new EntityIteratorAdapter(aWhereClause, anOrderByClause, 1, getModel(), aDefinition, 1, 0);
149
150       if (i.hasNext())
151         return (EntityAdapter) i.next();
152                         return null;
153     }
154     catch (Throwable t) {
155       throw new RuntimeException(t.getMessage());
156     }
157   }
158
159   public EntityAdapter getComplexToOneRelation(String aMainTablePrefix, List someExtraTables,
160                                                String aWhereClause, String anOrderByClause, String aDefinition) {
161     try {
162       Iterator i = new EntityIteratorAdapter(aMainTablePrefix, someExtraTables, aWhereClause, anOrderByClause, -1,
163           getModel(), aDefinition, 1, 0);
164
165       if (i.hasNext())
166         return (EntityAdapter) i.next();
167                         return null;
168     }
169     catch (Throwable t) {
170       throw new RuntimeException(t.getMessage());
171     }
172   }
173
174 }