Developer Guidelines - deegree/deegree3 GitHub Wiki

Source code formatting

Contributors should use the Maven plugin spring-javaformat-maven-plugin for formatting all source codes. Read further in Setting-up deegree3 in your IDE how to enable it in your IDE.

Note that you can automatically apply the formatter by running the maven plugin:

mvn spring-javaformat:apply

Java file headers

This is the header to use for new java files. Download https://raw.github.com/wiki/deegree/deegree3/codetemplates.xml for easy Eclipse import (includes class headers).

See it here:

/*----------------------------------------------------------------------------
 This file is part of deegree
 Copyright (C) 2001-2024 by:
 - Department of Geography, University of Bonn -
 and
 - lat/lon GmbH -
 and others

 This library is free software; you can redistribute it and/or modify it under
 the terms of the GNU Lesser General Public License as published by the Free
 Software Foundation; either version 2.1 of the License, or (at your option)
 any later version.
 This library is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 details.
 You should have received a copy of the GNU Lesser General Public License
 along with this library; if not, write to the Free Software Foundation, Inc.,
 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

 Contact information:

 e-mail: [email protected]
 website: http://www.deegree.org/
----------------------------------------------------------------------------*/

Javadoc class headers

This is the template to be used for class javadocs.

Download https://raw.github.com/wiki/deegree/deegree3/codetemplates.xml for easy eclipse import (includes the file headers).

See an example here:

/**
 * This class is responsible for these things.
 * 
 * @author <a href="mailto:[email protected]">John Doe</a>
 *
 * @since 3.4
 */

Dealing with exceptions in deegree

As a starting point read the following post which gives an overview of dos and don'ts: https://nobugsproject.com/2017/05/28/11-mistakes-java-developers-make-when-using-exceptions/

Logging

In deegree 3, we're usually using slf4j as API and log4j as the underlying logging framework. It is generally a nice thing to have a 'template' log4j2.properties, where the important classes are listed together with a description what is logged on which level, like this:

# logs very important information
#log4j.logger.org.deegree.services.wms.MostImportantClass=TRACE

# logs the most important information
#log4j.logger.org.deegree.services.wms.MostImportantClass=DEBUG

A useful log4j2.properties file is located in deegree-services/deegree-webservices/src/main/resources/log4j2.properties. For more information about logging see also the deegree webservices handbook, chapter "Logging".

Following good practices, we would like to encourage deegree developers to use parametrized logging whenever possible.

LOG.debug("The new entry is {}. It replaces {}.", entry, oldEntry);

This speeds up logging when the requested level is turned off, for example. It also makes it easier to find messages in the source tree or to filter logging during runtime.

For more details, see https://www.slf4j.org/faq.html#logging_performance

XMLStreamWriter

XMLStreamReader and XMLStreamWriter are used heavily in deegree 3 for processing streams of XML. Special care has to be taken in order to use XMLStreamWriter in a way that is compatible with different StaX implementations (e.g. bundled versions with JDK, Woodstox, StaX implementation on Oracle Weblogic). Problems occur when dealing with qualified element/attribute names and binding namespaces.

Best practices:

  • See http://ws.apache.org/axiom/devguide/ch03.html for more info on established usage patterns for XMLStreamWriter. All deegree code should follow usage pattern 3.
  • Don't set javax.xml.stream.isRepairingNamespaces to true when creating the XMLStreamWriter. It may look like a good idea for easing the task of binding namespaces and catching unbound namespaces, but it turned out that the introduced behaviour differs between different StaX-implementations and it is makes it hard to detect possible errors. Without it, you have to call XMLStreamWriter.writeNamespace(String prefix, String uri) manually, but at least a dependable behavior is achieved among implementations.
  • Understand that (in non-repairing mode) XMLStreamWriter.setPrefix(String prefix, String uri) only makes a namespace binding known to the XMLStreamWriter instance, but does not actually write xmlns:prefix="namespace" to the stream. XMLStreamWriter.writeNamespace(String prefix, String uri) writes xmlns:prefix="namespace" to the stream (and makes the binding known as well).
  • Using XMLStreamWriter.write (String namespaceURI, String localName) should be preferred over XMLStreamWriter.write (String prefix, String localName, String namespaceURI), as it eases the task of changing the prefix (and avoids redundancy in general). Only use XMLStreamWriter.write (String prefix,String localName,String namespaceURI) in case an element needs to be written that has a namespace that may be unbound at this point.
  • There's a special issue with writeEmptyElement(...). The problem is that the local bindings for this element are kept after the empty element has been written. Apparently, StaX must do so in order to allow writing of (qualified) attributes. In order to make the namespace context forget the local bindings, writer.writeCharacters( "" ); seems to do the trick.