Source Code Cross Referenced for Node.java in  » Scripting » oscript-2.10.4 » ti » chimera » registry » 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 » Scripting » oscript 2.10.4 » ti.chimera.registry 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*=============================================================================
002:         *     Copyright Texas Instruments 2002. All Rights Reserved.
003:         * 
004:         *  This program is free software; you can redistribute it and/or modify
005:         *  it under the terms of the GNU General Public License as published by
006:         *  the Free Software Foundation; either version 2 of the License, or
007:         *  (at your option) any later version.
008:         * 
009:         *  This program is distributed in the hope that it will be useful,
010:         *  but WITHOUT ANY WARRANTY; without even the implied warranty of
011:         *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012:         *  GNU General Public License for more details.
013:         * 
014:         *  You should have received a copy of the GNU General Public License
015:         *  along with this program; if not, write to the Free Software
016:         *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
017:         */
018:
019:        package ti.chimera.registry;
020:
021:        import ti.chimera.Main;
022:        import ti.exceptions.ProgrammingErrorException;
023:        import ti.pub.WorkerThread;
024:
025:        import java.util.LinkedList;
026:        import java.util.Iterator;
027:
028:        import javax.swing.JOptionPane;
029:
030:        /**
031:         * Base class for a node in the tree.  A node can have an optional contract,
032:         * which constraints what values can be assigned to this node.  If no
033:         * contract is specified, the null-contract (ie. accept any value) will be
034:         * used.
035:         * <p>
036:         * Clients can subscribe to the value of the node, in which case every time
037:         * the node's value is changed, the new value will be published to them.
038:         * (Also, the current value is immediately published, upon subscription.)
039:         * All changes to a node are published in the order they occur.
040:         * <p>
041:         * NOTE:  currently it is possible that a value be published to a subscriber
042:         * <i>after</i> the subscriber has been unsubscribed, but only if the change
043:         * that is being published occurred <i>before</i> the subscriber unsubscribed.
044:         * 
045:         * @author ;Rob Clark;a0873619;San Diego;;
046:         * @version 0.1
047:         */
048:        public class Node {
049:            /**
050:             * The node's contract, determines what sorts of values can be assigned to 
051:             * the node.
052:             */
053:            private NodeContract contract;
054:
055:            /**
056:             * The node's current value
057:             */
058:            private Object value;
059:
060:            /**
061:             * A description of the node.
062:             */
063:            private String comment;
064:
065:            /**
066:             * The list of paths this node is currently linked in to, starting 
067:             * with the earliest path linked to.
068:             */
069:            private LinkedList pathList = new LinkedList();
070:
071:            /**
072:             * The list of node-subscribers.
073:             */
074:            private LinkedList subscriberList = new LinkedList();
075:
076:            /**
077:             * The cached array of subscribers... this is nuked whenever the 
078:             * subscriber list changes, but we cache it to avoid repeated
079:             * toArray()s whenever the value is changed
080:             */
081:            private NodeSubscriber[] subscribers = null;
082:
083:            /*=======================================================================*/
084:            /**
085:             * Class Constructor.
086:             * 
087:             * @param value        the node's initial value
088:             * @param contract     the node's contract, or <code>null</code>
089:             * @param comment      a string containing a description of the purpose
090:             *   of this node, the node's usage, etc.  Can contain HTML markup.
091:             */
092:            public Node(Object value, NodeContract contract, String comment) {
093:                if (contract == null)
094:                    contract = NodeContract.NULL_CONTRACT;
095:
096:                this .contract = contract;
097:                this .comment = comment;
098:
099:                setValue(value);
100:            }
101:
102:            /*=======================================================================*/
103:            /**
104:             * Get the node's contract.
105:             * 
106:             * @return the <code>NodeContract</code>
107:             */
108:            public NodeContract getNodeContract() {
109:                return contract;
110:            }
111:
112:            /*=======================================================================*/
113:            /**
114:             * Get the node's comment.
115:             * 
116:             * @return a string
117:             */
118:            public String getComment() {
119:                return comment;
120:            }
121:
122:            /*=======================================================================*/
123:            /**
124:             * Set the value of this node, and publish the new value to all the
125:             * subscribers.
126:             * 
127:             * @param value        the node's new value
128:             */
129:            public void setValue(Object value) {
130:                if (!contract.accepts(value))
131:                    throw new ProgrammingErrorException("value (" + value
132:                            + ") does not meet contract (" + contract + ")");
133:
134:                synchronized (RegistryCore.lock) {
135:                    this .value = value;
136:
137:                    if (subscribers == null)
138:                        subscribers = (NodeSubscriber[]) (subscriberList
139:                                .toArray(new NodeSubscriber[subscriberList
140:                                        .size()]));
141:
142:                    publish(this , subscribers, value);
143:                }
144:            }
145:
146:            /*=======================================================================*/
147:            /**
148:             * Get the current value of the node.
149:             * 
150:             * @return the node's current value
151:             */
152:            public Object getValue() {
153:                return value;
154:            }
155:
156:            /*=======================================================================*/
157:            /**
158:             * Called by the registry before this node is linked in to the tree.  This
159:             * should not be called anywhere else, otherwise undefined behaviour may
160:             * ensue.  (Translation: <i>Nothing to see here, move along.</i>).
161:             */
162:            void link(String path) {
163:                pathList.addLast(path);
164:            }
165:
166:            /*=======================================================================*/
167:            /**
168:             * Called by the registry before this node is unlinked in from the tree.  
169:             * This should not be called anywhere else, otherwise undefined behaviour 
170:             * may ensue.  (Translation: <i>Nothing to see here, move along.</i>).
171:             */
172:            void unlink(String path) {
173:                pathList.remove(path);
174:            }
175:
176:            /**
177:             * Get the number of paths this node is linked in to.  This is used
178:             * by the registry-core because it is an error to remove the last
179:             * link to a node if it still has children.
180:             */
181:            int getPathCount() {
182:                return pathList.size();
183:            }
184:
185:            /*=======================================================================*/
186:            /**
187:             * Get the primary path of this node.  If the node is not linked into
188:             * the registry tree, then this will be <code>null</code>.  Otherwise
189:             * this will be the first path this node is linked in to but has not
190:             * yet been unlinked from.
191:             * 
192:             * @return a path or <code>null</code>.
193:             */
194:            public String getPrimaryPath() {
195:                if (pathList.size() == 0)
196:                    return null;
197:                return (String) (pathList.getFirst());
198:            }
199:
200:            /*=======================================================================*/
201:            /**
202:             * Add the subscriber to the list of registered subscribers, and 
203:             * immediately publish the current value.
204:             * 
205:             * @param s            the subscriber
206:             */
207:            public void subscribe(NodeSubscriber s) {
208:                synchronized (RegistryCore.lock) {
209:                    subscribers = null;
210:                    subscriberList.add(s);
211:                    publish(this , new NodeSubscriber[] { s }, value);
212:                }
213:            }
214:
215:            /*=======================================================================*/
216:            /**
217:             * Remove the subscriber from the list of registered subscribers.
218:             * 
219:             * @param s            the subscriber
220:             */
221:            public void unsubscribe(NodeSubscriber s) {
222:                synchronized (RegistryCore.lock) {
223:                    subscribers = null;
224:                    subscriberList.remove(s);
225:                }
226:            }
227:
228:            /*=======================================================================*/
229:            /**
230:             * Publish the <code>value</code> to the <code>subscribers</code>.  Note
231:             * that it is important how we pass the current snapshot of the value and
232:             * subscriber list, because there may be some period of time between when
233:             * this is called and when we actually publish the value (due to the fact
234:             * that we serialize publishing values), and either the current value or
235:             * the list of subscribers may change between now and when the results
236:             * actually get published.
237:             */
238:            private void publish(Node node, NodeSubscriber[] subscribers,
239:                    Object value) {
240:                if (subscribers.length > 0)
241:                    worker.invokeLater(new PublishRunnable(node, subscribers,
242:                            value));
243:            }
244:
245:            private class PublishRunnable implements  Runnable {
246:                private Node node;
247:                private NodeSubscriber[] subscribers;
248:                private Object value;
249:
250:                PublishRunnable(Node node, NodeSubscriber[] subscribers,
251:                        Object value) {
252:                    this .node = node;
253:                    this .subscribers = subscribers;
254:                    this .value = value;
255:                }
256:
257:                public void run() {
258:                    for (int i = 0; i < subscribers.length; i++)
259:                        if (subscriberList.contains(subscribers[i])) // subscriber may have already been removed
260:                            subscribers[i].publish(node, value); // since publish was scheduled!
261:                }
262:
263:                public String toString() {
264:                    return "publishing to " + node;
265:                }
266:            }
267:
268:            private static Worker worker;
269:
270:            /* note: load worker reflectively to avoid loading any class with a reference
271:             * to swing/AWT if running in a "headless" applicatioin
272:             */
273:            static {
274:                try {
275:                    worker = (Worker) (Class.forName(System.getProperty(
276:                            "ti.chimera.registry.workerClass",
277:                            "ti.chimera.registry.Node$SwingWorker"))
278:                            .newInstance());
279:                } catch (Exception e) {
280:                    e.printStackTrace();
281:                    System.exit(-1);
282:                }
283:            }
284:
285:            private interface Worker {
286:                public void invokeLater(Runnable r);
287:            }
288:
289:            public static class SwingWorker implements  Worker {
290:                public void invokeLater(Runnable r) {
291:                    javax.swing.SwingUtilities.invokeLater(r);
292:                }
293:            }
294:
295:            public static class NonSwingWorker extends WorkerThread implements 
296:                    Worker {
297:                private Runnable lastRunnable;
298:
299:                NonSwingWorker() {
300:                    super ("Registry Worker", 9, 10000);
301:                }
302:
303:                public void run(Runnable r) {
304:                    lastRunnable = r;
305:                    super .run(r);
306:                    lastRunnable = null; // note:  not in finally because we *don't* want it to be cleared if exception is thrown
307:                }
308:
309:                // XXX we can't actually kill the registry thread, or the UI will
310:                // stop working... we need to spawn a background thread to bring
311:                // up talkback in or something...
312:                public void unhandledException(final Throwable e) {
313:                    (new Thread() {
314:
315:                        public void run() {
316:                            NonSwingWorker.this .getThreadGroup()
317:                                    .uncaughtException(NonSwingWorker.this , e);
318:                        }
319:
320:                    }).start();
321:                }
322:
323:                public void watchdogTimeoutExceeded() {
324:                    System.err.println("lastRunnable=" + lastRunnable);
325:                    interrupt();
326:                }
327:            }
328:
329:            /**
330:             * For debug
331:             */
332:            public String toString() {
333:                String path = getPrimaryPath();
334:                return "[node: " + ((path != null) ? path : "<not linked>")
335:                        + "]";
336:            }
337:        }
338:
339:        /*
340:         *   Local Variables:
341:         *   tab-width: 2
342:         *   indent-tabs-mode: nil
343:         *   mode: java
344:         *   c-indentation-style: java
345:         *   c-basic-offset: 2
346:         *   eval: (c-set-offset 'substatement-open '0)
347:         *   eval: (c-set-offset 'case-label '+)
348:         *   eval: (c-set-offset 'inclass '+)
349:         *   eval: (c-set-offset 'inline-open '0)
350:         *   End:
351:         */
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.