1+ <!--
2+ ~ Copyright (C) 2012 United States Government as represented by the Administrator of the
3+ ~ National Aeronautics and Space Administration.
4+ ~ All Rights Reserved.
5+ -->
6+
7+ <!-- $Id: Design and Coding Guidelines.html 1171 2013-02-11 21:45:02Z dcollins $ -->
8+ < body >
9+ < h1 > WorldWind Multi-Platform Design and Coding Guidelines</ h1 >
10+
11+ < h2 > General</ h2 >
12+ < ul >
13+ < li >
14+ Our required target platforms are OS X, Windows XP and Vista, and the most popular versions of Linux. All code
15+ and all products must run on all those systems.
16+ </ li >
17+ < li >
18+ Read the WorldWind API's Overview section for a description of WorldWind architecture, design and usage. Read
19+ the overview pages of each WorldWind package for descriptions of those. These descriptions contain critical
20+ information that is not repeated elsewhere. To avoid making mistakes, everyone working on WorldWind must read
21+ them before using or modifying the code.
22+ </ li >
23+ < li >
24+ The project's development IDE is IntelliJ IDEA. The IDEA configuration files for this project are checked in to
25+ the code repository. They define within them global and local library links, formatting rules, etc.
26+ </ li >
27+ < li >
28+ Most major classes need a no-argument constructor so that the declarative instantiation mechanism can work. WW
29+ objects should avoid constructors with arguments so that they can be created generically by name. This means
30+ they should self-configure if at all possible, drawing their parameterized info from Configuration. They should
31+ also contain an interface to set the configuration details programmatically.
32+ </ li >
33+ < li >
34+ Make field and variable names clear and easy to read. Don't label them with "my" or "m_" or some other goofy
35+ notation. Within a class refer to all member fields with "this", e.g., this.tileCount.
36+ </ li >
37+ < li >
38+ The buffers one must use to pass arrays of info to JOGL must have their byte order set to that of the machine
39+ they're used on. Call nativeByteOrder() on NIO buffers when you deal with them, use the methods in
40+ com.jogamp.common.nio.Buffers.
41+ </ li >
42+ < li >
43+ Favor immutability (all fields final) in classes representing some small entity like a Point or Vector.
44+ Immutable classes are fully thread safe and generally less error prone.
45+ </ li >
46+ < li >
47+ Don't worry too much about frequent memory allocations. Java is now so optimized for this that allocating an
48+ object on the heap has similar performance to allocating it on the stack, and this includes the cost of garbage
49+ collection. There is still a cost to executing any code, however, so be smart about allocation frequency.
50+ </ li >
51+ < li >
52+ Configuration items typically have two values and thus two attribute names: a DEFAULT value that is used if not
53+ overridden, and a non-default value that can be set programmatically (in Configuration) to a current value
54+ without losing the ability to recover the default value.
55+ </ li >
56+ < li >
57+ Classes such as BasicDataFileStore and the logger are effectively singletons but they are not defined in their
58+ class definition as such. Their singleton nature comes from their 1:1 association with the truly singleton
59+ WorldWind class, which provides access to instances of these "singleton" classes.
60+ </ li >
61+ < li >
62+ Do not use classes that are not available in the standard 1.6 JRE. Don't incur additional or external
63+ dependencies. The only 3rd-party library we rely on is JOGL.
64+ </ li >
65+ < li >
66+ Constants are defined as String and namespace qualified. This enables easy and non-conflicting extension.
67+ </ li >
68+ < li >
69+ Do not use GUI builders to generate interfaces for examples or applications. They prevent others from being able
70+ to maintain the code.
71+ </ li >
72+ < li >
73+ Protect OpenGL state within a rendering unit, such as a layer, by bracketing state changes within try/finally
74+ clauses. The util.OpenGLStackHandler utility class makes this easy. It manages both attribute state and matrix
75+ stack state. The goal is to isolate any OpenGL state changes to the rendering unit, both when the unit succeeds
76+ and when it fails.
77+ </ li >
78+ < li >
79+ WorldWind never crashes. Always catch exceptions at least at the highest entry point from the runtime, e.g., UI
80+ listeners, thread run() methods.
81+ </ li >
82+ < li >
83+ Within a rendering pass WorldWind does not touch the disk or the network. Always fork off a thread to do that.
84+ Use the TaskManager and Retriever systems to start threads during rendering. These are set up to govern thread
85+ usage to avoid swamping the local machine and the server.
86+ </ li >
87+ < li >
88+ Too much micromanagement of state makes the code brittle. Try to design so that the right thing just happens
89+ once things are set up, and the effect of something going wrong is benign. For example, Layers fork off
90+ Retriever objects to retrieve data from the network. But they don't try to keep track of these. If the retriever
91+ succeeds then the data will be available the next time the layer looks for it. The fact that it's not there
92+ because of a timeout or something tells the layer to ask for it again if it needs it.
93+ </ li >
94+ < li >
95+ DOMs are expensive in memory and time. Use an event for any documents that might be large. Use the parser in
96+ gov.nasa.worldwind.util.xml when appropriate.
97+ </ li >
98+ </ ul >
99+
100+ < h2 > Exceptions</ h2 >
101+ < ul >
102+ < li >
103+ WW objects running in the Main thread pass exceptions through to the application unless there's good
104+ reactive/corrective behavior that can be applied within WW.
105+ </ li >
106+ < li >
107+ Log any exceptions prior to throwing them. Use the same message for the log as for the exception.
108+ </ li >
109+ < li >
110+ Ensure all exception messages are generated using the i18n method details below.
111+ </ li >
112+ < li >
113+ Public methods validate their arguments and throw the appropriate exception, typically InvalidArgumentException,
114+ and identify the exception message the parameter name and the problem -- null, out of range, etc. See the
115+ message resource file, util.MessageStrings.properties, for common messages and their identifiers.
116+ </ li >
117+ < li >
118+ In Retriever threads, do not catch Throwable. Catch and react to Exception if there's a good reactive/corrective
119+ behavior to apply, otherwise allow them to pass up the stack. Retriever threads should have an uncaught
120+ Exception handler specified for the thread. The method should log the Exception or Throwable and then return.
121+ </ li >
122+ < li >
123+ Private and protected methods whose calling client can't be trusted validate their arguments and throw an
124+ appropriate exception.
125+ </ li >
126+ < li >
127+ The audience for exceptions is not primarily the user of the client program, but the application or WorldWind
128+ developer. Throw exceptions that would let them know immediately that they're using faulty logic or data.
129+ </ li >
130+ </ ul >
131+
132+ < h2 > Logging</ h2 >
133+ < ul >
134+ < li >
135+ Logging using java.util.logging has the nice feature of capturing the class and method name at the site of the
136+ logging call. That's why there is the common idiom of create message, log message, throw exception. Wrapping
137+ these three actions in some utility method would lose the class and method-name feature, so don't do that. Don't
138+ use any logging system other than that in the JRE.
139+ </ li >
140+ < li >
141+ Log all exceptional conditions before rethrowing or throwing a new exception.
142+ </ li >
143+ < li >
144+ Ensure all logging uses i18n messages as detailed below.
145+ </ li >
146+ < li >
147+ Use level SEVERE for things that prevent the intended action,e.g., file can't be written. Use level WARN for
148+ things that don't stop the action but seem exceptional, e.g., a file was retrieved or written redundantly. Use
149+ level FINE for simple notifications. Use FINER for method traces. Using the "FINE"series prevents screen display
150+ of these when the default JAVA logging settings are used. Since we're a component, we don't communicate such
151+ things directly to the application's user; the application does.
152+ </ li >
153+ </ ul >
154+
155+ < h2 > Concurrency</ h2 >
156+ < ul >
157+ < li >
158+ Use collection classes from the java.util.concurrent package if there's any chance at all that the collection
159+ may be accessed from multiple threads.
160+ </ li >
161+ < li >
162+ Except for simple atomic variables (but not long or double) the safest way to manage multi-thread access is
163+ through the blocking queue classes of java.util.concurrent.
164+ </ li >
165+ < li >
166+ Making a class' fields final avoids concurrency problems, but it makes the class much less extensible. If using
167+ private, make sure there are overridable set/get accessors.
168+ </ li >
169+ </ ul >
170+
171+ < h2 > Offline Mode</ h2 >
172+
173+ < p > WorldWind's use of the network can be disabled by calling {@link gov.nasa.WorldWind.setOfflineMode}. Prior to
174+ attempting retrieval of a network resource -- anything addressed by a URL -- WorldWind checks the offline-mode
175+ setting and does not attempt retrieval if the value is true. To honor this contract, all code must check network
176+ status prior to attempting retrieval of a resource on the network.</ p >
177+
178+ < h2 > Documentation</ h2 >
179+ < ul >
180+ < li >
181+ Use the appropriate Ant target to generate worldwind.jar and javadoc API documentation. Do not use the IDEA
182+ Tools command because it's not configured appropriately, only the Ant targets are.
183+ </ li >
184+ < li >
185+ All public and protected classes, methods and fields should be commented for javadoc documentation generation.
186+ </ li >
187+ < li >
188+ Descriptions of classes, methods, etc. should start with a capital letter. Parameter descriptions and
189+ return-value description should start with a lower-case letter. All descriptions end with a period.
190+ </ li >
191+ < li >
192+ If a class overrides methods from {@link Object} such as < code > toString()</ code > and < code > equals()</ code > ,
193+ their behavior for the specific class should be described. For < code > equals()</ code > that would be the fields
194+ compared. For < code > toString()</ code > that would be the representation returned.
195+ </ li >
196+ < li >
197+ Use links liberally, e.g., {@link WorldWind}. They help the reader get to information fast.
198+ </ li >
199+ </ ul >
200+
201+ < h2 > Code Formatting</ h2 >
202+ < ul >
203+ < li >
204+ Use the code formatting and style that's in the IDEA project file. It makes it possible to review previous code
205+ modifications.
206+ </ li >
207+ < li >
208+ Use the code formatting rules specified in WorldWindJ.ipr. They are in the project file under (Settings Project
209+ Settings Project Code Style). To apply them, simply use Code Auto-indent Lines. You can also just check the box
210+ at Subversion check-in time and the formatting will be applied before check-in. Be sure the formatting rules are
211+ not overridden in your IDEA workspace.
212+ </ li >
213+ < li >
214+ We generally use the traditional Sun coding conventions. Constants are in all upper case with words separated by
215+ underscores. Everything else is in camel case. Class names start with an upper case character, variables start
216+ in lower case.
217+ </ li >
218+ < li >
219+ White space is preferred over packing code into a small space. Please use white space liberally.
220+ </ li >
221+ < li >
222+ Set up IDEA to automatically place the standard project header in newly created files by putting the following
223+ as the File Header in the Includes tab of IDEA in the File Templates dialog: < br > < code > < br > /* Copyright (C)
224+ 2001, 2011 United
225+ States Government
226+ as represented by
227+ < br > the Administrator of the National Aeronautics and Space Administration. < br > All Rights Reserved. < br > */ < br > package
228+ ${PACKAGE_NAME};
229+ < br > < br > /** < br > * @author ${USER} < br > * @version $Id: Design and Coding Guidelines.html 1171 2013-02-11 21:45:02Z dcollins $ < br > */ </ code >
230+
231+ < p >
232+ Then remove the package name property from first line of the Class and Interface items of the Templates tab
233+ in the File Templates dialog. (The package name is in the "include" now, so it gets inserted after the
234+ copyright.) Test it out by creating a dummy class. Unfortunately this set-up is a personal configuration in
235+ IDEA, not project specific.</ p > </ li >
236+ < li >
237+ When creating a new file, the Id subversion keyword has to be explicitly set via Version Control --> Set
238+ Property --> Property name: svn:keywords, and the term Id included in the text box. If the property is not
239+ included in this list then Subversion doesn�t replace the property string when updating the file.
240+ </ li >
241+ < li >
242+ Resolve all IDEA warnings before checking in a file. If the warning refers to an intentional case, add an
243+ exception statement.
244+ </ li >
245+
246+ </ ul >
247+
248+ < h2 > Internationalization (i18n)</ h2 >
249+ < ul >
250+ < li >
251+ String "constants" are stored in separate resource files (e.g. MessageStrings.properties). These files must end
252+ in ".properties" and must be stored in the src directory. Strings are stored with the format:
253+ packageOfClass.className.nameOfString=value of the string
254+ </ li >
255+ < li >
256+ Access the string constants by using the following pattern: (e.g.
257+ Logging.getMessage("myPackage.myClass.targetStringName");).
258+ </ li >
259+ </ ul >
260+
261+ < h2 > Books</ h2 >
262+ The books we go back to again and again are the following:
263+ < ul >
264+ < li >
265+ < i > Core Java</ i > , Horstmann & Cornell, Volumes 1 and 2, Prentice Hall. Be sure to get the editions covering at
266+ least J2SE 5. Get the newest edition (currently 8).
267+ </ li >
268+ < li >
269+ < i > The Java Programming Language</ i > , Arnold & Gosling, Addison Wesley. Be sure to get the most recent edition
270+ covering at least Java 6.
271+ </ li >
272+ < li >
273+ < i > Concurrent Programming in Java</ i > , Lea, Addison Wesley
274+ </ li >
275+ < li >
276+ < i > Java Threads</ i > , Oaks & Wong, O�Reilly
277+ </ li >
278+ < li >
279+ < i > Java Cookbook</ i > , Darwin, O�Reilly
280+ </ li >
281+ < li >
282+ < i > OpenGL Programming Guide</ i > , Shreiner & Woo & et al, Addison Wesley. Be sure to get the version covering
283+ OpenGL 2.0, which is currently the Fifth Edition.
284+ </ li >
285+ < li >
286+ < i > Mathematics for 3D Game Programming & Computer Graphics</ i > , Lengyel, Charles River Media. Be sure to get the
287+ Second (or later if there is one) edition.
288+ </ li >
289+ </ ul >
290+ </ body >
0 commit comments