001: /*
002: * Copyright 2003 The Apache Software Foundation.
003: *
004: * Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
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:
017: package velosurf.context;
018:
019: import java.sql.SQLException;
020: import java.util.HashMap;
021: import java.util.Map;
022: import java.util.Iterator;
023:
024: import velosurf.model.Attribute;
025: import velosurf.model.Entity;
026: import velosurf.model.Action;
027: import velosurf.sql.Database;
028: import velosurf.util.Logger;
029: import velosurf.util.UserContext;
030:
031: /** <p>A context wrapper for the main database connection object.</p>
032: * <p>The "<code>$db</code>" context variable is assigned a new instance of this class at each velocity parsing.</p>
033: *
034: * @author <a href=mailto:claude.brisson@gmail.com>Claude Brisson</a>
035: */
036:
037: // FIXME : right now, extends HashMap bkoz velocity wants a HashMap for setters
038: public class DBReference extends HashMap<String, Object> {
039: /** Default constructor for use by derived classes.
040: */
041: protected DBReference() {
042: }
043:
044: /** Constructs a new database reference.
045: *
046: * @param db the wrapped database connection
047: */
048: public DBReference(Database db) {
049: init(db);
050: }
051:
052: /** Protected initialization method.
053: *
054: * @param db database connection
055: */
056: protected void init(Database db) {
057: this .db = db;
058: cache = new HashMap<String, Object>();
059: externalParams = new HashMap<String, Object>();
060: }
061:
062: /** <p>Generic getter, used to access entities or root attributes by their name.</p>
063: * <p>For attributes, the return value depends upon the type of the attribute :</p>
064: * <ul>
065: * <li>if the attribute is multivalued, returns an AttributeReference.
066: * <li>if the attribute is singlevalued, returns an Instance.
067: * <li>if the attribute is scalar, returns a String.
068: * </ul>
069: *
070: * @param key the name of the desired entity or root attribute.
071: * @return an entity, an attribute reference, an instance, a string or null
072: * if not found. See See above.
073: */
074: public Object get(Object key) {
075: String property = db.adaptCase((String) key);
076:
077: try {
078: Object result = null;
079:
080: /* 1) try the cache */
081: result = cache.get(property);
082: if (result != null)
083: return result;
084:
085: /* 2) try to get a root attribute */
086: Attribute attribute = db.getAttribute(property);
087: if (attribute != null) {
088: switch (attribute.getType()) {
089: case Attribute.ROWSET:
090: result = new AttributeReference(this , attribute);
091: break;
092: case Attribute.SCALAR:
093: result = attribute.evaluate(this );
094: break;
095: case Attribute.ROW:
096: result = attribute.fetch(this );
097: break;
098: default:
099: Logger
100: .error("Unknown attribute type encountered: db."
101: + property);
102: result = null;
103: }
104: cache.put(property, result);
105: return result;
106: }
107:
108: /* 3) try to get a root action */
109: Action action = db.getAction(property);
110: if (action != null)
111: return Integer.valueOf(action.perform(this ));
112:
113: /* 4) try to get an entity */
114: Entity entity = db.getEntity(property);
115: if (entity != null) {
116: result = new EntityReference(entity);
117: cache.put(property, result);
118: return result;
119: }
120:
121: /* 5) try to get an external param */
122: result = externalParams.get(property);
123: if (result != null)
124: return result;
125:
126: /* 6) try with the user context */
127: result = db.getUserContext().get(property);
128: if (result != null)
129: return result;
130:
131: /* Sincerely, I don't see... */
132: return null;
133: } catch (SQLException sqle) {
134: db.setError(sqle.getMessage());
135: Logger.log(sqle);
136: return null;
137: }
138: }
139:
140: /** Generic setter used to set external params for children attributes.
141: *
142: * @param key name of the external parameter
143: * @param value value given to the external parameter
144: * @return the previous value, if any
145: */
146: public Object put(String key, Object value) {
147: /*
148: * Clear actual values in the cache, because the value of attributes may change...
149: */
150: for (Iterator i = cache.keySet().iterator(); i.hasNext();) {
151: Object k = i.next();
152: Object v = cache.get(k);
153: if (!(v instanceof AttributeReference)
154: && !(v instanceof EntityReference)) {
155: i.remove();
156: }
157:
158: }
159: return externalParams.put(db.adaptCase((String) key), value);
160: }
161:
162: /** Get the schema name.
163: * @return the schema
164: */
165: public String getSchema() {
166: return db.getSchema();
167: }
168:
169: /** Obfuscate the given value.
170: * @param value value to obfuscate
171: *
172: * @return obfuscated value
173: */
174: public String obfuscate(Object value) {
175: return db.obfuscate(value);
176: }
177:
178: /** De-obfuscate the given value.
179: * @param value value to de-obfuscate
180: *
181: * @return obfuscated value
182: */
183: public String deobfuscate(Object value) {
184: return db.deobfuscate(value);
185: }
186:
187: /** User context getter
188: * @return current user context
189: */
190: public UserContext getUserContext() {
191: return db.getUserContext();
192: }
193:
194: /** User context setter
195: * @param userContext user context
196: */
197: public void setUserContext(UserContext userContext) {
198: db.setUserContext(userContext);
199: }
200:
201: /** The wrapped database connection.
202: */
203: private Database db = null;
204:
205: /** A cache used by the generic getter. Its purpose is to avoid the creation of several
206: * attribute references for the same multivalued attribute.
207: */
208: private Map<String, Object> cache = null;
209:
210: /** The map of external query parameters used by children attributes.
211: */
212: private Map<String, Object> externalParams = null;
213:
214: //public void displayStats() { db.displayStats(); }
215:
216: }
|