A Java style checker, checkStyle, is part of the build process. This should aid in the development of readable code. Jetspeed currently works with version 2.4 of the checkStyle. For more information see http://checkstyle.sourceforge.net. Here is a list of rules currently enforced by the style checker:
Please use spaces within method parameter lists:
Instead of: this.test(true,true,"test",true); please use: this.test(true, true, "test", true);
Use of brackets. Some developers have personal a preference to how they place brackets within their source code:
if (true) { //body } or if (true) { //body }
Please choose whatever style you want for new files but you should maintain the existing style of source you wish to modify.
If you have a method with multiple parameters, separate them across multiple lines.
Instead of having a long list of parameters on one one line, break your parameter list across several lines: private final PortletSet getPortlets(Portlets portlets, RunData rundata, boolean application, boolean applicationsOnly) { } private final PortletSet getPortlets(Portlets portlets, RunData rundata, boolean application, boolean applicationsOnly) { }
Testing is a great way to detect and prevent bug. By automating the testing process, the test are easy to run and identify failures. Jetspeed uses the testing facilities built into Ant, primarily Cactus and JUnit.
Test
and be
located in the package it test.
cvs checkout
, after a
cvs update
, and before a cvs commit
.
The required tests are made up of Cactus and JUnit test used to insure working, and hopefully bug free, code.
Command to run Test | Description |
---|---|
build unittest-all | Runs all required unit tests |
build tests_tomcat_32 | Runs all required Tomcat 3.x (JSP 1.1) tests |
build tests_tomcat_40 | Runs all required Tomcat 4.x (JSP 1.2) tests |
These are unit tests grouped logically. In some case there is a testing hierarchy. In the case of unittest-security. It is composed of the security implementation test, i.e. unittest-security-registry and unittest-security-turbine.
Below is just a sample of Unit Test Groups available
Command to run Test | Description |
---|---|
build unittest | General unittests. Long running test do not belong here |
build unittest-security | General unittests of Jetspeed Security implementations. |
build tests_cache | General unittests of caching subsystems. |
Cactus testing is used when rundata is required. The test usually involve generating a URL in beginTestName(). The URL is passed to a test, named testTestName(), running on a web server started by Cactus.
The execution of Cactus test are dependent on the version of the servlet engine. Currently their are two place in build.xml to add Cactus test.
Example of Cactus test can be found in org.apache.jetspeed.test.BasicSecurityTest
and org.apache.jetspeed.template.TestJetspeedLink
.
Documentation for Cactus can be found at http://jakarta.apache.org/cactus
JUnit testing is simpler the Cactus testing, in part because the do
not require a web server. These test generally test small functional
units, like reading a file into a data structure. Turbine services
also be tested with JUnit test, see org.apache.jetspeed.services.registry.TestMarshallRegistry
.
Example of JUnit test can be found in org.apache.jetspeed.services.registry.TestMarshallRegistry
and org.apache.jetspeed.template.TestJetspeedLinkFactory
.
Documentation for JUnit can be found at http://junit.org
Enter the property in the language propery file,
org.apache.jetspeed.modules.localization.JetspeedProperty_
language.properties
. All properties should be
placed in the english, en
, property file and any other
language property files. When adding/changing properties, these
properties should be added/changed in files for ALL languages. For example,
if a property is added or updated, the property should be
copied to all language property files with the English value. This will
serve as a reminder to the maintainer that the property file needs to updated.
CUSTOMIZER_REF_DEFAULTTITLE=Reference
Logging is very useful for diagnosing and resolving problems. As a general rule, all exceptions should be logged,
and done so in the following fashion:
logger.error("What went wrong", ex);
This way, both your message and a stack trace of the exception will be logged. Your error message should describe the
error, and where practical the cause and suggested solutions.
Do not log exceptions like this: logger.error(ex);
Whenever you want to log a Throwable, it should be the
second parameter of your fatal/error/warn/info/debug call.
Since the new logging scheme uses Log4J, the penalty of log statements that are not actually activated, such as debug,
is negligable. However, if your log message uses String concatenation ("+"), avoid loads of objects to be garbage collected by always
checking if the particular level you are logging is enabled, by calling eg. logger.isDebugEnabled()
.
This is not necessary for logging simple Strings. Also, if you are building your message by concatenation, use
StringBuffer and .append() instead of String and "+". Your code will be more efficient and produce less garbage.
Debug logging is intended for development and problem determination. It
is not intended for use in a "normal" production environment. Therefore do not depend on important
information to be logged using debug. Do, however, add a reasonable about of debug logging in your code, expecially where
robustness checks fail and "strange" things happen. This makes bug hunting a lot easier!
Do NOT use levels above debug, such as info, for debug messages!
if (logger.isDebugEnabled()) { StringBuffer msg = New StringBuffer("accessing rundata "); mgs.append(m_runDataStore.get(Thread.currentThread()); msg.append(" for thread: "); msg.append(Thread.currentThread()); logger.debug(msg.toString()); }
The following code snippet shows how to use the new logging features.
package mypackage; // The two imports needed import org.apache.jetspeed.services.logging.JetspeedLogFactoryService; import org.apache.jetspeed.services.logging.JetspeedLogger; class MyClass { /** * Static initialization of the logger for this class */ private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(MyClass.class.getName()); /** * Some method */ someMethod() { ... logger.debug("This message should be logged"); } }
All changes posted by non-committers should be submitted (and accepted) in form of patches. Patches can be created from root of the project using the this command:
cvs diff -u [file to be patched]
cvs diff -u src/java/org/apache/jetspeed/services/registry/CastorRegistryService.java
cvs diff -u
A properly structured patch can be applied using the cvs patch utility from the project's root as follows:
patch -i [patch file name] -p0
Index: src/java/org/apache/jetspeed/services/registry/CastorRegistryService.java =================================================================== RCS file: /home/cvspublic/jakarta-jetspeed/src/java/org/apache/jetspeed/services/registry/CastorRegistryService.java,v retrieving revision 1.31 diff -u -r1.31 CastorRegistryService.java --- src/java/org/apache/jetspeed/services/registry/CastorRegistryService.java 16 Apr 2003 14:52:57 -0000 1.31 +++ src/java/org/apache/jetspeed/services/registry/CastorRegistryService.java 4 May 2003 21:13:34 -0000 @@ -392,7 +392,7 @@ String name = (String) i.next(); String fragmentFileName = defaults.getString(name); - String absFileName = new File(directory, fragmentFileName + extension).getAbsolutePath(); + String absFileName = new File(directory, fragmentFileName + extension).getCanonicalPath(); // add this name in the list of available registries names.add(name);