KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jacorb > notification > AbstractMessage


1 package org.jacorb.notification;
2
3 /*
4  * JacORB - a free Java ORB
5  *
6  * Copyright (C) 1999-2004 Gerald Brose
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the Free
20  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  */

23
24 import java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26
27 import org.jacorb.notification.filter.ComponentName;
28 import org.jacorb.notification.filter.EvaluationContext;
29 import org.jacorb.notification.filter.EvaluationException;
30 import org.jacorb.notification.filter.EvaluationResult;
31 import org.jacorb.notification.filter.RuntimeVariable;
32 import org.jacorb.notification.interfaces.Disposable;
33 import org.jacorb.notification.interfaces.FilterStage;
34 import org.jacorb.notification.interfaces.Message;
35 import org.jacorb.notification.util.AbstractPoolable;
36 import org.omg.CORBA.Any JavaDoc;
37 import org.omg.CORBA.AnyHolder JavaDoc;
38 import org.omg.CORBA.ORB JavaDoc;
39 import org.omg.CosNotification.Property;
40 import org.omg.CosNotification.StructuredEvent;
41 import org.omg.CosNotifyFilter.Filter;
42 import org.omg.CosNotifyFilter.MappingFilter;
43 import org.omg.CosNotifyFilter.UnsupportedFilterableData;
44
45 /**
46  * @author Alphonse Bendt
47  * @version $Id: AbstractMessage.java,v 1.26 2005/04/27 10:32:27 alphonse.bendt Exp $
48  */

49
50 public abstract class AbstractMessage extends AbstractPoolable
51 {
52     /**
53      * Instead of directly using an instance of AbstractMessage an indirection via MessageHandle is
54      * used. This way the Data in AbstractMessage is kept only once. MessageHandle uses reference
55      * counting. As the last MessageHandle is disposed the AbstractMessage containing the data can
56      * be disposed. MessageHandle also allows the priority and timeout to be changed on a per handle
57      * base (the underlying AbstractMessage isn't affected by this)
58      */

59     class MessageHandle implements Message, Disposable
60     {
61         /**
62          * Listener that gets notified if the State of this MessageHandle changes.
63          */

64         private MessageStateListener eventStateListener_;
65
66         private boolean isInvalid_ = false;
67
68         /**
69          * flag to indicate that the Priority has been changed for this Messagehandle.
70          */

71         private boolean isPrioritySet_ = false;
72
73         /**
74          * if isPrioritySet_ is true priority_ contains the Priority for this MessageHandle.
75          */

76         private int priority_;
77
78         /**
79          * flag to indicate that the Timeout has been changed for this Messagehandle.
80          */

81         private boolean isTimeoutSet_ = false;
82
83         /**
84          * if isTimeoutSet_ is true timeOut_ contains the Timeout for this MessageHandle.
85          */

86         private long timeOut_;
87
88         ////////////////////
89

90         /**
91          * default ctor. adds a reference to the underlying message.
92          */

93         MessageHandle()
94         {
95             addReference();
96         }
97
98         /**
99          * copy ctor. adds a reference to the underlying message.
100          */

101         private MessageHandle(int priority, boolean priorityOverride, long timeout,
102                 boolean timeoutOverride)
103         {
104             // i would like to write this() here to call the no-args
105
// constructor.
106
// this compiles but results in java.lang.VerifyErrors
107
// at runtime
108
addReference();
109
110             priority_ = priority;
111             isPrioritySet_ = priorityOverride;
112             timeOut_ = timeout;
113             isTimeoutSet_ = timeoutOverride;
114         }
115
116         /**
117          * set the Inital FilterStage (the ProxyConsumer that has received the Message).
118          */

119         public void setInitialFilterStage(FilterStage s)
120         {
121             AbstractMessage.this.setFilterStage(s);
122         }
123
124         public FilterStage getInitialFilterStage()
125         {
126             return AbstractMessage.this.getFilterStage();
127         }
128
129         public String JavaDoc getConstraintKey()
130         {
131             return AbstractMessage.this.getConstraintKey();
132         }
133
134         public Any JavaDoc toAny()
135         {
136             return AbstractMessage.this.toAny();
137         }
138
139         public Property[] toTypedEvent() throws NoTranslationException
140         {
141             return AbstractMessage.this.toTypedEvent();
142         }
143
144         public StructuredEvent toStructuredEvent()
145         {
146             return AbstractMessage.this.toStructuredEvent();
147         }
148
149         public int getType()
150         {
151             return AbstractMessage.this.getType();
152         }
153
154         public EvaluationResult extractValue(EvaluationContext context,
155                 ComponentName componentName, RuntimeVariable runtimeVariable)
156                 throws EvaluationException
157         {
158             return AbstractMessage.this.extractValue(context, componentName, runtimeVariable);
159         }
160
161         public EvaluationResult extractValue(EvaluationContext context, ComponentName componentName)
162                 throws EvaluationException
163         {
164             return AbstractMessage.this.extractValue(context, componentName);
165         }
166
167         public EvaluationResult extractFilterableData(EvaluationContext context,
168                 ComponentName componentRootNode, String JavaDoc variable) throws EvaluationException
169         {
170             return AbstractMessage.this.extractFilterableData(context, componentRootNode, variable);
171         }
172
173         public EvaluationResult extractVariableHeader(EvaluationContext context,
174                 ComponentName componentName, String JavaDoc s) throws EvaluationException
175         {
176             return AbstractMessage.this.extractVariableHeader(context, componentName, s);
177         }
178
179         public boolean hasStartTime()
180         {
181             return AbstractMessage.this.hasStartTime();
182         }
183
184         public long getStartTime()
185         {
186             return AbstractMessage.this.getStartTime();
187         }
188
189         public boolean hasStopTime()
190         {
191             return AbstractMessage.this.hasStopTime();
192         }
193
194         public long getStopTime()
195         {
196             return AbstractMessage.this.getStopTime();
197         }
198
199         public boolean hasTimeout()
200         {
201             return isTimeoutSet_ || AbstractMessage.this.hasTimeout();
202         }
203
204         public long getTimeout()
205         {
206             if (isTimeoutSet_)
207             {
208                 return timeOut_;
209             }
210             return AbstractMessage.this.getTimeout();
211
212         }
213
214         public void setTimeout(long timeout)
215         {
216             timeOut_ = timeout;
217
218             isTimeoutSet_ = true;
219
220             if (eventStateListener_ != null)
221             {
222                 eventStateListener_.actionLifetimeChanged(timeout);
223             }
224         }
225
226         public void setPriority(int priority)
227         {
228             isPrioritySet_ = true;
229
230             priority_ = priority;
231         }
232
233         public int getPriority()
234         {
235             if (isPrioritySet_)
236             {
237                 return priority_;
238             }
239             return AbstractMessage.this.getPriority();
240         }
241
242         public boolean match(FilterStage s)
243         {
244             return AbstractMessage.this.match(s);
245         }
246
247         public boolean match(MappingFilter m, AnyHolder JavaDoc r) throws UnsupportedFilterableData
248         {
249             return AbstractMessage.this.match(m, r);
250         }
251
252         public Object JavaDoc clone()
253         {
254             try
255             {
256                 checkInvalid();
257
258                 return new MessageHandle(priority_, isPrioritySet_, timeOut_, isTimeoutSet_);
259             } catch (IllegalArgumentException JavaDoc e)
260             {
261                 return null;
262             }
263         }
264
265         public void dispose()
266         {
267             removeReference();
268         }
269
270         public synchronized boolean isInvalid()
271         {
272             return isInvalid_;
273         }
274
275         public void setMessageStateListener(MessageStateListener l)
276         {
277             eventStateListener_ = l;
278         }
279
280         public MessageStateListener removeMessageStateListener()
281         {
282             MessageStateListener _l = eventStateListener_;
283             eventStateListener_ = null;
284
285             return _l;
286         }
287
288         public synchronized void actionTimeout()
289         {
290             isInvalid_ = true;
291         }
292
293         public String JavaDoc toString()
294         {
295             return "[Message/" + AbstractMessage.this + "]";
296         }
297
298         private void checkInvalid() throws IllegalArgumentException JavaDoc
299         {
300             if (isInvalid())
301             {
302                 throw new IllegalArgumentException JavaDoc("This Notification has been invalidated");
303             }
304         }
305     }
306
307     ////////////////////////////////////////
308

309     static final ORB JavaDoc sOrb = ORB.init();
310
311     protected boolean proxyConsumerFiltered_;
312
313     protected boolean supplierAdminFiltered_;
314
315     protected boolean consumerAdminFiltered_;
316
317     protected boolean proxySupplierFiltered_;
318
319     private FilterStage currentFilterStage_;
320
321     ////////////////////////////////////////
322

323     /**
324      * get the Constraint Key for this Event. The Constraint Key is used to fetch the Filter
325      * Constraints that must be evaluated for this Event. The Constraint Key consists of domain_name
326      * and type_name of the Event.
327      *
328      * @return a <code>String</code> value
329      */

330     public abstract String JavaDoc getConstraintKey();
331
332     /**
333      * Access this NotificationEvent as Any.
334      *
335      * @return an <code>Any</code> value
336      */

337     public abstract Any JavaDoc toAny();
338
339     /**
340      * convert this message to a TypedEvent.
341      *
342      * @return a sequence of name-value pairs.
343      * @throws NoTranslationException
344      * if the contents of the message cannot be translated into a TypedEvent.
345      */

346     public abstract Property[] toTypedEvent() throws NoTranslationException;
347
348     /**
349      * Access this NotificationEvent as StructuredEvent.
350      *
351      * @return a <code>StructuredEvent</code> value
352      */

353     public abstract StructuredEvent toStructuredEvent();
354
355     /**
356      * get the Type of this NotificationEvent. The value is one of
357      * {@link org.jacorb.notification.interfaces.Message#TYPE_ANY},{@link
358      * org.jacorb.notification.interfaces.Message#TYPE_STRUCTURED}, or {@link
359      * org.jacorb.notification.interfaces.Message#TYPE_TYPED}.
360      *
361      * @return the Type of this NotificationEvent.
362      */

363     public abstract int getType();
364
365     /**
366      * Internal Reference Counter.
367      */

368     protected int referenced_ = 0;
369
370     public void reset()
371     {
372         referenced_ = 0;
373         currentFilterStage_ = null;
374     }
375
376     /**
377      * Add a reference on this NotificationEvent. After Usage removeReference must be called.
378      */

379     public synchronized void addReference()
380     {
381         ++referenced_;
382     }
383
384     /**
385      * release this NotificationEvent. If the internal Refcounter is zero the NotificationEvent is
386      * returned to its pool.
387      */

388     protected synchronized void removeReference()
389     {
390         if (referenced_ > 0)
391         {
392             --referenced_;
393         }
394
395         if (referenced_ == 0)
396         {
397             super.dispose();
398         }
399     }
400
401     public void setFilterStage(FilterStage node)
402     {
403         currentFilterStage_ = node;
404     }
405
406     public FilterStage getFilterStage()
407     {
408         return currentFilterStage_;
409     }
410
411     public EvaluationResult extractValue(EvaluationContext context,
412             ComponentName componentRootNode, RuntimeVariable runtimeVariable)
413             throws EvaluationException
414     {
415         EvaluationResult _ret = null;
416
417         String JavaDoc _completePath = componentRootNode.getComponentName();
418
419         if (logger_.isDebugEnabled())
420         {
421             logger_.debug("extractValue: " + _completePath);
422             logger_.debug("runtimeVariable=" + runtimeVariable);
423         }
424
425         _ret = context.lookupResult(_completePath);
426
427         if (_ret == null)
428         {
429             _ret = runtimeVariable.evaluate(context);
430
431             _ret = context.extractFromMessage(_ret, componentRootNode, runtimeVariable);
432
433             context.storeResult(_completePath, _ret);
434         }
435
436         if (_ret == null)
437         {
438             throw new EvaluationException("Could not resolve " + _completePath);
439         }
440         
441         return _ret;
442     }
443
444     public abstract EvaluationResult extractFilterableData(EvaluationContext context,
445             ComponentName componentRootNode, String JavaDoc variable) throws EvaluationException;
446
447     public abstract EvaluationResult extractVariableHeader(EvaluationContext context,
448             ComponentName componentRootNode, String JavaDoc variable) throws EvaluationException;
449
450     public EvaluationResult extractValue(EvaluationContext evaluationContext,
451             ComponentName componentRootNode) throws EvaluationException
452     {
453         EvaluationResult _ret = null;
454
455         String JavaDoc _completeExpr = componentRootNode.getComponentName();
456
457         if (logger_.isDebugEnabled())
458         {
459             logger_.debug("extractValue path: " + componentRootNode.toStringTree()
460                     + "\n\tcomplete Expression=" + _completeExpr);
461         }
462
463         // check if the value is available in the cache
464
_ret = evaluationContext.lookupResult(_completeExpr);
465
466         if (logger_.isDebugEnabled())
467         {
468             logger_.debug("Cache READ: " + _ret);
469         }
470
471         if (_ret == null)
472         {
473             logger_.debug("Cache MISS");
474
475             _ret = evaluationContext.extractFromMessage(this, componentRootNode);
476
477             // Cache the EvaluationResult
478
if (_ret != null)
479             {
480                 if (logger_.isDebugEnabled())
481                 {
482                     logger_.debug("Cache WRITE: " + _completeExpr + " => " + _ret);
483                 }
484                 evaluationContext.storeResult(_completeExpr, _ret);
485             }
486         }
487
488         if (_ret == null)
489         {
490             throw new EvaluationException("Could not resolve " + _completeExpr);
491         }
492
493         return _ret;
494     }
495
496     public Message getHandle()
497     {
498         return new MessageHandle();
499     }
500
501     public abstract boolean hasStartTime();
502
503     public abstract long getStartTime();
504
505     public abstract boolean hasStopTime();
506
507     public abstract long getStopTime();
508
509     public abstract boolean hasTimeout();
510
511     public abstract long getTimeout();
512
513     public abstract int getPriority();
514
515     public abstract boolean match(Filter filter) throws UnsupportedFilterableData;
516
517     public boolean match(FilterStage filterStage)
518     {
519         List JavaDoc _filterList = filterStage.getFilters();
520
521         if (_filterList.isEmpty())
522         {
523             return true;
524         }
525
526         Iterator JavaDoc _filterIterator = _filterList.iterator();
527
528         while (_filterIterator.hasNext())
529         {
530             try
531             {
532                 Filter _filter = (Filter) _filterIterator.next();
533
534                 if (match(_filter))
535                 {
536                     return true;
537                 }
538             } catch (UnsupportedFilterableData e)
539             {
540                 // no problem
541
// error means false
542
logger_.info("unsupported filterable data. match result defaults to false.", e);
543             }
544         }
545
546         return false;
547     }
548
549     public abstract boolean match(MappingFilter filter, AnyHolder JavaDoc value)
550             throws UnsupportedFilterableData;
551
552     /**
553      * Provide a Uniform Mapping from domain_name and type_name to a Key that can be used to put
554      * EventTypes into a Map. if (d1 == d2) AND (t1 == t2) => calcConstraintKey(d1, t1) ==
555      * calcConstraintKey(d2, t2).
556      *
557      * @param domain_name
558      * a <code>String</code> value
559      * @param type_name
560      * a <code>String</code> value
561      * @return an Unique Constraint Key.
562      */

563     public static String JavaDoc calcConstraintKey(String JavaDoc domain_name, String JavaDoc type_name)
564     {
565         if ("".equals(domain_name))
566         {
567             domain_name = "*";
568         }
569
570         if ("".equals(type_name))
571         {
572             type_name = "*";
573         }
574
575         StringBuffer JavaDoc _b = new StringBuffer JavaDoc(domain_name);
576
577         // insert a magic string-seperator
578
// has no meaning though
579
_b.append("_%_");
580         _b.append(type_name);
581
582         return _b.toString();
583     }
584 }
Popular Tags