KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > sql > conn > GenericLanguageConnectionFactory


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.conn.GenericLanguageConnectionFactory
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.sql.conn;
23
24 import org.apache.derby.iapi.reference.JDBC20Translation;
25 import org.apache.derby.iapi.reference.JDBC30Translation;
26
27 import org.apache.derby.iapi.sql.conn.LanguageConnectionFactory;
28 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
29 import org.apache.derby.iapi.sql.compile.CompilerContext;
30
31 import org.apache.derby.iapi.sql.LanguageFactory;
32 import org.apache.derby.impl.sql.GenericStatement;
33
34 import org.apache.derby.impl.sql.conn.CachedStatement;
35
36 import org.apache.derby.iapi.services.uuid.UUIDFactory;
37 import org.apache.derby.iapi.services.compiler.JavaFactory;
38 import org.apache.derby.iapi.services.loader.ClassFactory;
39
40 import org.apache.derby.iapi.db.Database;
41
42 import org.apache.derby.iapi.store.access.TransactionController;
43
44 import org.apache.derby.iapi.sql.compile.TypeCompilerFactory;
45
46 import org.apache.derby.iapi.error.StandardException;
47
48 import org.apache.derby.iapi.sql.compile.NodeFactory;
49 import org.apache.derby.iapi.sql.compile.Parser;
50
51 import org.apache.derby.iapi.sql.Activation;
52
53 import org.apache.derby.iapi.store.access.AccessFactory;
54 import org.apache.derby.iapi.services.property.PropertyFactory;
55
56 import org.apache.derby.iapi.sql.Statement;
57 import org.apache.derby.iapi.sql.compile.OptimizerFactory;
58 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
59 import org.apache.derby.iapi.types.DataValueFactory;
60 import org.apache.derby.iapi.sql.execute.ExecutionFactory;
61 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
62
63 import org.apache.derby.iapi.services.sanity.SanityManager;
64
65 import org.apache.derby.iapi.services.monitor.Monitor;
66 import org.apache.derby.iapi.services.monitor.ModuleControl;
67 import org.apache.derby.iapi.services.monitor.ModuleSupportable;
68 import org.apache.derby.iapi.services.monitor.ModuleFactory;
69 import org.apache.derby.iapi.services.context.ContextManager;
70
71 import org.apache.derby.iapi.services.cache.CacheFactory;
72 import org.apache.derby.iapi.services.cache.CacheManager;
73 import org.apache.derby.iapi.services.cache.CacheableFactory;
74 import org.apache.derby.iapi.services.cache.Cacheable;
75
76 import org.apache.derby.iapi.services.property.PropertyUtil;
77 import org.apache.derby.iapi.services.property.PropertySetCallback;
78
79 import org.apache.derby.iapi.services.i18n.LocaleFinder;
80 import org.apache.derby.iapi.reference.SQLState;
81 import org.apache.derby.iapi.reference.Property;
82 import org.apache.derby.iapi.reference.EngineType;
83
84 import java.util.Properties JavaDoc;
85 import java.util.Locale JavaDoc;
86 import java.util.Dictionary JavaDoc;
87 import java.io.Serializable JavaDoc;
88 import org.apache.derby.iapi.util.IdUtil;
89 import org.apache.derby.iapi.services.daemon.Serviceable;
90 import org.apache.derby.iapi.util.StringUtil;
91
92 /**
93  * LanguageConnectionFactory generates all of the items
94  * a language system needs that is specific to a particular
95  * connection. Alot of these are other factories.
96  *
97  * @author ames
98  */

99 public class GenericLanguageConnectionFactory
100     implements LanguageConnectionFactory, CacheableFactory, PropertySetCallback, ModuleControl, ModuleSupportable {
101
102     /*
103         fields
104      */

105     protected DataDictionary dd;
106     private ExecutionFactory ef;
107     private OptimizerFactory of;
108     private TypeCompilerFactory tcf;
109     private DataValueFactory dvf;
110     private UUIDFactory uuidFactory;
111     private JavaFactory javaFactory;
112     private ClassFactory classFactory;
113     private NodeFactory nodeFactory;
114     private AccessFactory af;
115     private PropertyFactory pf;
116
117     private int nextLCCInstanceNumber;
118
119     /*
120       for caching prepared statements
121     */

122     private int cacheSize = org.apache.derby.iapi.reference.Property.STATEMENT_CACHE_SIZE_DEFAULT;
123     private CacheManager singleStatementCache;
124
125     /*
126        constructor
127     */

128     public GenericLanguageConnectionFactory() {
129     }
130
131     /*
132        LanguageConnectionFactory interface
133     */

134
135     /*
136         these are the methods that do real work, not just look for factories
137      */

138
139     /**
140         Get a Statement for the connection
141         @param compilationSchema schema
142         @param statementText the text for the statement
143         @param forReadOnly if concurrency is CONCUR_READ_ONLY
144         @return The Statement
145      */

146         public Statement getStatement(SchemaDescriptor compilationSchema, String JavaDoc statementText, boolean forReadOnly)
147         {
148         return new GenericStatement(compilationSchema, statementText, forReadOnly);
149     }
150
151
152     /**
153         Get a LanguageConnectionContext. this holds things
154         we want to remember about activity in the language system,
155         where this factory holds things that are pretty stable,
156         like other factories.
157         <p>
158         The returned LanguageConnectionContext is intended for use
159         only by the connection that requested it.
160
161         @return a language connection context for the context stack.
162         @exception StandardException the usual -- for the subclass
163      */

164
165     public LanguageConnectionContext newLanguageConnectionContext(
166         ContextManager cm,
167         TransactionController tc,
168         LanguageFactory lf,
169         Database db,
170         String JavaDoc userName,
171         String JavaDoc drdaID,
172         String JavaDoc dbname) throws StandardException {
173         
174         pushDataDictionaryContext(cm);
175
176         return new GenericLanguageConnectionContext(cm,
177                                                     tc,
178                                                     lf,
179                                                     this,
180                                                     db,
181                                                     userName,
182                                                     getNextLCCInstanceNumber(),
183                                                     drdaID,
184                                                     dbname);
185     }
186
187     public Cacheable newCacheable(CacheManager cm) {
188         return new CachedStatement();
189     }
190
191     /*
192         these methods all look for factories that we booted.
193      */

194      
195      /**
196         Get the UUIDFactory to use with this language connection
197         REMIND: this is only used by the compiler; should there be
198         a compiler module control class to boot compiler-only stuff?
199      */

200     public UUIDFactory getUUIDFactory()
201     {
202         return uuidFactory;
203     }
204
205     /**
206         Get the ClassFactory to use with this language connection
207      */

208     public ClassFactory getClassFactory()
209     {
210         return classFactory;
211     }
212
213     /**
214         Get the JavaFactory to use with this language connection
215         REMIND: this is only used by the compiler; should there be
216         a compiler module control class to boot compiler-only stuff?
217      */

218     public JavaFactory getJavaFactory()
219     {
220         return javaFactory;
221     }
222
223     /**
224         Get the NodeFactory to use with this language connection
225         REMIND: is this only used by the compiler?
226      */

227     public NodeFactory getNodeFactory()
228     {
229         return nodeFactory;
230     }
231
232     /**
233         Get the ExecutionFactory to use with this language connection
234      */

235     public ExecutionFactory getExecutionFactory() {
236         return ef;
237     }
238
239     /**
240         Get the AccessFactory to use with this language connection
241      */

242     public AccessFactory getAccessFactory()
243     {
244         return af;
245     }
246
247     /**
248         Get the PropertyFactory to use with this language connection
249      */

250     public PropertyFactory getPropertyFactory()
251     {
252         return pf;
253     }
254
255     /**
256         Get the OptimizerFactory to use with this language connection
257      */

258     public OptimizerFactory getOptimizerFactory() {
259         return of;
260     }
261     /**
262         Get the TypeCompilerFactory to use with this language connection
263      */

264     public TypeCompilerFactory getTypeCompilerFactory() {
265         return tcf;
266     }
267
268     /**
269         Get the DataValueFactory to use with this language connection
270      */

271     public DataValueFactory getDataValueFactory() {
272         return dvf;
273     }
274
275     protected void pushDataDictionaryContext(ContextManager cm) {
276         // we make sure there is a data dictionary context in place.
277
dd.pushDataDictionaryContext(cm);
278     }
279
280     /*
281         ModuleControl interface
282      */

283
284     /**
285         this implementation will not support caching of statements.
286      */

287     public boolean canSupport(Properties JavaDoc startParams) {
288
289         return Monitor.isDesiredType( startParams, EngineType.STANDALONE_DB);
290     }
291
292     private int statementCacheSize(Properties JavaDoc startParams)
293     {
294         String JavaDoc wantCacheProperty = null;
295
296         wantCacheProperty =
297             PropertyUtil.getPropertyFromSet(startParams, org.apache.derby.iapi.reference.Property.STATEMENT_CACHE_SIZE);
298
299         if (SanityManager.DEBUG)
300             SanityManager.DEBUG("StatementCacheInfo", "Cacheing implementation chosen if null or 0<"+wantCacheProperty);
301
302         if (wantCacheProperty != null) {
303             try {
304                 cacheSize = Integer.parseInt(wantCacheProperty);
305             } catch (NumberFormatException JavaDoc nfe) {
306                 cacheSize = org.apache.derby.iapi.reference.Property.STATEMENT_CACHE_SIZE_DEFAULT;
307             }
308         }
309
310         return cacheSize;
311     }
312     
313     /**
314      * Start-up method for this instance of the language connection factory.
315      * Note these are expected to be booted relative to a Database.
316      *
317      * @param startParams The start-up parameters (ignored in this case)
318      *
319      * @exception StandardException Thrown on failure to boot
320      */

321     public void boot(boolean create, Properties JavaDoc startParams)
322         throws StandardException {
323
324         dvf = (DataValueFactory) Monitor.bootServiceModule(create, this, org.apache.derby.iapi.reference.ClassName.DataValueFactory, startParams);
325         javaFactory = (JavaFactory) Monitor.startSystemModule(org.apache.derby.iapi.reference.Module.JavaFactory);
326         uuidFactory = Monitor.getMonitor().getUUIDFactory();
327         classFactory = (ClassFactory) Monitor.getServiceModule(this, org.apache.derby.iapi.reference.Module.ClassFactory);
328         if (classFactory == null)
329             classFactory = (ClassFactory) Monitor.findSystemModule(org.apache.derby.iapi.reference.Module.ClassFactory);
330
331         bootDataDictionary(create, startParams);
332
333         //set the property validation module needed to do propertySetCallBack
334
//register and property validation
335
setValidation();
336
337         setStore();
338
339         ef = (ExecutionFactory) Monitor.bootServiceModule(create, this, ExecutionFactory.MODULE, startParams);
340         of = (OptimizerFactory) Monitor.bootServiceModule(create, this, OptimizerFactory.MODULE, startParams);
341         tcf =
342            (TypeCompilerFactory) Monitor.startSystemModule(TypeCompilerFactory.MODULE);
343         nodeFactory = (NodeFactory) Monitor.bootServiceModule(create, this, NodeFactory.MODULE, startParams);
344
345         // If the system supports statement caching boot the CacheFactory module.
346
int cacheSize = statementCacheSize(startParams);
347         if (cacheSize > 0) {
348             CacheFactory cacheFactory = (CacheFactory) Monitor.startSystemModule(org.apache.derby.iapi.reference.Module.CacheFactory);
349             singleStatementCache = cacheFactory.newCacheManager(this,
350                                                 "StatementCache",
351                                                 cacheSize/4,
352                                                 cacheSize);
353         }
354
355     }
356
357     protected void bootDataDictionary(boolean create, Properties JavaDoc startParams) throws StandardException {
358         dd = (DataDictionary) Monitor.bootServiceModule(create, this, DataDictionary.MODULE, startParams);
359     }
360
361     /**
362      * returns the statement cache that this connection should use; currently
363      * there is a statement cache per connection.
364      */

365     
366
367     public CacheManager getStatementCache()
368     {
369         return singleStatementCache;
370     }
371
372     /**
373      * Stop this module. In this case, nothing needs to be done.
374      */

375     public void stop() {
376     }
377
378     /*
379     ** Methods of PropertySetCallback
380     */

381
382     public void init(boolean dbOnly, Dictionary p) {
383         // not called yet ...
384
}
385
386     /**
387       @see PropertySetCallback#validate
388       @exception StandardException Thrown on error.
389     */

390     public boolean validate(String JavaDoc key,
391                          Serializable JavaDoc value,
392                          Dictionary p)
393         throws StandardException {
394         if (value == null)
395             return true;
396         else if (key.equals(Property.DEFAULT_CONNECTION_MODE_PROPERTY))
397         {
398             String JavaDoc value_s = (String JavaDoc)value;
399             if (value_s != null &&
400                 !StringUtil.SQLEqualsIgnoreCase(value_s, Property.NO_ACCESS) &&
401                 !StringUtil.SQLEqualsIgnoreCase(value_s, Property.READ_ONLY_ACCESS) &&
402                 !StringUtil.SQLEqualsIgnoreCase(value_s, Property.FULL_ACCESS))
403                 throw StandardException.newException(SQLState.AUTH_INVALID_AUTHORIZATION_PROPERTY, key, value_s);
404
405             return true;
406         }
407         else if (key.equals(Property.READ_ONLY_ACCESS_USERS_PROPERTY) ||
408                  key.equals(Property.FULL_ACCESS_USERS_PROPERTY))
409         {
410             String JavaDoc value_s = (String JavaDoc)value;
411
412             /** Parse the new userIdList to verify its syntax. */
413             String JavaDoc[] newList_a;
414             try {newList_a = IdUtil.parseIdList(value_s);}
415             catch (StandardException se) {
416                 throw StandardException.newException(SQLState.AUTH_INVALID_AUTHORIZATION_PROPERTY, se, key,value_s);
417             }
418
419             /** Check the new list userIdList for duplicates. */
420             String JavaDoc dups = IdUtil.dups(newList_a);
421             if (dups != null) throw StandardException.newException(SQLState.AUTH_DUPLICATE_USERS, key,dups);
422
423             /** Check for users with both read and full access permission. */
424             String JavaDoc[] otherList_a;
425             String JavaDoc otherList;
426             if (key.equals(Property.READ_ONLY_ACCESS_USERS_PROPERTY))
427                 otherList = (String JavaDoc)p.get(Property.FULL_ACCESS_USERS_PROPERTY);
428             else
429                 otherList = (String JavaDoc)p.get(Property.READ_ONLY_ACCESS_USERS_PROPERTY);
430             otherList_a = IdUtil.parseIdList(otherList);
431             String JavaDoc both = IdUtil.intersect(newList_a,otherList_a);
432             if (both != null) throw StandardException.newException(SQLState.AUTH_USER_IN_READ_AND_WRITE_LISTS, both);
433             
434             return true;
435         }
436
437         return false;
438     }
439     /** @see PropertySetCallback#apply */
440     public Serviceable apply(String JavaDoc key,
441                              Serializable JavaDoc value,
442                              Dictionary p)
443     {
444              return null;
445     }
446     /** @see PropertySetCallback#map */
447     public Serializable JavaDoc map(String JavaDoc key, Serializable JavaDoc value, Dictionary p)
448     {
449         return null;
450     }
451
452     protected void setValidation() throws StandardException {
453         pf = (PropertyFactory) Monitor.findServiceModule(this,
454             org.apache.derby.iapi.reference.Module.PropertyFactory);
455         pf.addPropertySetNotification(this);
456     }
457
458     protected void setStore() throws StandardException {
459         af = (AccessFactory) Monitor.findServiceModule(this,AccessFactory.MODULE);
460     }
461
462     public Parser newParser(CompilerContext cc)
463     {
464         return new org.apache.derby.impl.sql.compile.ParserImpl(cc);
465     }
466
467     // Class methods
468

469     /**
470      * Get the instance # for the next LCC.
471      * (Useful for logStatementText=true output.
472      *
473      * @return instance # of next LCC.
474      */

475     protected synchronized int getNextLCCInstanceNumber()
476     {
477         return nextLCCInstanceNumber++;
478     }
479 }
480
Popular Tags