diff options
Diffstat (limited to 'projects/net.wotonomy.all/src/site')
| -rw-r--r-- | projects/net.wotonomy.all/src/site/apt/index.apt | 9 | ||||
| -rw-r--r-- | projects/net.wotonomy.all/src/site/apt/license.apt | 461 | ||||
| -rw-r--r-- | projects/net.wotonomy.all/src/site/build.xml | 175 | ||||
| -rw-r--r-- | projects/net.wotonomy.all/src/site/fml/faq.fml | 145 | ||||
| -rw-r--r-- | projects/net.wotonomy.all/src/site/resources/doc/control-guide.txt | 53 | ||||
| -rw-r--r-- | projects/net.wotonomy.all/src/site/resources/doc/ui-guide.html | 469 | ||||
| -rw-r--r-- | projects/net.wotonomy.all/src/site/resources/doc/ui-guide.txt | 341 | ||||
| -rw-r--r-- | projects/net.wotonomy.all/src/site/resources/images/standard-mvc.gif | bin | 0 -> 11657 bytes | |||
| -rw-r--r-- | projects/net.wotonomy.all/src/site/resources/images/wotonomy-er.gif | bin | 0 -> 8073 bytes | |||
| -rw-r--r-- | projects/net.wotonomy.all/src/site/resources/images/wotonomy-mvc.gif | bin | 0 -> 10332 bytes | |||
| -rw-r--r-- | projects/net.wotonomy.all/src/site/resources/index-old.html | 105 | ||||
| -rw-r--r-- | projects/net.wotonomy.all/src/site/site.xml | 37 |
12 files changed, 1795 insertions, 0 deletions
diff --git a/projects/net.wotonomy.all/src/site/apt/index.apt b/projects/net.wotonomy.all/src/site/apt/index.apt new file mode 100644 index 0000000..51005b5 --- /dev/null +++ b/projects/net.wotonomy.all/src/site/apt/index.apt @@ -0,0 +1,9 @@ + -------------------------------- + Wotonomy + -------------------------------- + + +Wotonomy + + Wotonomy is a pure java user interface framework for building both web and gui applications. It is heavily inspired by the NeXT and OpenStep APIs and it includes clean-room implementations of portions of the WebObjects and JavaClient frameworks. + diff --git a/projects/net.wotonomy.all/src/site/apt/license.apt b/projects/net.wotonomy.all/src/site/apt/license.apt new file mode 100644 index 0000000..e6be04b --- /dev/null +++ b/projects/net.wotonomy.all/src/site/apt/license.apt @@ -0,0 +1,461 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + + diff --git a/projects/net.wotonomy.all/src/site/build.xml b/projects/net.wotonomy.all/src/site/build.xml new file mode 100644 index 0000000..a71e2fb --- /dev/null +++ b/projects/net.wotonomy.all/src/site/build.xml @@ -0,0 +1,175 @@ +<?xml version="1.0" encoding="utf-8" ?> +<project name="wotonomy" default="build" basedir="."> + <!-- + <taskdef name="junit" classname="org.apache.tools.ant.taskdefs.optional.junit.JUnitTask" /> + --> + <!-- + Sets the compiler property. + Options are "classic" or "modern" or "jikes". + --> + <property name="build.compiler" value="modern"/> + <property name="project.dir.src" value="${basedir}" /> + <property name="project.dir.src.main.java" value="${project.dir.src}" /> + <property name="project.dir.src.test.java" value="${basedir}/src/test/java" /> + <property name="project.dir.target" value="${basedir}/target" /> + <property name="project.dir.classes" value="${project.dir.target}/classes" /> + <property name="project.dir.test-classes" value="${project.dir.target}/test-classes" /> + + <property name="project.dir.resources" value="${basedir}" /> + + <property name="project.dir.lib" value="${basedir}/lib" /> + + <property name="project.dir.javadoc" value="${project.dir.target}/javadoc/api-docs" /> + + <property name="project.version" value="0.5-SNAPSHOT" /> + + <property name="package.jar.filename.prefix" value="${project.dir.target}/${ant.project.name}" /> + <property name="package.jar.filename.suffix" value=".jar" /> + <property name="package.jar.filename" value="${package.jar.filename.prefix}-${project.version}${package.jar.filename.suffix}" /> + + + <!-- + Builds the entire wotonomy package. + Requires ognl.jar, servlet.jar, xerces.jar, and xp.jar. + --> + + <target name="build" description="Build all sources and build the library" depends="clean,test,package-libraries" /> + + <target name="compile-main"> + <javac destdir="${project.dir.classes}" + includes="**/*.java"> + <src path="${project.dir.src.main.java}" /> + <exclude name="src/**" /> + <exclude name="target/**" /> + <exclude name="docs/**" /> + <exclude name="${project.dir.lib}/**" /> + <classpath> + <pathelement location="${project.dir.lib}/servlet.jar" /> + <pathelement location="${project.dir.lib}/xp.jar" /> + <pathelement location="${project.dir.lib}/xerces.jar" /> + <pathelement location="${project.dir.lib}/ognl.jar" /> + </classpath> + </javac> + </target> + + + <!-- + Generates documentation for all wotonomy packages. + --> + <target name="docs" depends="javadoc" description="Original doc generation target (deprecated)" /> + <target name="javadoc"> + <mkdir dir="docs" /> + <javadoc sourcepath="." destdir="${project.dir.javadoc}" + packagenames="net.wotonomy.control.*,net.wotonomy.foundation.*,net.wotonomy.ui.*,net.wotonomy.util.*,net.wotonomy.web.*,net.wotonomy.xml.*" + windowtitle="wotonomy" + Overview="overview.html"> + <classpath> + <pathelement location="${project.dir.lib}/servlet.jar" /> + <pathelement location="${project.dir.lib}/xp.jar" /> + </classpath> + </javadoc> + </target> + + <!-- + Builds an executable jar file containing + the license file, anything in the images + directory, and everything in net/wotonomy, + but excludes all .java source files. + --> + <target name="library" depends="package" description="Original packaging target (deprecated)." /> + <target name="package" depends="compile-main"> + <property name="jar.filename.library" value="${project.dir.target}/${ant.project.name}-${project.version}.jar" /> + <delete failonerror="false" file="${jar.filename.library}" /> + <mkdir dir="${project.dir.target}" /> + <jar jarfile="${jar.filename.library}" basedir="${project.dir.resources}" + includes="license.txt" manifest="manifest.txt" /> + <jar update="true" jarfile="${jar.filename.library}" basedir="${project.dir.classes}" /> + </target> + + <target name="package-libraries" depends="compile-main"> + <jar jarfile="${package.jar.filename.prefix}_ui_components-${project.version}${package.jar.filename.suffix}" + basedir="${project.dir.resources}" includes="license.txt" /> + <jar jarfile="${package.jar.filename.prefix}_ui_components-${project.version}${package.jar.filename.suffix}" + update="true" basedir="${project.dir.classes}" includes="net/wotonomy/ui/swing/**/*.java" + excludes="net/wotonomy/ui/swing/*.java" /> + + <jar jarfile="${package.jar.filename.prefix}_datastore-${project.version}${package.jar.filename.suffix}" + basedir="${project.dir.resources}" includes="license.txt" /> + <jar jarfile="${package.jar.filename.prefix}_datastore-${project.version}${package.jar.filename.suffix}" + update="true" basedir="${project.dir.classes}" includes="net/wotonomy/datastore/**/*.java" /> + + <jar jarfile="${package.jar.filename.prefix}_foundation-${project.version}${package.jar.filename.suffix}" + basedir="${project.dir.resources}" includes="license.txt" /> + <jar jarfile="${package.jar.filename.prefix}_foundation-${project.version}${package.jar.filename.suffix}" + update="true" basedir="${project.dir.classes}" includes="net/wotonomy/foundation/**/*.java" /> + + <jar jarfile="${package.jar.filename.prefix}_control-${project.version}${package.jar.filename.suffix}" + basedir="${project.dir.resources}" includes="license.txt" /> + <jar jarfile="${package.jar.filename.prefix}_control-${project.version}${package.jar.filename.suffix}" + update="true" basedir="${project.dir.classes}" includes="net/wotonomy/control/**/*.java" /> + + <jar jarfile="${package.jar.filename.prefix}_ui-${project.version}${package.jar.filename.suffix}" + basedir="${project.dir.resources}" includes="license.txt" /> + <jar jarfile="${package.jar.filename.prefix}_ui-${project.version}${package.jar.filename.suffix}" + update="true" basedir="${project.dir.classes}" includes="net/wotonomy/ui/**/*.java" /> + + <jar jarfile="${package.jar.filename.prefix}_foundation-${project.version}${package.jar.filename.suffix}" + basedir="${project.dir.resources}" includes="license.txt" /> + <jar jarfile="${package.jar.filename.prefix}_foundation-${project.version}${package.jar.filename.suffix}" + update="true" basedir="${project.dir.classes}" includes="net/wotonomy/foundation/**/*.java" /> + + <jar jarfile="${package.jar.filename.prefix}_util-${project.version}${package.jar.filename.suffix}" + basedir="${project.dir.resources}" includes="license.txt" /> + <jar jarfile="${package.jar.filename.prefix}_util-${project.version}${package.jar.filename.suffix}" + update="true" basedir="${project.dir.classes}" includes="net/wotonomy/util/**/*.java" /> + + <jar jarfile="${package.jar.filename.prefix}_web-${project.version}${package.jar.filename.suffix}" + basedir="${project.dir.resources}" includes="license.txt" /> + <jar jarfile="${package.jar.filename.prefix}_web-${project.version}${package.jar.filename.suffix}" + update="true" basedir="${project.dir.classes}" includes="net/wotonomy/web/**/*.java" /> + + <jar jarfile="${package.jar.filename.prefix}_xml-${project.version}${package.jar.filename.suffix}" + basedir="${project.dir.resources}" includes="license.txt" /> + <jar jarfile="${package.jar.filename.prefix}_xml-${project.version}${package.jar.filename.suffix}" + update="true" basedir="${project.dir.classes}" includes="net/wotonomy/xml/**/*.java" /> +</target> + + <!-- + Deletes all class files in the wotonomy + directories, and any recognized temp files. + --> + <target name="clean"> + <delete dir="${project.dir.target}" includes="**/*"/> + </target> + + <target name="compile-test" depends="package"> + <javac destdir="${project.dir.classes}"> + <compilerarg value="-Xlint:unchecked" /> + <src path="${project.dir.src.test.java}" /> + <classpath> + <pathelement location="${project.dir.lib}/servlet.jar" /> + <pathelement location="${project.dir.lib}/xp.jar" /> + <pathelement location="${project.dir.lib}/xerces.jar" /> + <pathelement location="${project.dir.lib}/ognl.jar" /> + <pathelement location="${project.dir.lib}/junit.jar" /> + <pathelement location="${package.jar.filename}" /> + </classpath> + </javac> + </target> + + <target name="test" depends="package,compile-test"> + <echo message="TODO: Make junit tests work from ant." /> + <!-- + <junit fork="true" includeantruntime="true" haltonerror="true" haltonfailure="true" printsummary="true"> + <classpath> + <pathelement path="${package.jar.filename}" /> + <pathelement path="${project.dir.test-classes}" /> + </classpath> + </junit> + --> + </target> + + <target name="env" description="Display all properties"> + + </target> +</project> diff --git a/projects/net.wotonomy.all/src/site/fml/faq.fml b/projects/net.wotonomy.all/src/site/fml/faq.fml new file mode 100644 index 0000000..4f3f7cd --- /dev/null +++ b/projects/net.wotonomy.all/src/site/fml/faq.fml @@ -0,0 +1,145 @@ +<faqs> + <part id="about"> + <title>About the Project</title> + <faq id="about1"> + <question> + What is Wotonomy? + </question> + <answer> + <p> Wotonomy is a pure-java open-source application framework. It contains + an "Object/Relational" mapping framework (such as TopLink or hibernate). + It contains a Web Application framework that is J2EE compliant. It is, + in particular, a clean-room re-implementation of Apple's WebObjects + platform, originally written by NeXT Software, Inc. </p> + </answer> + </faq> + <faq id="about2"> + <question> + Why is it called Wotonomy? + </question> + <answer> + <p> Wotonomy is a play on WebObjects and autonomy. One of the early project + goals was to make sure that projects that relied on WebObjects would not + be jepardized by WebObjects being discontinued. At the time, Apple had + recently purchased NeXT, and their plan for WebObjects' long-term + continuity was unclear. Therefore, using Wotonomy gives a project + autonomy from WebObjects. Simple...</p> + </answer> + </faq> + <faq id="about3"> + <question> + Do I need to run Apple hardware/software to use Wotonomy? + </question> + <answer> + <p> Wotonomy is pure-java and open-source. As such, it does not rely on + any commercial software. + Wotonomy should run on any standard J2SE platform, and web-applications + written with Wotonomy should deploy to J2EE 1.2 compliant application + servers. </p> + <p>* Wotonomy currently relies on xml code from + www.jclark.com, but this is being refactored to avoid any licensing + concerns.</p> + </answer> + </faq> + <faq id="about4"> + <question> + Is this project active? Why have there been no releases for over a year? + </question> + <answer> + <p> Yes, the project is active, but all of the updates have been to CVS. + There have been few formal packaged updates, and the project has + undergone a change in active contributors.</p> + <p> CVS updates have been tapering off because the ui and + control libraries have become vey mature. (They've verifiably + saved at least one startup from extinction) Another alpha release + has been cut so that the non-CVS-using audience can take advantage + of the current state.</p> + </answer> + </faq> + <faq id="about5"> + <question> + Do you need help? How can I help? + </question> + <answer> + <p> One word: yes. Grab the source, start hacking, and send in your diffs.</p> + </answer> + </faq> + </part> + <part id="audience"> + <title>Audience</title> + <faq id="audience1"> + <question> + I'm a Java developer: what's in it for me? + </question> + <answer> + <p> Java developers will find the design patterns in wotonomy useful for + greatly reducing the complexities of data-driven application development. + Swing developers will additionally find a wealth of reusable components + that help you "go the extra mile" in creating usable and polished Swing + applications.</p> + </answer> + </faq> + <faq id="audience2"> + <question> + I'm an OpenStep developer: what's in it for me? + </question> + <answer> + <p> OpenStep developers will find that they can use familiar APIs while still + writing pure java applications. Wotonomy provides clean-room and + near-API-compatible implementations of the EOInterface/EOControl, + WebObjects, and Foundation frameworks that interoperate with and + extend the Java Swing, Servlet, and Collections packages respectively. + Wotonomy tries to be as API-compatible as possible while still tightly + integrating with Java. Wotonomy wants to make you feel at home.</p> + </answer> + </faq> + </part> + <!-- + <part id="developers"> + <title>Developers</title> + </part> + --> + <part id="misc"> + <title>Miscellaneous</title> + <faq id="misc1"> + <question> + Why not use GNUStep? + </question> + <answer> + <p> GNUStep is awesome, but it's an Objective-C framework. The Java + bridge is great, but even Apple is backpedaling on that approach + with their pure-Java version of WebObjects, due to performance + problems and conceptual difficulties in development. Additionally, + GNUStep may not be available or stable on your platform.</p> + + <p> Wotonomy has the same license (GNU Lesser Public License), and is + written completely in Java.</p> + </answer> + </faq> + <faq id="misc2"> + <question> + WebObjects is pure-java, so why would I need Wotonomy? + </question> + <answer> + <p> You don't need Wotonomy: WO5 is what wotonomy wants to be, and $499 + is an absolute steal. If your project needs this capabilities in a + complete and mature product, you should run, not walk, to your + nearest web-browser and buy a license.</p> + + <p> However, some people cannot or will not develop on Apple hardware or + software, and some people prefer to use Free Software. Moreover, + wotonomy integrates more tightly with java. For example, Foundation's + collections extend J2SE 1.3+ java.util collections, which makes coding + much nicer. There's also a lot of benefit in having source code to + see what's going on behind the scenes. The developers have learned a + heck of a lot about WebObjects by trying to implement it. </p> + + <p> Perhaps if enough people adopt wotonomy for their Java projects, + they'll see the advantage of investing in Apple technology. + Additionally, applications using wotonomy will be extremely + portable to Apple platforms. </p> + </answer> + </faq> + </part> +</faqs> + diff --git a/projects/net.wotonomy.all/src/site/resources/doc/control-guide.txt b/projects/net.wotonomy.all/src/site/resources/doc/control-guide.txt new file mode 100644 index 0000000..53d6547 --- /dev/null +++ b/projects/net.wotonomy.all/src/site/resources/doc/control-guide.txt @@ -0,0 +1,53 @@ +*Title: wotonomy user guide: control package + +*TOC + +* Introduction + +** Scope + +This document is intended to serve as a Java developer's introduction to the wotonomy control framework and how to use it to back an application built with the wotonomy ui or web frameworks with data from a database or other persistent storage mechanism. + +** Overview + +The wotonomy classes contained in the net.wotonomy.control package provide nestable editing buffers that decouple the model portion of your application from any specific persistence mechanism. + +*** Where does it fit in? + +The control package supports both the ui and web packages. Both ui and web packages can be used without the control package, but the control package enhances both significantly. The point of contact is the EODataSource, which can be used to populate both EODisplayGroups and WODisplayGroups. + +But aside from the EODataSource, the ui and control packages work in parallel. The data model objects that are observed by a display group are also observed by an editing context. The edi + + - EOObjectStore + - abstract class: encapsulates something to save changes to + - while you will work almost exclusively with editing contexts, most of the methods you will call are defined in object store. + - getting data + + - data objects are specific to the type of object store + - faulting + + - EOEditingContext + - parent is object store + - supports all methods of object store + - additional methods + - saveChanges + - hasChanges + - insertedObjects + - updatedObjects + - deletedObjects + + - object graph / edit buffer / in-place editing + - versioning of objects + - observes objects / maintains lists + + - NSNotificationCenter + - Notifications + - Subscribing + - Posting + - Center + - Queue + + + + - EODataSource + - bridge between ui and control diff --git a/projects/net.wotonomy.all/src/site/resources/doc/ui-guide.html b/projects/net.wotonomy.all/src/site/resources/doc/ui-guide.html new file mode 100644 index 0000000..992eefa --- /dev/null +++ b/projects/net.wotonomy.all/src/site/resources/doc/ui-guide.html @@ -0,0 +1,469 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> +<title>wotonomy ui user guide</title> + <meta name="author" content=""> + <meta name="GENERATOR" content = "Almost Free Text v5.06; Copyright 1996-2000 Todd Coram. All rights reserved."> +</head> +<body> + +<br><h1><a name="AFT-top"><center>wotonomy ui user guide</center></a></h1> +<!-- AFT Table of Contents (auto generated) --> +<ul> +<li> <a href="#Introduction">Introduction</a></li> +<ul> +<li> <a href="#Scope">Scope</a></li> +<li> <a href="#Overview">Overview</a></li> +<ul> +<li> <a href="#Where does it fit in?">Where does it fit in?</a></li> +<li> <a href="#A Typical MVC Java application">A Typical MVC Java application</a></li> +<li> <a href="#A Typical wotonomy Application">A Typical wotonomy Application</a></li> +<li> <a href="#Expanded Framework">Expanded Framework</a></li> +</ul> +</ul> +<li> <a href="#Using wotonomy">Using wotonomy</a></li> +<ul> +<li> <a href="#Designing Data Objects">Designing Data Objects</a></li> +<ul> +<li> <a href="#Java Bean Conventions">Java Bean Conventions</a></li> +<li> <a href="#Change Notification">Change Notification</a></li> +</ul> +<li> <a href="#Display Groups">Display Groups</a></li> +<ul> +<li> <a href="#Creating a Display Group">Creating a Display Group</a></li> +<li> <a href="#Populating a Display Group">Populating a Display Group</a></li> +<li> <a href="#Qualifying Displayed Objects">Qualifying Displayed Objects</a></li> +<li> <a href="#Handling Selection">Handling Selection</a></li> +<li> <a href="#Handling Insertions and Deletions">Handling Insertions and Deletions</a></li> +<li> <a href="#Delegate">Delegate</a></li> +</ul> +<li> <a href="#Associations">Associations</a></li> +<ul> +<li> <a href="#Creating Associations">Creating Associations</a></li> +<li> <a href="#Kinds of Associations">Kinds of Associations</a></li> +<li> <a href="#Master-Detail Associations">Master-Detail Associations</a></li> +<li> <a href="#Binding Aspects and Establishing Connections">Binding Aspects and Establishing Connections</a></li> +</ul> +<li> <a href="#Editing Contexts">Editing Contexts</a></li> +<ul> +<li> <a href="#Object Stores">Object Stores</a></li> +<li> <a href="#Creating an Editing Context">Creating an Editing Context</a></li> +</ul> +</ul> +<li> <a href="#What's next?">What's next?</a> + +</li> +</ul> +<h2><a name="Introduction">Introduction</a></h2> +<h3><a name="Scope">Scope</a></h3> +<p> +This document is intended to serve as a Java developer's introduction to the wotonomy user interface framework and how to use it to build a graphical user interface application with Swing. +</p> +<!--End Section h3--> +<h3><a name="Overview">Overview</a></h3> +<p> +The wotonomy user interface package contained in net.wotonomy.ui provides a design pattern that further abstracts and decouples the model, view, and controller portions of a graphical user interface application. It lets you do more with less code. +</p> +<h4><a name="Where does it fit in?">Where does it fit in?</a></h4> +<p> +Let's begin by looking at the standard model-view-controller (MVC) architecture, and then we'll look at how the design changes with wotonomy. +</p> +<!--End Section h4--> +<h4><a name="A Typical MVC Java application">A Typical MVC Java application</a></h4> +<p> +A typical Java application can be described in a very high-level way as simply reading a bunch of data objects into memory from the file system or JDBC or elsewhere and rendering a graphical representation of the data for the user. Additionally, the user may be allowed to edit some or all the data represented, and in that case the modifications are copied back from whence they were read. +</p> +<img src="images/standard-mvc.gif" alt="" align=bottom> +<p> +In MVC parlance, the model is an object-oriented representation of your data and business logic. In the typical application example, the data objects are the model. To afford maximum reuse, these data objects have no knowledge of and no dependencies on the view or controller portions of your application. In the Enterprise Java Bean (EJB) world, entity beans are usually good examples of data objects. +</p> +<p> +The view is the user interface of your application, where the data objects are represented on screen using labels, text fields, sliders, and the like. While you might need to know a little bit about the data you are trying to visualize when constructing the user interface, the view classes have no code dependencies on the data object classes in the model. And the view similarly has no code dependencies on the controller. To afford maximum flexibility, the view consists only of the Swing components arranged in the proper layouts and nothing more. +</p> +<p> +The controller, on the other hand, contains the logic specific to the Java Swing application you are writing, and it is tightly coupled with and has deep code dependencies on the model and view. +</p> +<p> +The controller is responsible for fetching the data objects that will be viewed or edited, and is responsible for populating each user interface component in the view with data from the data objects. This means that the controller directly calls methods on both the model's data objects and the view's user interface components. +</p> +<p> +If the application supports editing, the controller is responsible for even more. It must detect changes to the view, like edited text fields or moved sliders, and update the model to reflect the changes. And it must detect changes in the model and update the view components accordingly (especially for side-effect changes like a task's status changing in the data model when the user assigns a worker). These responsibilities deepen the couplings with both the model and the view. +</p> +<p> +Furthermore, the controller must track commits and reverts of sets of changes to the data model, and it must track lists of edited, added, and deleted objects to efficiently update the persistent data store. And these responsibilities deepen the complexity of the logic contained in the controller. +</p> +<!--End Section h4--> +<h4><a name="A Typical wotonomy Application">A Typical wotonomy Application</a></h4> +<p> +Because so much code resides in the controller portion of an application, and because the controller is the least generic and therefore least reusable code in an application, wotonomy is designed to abstract and simplify the responsibilities of the controller to reduce the cost of writing and maintaining it. +</p> +<img src="images/wotonomy-mvc.gif" alt="" align=bottom> +<p> +With wotonomy, the only requirement on the model portion of your application is that the data objects adhere to Java Bean naming conventions for properties. Wotonomy further decouples your model from the rest of your application by working with it only through the use of bean properties. +</p> +<p> +The view portion of your application remains the same. The controller portion, however, is vastly simplified. +</p> +<p> +The fetched data objects are placed into an EditingContext. The editing context monitors the objects for changes, and tracks insertions and deletions, and handles commits and reverts. The controller is only responsible for providing the glue to allow the editing context to talk to whatever persistent object storage is used for the application. If your data is read only or if your data model is fairly simple, then the editing context can be omitted and your job is even easier. +</p> +<p> +A DisplayGroup then retrieves some or all of those objects from the EditingContext. A display group maintains an ordered collection of objects, monitoring them for changes. The display group additionally tracks the concept of selection: a subset of objects in the display group are selected, and the selection might contain zero, one, many, or all objects in the group. The display group broadcasts notifications of changes to the data object or to the selection to interested listeners. The controller is only responsible for creating the display group and deciding what objects from the editing context should be placed in the group. +</p> +<p> +An Association is then created for each user interface component in the view. Each association is bound to the display group as a listener for change notifications. Different types of associations correspond to different kinds of user interface objects: a JTextField with a TextAssociation will display the value of a property for the selected object in the bound display group, while a TableColumn with a TableColumnAssociation will display the value of a property for all objects in the bound display group, highlighting those objects that are selected. The controller is only responsible for creating the associations, connecting them to the user interface components, and binding them to the display group. +</p> +<p> +Your controller will not need to directly touch any data objects, and will only need to access the view to get references to the user interface components and pass them on to the associations. After all the pieces are connected, they'll just work and it's pretty much fire and forget. +</p> +<!--End Section h4--> +<h4><a name="Expanded Framework">Expanded Framework</a></h4> +<p> +On the whole, an application may have one or more editing contexts, each of which may be used by one or more display groups, each of which is observed by one or more associations, each of which is connected to a single user interface component. But there's a little more to this story. +</p> +<img src="images/wotonomy-er.gif" alt="" align=bottom> +<p> +As the diagram shows, a display group actually has a data source which has an editing context, and editing contexts have object stores which can in turn be editing contexts. This means that editing contexts can be nested within one another. And there are associations that can control a display group instead of a Swing component, which means that display groups can also be nested. +</p> +<p> +However, you can write a fully-functional application using just display groups and associations, skipping the editing contexts and data sources completely. +</p> +<p> +Wotonomy makes the simple things easy while still making complex things possible. +</p> +<!--End Section h4--> +<!--End Section h3--> +<!--End Section h2--> +<h2><a name="Using wotonomy">Using wotonomy</a></h2> +<p> +Wotonomy is a design pattern as well as a Java library, so you'll want to understand how to structure your application to best leverage the framework. +</p> +<h3><a name="Designing Data Objects">Designing Data Objects</a></h3> +<p> +In short, any objects that have getter and setter methods can be used in a display group. Your objects probably have those already. Even better are objects that use Java Bean naming conventions to define properties. You probably do that too. For change notifications, extending java.util.Observable is helpful, but since your objects probably don't already do that, there is an alternate way to post change notifications. Or you can choose to not post notifications at all. The requirements of wotonomy on your data model are minimal. +</p> +<h4><a name="Java Bean Conventions">Java Bean Conventions</a></h4> +<p> +A java bean property is defined by having a method of the form getProperty() where Property is the name of the property, for example, a name property is defined by the method getName(). The get method can have no parameters and the return type defines the type of the property. (The alternate form for getters that omits the get in the method name, e.g. property(), is also supported.) +</p> +<p> +An editable property is defined by additionally having a method of the form setProperty( Object aProperty ) where the return value is void and the type of the parameter matches the type of the getter method. (When a property has a getter method but no setter method, that property is considered-read only.) +</p> +<p> +An indexed property works the same way but the type is either an Array (like Object[] or String[]) or a Collection (like Set or List). Indexed properties typically define one-to-many relationships in your data model. Indexed properties are useful for nested display groups and recursive tree associations. +</p> +<!--End Section h4--> +<h4><a name="Change Notification">Change Notification</a></h4> +<p> +The Java way for objects to post change notifications is to extend java.util.Observable and call notifyObservers() after your change has taken place. If your data object extends Observable, DisplayGroups will register themselves as observers and expect notifications for changes that occur to the object, whether from user interaction or from external influence. +</p> +<p> +The Observable approach may be undesirable if you need to subclass a third party object that does not extend Observable or if you don't want a strong reference to an observer from your data object that may need to be manually cleared later. +</p> +<p> +For objects that do not extend Observer, you can get much the same effect by calling the static method <a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EOObserverCenter.html#notifyObserversObjectWillChange">EOObserverCenter.notifyObserversObjectWillChange()</a> before your change takes place. +</p> +<p> +Wotonomy uses <a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EOObserverCenter.html">EOObserverCenter</a> exclusively within the framework and it presents a preferrable alternative to Observable because it uses weak references to track objects and it relaxes the requirement that observed objects extend a particular class by requiring that observing objects implement the EOObserving interface. The EOObserverCenter can also coalesce change events if the observing object extends <a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EODelayedObserver.html">EODelayedObserver</a>. +</p> +<p> +Please note that if your object does not post change notifications, most of wotonomy will continue to work. The only problem will then be that changes external to wotonomy - changes made to your data model by your data model or by a timed refresh or something similar - will not be automatically reflected in the user interface. Manually calling <a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/EODisplayGroup.html#updateDisplayedObjects">EODisplayGroup.updateDisplayedObjects()</a> can refresh the display. +</p> +<!--End Section h4--> +<!--End Section h3--> +<h3><a name="Display Groups">Display Groups</a></h3> +<p> +<a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/EODisplayGroup.html">Display groups</a> are objects that manage an ordered list of data objects. Of this list, a subset are considered to be "displayed" objects that are visible to the user. Of the displayed objects, a subset are considered "selected". In common usage, all of the objects are displayed, but only one object and sometimes no objects are selected. +</p> +<p> +Display groups monitor changes to the list, changes to what objects are in the list, changes to which objects are selected, as well as changes to the properties of the objects themselves, and notify any bound associations of these changes. +</p> +<p> +If the display group has a delegate, the delegate is informed of these changes and more so that the delegate can fine-tune the behavior of the display group. +</p> +<h4><a name="Creating a Display Group">Creating a Display Group</a></h4> +<p> +A display group is created very simply with the default constructor. +This creates a display group with no data source, no delegate, and no objects to manage. +</p> +<pre> + EODisplayGroup displayGroup = new EODisplayGroup(); +</pre> +<!--End Section h4--> +<h4><a name="Populating a Display Group">Populating a Display Group</a></h4> +<p> +You can populate the display group with objects in two ways. +</p> +<p> +The direct way is easiest. Simply pass in a List containing the objects to be managed in the order they should appear. +</p> +<pre> + List objectList = new LinkedList(); + objectList.add( new TestObject() ); + displayGroup.setObjectArray( objectList ); +</pre> +<p> +Alternately, you can specify a data source for the display group to use to retrieve objects. +</p> +<p> +<a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EODataSource.html">EODataSource</a> is an abstract class that you will extend with methods to create, insert, and delete objects from whatever persistent object store you are using. This class is particularly useful for rendering recursive tree-like object relationships that the data objects do not explicitly model. +</p> +<p> +If you will be using an editing context, you will need to use a data source. +</p> +<pre> + EODataSource dataSource = new MyDataSource(); + displayGroup.setDataSource( dataSource ); + displayGroup.fetch(); +</pre> +<!--End Section h4--> +<h4><a name="Qualifying Displayed Objects">Qualifying Displayed Objects</a></h4> +<p> +The displayed objects are a subset of the list of objects that the display group manages. By default all objects are displayed. +</p> +<p> +You can change this behavior by specifying a qualifier for the display group. This is an instance of <a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EOQualifier.html">EOQualifier</a> and it will have evaluateWithObject called for every object in the display group. Only those objects for which the return value is true will be in the displayed objects list. Call updateDisplayedObjects() on the display group to apply the qualifier. +</p> +<p> +You would typically use this feature when you want to preload a large number of data objects into the display group so that the user can quickly and repeatedly apply different filters to sift through the data. +</p> +<pre> + // show only Powers in San Antonio + + Map matchValues = new HashMap(); + matchValues.put( "lastName", "Powers" ); + matchValues.put( "city", "San Antonio" ); + + EOQualifier qualifier = + EOQualifier.qualifierToMatchAllValues( matchValues ); + displayGroup.setQualifier( qualifier ); + displayGroup.updateDisplayedObjects(); +</pre> +<!--End Section h4--> +<h4><a name="Handling Selection">Handling Selection</a></h4> +<p> +Display groups also track which of the displayed objects are selected. By default no objects are selected, but you can change the selection programmatically. Certain associations allow the user to change the selection as well. +</p> +<p> +If you do not provide the user with an association that can change the selection, you should make sure to set the selection to some object. +</p> +<pre> + // select all objects + displayGroup.setSelectedObjects( + displayGroup.displayedObjects() ); + + // select the third object + List selectionList = new LinkedList(); + selectionList.add( new Integer( 2 ) ); + displayGroup.setSelectedIndexes( selectionList ); + + // select the next object + displayGroup.selectNext(); + + // clear the selection + displayGroup.clearSelection(); +</pre> +<!--End Section h4--> +<h4><a name="Handling Insertions and Deletions">Handling Insertions and Deletions</a></h4> +<p> +You can programmatically insert or delete objects from a display group, although only if they are displayed. Any associations that display all of the displayed objects (like TableColumns) will be updated automatically. +</p> +<p> +Deleted objects that were selected are removed from the selection. Inserted objects are not selected, so you will need to select them manually if desired. Default values for inserted objects can be specified with setInsertedObjectDefaultValues(). +</p> +<p> +If a data source is used, the data source will be informed of the insertion or deletion, which will notify the editing context if it has one, which would update the persistent store on commit. +</p> +<p> +Also, if a data source is used, the display group can be asked to simply create an object to be inserted into the group, which will call createObject() on the data source. +</p> +<pre> + // insert an object + displayGroup.insertObjectAtIndex( new TestObject(), 0 ); + + // delete that object + displayGroup.deleteObjectAtIndex(); + + // select the next object + displayGroup.selectNext(); + + // delete that object + displayGroup.deleteSelection(); + + // insert a new object + displayGroup.insertNewObjectAtIndex( 0 ); +</pre> +<!--End Section h4--> +<h4><a name="Delegate">Delegate</a></h4> +<p> +Display groups check with their delegate before performing almost any operation, you can easily customize the behavior of a display group by providing a class that implements the <a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/EODisplayGroup.Delegate.html">DisplayGroup.Delegate</a> interface. +</p> +<p> +Display groups ask their delegate for permission to fetch, insert, delete, edit, create, and change selection, and then notify their delegate after each of these operations has taken place. Wotonomy provides a DelegateAdapter class that you can easily subclass to implement the required interface. +</p> +<!--End Section h4--> +<!--End Section h3--> +<h3><a name="Associations">Associations</a></h3> +<p> +<a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/EOAssociation.html">Associations</a> are the bridge between the controller and the view. An association has exactly one "controlled object", which is usually a user interface component. They also have one or sometimes more "aspects", each of which has a name, like ValueAspect or EnabledAspect. +You bind an aspect of an association with a display group and/or a key. Then you establish the connection between the association and the controlled object and you're done and you can forget about it. The association will keep the user interface object synchronized with the objects in the display group. +</p> +<h4><a name="Creating Associations">Creating Associations</a></h4> +<p> +You create an association by calling the constructor of the subclass of EOAssociation that is appropriate for the controlled object. Most associations are applicable to many kinds of objects, so the constructor is expected to take an Object. (This means that if you specify the wrong kind of object for the association, you won't hear about it until runtime.) +</p> +<pre> + EOAssociation association = new TextAssociation( textField ); +</pre> +<!--End Section h4--> +<h4><a name="Kinds of Associations">Kinds of Associations</a></h4> +<p> +Associations fall into one of two categories: overview associations and detail associations. Almost all associations are used to control some kind of user interface component. +</p> +<p> +Overview associations show some property of all the items in the display group. Overview associations usually allow the user to select and deselect objects in the display group. +</p> +<p> +For example, a JList might be used with a <a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/swing/ListAssociation.html">ListAssociation</a> to show the "name" property of all of the displayed objects in the display group, in the same order. Clicking the fourth name in the list would cause the fourth object in the display group to be selected, and - depending on the JList's selection model - cause whatever was previously selected to become unselected. +</p> +<p> +Detail associations show some property of only the first selected object in the display group. If there is no selection, the detail association causes the controlled component to be blank or otherwise empty. If multiple objects are selected, the detail association shows the property of only the first object in the selected objects list. +</p> +<p> +In our example, a JTextField might be used with a <a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/swing/TextAssociation.html">TextAssociation</a> to display the "email" property of the selected item in the display group. Clicking the fourth name in the list causes the fourth item in the display group to be selected, which populates the text field with the value of the email property for that object. Changing the value in the text field changes the value of that object's email property automatically. +</p> +<!--End Section h4--> +<h4><a name="Master-Detail Associations">Master-Detail Associations</a></h4> +<p> +While nearly all associations control user interface components, the <a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/MasterDetailAssociation.html">MasterDetailAssociation</a> is worthy of note because it does not. +</p> +<p> +A MasterDetailAssociation controls a display group and binds to an indexed property of the objects in another display group. It is a detail association, with the bound display group as the "master" and the controlled display group as the "detail" component. +</p> +<p> +Again using our example, another JList might be used with a ListAssociation to show all the dependents of the person selected in the first JList. +</p> +<p> +First we would create a new display group and then create a MasterDetailAssociation with our new display group as the parameter to the constructor. Then we would bind that association to our original master display group with the "dependents" property (assuming there is a method on our data object called getDependents() that returns an array or a collection of objects). Then we would create our new ListAssociation controlling our new JList, and bind that to our new display group with the "name" property. Seeing the source might make this clearer - that's coming in the next section. +</p> +<p> +Clicking on a name in the name list would then display the email address in the text field and a list of names of all the dependents. +</p> +<!--End Section h4--> +<h4><a name="Binding Aspects and Establishing Connections">Binding Aspects and Establishing Connections</a></h4> +<p> +An association has one or more aspects. Most of the time, you'll just need one aspect, sometimes called the "primary aspect". Aspects are referred to by name, like ValueAspect, and the names of an association's aspects are static members of that association's class. +</p> +<p> +The primary aspect is usually responsible for populating the controlled object with data from the display group. The other aspects are useful, but they'll do different things depending on the nature of the association, so you should consult the documentation for the association you will be using. +</p> +<p> +To bind an aspect, you call bindAspect() with the name of the aspect, a display group and a string "key". +</p> +<p> +Usually, all three are specified, and the key is a property name. The association will display or edit the value of this property for the objects in the display group. +</p> +<p> +The key may be an empty string, and this is considered the "identity property", and the value of the actual object in the display group will be used instead of a property on that object. This is sometimes useful for view components like JTrees for which you want to write custom renderers: with the identity property, the renderer receives the value of the actual object. +</p> +<p> +The display group may be left null, in which case the key is treated as a value, acting as if all objects in the display group for the given property returned that value. This is useful for certain aspects of certain associations, like the EnabledAspect of <a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/swing/TextAssociation.html">TextAssociation</a>, or the EditableAspect of <a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/swing/TableColumnAssociation.html">TableColumnAssociation</a>. +</p> +<p> +After all the aspects have been bound, you need to call establishConnection() to put the association to work. Importantly, you do not need to retain a reference to the associations you create - they will exist as long as their controlled components exist, and when the controlled component is garbage collected, the association will be garbage collected. +</p> +<pre> + // set up the master display group + EODisplayGroup masterGroup = new EODisplayGroup(); + masterGroup.setObjectArray( getMyUsers() ); + + EOAssociation association; + + // set up names list + association = new ListAssociation( usersList ); + association.bindAspect( + EOAssociation.TitlesAspect, masterGroup, "name" ); + association.establishConnection(); + + // set up email field and for fun make it non-editable + association = new TextAssociation( emailField ); + association.bindAspect( + EOAssociation.ValueAspect, masterGroup, "email" ); + association.bindAspect( + EOAssociation.EditableAspect, null, "false" ); + association.establishConnection(); + + // set up detail display group + EODisplayGroup detailGroup = new EODisplayGroup(); + association = new MasterDetailAssociation( detailGroup ); + association.bindAspect( + EOAssociation.ParentAspect, masterGroup, "dependents" ); + association.establishConnection(); + + // set up dependents' names list + association = new ListAssociation( dependentsList ); + association.bindAspect( + EOAssociation.TitlesAspect, detailGroup, "name" ); + association.establishConnection(); + + // we're done! +</pre> +<!--End Section h4--> +<!--End Section h3--> +<h3><a name="Editing Contexts">Editing Contexts</a></h3> +<p> +<a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EOEditingContext.html">Editing contexts</a> allow multiple display groups to manipulate the same set of objects, such that objects edited in one display group are updated in the associations of all other display groups that contain that object. +</p> +<p> +Editing contexts monitor all inserts, edits, and deletes in the display groups that use them, allowing these sets of changes to be committed or rolled-back as a single transaction. +</p> +<p> +Furthermore, editing contexts can be nested, so that a new editing context will reflect the existing state of another editing context, but all changes made to the new context are not applied to the parent context until they have been committed in the child context. +</p> +<h4><a name="Object Stores">Object Stores</a></h4> +<p> +Two concepts are critical to an understanding of editing contexts: (1) An editing context must have an object store, and (2) an editing context is an object store. +</p> +<p> +Because you need an object store to instantiate an editing context, there must be some implementation of <a href="http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EOObjectStore.html">EOObjectStore</a> that is not an editing context. That object store will be responsible for directly reading and writing to the persistent storage. +</p> +<p> +Because editing contexts do implement object stores, you can then create other editing contexts that use the first editing context, which uses the first object store. This is what allows editing contexts to be nest. +</p> +<!--End Section h4--> +<h4><a name="Creating an Editing Context">Creating an Editing Context</a></h4> +<p> +To use an editing context in your application, you must create an object store. Your implementation of EOObjectStore will act as the glue between wotonomy and whatever persistent storage mechanism your application uses. +</p> +<p> +You will then create your primary editing context, specifying your object store as the parameter to the constructor. You will probably have only one object store per application, and one primary editing context that uses it. Any other editing contexts you create will use your primary context as their object store. +</p> +<pre> + // initial application setup + EOObjectStore objectStore = new MyObjectStore(); + EOEditingContext mainContext = new EOEditingContext( objectStore ); + + // set up a child display group + EOEditingContext childContext = new EOEditingContext( mainContext ); + EODataSource dataSource = new MyDataSource( childContext ); + EODisplayGroup displayGroup = new EODisplayGroup(); + displayGroup.setDataSource( dataSource ); + displayGroup.fetch(); +</pre> +<!--End Section h4--> +<!--End Section h3--> +<!--End Section h2--> +<h2><a name="What's next?">What's next?</a></h2> +<p> +This document gives you a very basic overview and brief introduction to the major players in the wotonomy user interface framework. You'll probably want to check out the <a href="http://wotonomy.sourceforge.net/docs">API Reference</a> + next +</p> +<!--End Section h2--> +<br> +<hr> +<center><small><em> +This document was generated using <a href="http://www.maplefish.com/todd/aft.html">AFT v5.06</a> +</em></small></center> +</body> +</html> + diff --git a/projects/net.wotonomy.all/src/site/resources/doc/ui-guide.txt b/projects/net.wotonomy.all/src/site/resources/doc/ui-guide.txt new file mode 100644 index 0000000..d9d0bb1 --- /dev/null +++ b/projects/net.wotonomy.all/src/site/resources/doc/ui-guide.txt @@ -0,0 +1,341 @@ +*Title: wotonomy user guide: ui package + +*TOC + +* Introduction + +** Scope + +This document is intended to serve as a Java developer's introduction to the wotonomy user interface framework and how to use it to build a graphical user interface application with Swing. + +** Overview + +The wotonomy user interface package contained in net.wotonomy.ui provides a design pattern that further abstracts and decouples the model, view, and controller portions of a graphical user interface application. It lets you do more with less code. + +*** Where does it fit in? + +Let's begin by looking at the standard model-view-controller (MVC) architecture, and then we'll look at how the design changes with wotonomy. + +*** A Typical MVC Java application + +A typical Java application can be described in a very high-level way as simply reading a bunch of data objects into memory from the file system or JDBC or elsewhere and rendering a graphical representation of the data for the user. Additionally, the user may be allowed to edit some or all the data represented, and in that case the modifications are copied back from whence they were read. + +*Image: images/standard-mvc.gif + +In MVC parlance, the model is an object-oriented representation of your data and business logic. In the typical application example, the data objects are the model. To afford maximum reuse, these data objects have no knowledge of and no dependencies on the view or controller portions of your application. In the Enterprise Java Bean (EJB) world, entity beans are usually good examples of data objects. + +The view is the user interface of your application, where the data objects are represented on screen using labels, text fields, sliders, and the like. While you might need to know a little bit about the data you are trying to visualize when constructing the user interface, the view classes have no code dependencies on the data object classes in the model. And the view similarly has no code dependencies on the controller. To afford maximum flexibility, the view consists only of the Swing components arranged in the proper layouts and nothing more. + +The controller, on the other hand, contains the logic specific to the Java Swing application you are writing, and it is tightly coupled with and has deep code dependencies on the model and view. + +The controller is responsible for fetching the data objects that will be viewed or edited, and is responsible for populating each user interface component in the view with data from the data objects. This means that the controller directly calls methods on both the model's data objects and the view's user interface components. + +If the application supports editing, the controller is responsible for even more. It must detect changes to the view, like edited text fields or moved sliders, and update the model to reflect the changes. And it must detect changes in the model and update the view components accordingly (especially for side-effect changes like a task's status changing in the data model when the user assigns a worker). These responsibilities deepen the couplings with both the model and the view. + +Furthermore, the controller must track commits and reverts of sets of changes to the data model, and it must track lists of edited, added, and deleted objects to efficiently update the persistent data store. And these responsibilities deepen the complexity of the logic contained in the controller. + +*** A Typical wotonomy Application + +Because so much code resides in the controller portion of an application, and because the controller is the least generic and therefore least reusable code in an application, wotonomy is designed to abstract and simplify the responsibilities of the controller to reduce the cost of writing and maintaining it. + +*Image: images/wotonomy-mvc.gif + +With wotonomy, the only requirement on the model portion of your application is that the data objects adhere to Java Bean naming conventions for properties. Wotonomy further decouples your model from the rest of your application by working with it only through the use of bean properties. + +The view portion of your application remains the same. The controller portion, however, is vastly simplified. + +The fetched data objects are placed into an EditingContext. The editing context monitors the objects for changes, and tracks insertions and deletions, and handles commits and reverts. The controller is only responsible for providing the glue to allow the editing context to talk to whatever persistent object storage is used for the application. If your data is read only or if your data model is fairly simple, then the editing context can be omitted and your job is even easier. + +A DisplayGroup then retrieves some or all of those objects from the EditingContext. A display group maintains an ordered collection of objects, monitoring them for changes. The display group additionally tracks the concept of selection: a subset of objects in the display group are selected, and the selection might contain zero, one, many, or all objects in the group. The display group broadcasts notifications of changes to the data object or to the selection to interested listeners. The controller is only responsible for creating the display group and deciding what objects from the editing context should be placed in the group. + +An Association is then created for each user interface component in the view. Each association is bound to the display group as a listener for change notifications. Different types of associations correspond to different kinds of user interface objects: a JTextField with a TextAssociation will display the value of a property for the selected object in the bound display group, while a TableColumn with a TableColumnAssociation will display the value of a property for all objects in the bound display group, highlighting those objects that are selected. The controller is only responsible for creating the associations, connecting them to the user interface components, and binding them to the display group. + +Your controller will not need to directly touch any data objects, and will only need to access the view to get references to the user interface components and pass them on to the associations. After all the pieces are connected, they'll just work and it's pretty much fire and forget. + +*** Expanded Framework + +On the whole, an application may have one or more editing contexts, each of which may be used by one or more display groups, each of which is observed by one or more associations, each of which is connected to a single user interface component. But there's a little more to this story. + +*Image: images/wotonomy-er.gif + +As the diagram shows, a display group actually has a data source which has an editing context, and editing contexts have object stores which can in turn be editing contexts. This means that editing contexts can be nested within one another. And there are associations that can control a display group instead of a Swing component, which means that display groups can also be nested. + +However, you can write a fully-functional application using just display groups and associations, skipping the editing contexts and data sources completely. + +Wotonomy makes the simple things easy while still making complex things possible. + +* Using wotonomy + +Wotonomy is a design pattern as well as a Java library, so you'll want to understand how to structure your application to best leverage the framework. + +** Designing Data Objects + +In short, any objects that have getter and setter methods can be used in a display group. Your objects probably have those already. Even better are objects that use Java Bean naming conventions to define properties. You probably do that too. For change notifications, extending java.util.Observable is helpful, but since your objects probably don't already do that, there is an alternate way to post change notifications. Or you can choose to not post notifications at all. The requirements of wotonomy on your data model are minimal. + +*** Java Bean Conventions + +A java bean property is defined by having a method of the form getProperty() where Property is the name of the property, for example, a name property is defined by the method getName(). The get method can have no parameters and the return type defines the type of the property. (The alternate form for getters that omits the get in the method name, e.g. property(), is also supported.) + +An editable property is defined by additionally having a method of the form setProperty( Object aProperty ) where the return value is void and the type of the parameter matches the type of the getter method. (When a property has a getter method but no setter method, that property is considered-read only.) + +An indexed property works the same way but the type is either an Array (like Object[] or String[]) or a Collection (like Set or List). Indexed properties typically define one-to-many relationships in your data model. Indexed properties are useful for nested display groups and recursive tree associations. + +*** Change Notification + +The Java way for objects to post change notifications is to extend java.util.Observable and call notifyObservers() after your change has taken place. If your data object extends Observable, DisplayGroups will register themselves as observers and expect notifications for changes that occur to the object, whether from user interaction or from external influence. + +The Observable approach may be undesirable if you need to subclass a third party object that does not extend Observable or if you don't want a strong reference to an observer from your data object that may need to be manually cleared later. + +For objects that do not extend Observer, you can get much the same effect by calling the static method {-EOObserverCenter.notifyObserversObjectWillChange()@http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EOObserverCenter.html#notifyObserversObjectWillChange-} before your change takes place. + +Wotonomy uses {-EOObserverCenter@http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EOObserverCenter.html-} exclusively within the framework and it presents a preferrable alternative to Observable because it uses weak references to track objects and it relaxes the requirement that observed objects extend a particular class by requiring that observing objects implement the EOObserving interface. The EOObserverCenter can also coalesce change events if the observing object extends {-EODelayedObserver@http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EODelayedObserver.html-}. + +Please note that if your object does not post change notifications, most of wotonomy will continue to work. The only problem will then be that changes external to wotonomy - changes made to your data model by your data model or by a timed refresh or something similar - will not be automatically reflected in the user interface. Manually calling {-EODisplayGroup.updateDisplayedObjects()@http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/EODisplayGroup.html#updateDisplayedObjects-} can refresh the display. + +** Display Groups + +{-Display groups@http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/EODisplayGroup.html-} are objects that manage an ordered list of data objects. Of this list, a subset are considered to be "displayed" objects that are visible to the user. Of the displayed objects, a subset are considered "selected". In common usage, all of the objects are displayed, but only one object and sometimes no objects are selected. + +Display groups monitor changes to the list, changes to what objects are in the list, changes to which objects are selected, as well as changes to the properties of the objects themselves, and notify any bound associations of these changes. + +If the display group has a delegate, the delegate is informed of these changes and more so that the delegate can fine-tune the behavior of the display group. + +*** Creating a Display Group + +A display group is created very simply with the default constructor. +This creates a display group with no data source, no delegate, and no objects to manage. + +^<< + EODisplayGroup displayGroup = new EODisplayGroup(); +^>> + +*** Populating a Display Group + +You can populate the display group with objects in two ways. + +The direct way is easiest. Simply pass in a List containing the objects to be managed in the order they should appear. + +^<< + List objectList = new LinkedList(); + objectList.add( new TestObject() ); + displayGroup.setObjectArray( objectList ); +^>> + +Alternately, you can specify a data source for the display group to use to retrieve objects. + +{-EODataSource@http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EODataSource.html-} is an abstract class that you will extend with methods to create, insert, and delete objects from whatever persistent object store you are using. This class is particularly useful for rendering recursive tree-like object relationships that the data objects do not explicitly model. + +If you will be using an editing context, you will need to use a data source. + +^<< + EODataSource dataSource = new MyDataSource(); + displayGroup.setDataSource( dataSource ); + displayGroup.fetch(); +^>> + +*** Qualifying Displayed Objects + +The displayed objects are a subset of the list of objects that the display group manages. By default all objects are displayed. + +You can change this behavior by specifying a qualifier for the display group. This is an instance of {-EOQualifier@http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EOQualifier.html-} and it will have evaluateWithObject called for every object in the display group. Only those objects for which the return value is true will be in the displayed objects list. Call updateDisplayedObjects() on the display group to apply the qualifier. + +You would typically use this feature when you want to preload a large number of data objects into the display group so that the user can quickly and repeatedly apply different filters to sift through the data. + +^<< + // show only Powers in San Antonio + + Map matchValues = new HashMap(); + matchValues.put( "lastName", "Powers" ); + matchValues.put( "city", "San Antonio" ); + + EOQualifier qualifier = + EOQualifier.qualifierToMatchAllValues( matchValues ); + displayGroup.setQualifier( qualifier ); + displayGroup.updateDisplayedObjects(); +^>> + +*** Handling Selection + +Display groups also track which of the displayed objects are selected. By default no objects are selected, but you can change the selection programmatically. Certain associations allow the user to change the selection as well. + +If you do not provide the user with an association that can change the selection, you should make sure to set the selection to some object. + +^<< + // select all objects + displayGroup.setSelectedObjects( + displayGroup.displayedObjects() ); + + // select the third object + List selectionList = new LinkedList(); + selectionList.add( new Integer( 2 ) ); + displayGroup.setSelectedIndexes( selectionList ); + + // select the next object + displayGroup.selectNext(); + + // clear the selection + displayGroup.clearSelection(); +^>> + +*** Handling Insertions and Deletions + +You can programmatically insert or delete objects from a display group, although only if they are displayed. Any associations that display all of the displayed objects (like TableColumns) will be updated automatically. + +Deleted objects that were selected are removed from the selection. Inserted objects are not selected, so you will need to select them manually if desired. Default values for inserted objects can be specified with setInsertedObjectDefaultValues(). + +If a data source is used, the data source will be informed of the insertion or deletion, which will notify the editing context if it has one, which would update the persistent store on commit. + +Also, if a data source is used, the display group can be asked to simply create an object to be inserted into the group, which will call createObject() on the data source. + +^<< + // insert an object + displayGroup.insertObjectAtIndex( new TestObject(), 0 ); + + // delete that object + displayGroup.deleteObjectAtIndex(); + + // select the next object + displayGroup.selectNext(); + + // delete that object + displayGroup.deleteSelection(); + + // insert a new object + displayGroup.insertNewObjectAtIndex( 0 ); +^>> + +*** Delegate + +Display groups check with their delegate before performing almost any operation, you can easily customize the behavior of a display group by providing a class that implements the {-DisplayGroup.Delegate@http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/EODisplayGroup.Delegate.html-} interface. + +Display groups ask their delegate for permission to fetch, insert, delete, edit, create, and change selection, and then notify their delegate after each of these operations has taken place. Wotonomy provides a DelegateAdapter class that you can easily subclass to implement the required interface. + +** Associations + +{-Associations@http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/EOAssociation.html-} are the bridge between the controller and the view. An association has exactly one "controlled object", which is usually a user interface component. They also have one or sometimes more "aspects", each of which has a name, like ValueAspect or EnabledAspect. +You bind an aspect of an association with a display group and/or a key. Then you establish the connection between the association and the controlled object and you're done and you can forget about it. The association will keep the user interface object synchronized with the objects in the display group. + +*** Creating Associations + +You create an association by calling the constructor of the subclass of EOAssociation that is appropriate for the controlled object. Most associations are applicable to many kinds of objects, so the constructor is expected to take an Object. (This means that if you specify the wrong kind of object for the association, you won't hear about it until runtime.) + +^<< + EOAssociation association = new TextAssociation( textField ); +^>> + +*** Kinds of Associations + +Associations fall into one of two categories: overview associations and detail associations. Almost all associations are used to control some kind of user interface component. + +Overview associations show some property of all the items in the display group. Overview associations usually allow the user to select and deselect objects in the display group. + +For example, a JList might be used with a {-ListAssociation@http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/swing/ListAssociation.html-} to show the "name" property of all of the displayed objects in the display group, in the same order. Clicking the fourth name in the list would cause the fourth object in the display group to be selected, and - depending on the JList's selection model - cause whatever was previously selected to become unselected. + +Detail associations show some property of only the first selected object in the display group. If there is no selection, the detail association causes the controlled component to be blank or otherwise empty. If multiple objects are selected, the detail association shows the property of only the first object in the selected objects list. + +In our example, a JTextField might be used with a {-TextAssociation@http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/swing/TextAssociation.html-} to display the "email" property of the selected item in the display group. Clicking the fourth name in the list causes the fourth item in the display group to be selected, which populates the text field with the value of the email property for that object. Changing the value in the text field changes the value of that object's email property automatically. + +*** Master-Detail Associations + +While nearly all associations control user interface components, the {-MasterDetailAssociation@http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/MasterDetailAssociation.html-} is worthy of note because it does not. + +A MasterDetailAssociation controls a display group and binds to an indexed property of the objects in another display group. It is a detail association, with the bound display group as the "master" and the controlled display group as the "detail" component. + +Again using our example, another JList might be used with a ListAssociation to show all the dependents of the person selected in the first JList. + +First we would create a new display group and then create a MasterDetailAssociation with our new display group as the parameter to the constructor. Then we would bind that association to our original master display group with the "dependents" property (assuming there is a method on our data object called getDependents() that returns an array or a collection of objects). Then we would create our new ListAssociation controlling our new JList, and bind that to our new display group with the "name" property. Seeing the source might make this clearer - that's coming in the next section. + +Clicking on a name in the name list would then display the email address in the text field and a list of names of all the dependents. + +*** Binding Aspects and Establishing Connections + +An association has one or more aspects. Most of the time, you'll just need one aspect, sometimes called the "primary aspect". Aspects are referred to by name, like ValueAspect, and the names of an association's aspects are static members of that association's class. + +The primary aspect is usually responsible for populating the controlled object with data from the display group. The other aspects are useful, but they'll do different things depending on the nature of the association, so you should consult the documentation for the association you will be using. + +To bind an aspect, you call bindAspect() with the name of the aspect, a display group and a string "key". + +Usually, all three are specified, and the key is a property name. The association will display or edit the value of this property for the objects in the display group. + +The key may be an empty string, and this is considered the "identity property", and the value of the actual object in the display group will be used instead of a property on that object. This is sometimes useful for view components like JTrees for which you want to write custom renderers: with the identity property, the renderer receives the value of the actual object. + +The display group may be left null, in which case the key is treated as a value, acting as if all objects in the display group for the given property returned that value. This is useful for certain aspects of certain associations, like the EnabledAspect of {-TextAssociation@http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/swing/TextAssociation.html-}, or the EditableAspect of {-TableColumnAssociation@http://wotonomy.sourceforge.net/docs/net/wotonomy/ui/swing/TableColumnAssociation.html-}. + +After all the aspects have been bound, you need to call establishConnection() to put the association to work. Importantly, you do not need to retain a reference to the associations you create - they will exist as long as their controlled components exist, and when the controlled component is garbage collected, the association will be garbage collected. + +^<< + // set up the master display group + EODisplayGroup masterGroup = new EODisplayGroup(); + masterGroup.setObjectArray( getMyUsers() ); + + EOAssociation association; + + // set up names list + association = new ListAssociation( usersList ); + association.bindAspect( + EOAssociation.TitlesAspect, masterGroup, "name" ); + association.establishConnection(); + + // set up email field and for fun make it non-editable + association = new TextAssociation( emailField ); + association.bindAspect( + EOAssociation.ValueAspect, masterGroup, "email" ); + association.bindAspect( + EOAssociation.EditableAspect, null, "false" ); + association.establishConnection(); + + // set up detail display group + EODisplayGroup detailGroup = new EODisplayGroup(); + association = new MasterDetailAssociation( detailGroup ); + association.bindAspect( + EOAssociation.ParentAspect, masterGroup, "dependents" ); + association.establishConnection(); + + // set up dependents' names list + association = new ListAssociation( dependentsList ); + association.bindAspect( + EOAssociation.TitlesAspect, detailGroup, "name" ); + association.establishConnection(); + + // we're done! +^>> + +** Editing Contexts + +{-Editing contexts@http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EOEditingContext.html-} allow multiple display groups to manipulate the same set of objects, such that objects edited in one display group are updated in the associations of all other display groups that contain that object. + +Editing contexts monitor all inserts, edits, and deletes in the display groups that use them, allowing these sets of changes to be committed or rolled-back as a single transaction. + +Furthermore, editing contexts can be nested, so that a new editing context will reflect the existing state of another editing context, but all changes made to the new context are not applied to the parent context until they have been committed in the child context. + +*** Object Stores + +Two concepts are critical to an understanding of editing contexts: (1) An editing context must have an object store, and (2) an editing context is an object store. + +Because you need an object store to instantiate an editing context, there must be some implementation of {-EOObjectStore@http://wotonomy.sourceforge.net/docs/net/wotonomy/control/EOObjectStore.html-} that is not an editing context. That object store will be responsible for directly reading and writing to the persistent storage. + +Because editing contexts do implement object stores, you can then create other editing contexts that use the first editing context, which uses the first object store. This is what allows editing contexts to be nest. + +*** Creating an Editing Context + +To use an editing context in your application, you must create an object store. Your implementation of EOObjectStore will act as the glue between wotonomy and whatever persistent storage mechanism your application uses. + +You will then create your primary editing context, specifying your object store as the parameter to the constructor. You will probably have only one object store per application, and one primary editing context that uses it. Any other editing contexts you create will use your primary context as their object store. + +^<< + // initial application setup + EOObjectStore objectStore = new MyObjectStore(); + EOEditingContext mainContext = new EOEditingContext( objectStore ); + + // set up a child display group + EOEditingContext childContext = new EOEditingContext( mainContext ); + EODataSource dataSource = new MyDataSource( childContext ); + EODisplayGroup displayGroup = new EODisplayGroup(); + displayGroup.setDataSource( dataSource ); + displayGroup.fetch(); +^>> + +* What's next? + +This document gives you a very basic overview and brief introduction to the major players in the wotonomy user interface framework. You'll probably want to check out the {-API Reference@http://wotonomy.sourceforge.net/docs-} + next.
\ No newline at end of file diff --git a/projects/net.wotonomy.all/src/site/resources/images/standard-mvc.gif b/projects/net.wotonomy.all/src/site/resources/images/standard-mvc.gif Binary files differnew file mode 100644 index 0000000..5528e07 --- /dev/null +++ b/projects/net.wotonomy.all/src/site/resources/images/standard-mvc.gif diff --git a/projects/net.wotonomy.all/src/site/resources/images/wotonomy-er.gif b/projects/net.wotonomy.all/src/site/resources/images/wotonomy-er.gif Binary files differnew file mode 100644 index 0000000..48560cb --- /dev/null +++ b/projects/net.wotonomy.all/src/site/resources/images/wotonomy-er.gif diff --git a/projects/net.wotonomy.all/src/site/resources/images/wotonomy-mvc.gif b/projects/net.wotonomy.all/src/site/resources/images/wotonomy-mvc.gif Binary files differnew file mode 100644 index 0000000..52eb211 --- /dev/null +++ b/projects/net.wotonomy.all/src/site/resources/images/wotonomy-mvc.gif diff --git a/projects/net.wotonomy.all/src/site/resources/index-old.html b/projects/net.wotonomy.all/src/site/resources/index-old.html new file mode 100644 index 0000000..d21e8c1 --- /dev/null +++ b/projects/net.wotonomy.all/src/site/resources/index-old.html @@ -0,0 +1,105 @@ +<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> +<html> +<head> +<title>wotonomy</title> + <meta name="author" content=""> + <meta name="GENERATOR" content = "Almost Free Text v5.06; Copyright 1996-2000 Todd Coram. All rights reserved."> +</head> +<body> + +<br><h1><a name="AFT-top"><center>wotonomy</center></a></h1> +<p> +Wotonomy is a pure java user interface framework for building both web and gui applications. It is heavily inspired by the NeXT and OpenStep APIs and it includes clean-room implementations of portions of the WebObjects and JavaClient frameworks. +</p> +<h2><a name="Useful links">Useful links</a></h2> +<ul> +<li> Developer Guide (for the user interface package)</li> +<ul> +<li> <a href="http://wotonomy.sourceforge.net/docs/ui-guide.html">http://wotonomy.sourceforge.net/docs/ui-guide.html</a></li> +</ul> +<li> API Reference (javadoc)</li> +<ul> +<li> <a href="http://wotonomy.sourceforge.net/docs">http://wotonomy.sourceforge.net/docs</a></li> +</ul> +<li> Sourceforge project page (includes downloads)</li> +<ul> +<li> <a href="http://sourceforge.net/projects/wotonomy">http://sourceforge.net/projects/wotonomy</a></li> +</ul> +<li> Browse the source repository</li> +<ul> +<li> <a href="http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/wotonomy">http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/wotonomy</a></li> +</ul> +<li> Download wotonomy library (includes demo, use java -jar to run)</li> +<ul> +<li> <a href="http://download.sourceforge.net/wotonomy/wotonomy.jar">http://download.sourceforge.net/wotonomy/wotonomy.jar</a></li> +</ul> +</ul> +<!-- AFT Table of Contents (auto generated) --> +<ul> +<li> <a href="#Frequently Asked Questions">Frequently Asked Questions</a></li> +<ul> +<li> <a href="#I'm a Java developer: what's in it for me?">I'm a Java developer: what's in it for me?</a></li> +<li> <a href="#I'm an OpenStep developer: what's in it for me?">I'm an OpenStep developer: what's in it for me?</a></li> +<li> <a href="#What's the current status?">What's the current status?</a></li> +<li> <a href="#Why not use GNUStep?">Why not use GNUStep?</a></li> +<li> <a href="#Why not use WebObjects?">Why not use WebObjects?</a></li> +<li> <a href="#Did you say MacOS9?">Did you say MacOS9?</a> + +</li> +</ul> +</ul> +<!--End Section h2--> +<h2><a name="Frequently Asked Questions">Frequently Asked Questions</a></h2> +<h3><a name="I'm a Java developer: what's in it for me?">I'm a Java developer: what's in it for me?</a></h3> +<p> +Java developers will find the design patterns in wotonomy useful for reducing the complexities of data-driven application development. Swing developers will additionally find a number of useful Swing components and utilities. +</p> +<!--End Section h3--> +<h3><a name="I'm an OpenStep developer: what's in it for me?">I'm an OpenStep developer: what's in it for me?</a></h3> +<p> +OpenStep developers will find that they can use familiar APIs while still writing pure java applications. Wotonomy provides clean-room and API-compatible implementations of the EOInterface/EOControl, WebObjects, and Foundation frameworks that interoperate with and extend the Java Swing, Servlet, and Collections packages respectively. Wotonomy tries to be as API-compatible as possible while still tightly integrating with Java. +</p> +<!--End Section h3--> +<h3><a name="What's the current status?">What's the current status?</a></h3> +<p> +The current status of the framework is alpha. The user interface package is suitable for simple to moderate application development and has working associations for all Swing components and a display group that supports data sources, sorting, and delegates. Editing contexts are in development. The web package is a proof-of-concept implementation that currently only supports WOString. The foundation package has pure java ports of all classes needed by the ui and web packages, including NSArray and NSDictionary classes that implement the List and Map interfaces respectively. +</p> +<!--End Section h3--> +<h3><a name="Why not use GNUStep?">Why not use GNUStep?</a></h3> +<p> +GNUStep is awesome, but it's an Objective-C framework. The new Java bridge is great, but even Apple is backpedaling on that approach with their pure-Java version of WebObjects, due to performance problems and conceptual difficulties in development. +</p> +<p> +Wotonomy has the same license (GNU Lesser Public License), and is written completely in Java. +</p> +<!--End Section h3--> +<h3><a name="Why not use WebObjects?">Why not use WebObjects?</a></h3> +<p> +Yes, you should if at all possible. Then you'll get tools like InterfaceBuilder and EOModeler and ProjectBuilder and you'll be even more productive. But some of us have to deploy applications on Windows or Linux or MacOS9. +</p> +<p> +It's not an issue of free beer: WebObjects is worth at least ten times the price (which is currently way cheap at ~$500). It's the restrictions on deployment that create the problem. +</p> +<p> +The other problem is political. Perhaps if enough people adopt wotonomy for their Java projects, they'll see the advantage of investing in Apple technology. Additionally, applications using wotonomy will be extremely portable to Apple platforms. +</p> +<!--End Section h3--> +<h3><a name="Did you say MacOS9?">Did you say MacOS9?</a></h3> +<p> +Yes, it should be possible to get wotonomy running on JDK1.1, although it doesn't work right now. The collections packages would have to be renamed and the weak references would have to be looked at, but it looks do-able. +</p> +<p> +If your application used only NSArrays and NSDictionaries and no java2 collections, you could just link your app against a version of the wotonomy library built for 1.1 and it will just work. +</p> +<hr> +<img src="http://sourceforge.net/sflogo.php?group_id=12936&type=1" alt="" align=bottom> +<!--End Section h3--> +<!--End Section h2--> +<br> +<hr> +<center><small><em> +This document was generated using <a href="http://www.maplefish.com/todd/aft.html">AFT v5.06</a> +</em></small></center> +</body> +</html> + diff --git a/projects/net.wotonomy.all/src/site/site.xml b/projects/net.wotonomy.all/src/site/site.xml new file mode 100644 index 0000000..65ae393 --- /dev/null +++ b/projects/net.wotonomy.all/src/site/site.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="${project.name}"> + <bannerLeft> + <name>${project.name}</name> + </bannerLeft> + <bannerRight> + <src>http://sourceforge.net/sflogo.php?group_id=12936&type=1</src> + </bannerRight> + <body> + + <menu ref="parent" inherit="top" /> + <menu name="Wotonomy Documentation"> + <item name="FAQ" href="faq.html" /> + <item name="UI Developer's Guide" href="doc/ui-guide.html" /> + <item name="Persistence Control Guide" href="doc/control-guide.txt" /> + </menu> + <menu ref="modules" /> + <menu ref="reports" /> + + <menu name="Developer Instructions"> + <item name="Project Folder Layout" href="layout.html" /> + <item name="Source Control Help" href="scm.html" /> + <item name="Build Help" href="build.html" /> + <item name="Eclipse Help" href="eclipse.html" /> + </menu> + <menu name="Downloads" inherit="bottom" > + <item name="wotonomy packages" href="http://sourceforge.net/project/showfiles.php?group_id=12936"/> + </menu> + <menu name="Links" inherit="bottom" > + <item name="Sourceforge Project" href="http://www.sourceforge.net/projects/wotonomy/" /> + <item name="Israfil Maven Repository" href="http://www.israfil.net/maven2/" /> + <item name="Browse Sourceforge Repository" href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/wotonomy/wotonomy/" /> + </menu> + + </body> +</project> + |
