You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

design.xml 13 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. <?xml version="1.0"?>
  2. <!--
  3. Copyright 2003-2004 The Apache Software Foundation
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. -->
  14. <document>
  15. <properties>
  16. <index value="1"/>
  17. <author email="simeon@fitch.net">Simeon H. K. Fitch</author>
  18. <author email="christoph.wilhelms@t-online.de">Christoph Wilhelms</author>
  19. <title>Design Overview</title>
  20. </properties>
  21. <body>
  22. <section name="Introduction">
  23. <p>The purpose of this document is to communicate the overall
  24. structure and design patters used in Antidote, the GUI for
  25. Ant. This document is a work in progress, as well as a living
  26. document, and it is most likely not be in full synchronization with
  27. the source code. Therefore, if there is any doubt, view the source
  28. ;-)
  29. </p>
  30. </section>
  31. <section name="Overview">
  32. <p>The Antidote architecture design aims to provide a high level
  33. of modularity and extensibility. Ideally the components of
  34. Antidote will be able to be assembled in different configurations
  35. to provide the type of application or plug-in desired.
  36. </p>
  37. <p>To achieve this modularity, a high level of decoupling is
  38. necessary. The standard UI design approach of providing separation
  39. of view (presentation) from model (data) is applied, leveraging
  40. the built-in Ant data model where possible, as well as the
  41. predefined Swing model interfaces. Furthermore, the architecture
  42. is highly event driven, whereby modules communicate via a shared
  43. communications channel.
  44. </p>
  45. <p>To a large extent, the configuration of application modules is
  46. driven by localized configuration files, allowing new modules or
  47. data views to be added, as well as providing multi-language
  48. support.
  49. </p>
  50. <p>The diagram below conveys a high altitude view of the
  51. application's structure. As the application grows, new components
  52. will be plugged in to what will be described as the <code>EventBus</code>
  53. </p>
  54. </section>
  55. <section name="Antidote Component Architecture/Event Bus">
  56. <source>
  57. +---------------+ +----------------+ +-------------+ +-------------+<br/>
  58. | | | | | | | |<br/>
  59. | ActionManager | | EventResponder | | AntModule | | AntModule |<br/>
  60. | | | | |(ProjectNav) | |(SourceEdit) |<br/>
  61. +---------------+ +----------------+ +-------------+ +-------------+<br/>
  62. | ^ ^ ^<br/>
  63. | | | |<br/>
  64. ActionEvent EventObject AntEvent AntEvent<br/>
  65. | | | |<br/>
  66. v v v v<br/>
  67. /---------------------------------------------------------------------\<br/>
  68. / \<br/>
  69. &lt; EventBus &gt;<br/>
  70. \ /<br/>
  71. \---------------------------------------------------------------------/<br/>
  72. | ^ ^ ^<br/>
  73. | | | |<br/>
  74. EventObject ChangeEvent BuildEvent EventObject<br/>
  75. | | | |<br/>
  76. v | | v<br/>
  77. +---------------+ +----------------+ +-------------+ +--------------+<br/>
  78. | | | | | | | |<br/>
  79. | Console | | ProjectProxy | | Ant | | (Your Module)|<br/>
  80. | | | | | | | |<br/>
  81. +---------------+ +----------------+ +-------------+ +--------------+
  82. </source>
  83. <p>The backbone of the application is the <code>EventBus</code>. Any
  84. component of the application can post events to the
  85. <code>EventBus</code>. Components that wish to receive events are
  86. called <code>BusMember</code>s.
  87. </p>
  88. <p>The <code>EventBus</code> will dispatch any object of type
  89. <code>java.util.Event</code>, which means that Ant <code>BuildEvent</code>
  90. objects, as well as <code>AWTEvent</code> objects can be posted (if desired). A
  91. new class of events called <code>AntEvent</code> is defined for Antidote
  92. specific events, which have the additional capability of being
  93. canceled mid-dispatch.
  94. </p>
  95. <p>Each <code>BusMember</code> must provide a <code>BusFilter</code> instance,
  96. which is the members' means of telling the bus which
  97. events it is interested in. This allows a <code>BusMember</code> to,
  98. say, only receive <code>AntEvent</code> objects.
  99. </p>
  100. <p>When a <code>BusMember</code> registers itself with the
  101. <code>EventBus</code>, it must provide a (so called) <i>interrupt
  102. level</i> which is a integer value defining a relative ordering
  103. for dispatching <code>EventObject</code>s to <code>BusMember</code>s. The
  104. purpose of this is to allow certain <code>BusMember</code> instances
  105. to see an event before others, and in the case of <code>AntEvent</code>
  106. objects, keep the event from propagating onward. The
  107. <code>EventBus</code> class defines the interrupt level constants
  108. <code>VETOING=1</code>, <code>MONITORING=5</code>, and <code>RESPONDING=10</code> to
  109. help define categories of members. The implied purpose being that:
  110. </p>
  111. <ul>
  112. <li><code>VETOING</code>: Listens for certain types of events, and
  113. may process them in a non-default manner to determine if the
  114. event should be canceled before being dispatched to the
  115. <code>RESPONDING</code> group.
  116. </li>
  117. <li><code>MONITORING</code>: Just listens for events, like a logger
  118. or status monitor.
  119. </li>
  120. <li><code>RESPONDING</code>: Process events in a default manner,
  121. knowing that the event has passed any <code>VETOING</code> members.
  122. </li>
  123. </ul>
  124. <p>Within a specific interrupt level, the order in which members will
  125. receive events is undefined. A <code>BusMember</code> may be registered
  126. at a level that is +/- of one of the defined levels, as long as it
  127. follows the constraint <code>MONITORING &lt;= interruptLevel &lt;=
  128. MAX_INTERRUPT</code>.
  129. </p>
  130. </section>
  131. <section name="Actions and ActionManager">
  132. <p>Extensive use of the <code>javax.swing.Action</code> interface is
  133. made for defining the set of menu and tool bar options that are
  134. available. The configuration file <code>action.properties</code>
  135. exists to define what should appear in the menu and toolbar, how
  136. it is displayed, and the <code>Action</code> command name that is
  137. dispatched when the user invokes that action. A class called
  138. <code>ActionManager</code> exists for not only processing the
  139. configuration file, but also for dispatching invoked action events
  140. to the <code>EventBus</code>, and for controlling the enabled state of
  141. an <code>Action</code>. When a new menu item or toolbar button is
  142. desired, first it is added to the <code>action.properties</code> file,
  143. and then the code to respond to it is added to the
  144. <code>EventResponder</code> (see below).
  145. </p>
  146. </section>
  147. <section name="Commands and EventResponder">
  148. <p>At some point in the stages of event processing, an event may
  149. require the data model to be modified, or some other task be
  150. performed. The <code>Command</code> interface is defined to classify
  151. code which performs some task or operation. This is distinct from
  152. an <code>Action</code>, which is a user request for an operation. A
  153. <code>Command</code> class is the encapsulation of the operation
  154. itself.
  155. </p>
  156. <p>When an <code>Action</code> generates an <code>ActionEvent</code>, the
  157. event is posted to the <code>EventBus</code> which delivers the event
  158. to all interested <code>BusMember</code>s. It eventually makes it to
  159. the <code>EventResponder</code> instance (registered at the
  160. <code>RESPONDING</code> interrupt level), which is responsible for
  161. translating specific events into <code>Command</code> objects, and
  162. then executing the <code>Command</code> object. For example, when the
  163. user selects the "Open..." menu option, an <code>ActionEvent</code> is
  164. generated by the Swing <code>MenuItem</code> class, which is then
  165. posted to the <code>EventBus</code> by the <code>ActionManager</code>. The
  166. <code>ActionEvent</code> is delivered to the <code>EventResponder</code>,
  167. which converts the <code>ActionEvent</code> into a <code>Command</code>
  168. instance. The <code>EventResponder</code> then calls the method
  169. <code>Command.execute()</code> to invoke the command (which displays a
  170. dialog for selecting a file to open).
  171. </p>
  172. <p>When adding new <code>Action</code>s or general tasks to the
  173. application, a <code>Command</code> object should be created to
  174. encapsulate the behavior. This includes most operations which
  175. modify the state of the data model.
  176. </p>
  177. <p>The purpose of this encapsulation is to allow the clean
  178. separation of making a request, and servicing a request. Due to
  179. various conditions in the application state, the actually response
  180. to a request may change, as well as who services it. This
  181. design approach facilitates that.
  182. </p>
  183. </section>
  184. <section name="Data Model and Views">
  185. <p><i>NB: This part of the architecture is not fleshed out very well. There
  186. needs to be a discussion of the degree to which the Antidote development
  187. should be able to impose changes on the Ant data model, and to what level
  188. that model should be mirrored in the Antidote code base. The coupling
  189. between them should be kept low, and at the same time changes to one should
  190. affect the other minimally. Still, features like property change events and
  191. bean introspection (or BeanInfo) may be needed to be added to the Ant data
  192. model. Right now the data model is encapsulated in the package
  193. <code>org.apache.tools.ant.gui.acs</code> (where "<code>acs</code>" stands for "Ant Construction Set").</i>
  194. </p>
  195. </section>
  196. <section name="Application Context">
  197. <p>In order to keep the coupling among application modules to a
  198. minimum, a single point of reference is needed for coordination
  199. and data sharing. The class <code>AppContext</code> is the catch-all
  200. class for containing the application state. Most modules and
  201. <code>Command</code> classes require an instance of the
  202. <code>AppContext</code> class. Because all state information in
  203. contained in an <code>AppContext</code> instance, multiple instances
  204. of Antidote can run inside the same JVM as long as each has it's
  205. own <code>AppContext</code>. (Interestingly, two instances of the
  206. Antidote could conceivably share an <code>AppContext</code> instance
  207. through RMI, allowing remote interaction/collaboration.)
  208. </p>
  209. </section>
  210. <section name="Configuration and ResourceManager">
  211. <p>Full "i18n" support should be assumed in modern applications,
  212. and all user viewable strings should be defined in a configuration
  213. file. For Antidote this configuration file is
  214. <code>antidote.properties</code>, which is located (with other UI
  215. resources) in the sub-package "resources".
  216. </p>
  217. <p>To aid in the lookup of text properties, as well as other
  218. resources like icons, a class called <code>ResourceManager</code> is
  219. defined. There are various convenience methods attached to this
  220. class, which will likely grow to make looking up configuration
  221. values as easy as possible.
  222. </p>
  223. <p>The organization of configuration properties is based on the
  224. fully qualified path of the class that requires the property. For
  225. example, the "about" box contains a messages, so it looks for the
  226. property "<code>org.apache.tools.ant.gui.About.message</code>" for the text
  227. message it should display. Therefore, the <code>ResourceManager</code>
  228. method <code>getString()</code> takes a <code>Class</code> instance as
  229. well as a <code>String</code> key. Please see the
  230. <code>ResourceManager</code> documentation for more information. Given
  231. this support, no user visible strings should appear in the source
  232. code itself.
  233. </p>
  234. </section>
  235. </body>
  236. </document>