Production Coding Standards

From FilteredPush
Jump to: navigation, search

Documentation/Coding Standards

These are the coding standards, conventions, and engineering practices for developing the production FilteredPush software.

EJB 3.0 Programming restrictions (taken from the EJB 3.0 Specification)

21.1.2 Programming Restrictions (see the following link for the pdf download of the specification http://jcp.org/aboutJava/communityprocess/final/jsr220/)

This section describes the programming restrictions that a Bean Provider must follow to ensure that the enterprise bean is portable and can be deployed in any compliant EJB 3.0 container. The restrictions apply to the implementation of the business methods. Section 21.2, which describes the container’s view of these restrictions, defines the programming environment that all EJB containers must provide.

  • An enterprise bean must not use read/write static fields. Using read-only static fields is allowed. Therefore, it is recommended that all static fields in the enterprise bean class bedeclared as final.

This rule is required to ensure consistent runtime semantics because while some EJB containers may use a single JVM to execute all enterprise bean’s instances, others may distribute the instances across multiple JVMs.

  • An enterprise bean must not use thread synchronization primitives to synchronize execution of multiple instances.

This is for the same reason as above. Synchronization would not work if the EJB container distributed enterprise bean’s instances across multiple JVMs.

  • An enterprise bean must not use the AWT functionality to attempt to output information to a display, or to input information from a keyboard.

Most servers do not allow direct interaction between an application program and a keyboard/display attached to the server system.

  • An enterprise bean must not use the java.io package to attempt to access files and directories in the file system.

The file system APIs are not well-suited for business components to access data. Business components should use a resource manager API, such as JDBC, to store data.

  • An enterprise bean must not attempt to listen on a socket, accept connections on a socket, or use a socket for multicast.

The EJB architecture allows an enterprise bean instance to be a network socket client, but it does not allow it to be a network server. Allowing the instance to become a network server would conflict with the basic function of the enterprise bean— to serve the EJB clients.

  • The enterprise bean must not attempt to query a class to obtain information about the declared members that are not otherwise accessible to the enterprise bean because of the security rules of the Java language. The enterprise bean must not attempt to use the Reflection API to access information that the security rules of the Java programming language make unavailable.

Allowing the enterprise bean to access information about other classes and to access the classes in a manner that is normally disallowed by the Java programming language could compromise security.Runtime Environment Enterprise JavaBeans 3.0, Final Release Bean Provider’s Responsibilities

  • The enterprise bean must not attempt to create a class loader; obtain the current class loader; set the context class loader; set security manager; create a new security manager; stop the JVM; or change the input, output, and error streams.

These functions are reserved for the EJB container. Allowing the enterprise bean to use these functions could compromise security and decrease the container’s ability to properly manage the runtime environment.

  • The enterprise bean must not attempt to set the socket factory used by ServerSocket, Socket, or the stream handler factory used by URL.

These networking functions are reserved for the EJB container. Allowing the enterprise bean to use these functions could compromise security and decrease the container’s ability to properly manage the runtime environment.

  • The enterprise bean must not attempt to manage threads. The enterprise bean must not attempt to start, stop, suspend, or resume a thread, or to change a thread’s priority or name. The enterprise bean must not attempt to manage thread groups.

These functions are reserved for the EJB container. Allowing the enterprise bean to manage threads would decrease the container’s ability to properly manage the runtime environment.

  • The enterprise bean must not attempt to directly read or write a file descriptor.

Allowing the enterprise bean to read and write file descriptors directly could compromise security.

  • The enterprise bean must not attempt to obtain the security policy information for a particular code source.

Allowing the enterprise bean to access the security policy information would create a security hole.

  • The enterprise bean must not attempt to load a native library.

This function is reserved for the EJB container. Allowing the enterprise bean to load native code would create a security hole.

  • The enterprise bean must not attempt to gain access to packages and classes that the usual rules of the Java programming language make unavailable to the enterprise bean.

This function is reserved for the EJB container. Allowing the enterprise bean to perform this function would create a security hole.

  • The enterprise bean must not attempt to define a class in a package.

This function is reserved for the EJB container. Allowing the enterprise bean to perform this function would create a security hole.

  • The enterprise bean must not attempt to access or modify the security configuration objects (Policy, Security, Provider, Signer, and Identity).

These functions are reserved for the EJB container. Allowing the enterprise bean to use these functions could compromise security.

  • The enterprise bean must not attempt to use the subclass and object substitution features of the Java Serialization Protocol.

Allowing the enterprise bean to use these functions could compromise security.

  • The enterprise bean must not attempt to pass this as an argument or method result. The enterprise bean must pass the result of SessionContext.getBusinessObject, SessionContext.getEJBObject, SessionContext.getEJBLocalObject, EntityContext.getEJBObject, or EntityContext.getEJBLocalObject instead.

To guarantee portability of the enterprise bean’s implementation across all compliant EJB 3.0 containers, the Bean Provider should test the enterprise bean using a container with the security settings defined in Table 24. The tables define the minimal functionality that a compliant EJB container must provide to the enterprise bean instances at runtime.

Building

  • No generated files in SVN
  • Always possible to generate without eclipse

Logging

  • Use log4j for logging in Java. (auto generated(?) in eclipse).

Code documentation

  • Use javadoc format for class and method documentation.
  • Include SVN annotations in files. Note that $Author$ is the author of the svn change, which might not be the @author. See also svnAutoConf
  • Files should include the following documentation (embed in templates):
        Date created.  
	Copyright statement.
	License.
	@ see
	@ author (Author(s)) [all names spelled out in full]
	SVN annotations  $Date, $Author, $Rev, $Id.
 	* File last changed on $Date:$ by $Author:$ in $Rev:$.
	* $Id:$
  • At least $Id$ should be available programmatically from the class:
static final String classID= "$Id$";
...
public static String getClassID() {
     return classID;
}
  • Classes/interfaces (again, embed in templates)
	/** classname  summary sentence, purpose, patterns, relationship to other classses, example(s) of use including <code></code> blocks, role in APIs, stability  **/
  • Public constants, attributes
	   /** description  **/
  • Non-trivial public methods
	          /** method name summary sentence, purpose, uses, limitaions, error handling
                  * do not merely rephrase the method name, but rather provide additional information
                  * @param  for each parameter
                  * @returns
                  * @throws
                  **/
  • If relevant, particularly in public APIs, use @since (version) and @deprecated
  • Overloaded methods must have summary sentences that distinguish them from each other.
  • Trivial public methods, defined as get, set, is[boolean] that only set or return the value of a private attribute don't need specific documentation.

Unit Tests

  • Provide unit tests for every non-trivial method.
  • Unit tests must include fuzzing tests that demonstrate how the method handles extreme, edge, and attack values (e.g. methods that take an integer value as a parameter should demonstrate the behavior of the method for 0, maxint, maxint+1, minint, minint -1).
  • Methods that throw exceptions must include unit tests that test both the cases of values that are expected to throw exceptions and methods that are expected not to throw exceptions.

Components

  • Each component must include documentation and software engineering artifacts (e.g. UML class diagrams, sequence diagrams) that document the design of the component and provide an overview of the component for a programmer who is.
  • Each API to a component must be documented for programmers who might wish to code to that API.
  • Components can use the javadoc package.html file to document APIs as part of the generated javadocs, see http://java.sun.com/j2se/javadoc/writingdoccomments/#packagecomments for a template.

Repository commits

  • Each commit should relate to a single issue.
  • Document the bug tracking issue, the nature of the problem, and the details of the solution in each commit.
  • Commit messages must use the format “ISSUE: ... PURPOSE: ... DESCRIPTION: ...” where issue is a cross reference to the bug, purpose is an overview of the intent of the commit and the description includes details of the change. Example referencing issue 103
  • Repository organization
    • Trunk
      • {Component}
    • Tags
      • Use tags if no evolution is expected.
        • (e.g. {Component}6MonthRC1)
        • (e.g. {Component}LastRevBeforeMoveToSourceForge)
    • Branches
      • Use branches if evolution is expected.
    • VendorBranches
      • Use vendor branches to include source of software packages that we are modifying outside their normal repositories (e.g. Specify6, IPT), use the vendor branch to checkout unmodified current versions from the vendor's repository, and copy into relevant place in Trunk or Branches to make changes to our code (our changes should never be committed into a vendor branch, only to our separate modified copy in trunk or branches). To merge in an updated version of the vendor's code to our changes, update the checkout from the vendor's repository into the vendor branch, then merge this into the appropriate place in trunk or branches where our changes to the vendor's code are kept.
  • Non-code artifacts
    • Schemas, ontologies, etc.
      • Include SVN annotations $Date, $Author, $Rev, $Id.
      • Remember to add these SVN properties to the file.

. The documentation of the file should include:

		Date created.  
		Copyright statement.
		License.
		Author(s)  [names spelled out in full, since the svn $Author may be a username]
		File last changed on $Date:$ by $Author:$ in $Rev:$.
                $Id$
  • Document the purpose of the file.
  • Document everything.
    • Information Models. Follow style (subset of IDEFX1) from Phyloinformatics 7.
      • Entity-relationship diagram
      • List of all relationship cardinalities
      • Document each entity and attribute
        • Entities
          • Definition
          • Comment
          • See Also
        • Attributes
          • Definition
          • Domain
          • Business Rules [required; automatic, semi-manual, manual;
          • Example values
          • Comment

Code formatting

  • Use templates and set up your development environment to use these formats.

Java and PHP

  • Use spaces to indent. Indentation is 4 spaces.
  • Where to put braces and whitespace in method calls
int foo()
{
    if ( true ) // indentation: 4 spaces
    {
        foo();  // no space between () and ;
    }
    else
    {
        int bar = foo( a, b, c );
    }
}
  • Where to put whitespace in control structures
for ( int i=0; i<10; i++ )
{
    // do stuff
}
  • One line if statements version 1, acceptable form when condition and conditional block are short.
if ( true ) foo();  // this is OK
  • One line if statements version 2, preferred form when condition or conditional block are short, or when expansion of the conditional block is anticipated.
if ( true )         // this is OK too
{
    foo();
}
  • One line if statements versions not to use:
if ( true )         // this is NOT OK
    foo();
if ( true ) { foo(); }  // this is NOT OK

In general, blocks start and end with lines that only contain { and }.

XML

  • Space before close of empty element
<a />

User Turtle and Manchester for human readable rdf documents, but use RDF/XML for normative documents.

JSF

Use standard namespace abbreviations for JSF namespaces, e.g. h for http://java.sun.com/jsf/html and f for http://java.sun.com/jsf/core Where to put input values

<h:input value=”#{abc}” />
<h:outputText value=”abc” />
<h:input value="#{abc}">
    <f:validator  ... />
</h:input>

That is, put input values as values, not between tags.

SQL DDL

Avoid embedding SQL in Java. Use external configurations for SQL rather than embedding SQL queries in Java code. Push any SQL in Java to very limited back end pieces. Structure (use lower case for SQL reserved words and case sensitive table names).

create table Foo (          
    FooID bigint primary key,       
    fieldname vachar( 3 )
);


UML

No matter how encoded (if in some form of text), if the files are under subversion control, they should have a reasonable scheme for displaying the current value of the svn keyword "Id". When first created, they must explicitly be set with

svn propset svn:keywords "Id" filename [filename]

Keep in mind that you will not see expansion until that is invoked, and it will change only upon commit. svn keywords are expanded only on checkout or other fetch from the repository. Their value is not stored in the repository version of the file.

For those maintained with bouml, the following is the best practice:

  • On diagrams, in the upper right corner put a comment box with the string $Id$
  • On classes, add an attribute svnID with initial value the string "$Id$" (no quotation marks). This is done with right-click on the object in the bouml model panel.

Use extreme care when working with BOUML and SVN. Recommended practice:

  1. Checkout model within Eclipse
  2. SVN Update model
  3. Start BOUML and open model
  4. Make changes in BOUML
  5. Save changes in BOUML
  6. Close project in BOUML
  7. Refresh project in Eclipse
  8. SVN update
    1. If anything merged from repository, open project in BOUML and attempt to generate HTML documentation.
    2. If HTML generation succeeds, project is not corrupt and you can continue. If it fails, start again at step 1 with a fresh checkout from the repository.
    3. Close project in BOUML (to make sure that locks aren't committed).
  9. SVN commit from within Eclipse (to make sure any added files are added).
  10. Resume at step 2.

Ontology Coding and Documentation

See Ontology Coding and Documentation

Robustness

XML validation

Services and libraries consuming should be in a position to identify what, if any, schema for which they are implicitly or explictly expecting valid XML input. Such an artifact should also be in a position to report whether they are proceeding in the face of an invalid input, or whether it did not test validity.