KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > continuent > sequoia > controller > semantic > SemanticManager


1 /**
2  * Sequoia: Database clustering technology.
3  * Copyright (C) 2006 Continuent, Inc.
4  * Contact: sequoia@continuent.org
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * Initial developer(s): Emmanuel Cecchet.
19  * Contributor(s): Stephane Giron.
20  */

21
22 package org.continuent.sequoia.controller.semantic;
23
24 import java.util.ArrayList JavaDoc;
25 import java.util.HashMap JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.SortedSet JavaDoc;
29 import java.util.TreeSet JavaDoc;
30
31 import org.continuent.sequoia.common.log.Trace;
32 import org.continuent.sequoia.common.xml.DatabasesXmlTags;
33 import org.continuent.sequoia.common.xml.XmlComponent;
34 import org.continuent.sequoia.controller.requests.AbstractRequest;
35 import org.continuent.sequoia.controller.requests.StoredProcedure;
36 import org.continuent.sequoia.controller.sql.macros.AbstractMacro;
37
38 /**
39  * This class defines a SemanticManager that takes care of the semantic
40  * information for a virtual database.
41  *
42  * @author <a HREF="mailto:emmanuel.cecchet@continuent.com">Emmanuel Cecchet</a>
43  * @author <a HREF="mailto:stephane.giron@continuent.com">Stephane Giron</a>
44  * @version 1.0
45  */

46 public class SemanticManager implements XmlComponent
47 {
48   private List JavaDoc requestSemantic;
49   private HashMap JavaDoc storedProcedureSemantic;
50   private StoredProcedureSemantic defaultStoredProcedureSemantic;
51   private HashMap JavaDoc triggerSemantic;
52   private HashMap JavaDoc viewSemantic;
53
54   private Trace logger = Trace
55                                              .getLogger("org.continuent.sequoia.controller.semantic");
56
57   /**
58    * Creates a new <code>SemanticManager</code> object
59    */

60   public SemanticManager()
61   {
62     requestSemantic = new ArrayList JavaDoc();
63     storedProcedureSemantic = new HashMap JavaDoc();
64     triggerSemantic = new HashMap JavaDoc();
65     viewSemantic = new HashMap JavaDoc();
66   }
67
68   /**
69    * Add a RequestSemantic or replace the existing one if it matches the same
70    * pattern.
71    *
72    * @param semantic request semantic information
73    */

74   public void addRequestSemantic(RequestSemantic semantic)
75   {
76     if (requestSemantic.contains(semantic))
77     {
78       if (logger.isInfoEnabled())
79         logger.info("Replacing request semantic for "
80             + semantic.getSqlPattern());
81       requestSemantic.set(requestSemantic.indexOf(semantic), semantic);
82     }
83     else
84     {
85       if (logger.isDebugEnabled())
86         logger.debug("Adding request semantic for " + semantic.getSqlPattern());
87       requestSemantic.add(semantic);
88     }
89   }
90
91   /**
92    * Add a StoredProcedureSemantic or replace the existing one if it matches the
93    * same pattern.
94    *
95    * @param semantic request semantic information
96    */

97   public void addStoredProcedureSemantic(StoredProcedureSemantic semantic)
98   {
99     String JavaDoc storedProcedureKey = semantic.getProcedureKey();
100     if (logger.isInfoEnabled())
101     {
102       if (storedProcedureSemantic.containsKey(storedProcedureKey))
103         logger.info("Replacing semantic for StoredProcedure "
104             + storedProcedureKey);
105       else
106         logger.debug("Adding semantic for StoredProcedure "
107             + storedProcedureKey);
108     }
109     storedProcedureSemantic.put(storedProcedureKey, semantic);
110   }
111
112   /**
113    * Add a TriggerSemantic or replace the existing one if it matches the same
114    * pattern.
115    *
116    * @param semantic request semantic information
117    */

118   public void addTriggerSemantic(TriggerSemantic semantic)
119   {
120     String JavaDoc triggerName = semantic.getTriggerName();
121     if (logger.isInfoEnabled())
122     {
123       if (triggerSemantic.containsKey(triggerName))
124         logger.info("Replacing semantic for trigger " + triggerName);
125       else
126         logger.debug("Adding semantic for trigger " + triggerName);
127     }
128     triggerSemantic.put(triggerName, semantic);
129   }
130
131   /**
132    * Add a ViewSemantic or replace the existing one if it matches the same
133    * pattern.
134    *
135    * @param semantic request semantic information
136    */

137   public void addViewSemantic(ViewSemantic semantic)
138   {
139     String JavaDoc viewName = semantic.getViewName();
140     if (logger.isInfoEnabled())
141     {
142       if (viewSemantic.containsKey(viewName))
143         logger.info("Replacing semantic for view " + viewName);
144       else
145         logger.debug("Adding semantic for view " + viewName);
146     }
147     viewSemantic.put(viewName, semantic);
148   }
149
150   /**
151    * Returns the default Stored Procedure Semantic value.
152    *
153    * @return Returns the defaultStoredProcedureSemantic.
154    */

155   public StoredProcedureSemantic getDefaultStoredProcedureSemantic()
156   {
157     return defaultStoredProcedureSemantic;
158   }
159
160   /**
161    * Set the default Stored Procedure semantic definition.
162    *
163    * @param defaultSemantic the default semantic
164    */

165   public void setDefaultStoredProcedureSemantic(
166       StoredProcedureSemantic defaultSemantic)
167   {
168     this.defaultStoredProcedureSemantic = defaultSemantic;
169   }
170
171   /**
172    * Get the specific semantic behavior associated to a request. The first rule
173    * matching applies. If no rule matches, null is returned.
174    * <p>
175    * If the request is a stored procedure, we try to first match a request
176    * semantic to the call and if not applies, we call getStoredProcedureSemantic
177    * and return its result.
178    *
179    * @param request the request to look for
180    * @return the SemanticBehavior of the first matching rule or null
181    * @see #getStoredProcedureSemantic(StoredProcedure)
182    */

183   public SemanticBehavior getRequestSemantic(AbstractRequest request)
184   {
185     for (Iterator JavaDoc iter = requestSemantic.iterator(); iter.hasNext();)
186     {
187       RequestSemantic rs = (RequestSemantic) iter.next();
188       if (rs.matchesPattern(request.getSqlOrTemplate()))
189         return rs.getSemanticBehavior();
190     }
191
192     if (request instanceof StoredProcedure)
193       return getStoredProcedureSemantic((StoredProcedure) request);
194
195     return null;
196   }
197
198   /**
199    * Return the semantic behavior corresponding to the stored procedure. If no
200    * specific semantic matches, the default stored procedure is returned (might
201    * be null).
202    *
203    * @param procedure the procedure to look the semantic information for
204    * @return the semantic behavior for this stored procedure
205    */

206   public SemanticBehavior getStoredProcedureSemantic(StoredProcedure procedure)
207   {
208     StoredProcedureSemantic semantic = (StoredProcedureSemantic) storedProcedureSemantic
209         .get(procedure.getProcedureKey());
210
211     if (semantic != null)
212       return semantic.getSemanticBehavior();
213
214     semantic = (StoredProcedureSemantic) storedProcedureSemantic.get(procedure
215         .getProcedureName());
216     if (semantic != null)
217       return semantic.getSemanticBehavior();
218
219     if (defaultStoredProcedureSemantic != null)
220       return defaultStoredProcedureSemantic.getSemanticBehavior();
221
222     return null;
223   }
224
225   /**
226    * Return the semantic behavior corresponding to the stored procedure. If no
227    * specific semantic matches, the default stored procedure is returned (might
228    * be null).
229    *
230    * @param storedProcedureKey the procedure key to look the semantic
231    * information for
232    * @return the semantic behavior for this stored procedure
233    */

234   public SemanticBehavior getStoredProcedureSemantic(String JavaDoc storedProcedureKey)
235   {
236     StoredProcedureSemantic semantic = (StoredProcedureSemantic) storedProcedureSemantic
237         .get(storedProcedureKey);
238
239     if (semantic != null)
240       return semantic.getSemanticBehavior();
241
242     if (defaultStoredProcedureSemantic != null)
243       return defaultStoredProcedureSemantic.getSemanticBehavior();
244
245     return null;
246   }
247
248   /**
249    * Return the semantic behavior corresponding to the view.
250    *
251    * @param viewName the name of the view to look the semantic information for
252    * @return the semantic behavior for this view
253    */

254   public ViewSemantic getViewSemantic(String JavaDoc viewName)
255   {
256     ViewSemantic semantic = (ViewSemantic) this.viewSemantic.get(viewName);
257     return semantic;
258   }
259
260   /**
261    * Process the given semantic information and returns the list of tables that
262    * are write locked (includes view, triggers and references stored procedures
263    * resolution).
264    *
265    * @param semantic semantic information to process
266    * @return list of write locked tables
267    */

268   public SortedSet JavaDoc getWriteLockedTables(SemanticBehavior semantic)
269   {
270     // sanity check
271
if (semantic == null)
272       return new TreeSet JavaDoc();
273
274     SortedSet JavaDoc result = processTableList(semantic.getWriteSet());
275     result
276         .addAll(processStoredProcedureRef(semantic.getProceduresReferenced()));
277     processTriggersForTables(result);
278     return result;
279   }
280
281   /**
282    * Process the given set of tables to check if they are referenced by any
283    * triggers, add any tables that could be defined in the semantic information
284    * of those triggers and process any procedures referenced by those triggers.
285    * Process triggers again for new found tables.
286    *
287    * @param result list of write locked tables (including tables referenced by
288    * semantic information of triggers)
289    */

290   private void processTriggersForTables(SortedSet JavaDoc result)
291   {
292     /*
293      * For now, triggers are inserted in the set with a trigger name as key. It
294      * could be interesting for performance to access triggers by table, ie. a
295      * table has a trigger list defined on it.
296      */

297
298     if (result.isEmpty())
299       return;
300
301     SortedSet JavaDoc res = new TreeSet JavaDoc();
302     for (Iterator JavaDoc iter = result.iterator(); iter.hasNext();)
303     {
304       String JavaDoc tableName = (String JavaDoc) iter.next();
305       for (Iterator JavaDoc iterator = triggerSemantic.values().iterator(); iterator
306           .hasNext();)
307       {
308         TriggerSemantic element = (TriggerSemantic) iterator.next();
309         if (element.getOnTableOrView().equals(tableName))
310         {
311           SemanticBehavior semantic = element.getSemanticBehavior();
312           if (semantic == null)
313             return;
314           res = processTableList(semantic.getWriteSet());
315           res.addAll(processStoredProcedureRef(semantic
316               .getProceduresReferenced()));
317         }
318       }
319     }
320     processTriggersForTables(res);
321     result.addAll(res);
322   }
323
324   /**
325    * Process the given set of tables or views.
326    *
327    * @param list list of tables or views
328    * @return a processed table list
329    */

330   private SortedSet JavaDoc processTableList(SortedSet JavaDoc list)
331   {
332     SortedSet JavaDoc result = new TreeSet JavaDoc();
333     if (list == null)
334       return result;
335
336     for (Iterator JavaDoc iter = list.iterator(); iter.hasNext();)
337     {
338       String JavaDoc tableOrViewName = (String JavaDoc) iter.next();
339
340       // It is either a view or a table : check if we can find semantic
341
// information about such a view. If not, consider it to be a table.
342
ViewSemantic semantic = getViewSemantic(tableOrViewName);
343       if (semantic != null)
344       {
345         // We found a semantic associated to this view : process it
346
// recursively
347
result.addAll(processTableList(semantic.getWriteSet()));
348       }
349       else
350         // Not a view or no semantic information found
351
result.add(tableOrViewName);
352     }
353     return result;
354   }
355
356   /**
357    * Process the given stored procedure keys list to return the list of tables
358    * that are write locked (includes view, triggers and references stored
359    * procedures resolution).
360    *
361    * @param list list of stored procedure keys
362    * @return list of write locked tables by the stored procedures found in the
363    * list
364    */

365   private SortedSet JavaDoc processStoredProcedureRef(SortedSet JavaDoc list)
366   {
367     SortedSet JavaDoc result = new TreeSet JavaDoc();
368     if (list != null)
369       for (Iterator JavaDoc iter = list.iterator(); iter.hasNext();)
370       {
371         String JavaDoc storedProcedureKey = (String JavaDoc) iter.next();
372         SemanticBehavior spSemantic = getStoredProcedureSemantic(storedProcedureKey);
373
374         SortedSet JavaDoc writeSet = spSemantic.getWriteSet();
375
376         if (writeSet != null)
377           result.addAll(processTableList(writeSet));
378
379         writeSet = null;
380         SortedSet JavaDoc spReferenced = spSemantic.getProceduresReferenced();
381         if (spReferenced != null)
382           result.addAll(processStoredProcedureRef(spReferenced));
383
384       }
385     return result;
386   }
387
388   /**
389    * @see org.continuent.sequoia.common.xml.XmlComponent#getXml()
390    */

391   public String JavaDoc getXml()
392   {
393     StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
394     sb.append("<" + DatabasesXmlTags.ELT_Semantic + ">");
395     for (Iterator JavaDoc iter = requestSemantic.iterator(); iter.hasNext();)
396     {
397       AbstractMacro macro = (AbstractMacro) iter.next();
398       sb.append(macro.getXml());
399     }
400     sb.append("</" + DatabasesXmlTags.ELT_Semantic + ">");
401     return sb.toString();
402   }
403
404 }
405
Popular Tags