Stellation Project Guidelines
Coding Guidelines
General
1.
All
methods and fields should be explicitly tagged with a protection:
o Methods in the public interface of a
class should be public.
o Methods not in the public interface should,
by default, be protected.
o Methods implemented solely as a
specific helper function for a protected method should be private.
o By default, fields should be
protected.
o Only fields used to represent
constants should be public.
o Non-constant fields that are part of
the public interface of the class should be protected, with public accessor
methods.
2.
Exceptions
should be caught explicitly. That is, catch blocks should not catch Throwable
, but should catch the specific
types of exceptions thrown within the code inside the try. (If you're using
Eclipse, this is trivial: just highlight code that throws an exception, and do
"surround with try/catch block".)
As
an exception to this, when code in running inside of another application (e.g.,
Eclipse), and it is necessary to prevent unhandled exceptions, a Throwable
catch block can be placed in the outermost accessible code location. In this
case, the Throwable catch block must log all caught exceptions
3.
All
classes should provide an instance of the logging class from jakarta-log4j.
Logging statements should be used liberally to provide enough information for a
person debugging to understand the control flow.
4.
Source
code should be written using spaces instead of tabs, with a tab width of 4
spaces. To configure the Eclipse editor accordingly:
o Select Window > Preferences >
Java > Editor.
o Set Displayed tab width to
4.
o Select Window > Preferences >
Java > Code Formatter > Style.
o Clear the checkbox for Indentation
is represented by a tab.
o Set Number of spaces
representing a tab to 4.
Fields and Variables
1.
The
names of all instance fields should start with "_".
2.
All
field declarations should be placed together at the end of the source file,
after the last method declaration.
3.
All fields
should be explicitly initialized. If the initial value of a field is not
dependent on the values of the parameters passed to the class constructor, then
it should use an in-line initializer.
4.
Fields
should only be used for persistent data: if a value is only used within one
call chain from outside the class, then it should be passed as a parameter to
all the methods in the call chain.
1.
If the
value of the field is created by one call into the class, and then is used by
other independent calls into the class, then the value should be stored in a
field.
2.
If,
within a call to a method A, another method B is called to compute a value v,
and v is never used outside of the call to A, then v should be stored in a
local variable.
3.
If a
method's M sole purpose is to compute a persistent value v to be stored in a
field f, then M should return v, and M's caller should assign it to f.
5.
Fields
used to store constants should have fully capitalized names.
6.
In
general, static fields should have names starting with a capital letter.
7.
Non-constant
private and protected fields should be located at the end of the class
definition. This reduces visual clutter while code browsing, reduces visibility
of internal class details, and makes it easier to estimate instance size.
o Constants that are part of the
public class API should be located either at the start of the class definition,
or next to the public methods using them.
o The use of public non-constant
fields is discouraged, as noted above. If they must be used, they
should be located at the start of the class definition.
Strings
Strings should not be hard-coded in your code unless the following conditions hold:
· Only a single instance of this string will exist in the package containing the string.
· The string is language neutral and will never have to be translated into another language.
Language
neutral strings
These
strings should be placed in a class within each package that is reserved for
strings. Typically this will be the same class that is used for access to
internationalized strings. Code the string as a public static final String and
give it a name that is suggestive of the use of the string. If you have cases
where two strings that have substantially different uses have the same value
such as the string “version” used as a XML tag in two totally different files,
then make two entries for it with appropriate names such as “PROJECT_VERSION”
and “ARTIFACT_VERSION”.
Translatable strings
All strings that may be viewed by a human user should be translatable. Stellation uses a combination of Java and Eclipse facilities to support translatable strings. Eclipse provides a tool, the “Externalize String Wizard” that will convert strings in your code into a form that can be handled by the Java environment. Basically what happens is that every translatable string in your program is replaced by a method call that returns the value of the string in the current locale. The actual string that you coded is stored in a property file with a generated key that is used for retrieval. This property file provides the default string values to be used if there is no language specific version available. There will be a property file for each supported language that will contain the translation of the strings for a particular language and cultural environment.
See the following documents for further information on this subject.
http://www.eclipse.org/articles/Article-Internationalization/how2I18n.html
http://java.sun.com/docs/books/tutorial/i18n/intro/index.html
Strings with insertions
One area you should
be sensitive to is the situation where you build up a string from several
separate pieces that you concatenate together to form a final string. The
problem here is that the elements of the string may have to go together in
different orders for different languages. The solution is to use a Java class
java.text.MessageFormat. This class supports the use of a template and an array
of arguments to construct a string. The template specifies the framework for
the string and provides a means for specifying where arguments are to be
inserted into the string and how they are to be formatted. For example “insert
a string here: {0} and a number here {1, number, integer}.” Is an example of a
template. The fields within the {} pair specify which argument is to be inserted
and how simple formatting is to be done. The leading numbers are indexes into
an array of Object derived objects that provide the insertion data. Any object
that implements a toString() method can be used. See the documents referenced
above as well as http://java.sun.com/j2se/1.3/docs/api/java/text/MessageFormat.html
for further information. If you want to see code samples, the file
org.eclipse.stellation.workspace.Svc.java has many examples.
Putting strings
together
The string related
data and code are concentrated in two files per package. One is a string
management class and the other is a property file. The Eclipse Externalize
String Wizard generates both files and this wizard can maintain the
translatable strings.
Documentation
1.
All
code should have javadoc comments.
2.
In
addition to the Javadoc, complex components should have extra documentation to provide
a high level overview of the system. (For example, the repository core's use of
database tables for storage is described in a separate document.)
3.
When
you change code that is documented in one of the existing documents, you should
simultaneously change the corresponding documents.
4.
Documents
should be written in HTML.
Repository Code
We talk about certain components of the systems by names
that are shorter than the full package pathname. These short names are:
·
Repository
Core: the
repository core consists of the key fixed parts of the system that drive the
repository. The repository core consists of the code in
"org.eclipse.stellation.scm.repos", and the interfaces in
"org.eclipse.stellation.scm.artifact".
·
Workspace: the workspace refers to the code that
manages the command-line tools for Stellation. The code for the workspace is
primarily the code in "org.eclipse.stellation.scm.workspace", and
several of the IO implementations in "org.eclipse.stellation.scm.io".
·
Server: the server consists of the code
that makes up the communication layer that allows Stellation to work in
client/server mode. This includes the code in
"org.eclipse.stellation.comm" and its sub-packages, and the code in
"org.eclipse.stellation.scm.repos.messaging" and its subpackages.
·
Messaging: we refer to the basic
communication subsystem of Stellation as the messaging engine (a.k.a. Databus).
1.
The
repository core is "sealed", meaning that no types from
outside of "org.eclipse.stellation.scm.repos",
"org.eclipse.stellation.scm.artifact", or
"org.eclipse.stellation.repos.util" should ever be explicitly
referenced by code inside of the repository core. The repository core is the
code in org.eclipse.stellation.scm.repos.
2.
Code
in the repository core should not explicitly refer to any artifact types. The
only exception to this is when it is absolutely unavoidable. (For example, due
to a bug in the PostgreSQL implementation of JDBC, LOB operations must be
performed first in any transaction; thus, any artifact agents that perform LOB
operations need to be explicitly invoked before any other artifact agents.)
3.
In
general, all code in the system should try to avoid explicit references to
artifact types. When information about an atifact type is required by another
part of the system, that information should be accessed through the agent for
its artifact type.Methods can be added to the agent classes if they do not have
a method of answering an important question about an artifact type.
Coordination/Communication
1.
As in
any open-source project, all communications between programmers will be open,
through the public email developers list. Private discussions between
programmers working closely together are fine, but any decisions made in their
discussions should be sent to the open list.
2.
When
making any significant interface changes, you should send a note to the list
describing the changes. Before starting the changes, give list members enough
time to send mail if they have any significant objections.
3.
Be
aware of what components of the system are clients of the code that they are
working on. Before making any interface changes that affect other components,
you should inform people working on other components, and wait for them to
reach a convenient point before you start your changes.
4.
You should
merge with changes from the repository as often as reasonable possible. At a
minimum, you should be merging twice per week.
Last
modified on August 13, 2002 (jw)