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

Quick Search    Search Deep

Source code: org/apache/derby/impl/sql/conn/GenericLanguageConnectionFactory.java


1   /*
2   
3      Derby - Class org.apache.derby.impl.sql.conn.GenericLanguageConnectionFactory
4   
5      Copyright 1997, 2004 The Apache Software Foundation or its licensors, as applicable.
6   
7      Licensed under the Apache License, Version 2.0 (the "License");
8      you may not use this file except in compliance with the License.
9      You may obtain a copy of the License at
10  
11        http://www.apache.org/licenses/LICENSE-2.0
12  
13     Unless required by applicable law or agreed to in writing, software
14     distributed under the License is distributed on an "AS IS" BASIS,
15     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16     See the License for the specific language governing permissions and
17     limitations under the License.
18  
19   */
20  
21  package org.apache.derby.impl.sql.conn;
22  
23  import org.apache.derby.iapi.reference.JDBC20Translation;
24  import org.apache.derby.iapi.reference.JDBC30Translation;
25  
26  import org.apache.derby.iapi.sql.conn.LanguageConnectionFactory;
27  import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
28  import org.apache.derby.iapi.sql.compile.CompilerContext;
29  
30  import org.apache.derby.iapi.sql.LanguageFactory;
31  import org.apache.derby.impl.sql.GenericStatement;
32  
33  import org.apache.derby.impl.sql.conn.CachedStatement;
34  
35  import org.apache.derby.iapi.services.uuid.UUIDFactory;
36  import org.apache.derby.iapi.services.compiler.JavaFactory;
37  import org.apache.derby.iapi.services.loader.ClassFactory;
38  
39  import org.apache.derby.iapi.db.Database;
40  
41  import org.apache.derby.iapi.store.access.TransactionController;
42  
43  import org.apache.derby.iapi.sql.compile.TypeCompilerFactory;
44  
45  import org.apache.derby.iapi.error.StandardException;
46  
47  import org.apache.derby.iapi.sql.compile.NodeFactory;
48  import org.apache.derby.iapi.sql.compile.Parser;
49  
50  import org.apache.derby.iapi.sql.Activation;
51  
52  import org.apache.derby.iapi.store.access.AccessFactory;
53  import org.apache.derby.iapi.services.property.PropertyFactory;
54  
55  import org.apache.derby.iapi.sql.Statement;
56  import org.apache.derby.iapi.sql.compile.OptimizerFactory;
57  import org.apache.derby.iapi.sql.dictionary.DataDictionary;
58  import org.apache.derby.iapi.types.DataValueFactory;
59  import org.apache.derby.iapi.sql.execute.ExecutionFactory;
60  import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
61  
62  import org.apache.derby.iapi.services.sanity.SanityManager;
63  
64  import org.apache.derby.iapi.services.monitor.Monitor;
65  import org.apache.derby.iapi.services.monitor.ModuleControl;
66  import org.apache.derby.iapi.services.monitor.ModuleSupportable;
67  import org.apache.derby.iapi.services.monitor.ModuleFactory;
68  import org.apache.derby.iapi.services.context.ContextManager;
69  
70  import org.apache.derby.iapi.services.cache.CacheFactory;
71  import org.apache.derby.iapi.services.cache.CacheManager;
72  import org.apache.derby.iapi.services.cache.CacheableFactory;
73  import org.apache.derby.iapi.services.cache.Cacheable;
74  
75  import org.apache.derby.iapi.services.property.PropertyUtil;
76  import org.apache.derby.iapi.services.property.PropertySetCallback;
77  
78  import org.apache.derby.iapi.services.i18n.LocaleFinder;
79  import org.apache.derby.iapi.reference.SQLState;
80  import org.apache.derby.iapi.reference.Property;
81  import org.apache.derby.iapi.reference.EngineType;
82  
83  import java.util.Properties;
84  import java.util.Locale;
85  import java.util.Dictionary;
86  import java.io.Serializable;
87  import org.apache.derby.iapi.util.IdUtil;
88  import org.apache.derby.iapi.services.daemon.Serviceable;
89  import org.apache.derby.iapi.util.StringUtil;
90  
91  /**
92   * LanguageConnectionFactory generates all of the items
93   * a language system needs that is specific to a particular
94   * connection. Alot of these are other factories.
95   *
96   * @author ames
97   */
98  public class GenericLanguageConnectionFactory
99    implements LanguageConnectionFactory, CacheableFactory, PropertySetCallback, ModuleControl, ModuleSupportable {
100 
101   /*
102     fields
103    */
104   protected   DataDictionary  dd;
105   private   ExecutionFactory    ef;
106   private   OptimizerFactory    of;
107   private    TypeCompilerFactory    tcf;
108   private   DataValueFactory    dvf;
109   private   UUIDFactory        uuidFactory;
110   private   JavaFactory        javaFactory;
111   private   ClassFactory      classFactory;
112   private   NodeFactory        nodeFactory;
113   private   AccessFactory      af;
114   private   PropertyFactory      pf;
115 
116   private    int            nextLCCInstanceNumber;
117 
118   /*
119     for caching prepared statements 
120   */
121   private int cacheSize = org.apache.derby.iapi.reference.Property.STATEMENT_CACHE_SIZE_DEFAULT;
122   private CacheManager singleStatementCache;
123 
124   /*
125      constructor
126   */
127   public GenericLanguageConnectionFactory() {
128   }
129 
130   /*
131      LanguageConnectionFactory interface
132   */
133 
134   /*
135     these are the methods that do real work, not just look for factories
136    */
137 
138   /**
139     Get a Statement for the connection
140     
141     @param statementText the text for the statement
142     @return  The Statement
143    */
144   public Statement getStatement(SchemaDescriptor compilationSchema, String statementText)
145   {
146     return new GenericStatement(compilationSchema, statementText);
147   }
148 
149   /**
150     Get a LanguageConnectionContext. this holds things
151     we want to remember about activity in the language system,
152     where this factory holds things that are pretty stable,
153     like other factories.
154     <p>
155     The returned LanguageConnectionContext is intended for use
156     only by the connection that requested it.
157 
158     @return a language connection context for the context stack.
159     @exception StandardException the usual -- for the subclass
160    */
161 
162   public LanguageConnectionContext newLanguageConnectionContext(
163     ContextManager cm,
164     TransactionController tc,
165     LanguageFactory lf,
166     Database db,
167     String userName,
168     String drdaID,
169     String dbname) throws StandardException {
170     
171     pushDataDictionaryContext(cm);
172 
173     return new GenericLanguageConnectionContext(cm,
174                           tc,
175                           lf,
176                           this,
177                           db,
178                           userName,
179                           getNextLCCInstanceNumber(),
180                           drdaID,
181                           dbname);
182   }
183 
184   public Cacheable newCacheable(CacheManager cm) {
185     return new CachedStatement();
186   }
187 
188   /*
189     these methods all look for factories that we booted.
190    */
191    
192    /**
193     Get the UUIDFactory to use with this language connection
194     REMIND: this is only used by the compiler; should there be
195     a compiler module control class to boot compiler-only stuff?
196    */
197   public UUIDFactory  getUUIDFactory()
198   {
199     return uuidFactory;
200   }
201 
202   /**
203     Get the ClassFactory to use with this language connection
204    */
205   public ClassFactory  getClassFactory()
206   {
207     return classFactory;
208   }
209 
210   /**
211     Get the JavaFactory to use with this language connection
212     REMIND: this is only used by the compiler; should there be
213     a compiler module control class to boot compiler-only stuff?
214    */
215   public JavaFactory  getJavaFactory()
216   {
217     return javaFactory;
218   }
219 
220   /**
221     Get the NodeFactory to use with this language connection
222     REMIND: is this only used by the compiler?
223    */
224   public NodeFactory  getNodeFactory()
225   {
226     return nodeFactory;
227   }
228 
229   /**
230     Get the ExecutionFactory to use with this language connection
231    */
232   public ExecutionFactory  getExecutionFactory() {
233     return ef;
234   }
235 
236   /**
237     Get the AccessFactory to use with this language connection
238    */
239   public AccessFactory  getAccessFactory() 
240   {
241     return af;
242   }  
243 
244   /**
245     Get the PropertyFactory to use with this language connection
246    */
247   public PropertyFactory  getPropertyFactory() 
248   {
249     return pf;
250   }  
251 
252   /**
253     Get the OptimizerFactory to use with this language connection
254    */
255   public OptimizerFactory  getOptimizerFactory() {
256     return of;
257   }
258   /**
259     Get the TypeCompilerFactory to use with this language connection
260    */
261   public TypeCompilerFactory getTypeCompilerFactory() {
262     return tcf;
263   }
264 
265   /**
266     Get the DataValueFactory to use with this language connection
267    */
268   public DataValueFactory    getDataValueFactory() {
269     return dvf;
270   }
271 
272   protected void pushDataDictionaryContext(ContextManager cm) {
273     // we make sure there is a data dictionary context in place.
274     dd.pushDataDictionaryContext(cm, false);
275   }
276 
277   /*
278     ModuleControl interface
279    */
280 
281   /**
282     this implementation will not support caching of statements.
283    */
284   public boolean canSupport(Properties startParams) {
285 
286     return Monitor.isDesiredType( startParams, EngineType.STANDALONE_DB);
287   }
288 
289   private  int  statementCacheSize(Properties startParams)
290   {
291     String wantCacheProperty = null;
292 
293     wantCacheProperty =
294       PropertyUtil.getPropertyFromSet(startParams, org.apache.derby.iapi.reference.Property.STATEMENT_CACHE_SIZE);
295 
296     if (SanityManager.DEBUG)
297       SanityManager.DEBUG("StatementCacheInfo", "Cacheing implementation chosen if null or 0<"+wantCacheProperty);
298 
299     if (wantCacheProperty != null) {
300       try {
301           cacheSize = Integer.parseInt(wantCacheProperty);
302       } catch (NumberFormatException nfe) {
303         cacheSize = org.apache.derby.iapi.reference.Property.STATEMENT_CACHE_SIZE_DEFAULT; 
304       }
305     }
306 
307     return cacheSize;
308   }
309   
310   /**
311    * Start-up method for this instance of the language connection factory.
312    * Note these are expected to be booted relative to a Database.
313    *
314    * @param startParams  The start-up parameters (ignored in this case)
315    *
316    * @exception StandardException  Thrown on failure to boot
317    */
318   public void boot(boolean create, Properties startParams) 
319     throws StandardException {
320 
321     dvf = (DataValueFactory) Monitor.bootServiceModule(create, this, org.apache.derby.iapi.reference.ClassName.DataValueFactory, startParams);
322     javaFactory = (JavaFactory) Monitor.startSystemModule(org.apache.derby.iapi.reference.Module.JavaFactory);
323     uuidFactory = Monitor.getMonitor().getUUIDFactory();
324     classFactory = (ClassFactory) Monitor.getServiceModule(this, org.apache.derby.iapi.reference.Module.ClassFactory);
325     if (classFactory == null)
326        classFactory = (ClassFactory) Monitor.findSystemModule(org.apache.derby.iapi.reference.Module.ClassFactory);
327 
328     bootDataDictionary(create, startParams);
329 
330     //set the property validation module needed to do propertySetCallBack
331     //register and property validation
332     setValidation();
333 
334     setStore();
335 
336     ef = (ExecutionFactory) Monitor.bootServiceModule(create, this, ExecutionFactory.MODULE, startParams);
337     of = (OptimizerFactory) Monitor.bootServiceModule(create, this, OptimizerFactory.MODULE, startParams);
338     tcf =
339        (TypeCompilerFactory) Monitor.startSystemModule(TypeCompilerFactory.MODULE);
340     nodeFactory = (NodeFactory) Monitor.bootServiceModule(create, this, NodeFactory.MODULE, startParams);
341 
342     // If the system supports statement caching boot the CacheFactory module.
343     int cacheSize = statementCacheSize(startParams);
344     if (cacheSize > 0) {
345       CacheFactory cacheFactory = (CacheFactory) Monitor.startSystemModule(org.apache.derby.iapi.reference.Module.CacheFactory);
346       singleStatementCache = cacheFactory.newCacheManager(this,
347                         "StatementCache",
348                         cacheSize/4,
349                         cacheSize);
350     }
351 
352   }
353 
354   protected void bootDataDictionary(boolean create, Properties startParams) throws StandardException {
355     dd = (DataDictionary) Monitor.bootServiceModule(create, this, DataDictionary.MODULE, startParams);
356   }
357 
358   /**
359    * returns the statement cache that this connection should use; currently
360    * there is a statement cache per connection.
361    */
362   
363 
364   public CacheManager getStatementCache()
365   {
366     return singleStatementCache;
367   }
368 
369   /**
370    * Stop this module.  In this case, nothing needs to be done.
371    *
372    * @return  Nothing
373    */
374   public void stop() {
375   }
376 
377   /*
378   ** Methods of PropertySetCallback
379   */
380 
381   public void init(boolean dbOnly, Dictionary p) {
382     // not called yet ...
383   }
384 
385   /**
386     @see PropertySetCallback#validate
387     @exception StandardException Thrown on error.
388   */
389   public boolean validate(String key,
390              Serializable value,
391              Dictionary p)
392     throws StandardException {
393     if (value == null)
394       return true;
395     else if (key.equals(Property.DEFAULT_CONNECTION_MODE_PROPERTY))
396     {
397       String value_s = (String)value;
398       if (value_s != null &&
399         !StringUtil.SQLEqualsIgnoreCase(value_s, Property.NO_ACCESS) &&
400         !StringUtil.SQLEqualsIgnoreCase(value_s, Property.READ_ONLY_ACCESS) &&
401         !StringUtil.SQLEqualsIgnoreCase(value_s, Property.FULL_ACCESS))
402         throw StandardException.newException(SQLState.AUTH_INVALID_AUTHORIZATION_PROPERTY          , key,value_s);
403 
404       return true;
405     }
406     else if (key.equals(Property.READ_ONLY_ACCESS_USERS_PROPERTY) ||
407          key.equals(Property.FULL_ACCESS_USERS_PROPERTY))
408     {
409       String value_s = (String)value;
410 
411       /** Parse the new userIdList to verify its syntax. */
412       String[] newList_a;
413       try {newList_a = IdUtil.parseIdList(value_s);}
414       catch (StandardException se) {
415         throw StandardException.newException(SQLState.AUTH_INVALID_AUTHORIZATION_PROPERTY, key,value_s,se);
416       }
417 
418       /** Check the new list userIdList for duplicates. */
419       String dups = IdUtil.dups(newList_a);
420       if (dups != null) throw StandardException.newException(SQLState.AUTH_DUPLICATE_USERS, key,dups);
421 
422       /** Check for users with both read and full access permission. */
423       String[] otherList_a;
424       String otherList;
425       if (key.equals(Property.READ_ONLY_ACCESS_USERS_PROPERTY))
426         otherList = (String)p.get(Property.FULL_ACCESS_USERS_PROPERTY);
427       else
428         otherList = (String)p.get(Property.READ_ONLY_ACCESS_USERS_PROPERTY);
429       otherList_a = IdUtil.parseIdList(otherList);
430       String both = IdUtil.intersect(newList_a,otherList_a);
431       if (both != null) throw StandardException.newException(SQLState.AUTH_USER_IN_READ_AND_WRITE_LISTS, both);
432       
433       return true;
434     }
435 
436     return false;
437   }
438   /** @see PropertySetCallback#apply */
439   public Serviceable apply(String key,
440                Serializable value,
441                Dictionary p)
442   {
443        return null;
444   }
445   /** @see PropertySetCallback#map */
446   public Serializable map(String key, Serializable value, Dictionary p)
447   {
448     return null;
449   }
450 
451   protected void setValidation() throws StandardException {
452     pf = (PropertyFactory) Monitor.findServiceModule(this,
453       org.apache.derby.iapi.reference.Module.PropertyFactory);
454     pf.addPropertySetNotification(this);
455   }
456 
457   protected void setStore() throws StandardException {
458     af = (AccessFactory) Monitor.findServiceModule(this,AccessFactory.MODULE);
459   }
460 
461     public Parser newParser(CompilerContext cc)
462     {
463         return new org.apache.derby.impl.sql.compile.ParserImpl(cc);
464     }
465 
466   // Class methods
467 
468   /**
469    * Get the instance # for the next LCC.
470    * (Useful for logStatementText=true output.
471    *
472    * @return instance # of next LCC.
473    */
474   protected synchronized int getNextLCCInstanceNumber()
475   {
476     return nextLCCInstanceNumber++;
477   }
478 }