Source Code Cross Referenced for BaseComponent.java in  » Web-Framework » aranea-mvc-1.1.1 » org » araneaframework » core » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Framework » aranea mvc 1.1.1 » org.araneaframework.core 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * Copyright 2006 Webmedia Group Ltd.
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:         **/package org.araneaframework.core;
016:
017:        import java.util.Collections;
018:        import java.util.HashMap;
019:        import java.util.Iterator;
020:        import java.util.Map;
021:        import org.apache.commons.collections.map.LinkedMap;
022:        import org.apache.commons.logging.Log;
023:        import org.apache.commons.logging.LogFactory;
024:        import org.araneaframework.Component;
025:        import org.araneaframework.Composite;
026:        import org.araneaframework.Environment;
027:        import org.araneaframework.Message;
028:        import org.araneaframework.Relocatable;
029:        import org.araneaframework.Scope;
030:        import org.araneaframework.core.util.ExceptionUtil;
031:
032:        /**
033:         * The base class for all Aranea components. Base entities do not make a Composite pattern 
034:         * and only provide some very basic services (mainly syncronization and messaging service)
035:         * 
036:         * @author "Toomas Römer" <toomas@webmedia.ee>
037:         * @author Jevgeni Kabanov (ekabanov <i>at</i> araneaframework <i>dot</i> org)
038:         */
039:        public abstract class BaseComponent implements  Component {
040:            //*******************************************************************
041:            // FIELDS
042:            //*******************************************************************
043:            private static final Log log = LogFactory
044:                    .getLog(BaseComponent.class);
045:
046:            private Environment environment;
047:            private Scope scope;
048:            private Map children;
049:            private Map disabledChildren;
050:
051:            private static final byte UNBORN = 1;
052:            private static final byte ALIVE = 2;
053:            private static final byte DEAD = 3;
054:
055:            private byte state = UNBORN;
056:
057:            private transient int callCount = 0;
058:            private transient int reentrantCallCount = 0;
059:            private transient ThreadLocal reentrantTLS;
060:
061:            //*******************************************************************
062:            // PUBLIC METHODS
063:            //*******************************************************************
064:            public Component.Interface _getComponent() {
065:                return new ComponentImpl();
066:            }
067:
068:            //*******************************************************************
069:            // PROTECTED METHODS
070:            //*******************************************************************
071:            /**
072:             * Init callback. Gets called when the component is initilized.
073:             */
074:            protected void init() throws Exception {
075:            }
076:
077:            /**
078:             * Destroy callback. Gets called when the component is destroyed.
079:             */
080:            protected void destroy() throws Exception {
081:            }
082:
083:            protected void disable() throws Exception {
084:            }
085:
086:            protected void enable() throws Exception {
087:            }
088:
089:            protected void propagate(Message message) throws Exception {
090:            }
091:
092:            protected void handleException(Exception e) throws Exception {
093:                throw e;
094:            }
095:
096:            /**
097:             * Returns the Environment of this BaseComponent.
098:             */
099:            public Environment getEnvironment() {
100:                return environment;
101:            }
102:
103:            public Scope getScope() {
104:                return scope;
105:            }
106:
107:            /**
108:             * Returns true, if the BaseComponent has been initialized. 
109:             */
110:            public boolean isInitialized() {
111:                return state != UNBORN;
112:            }
113:
114:            public boolean isAlive() {
115:                return state == ALIVE;
116:            }
117:
118:            public boolean isDead() {
119:                return state == DEAD;
120:            }
121:
122:            /**
123:             * Sets the environment of this BaseComponent to environment. 
124:             */
125:            protected synchronized void _setEnvironment(Environment env) {
126:                this .environment = env;
127:            }
128:
129:            /**
130:             * Sets the environment of this BaseComponent to environment. 
131:             * 
132:             * @since 1.1
133:             */
134:            protected void _setScope(Scope scope) {
135:                this .scope = scope;
136:            }
137:
138:            /**
139:             * Waits until no call is made to the component. Used to synchronize calls
140:             * to the component.
141:             */
142:            protected synchronized void _waitNoCall()
143:                    throws InterruptedException {
144:                long waitStart = System.currentTimeMillis();
145:
146:                while (callCount != reentrantCallCount) {
147:                    this .wait(1000);
148:
149:                    if (callCount != reentrantCallCount) {
150:                        log
151:                                .warn("Deadlock or starvation suspected, call count '"
152:                                        + callCount
153:                                        + "', reentrant call count '"
154:                                        + reentrantCallCount + "'");
155:
156:                        if (waitStart < System.currentTimeMillis() - 10000) {
157:                            log
158:                                    .error(
159:                                            "Deadlock or starvation not solved in 10s, call count '"
160:                                                    + callCount
161:                                                    + "', reentrant call count '"
162:                                                    + reentrantCallCount + "'",
163:                                            new AraneaRuntimeException(
164:                                                    "Deadlock or starvation suspected!"));
165:                            return;
166:                        }
167:                    }
168:                }
169:            }
170:
171:            /**
172:             * Checks if a call is valid (component is in the required state), increments the call count.
173:             */
174:            protected synchronized void _startCall()
175:                    throws IllegalStateException {
176:                _checkCall();
177:                incCallCount();
178:            }
179:
180:            /**
181:             * @since 1.1
182:             */
183:            protected synchronized void _strictStartCall()
184:                    throws IllegalStateException {
185:                _strictCheckCall();
186:                incCallCount();
187:            }
188:
189:            /**
190:             * Decrements the call count. Wakes up all threads that are waiting on
191:             * this object's monitor
192:             */
193:            protected synchronized void _endCall() {
194:                decCallCount();
195:                this .notifyAll();
196:            }
197:
198:            /**
199:             * Used for starting a call that is a re-entrant call. Meaning a call of this component
200:             * is doing the calling
201:             */
202:            protected synchronized void _startWaitingCall() {
203:                if (getReentrantCount() >= 1)
204:                    reentrantCallCount++;
205:            }
206:
207:            /**
208:             * Decrements internal callcount counter.
209:             */
210:            protected synchronized void _endWaitingCall() {
211:                if (getReentrantCount() >= 1)
212:                    reentrantCallCount--;
213:            }
214:
215:            /**
216:             * Checks if this component was initialized. If not, throws IllegalStateException.
217:             * This is relatively loose check, allowing leftover calls to dead components.
218:             * @throws IllegalStateException when component has never been initialized
219:             */
220:            protected void _checkCall() throws IllegalStateException {
221:                if (!isInitialized()) {
222:                    throw new IllegalStateException("Component '"
223:                            + getClass().getName() + "' was never initialized!");
224:                }
225:            }
226:
227:            /**
228:             * Checks if this component is currently alive. 
229:             * This is strict check that disallows leftover calls to dead components.
230:             * @throws IllegalStateException when component is unborn or dead
231:             * @since 1.1
232:             */
233:            protected void _strictCheckCall() throws IllegalStateException {
234:                if (!isAlive()) {
235:                    throw new IllegalStateException("Component '"
236:                            + getClass().getName() + "' is not alive!");
237:                }
238:            }
239:
240:            /**
241:             * Returns the children of this component.
242:             */
243:            protected Map _getChildren() {
244:                synchronized (this ) {
245:                    if (children == null)
246:                        children = Collections
247:                                .synchronizedMap(new LinkedMap(1));
248:                }
249:                return children;
250:            }
251:
252:            /**
253:             * Returns the children of this component.
254:             */
255:            protected Map _getDisabledChildren() {
256:                synchronized (this ) {
257:                    if (disabledChildren == null)
258:                        disabledChildren = Collections
259:                                .synchronizedMap(new LinkedMap(1));
260:                }
261:                return disabledChildren;
262:            }
263:
264:            /**
265:             * Adds a child component to this component with the key and initilizes it with the
266:             * specified Environment env. 
267:             */
268:            protected void _addComponent(Object key, Component component,
269:                    Environment env) {
270:                _addComponent(key, component,
271:                        new StandardScope(key, getScope()), env);
272:            }
273:
274:            /**
275:             * Adds a child component to this component with the key and initilizes it with the
276:             * specified Environment env. 
277:             * 
278:             * @since 1.1
279:             */
280:            protected void _addComponent(Object key, Component component,
281:                    Scope scope, Environment env) {
282:                Assert.notNull(this , key, "Cannot add a component of class '"
283:                        + (component == null ? null : component.getClass())
284:                        + "' under a null key!");
285:                //Only Strings are supported by this implementation
286:                Assert.isInstanceOfParam(String.class, key, "key");
287:
288:                _checkCall();
289:
290:                // cannot add a child with key that clashes with a disabled child's key
291:                if (_getChildren().containsKey(key)) {
292:                    if (_getDisabledChildren().containsKey(key))
293:                        _enableComponent(key);
294:                    _removeComponent(key);
295:                }
296:
297:                // Sequence is very important as by the time of init 
298:                // component should be in place since during init the 
299:                // component might be overridden.
300:                _getChildren().put(key, component);
301:                component._getComponent().init(scope, env);
302:            }
303:
304:            /**
305:             * Removes the childcomponent with the specified key from the children and calls destroy on it.
306:             */
307:            protected void _removeComponent(Object key) {
308:                Assert.notNullParam(this , key, "key");
309:                //Only Strings are supported by this implementation
310:                Assert.isInstanceOfParam(String.class, key, "key");
311:
312:                _checkCall();
313:
314:                Component comp = (Component) _getChildren().get(key);
315:
316:                if (comp == null) {
317:                    return;
318:                }
319:
320:                //Sequence is very important, and guarantees that there won't 
321:                //be a second destroy call if the first one doesn't succeed.
322:                _getChildren().remove(key);
323:                comp._getComponent().destroy();
324:            }
325:
326:            /**
327:             * Disables the child component with the specified key. A disabled child is a child that is removed
328:             * from the standard set of children 
329:             */
330:            protected void _disableComponent(Object key) {
331:                Assert.notNullParam(this , key, "key");
332:                //Only Strings are supported by this implementation
333:                Assert.isInstanceOfParam(String.class, key, "key");
334:
335:                _checkCall();
336:
337:                boolean enabled = _getChildren().containsKey(key);
338:                boolean disabled = _getDisabledChildren().containsKey(key);
339:
340:                if (!enabled && !disabled) {
341:                    throw new NoSuchComponentException(key);
342:                }
343:
344:                if (enabled) {
345:                    ((Component) _getChildren().get(key))._getComponent()
346:                            .disable();
347:                    _getDisabledChildren().put(key, _getChildren().remove(key));
348:                }
349:            }
350:
351:            /**
352:             * Enables a disabled child component with the specified key.
353:             * @param key
354:             */
355:            protected void _enableComponent(Object key) {
356:                Assert.notNullParam(this , key, "key");
357:                //Only Strings are supported by this implementation
358:                Assert.isInstanceOfParam(String.class, key, "key");
359:
360:                _checkCall();
361:
362:                boolean enabled = _getChildren().containsKey(key);
363:                boolean disabled = _getDisabledChildren().containsKey(key);
364:
365:                if (!disabled && !enabled) {
366:                    throw new NoSuchComponentException(key);
367:                }
368:
369:                if (disabled) {
370:                    _getChildren().put(key, _getDisabledChildren().remove(key));
371:                    ((Component) _getChildren().get(key))._getComponent()
372:                            .enable();
373:                }
374:            }
375:
376:            /**
377:             * Relocates parent's child with keyFrom to this BaseComponent with a new key keyTo. The child
378:             * will get the Environment specified by newEnv.  
379:             * @param parent is the current parent of the child to be relocated.
380:             * @param newEnv the new Environment of the child.
381:             * @param keyFrom is the key of the child to be relocated.
382:             * @param keyTo is the the key, with which the child will be added to this StandardService.
383:             */
384:            protected void _relocateComponent(Composite parent,
385:                    Environment newEnv, Object keyFrom, Object keyTo) {
386:                Assert.notNull(this , parent,
387:                        "Cannot relocate a component from under key '"
388:                                + keyFrom + "' to key '" + keyTo
389:                                + "' from a null parent!");
390:                Assert.notNull(this , parent._getComposite().getChildren().get(
391:                        keyFrom),
392:                        "The component to be relocated must be a child under key '"
393:                                + keyFrom + "'!");
394:                Assert.isTrue(this , parent._getComposite().getChildren().get(
395:                        keyFrom) instanceof  Relocatable,
396:                        "The component of class '"
397:                                + parent._getComposite().getChildren().get(
398:                                        keyFrom).getClass()
399:                                + "' to be relocated from under key '"
400:                                + keyFrom + "' to key '" + keyTo
401:                                + "' must implement Relocatable!");
402:                //Only Strings are supported by this implementation
403:                Assert.isInstanceOfParam(String.class, keyFrom, "keyFrom");
404:                Assert.isInstanceOfParam(String.class, keyTo, "keyTo");
405:
406:                Relocatable comp = (Relocatable) parent._getComposite().detach(
407:                        keyFrom);
408:                comp._getRelocatable().overrideEnvironment(newEnv);
409:
410:                _getChildren().put(keyTo, comp);
411:            }
412:
413:            protected void _propagate(Message message) {
414:                Assert.notNullParam(this , message, "message");
415:
416:                if (children == null || isDead())
417:                    return;
418:
419:                Iterator ite = (new LinkedMap(_getChildren())).keySet()
420:                        .iterator();
421:                while (ite.hasNext()) {
422:                    Object key = ite.next();
423:
424:                    Component component = (Component) _getChildren().get(key);
425:
426:                    // message has not destroyed previously existing child
427:                    if (component != null) {
428:                        message.send(key, component);
429:                    }
430:                }
431:            }
432:
433:            //*******************************************************************
434:            // PRIVATE METHODS
435:            //*******************************************************************
436:
437:            private void incCallCount() {
438:                if (reentrantTLS == null)
439:                    reentrantTLS = new ThreadLocal();
440:
441:                if (reentrantTLS.get() == null)
442:                    reentrantTLS.set(new Counter(0));
443:
444:                callCount++;
445:                ((Counter) reentrantTLS.get()).counter++;
446:
447:                if (getReentrantCount() > 1)
448:                    reentrantCallCount++;
449:            }
450:
451:            private void decCallCount() {
452:                if (getReentrantCount() > 1)
453:                    reentrantCallCount--;
454:
455:                callCount--;
456:                ((Counter) reentrantTLS.get()).counter--;
457:            }
458:
459:            private int getReentrantCount() {
460:                return (reentrantTLS == null || reentrantTLS.get() == null) ? 0
461:                        : ((Counter) reentrantTLS.get()).counter;
462:            }
463:
464:            //*******************************************************************
465:            // PROTECTED CLASSES
466:            //*******************************************************************
467:            //component implementation
468:            protected class ComponentImpl implements  Component.Interface {
469:
470:                public synchronized void init(Scope scope, Environment env) {
471:                    Assert.notNull(this , env, "Environment cannot be null!");
472:                    Assert.isTrue(this , !isInitialized(),
473:                            "Cannot initialize the component more than once!");
474:
475:                    BaseComponent.this ._setScope(scope);
476:                    BaseComponent.this ._setEnvironment(env);
477:                    state = ALIVE;
478:                    try {
479:                        BaseComponent.this .init();
480:                    } catch (Exception e) {
481:                        ExceptionUtil.uncheckException(e);
482:                    }
483:                }
484:
485:                public void destroy() {
486:                    _startWaitingCall();
487:                    _strictCheckCall();
488:
489:                    try {
490:                        /* XXX synch logic a bit weird. 
491:                         * Second call to destroy should fail, not wait. */
492:                        _waitNoCall();
493:                        synchronized (this ) {
494:                            if (children != null)
495:                                for (Iterator i = new HashMap(_getChildren())
496:                                        .keySet().iterator(); i.hasNext();) {
497:                                    _removeComponent(i.next());
498:                                }
499:
500:                            if (disabledChildren != null)
501:                                for (Iterator i = _getDisabledChildren()
502:                                        .keySet().iterator(); i.hasNext();) {
503:                                    Component comp = (Component) _getDisabledChildren()
504:                                            .get(i.next());
505:                                    if (comp != null) {
506:                                        comp._getComponent().destroy();
507:                                    }
508:                                }
509:
510:                            BaseComponent.this .destroy();
511:                        }
512:                        state = DEAD;
513:                    } catch (Exception e) {
514:                        ExceptionUtil.uncheckException(e);
515:                    } finally {
516:                        _endWaitingCall();
517:                    }
518:                }
519:
520:                public void propagate(Message message) {
521:                    _startCall();
522:                    try {
523:                        BaseComponent.this .propagate(message);
524:                    } catch (Exception e) {
525:                        ExceptionUtil.uncheckException(e);
526:                    } finally {
527:                        _endCall();
528:                    }
529:                }
530:
531:                public void enable() {
532:                    _startCall();
533:                    try {
534:                        BaseComponent.this .enable();
535:                    } catch (Exception e) {
536:                        ExceptionUtil.uncheckException(e);
537:                    } finally {
538:                        _endCall();
539:                    }
540:                }
541:
542:                public void disable() {
543:                    _startCall();
544:                    try {
545:                        BaseComponent.this .disable();
546:                    } catch (Exception e) {
547:                        ExceptionUtil.uncheckException(e);
548:                    } finally {
549:                        _endCall();
550:                    }
551:                }
552:            }
553:
554:            //*******************************************************************
555:            // PRIVATE CLASSES
556:            //*******************************************************************
557:            private static class Counter {
558:                /**
559:                 * The value of the counter
560:                 */
561:                public int counter;
562:
563:                /**
564:                 * Initializes the counter with a value.
565:                 * @param counter value of the counter
566:                 */
567:                public Counter(int counter) {
568:                    this.counter = counter;
569:                }
570:            }
571:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.