2fff4d20d3e3754bd0edb514473ba788636d5a95
[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 java.util.Collection;
33 import java.util.HashMap;
34 import java.util.Iterator;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Set;
38
39 import mir.entity.Entity;
40 import mir.util.CachingRewindableIterator;
41
42 /** An EntityAdapter is a wrapper around an Entity meant to add
43  * missing functionality. It provides "calculated fields" 
44  * which mir installations can extend reasonably easilly.
45  * "calculated fields" compute values that are not directly present
46  * in the db table. For example:  
47  * a field to have the number of comments associated with an article;
48  * a field to get the list of hidden comments associated with an article;
49  * etc.
50  * <p>This whole framework is meant to be replaced by hibernate</p>
51  */
52 public class EntityAdapter implements Map {
53   private Entity entity;
54   private EntityAdapterDefinition definition;
55   private Map calculatedFieldsCache;
56   private EntityAdapterModel model;
57
58   public EntityAdapter(Entity anEntity, EntityAdapterDefinition aDefinition, EntityAdapterModel aModel) {
59     entity = anEntity;
60     definition = aDefinition;
61     calculatedFieldsCache = new HashMap();
62     model = aModel;
63   }
64
65   public boolean containsKey(Object aKey) {
66     try {
67       if (aKey instanceof String)
68         return     entity.hasField((String) aKey)
69                 || definition.hasCalculatedField((String) aKey);
70     }
71     catch (Throwable t) {
72     }
73
74     return false;
75   }
76
77   public boolean equals(Object anObject) {
78     return        anObject instanceof EntityAdapter
79            && ((EntityAdapter) anObject).entity.equals(entity);
80   }
81
82   public int hashCode() {
83     return entity.hashCode();
84   }
85
86   public Entity getEntity() {
87     return entity;
88   }
89
90   public EntityAdapterModel getModel() {
91     return model;
92   }
93
94   public Object get(Object aKey) {
95     Object result;
96
97     if (calculatedFieldsCache.containsKey(aKey)) {
98       return calculatedFieldsCache.get(aKey);
99     }
100     else if (aKey instanceof String && definition.hasCalculatedField((String) aKey)) {
101       result = definition.getCalculatedField((String) aKey).getValue(this);
102       calculatedFieldsCache.put(aKey, result);
103
104       return result;
105     }
106     else if (aKey instanceof String) {
107       return entity.getFieldValue((String) aKey);
108     }
109     else {
110       return null;
111     }
112   }
113
114   public boolean isEmpty() {
115     return false;
116   }
117
118   public Set keySet() {
119     throw new UnsupportedOperationException("EntityAdapter.keySet()");
120   }
121
122   public Object put(Object aKey, Object value) {
123     throw new UnsupportedOperationException("EntityAdapter.put()");
124   }
125
126   public void putAll(Map t) {
127     throw new UnsupportedOperationException("EntityAdapter.putAll()");
128   }
129
130   public Object remove(Object aKey) {
131     throw new UnsupportedOperationException("EntityAdapter.remove()");
132   }
133
134   public int size() {
135     throw new UnsupportedOperationException("EntityAdapter.size()");
136   }
137
138   public Collection values() {
139     throw new UnsupportedOperationException("EntityAdapter.values()");
140   }
141
142   public void clear() {
143     throw new UnsupportedOperationException("EntityAdapter.clear()");
144   }
145
146   public boolean containsValue(Object value) {
147     throw new UnsupportedOperationException("EntityAdapter.containsValue()");
148   }
149
150   public Set entrySet() {
151     throw new UnsupportedOperationException("EntityAdapter.entrySet()");
152   }
153
154   public Object getComplexRelation(String aMainTablePrefix, List someExtraTables,
155     String aWhereClause, String anOrderByClause, String aDefinition) {
156     try {
157       return
158           new CachingRewindableIterator(
159             new EntityIteratorAdapter(aMainTablePrefix, someExtraTables,
160                 aWhereClause, anOrderByClause,
161                 -1, getModel(), aDefinition, -1, 0)
162             );
163     }
164     catch (Throwable t) {
165       throw new RuntimeException(t.getMessage());
166     }
167   }
168
169
170   public Object getRelation(String aWhereClause, String anOrderByClause, String aDefinition) {
171     try {
172       return EntityAdapterEngine.retrieveAdapterList(model, aDefinition, aWhereClause, anOrderByClause, -1, 0);
173     }
174     catch (Throwable t) {
175       throw new RuntimeException(t.getMessage());
176     }
177   }
178
179   public EntityAdapter getToOneRelation(String aWhereClause, String anOrderByClause, String aDefinition) {
180     try {
181       Iterator i = new EntityIteratorAdapter(aWhereClause, anOrderByClause, 1, getModel(), aDefinition, 1, 0);
182
183       if (i.hasNext())
184         return (EntityAdapter) i.next();
185                         return null;
186     }
187     catch (Throwable t) {
188       throw new RuntimeException(t.getMessage());
189     }
190   }
191
192   public EntityAdapter getComplexToOneRelation(String aMainTablePrefix, List someExtraTables,
193                                                String aWhereClause, String anOrderByClause, String aDefinition) {
194     try {
195       Iterator i = new EntityIteratorAdapter(aMainTablePrefix, someExtraTables, aWhereClause, anOrderByClause, -1,
196           getModel(), aDefinition, 1, 0);
197
198       if (i.hasNext())
199         return (EntityAdapter) i.next();
200                         return null;
201     }
202     catch (Throwable t) {
203       throw new RuntimeException(t.getMessage());
204     }
205   }
206
207 }