Applied code formatter in guideline examples (#1073)

* Applied code formatter in guideline examples

- Applied code formatter in guideline examples
- Updated links (http, Java 8 and OSGi)

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>

* Update guidelines.md

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
pull/1075/head
Christoph Weitkamp 2019-11-12 20:35:14 +01:00 committed by Jerome Luckenbach
parent 559b54d65e
commit 8145798969
1 changed files with 48 additions and 42 deletions

View File

@ -27,24 +27,24 @@ The structure of a binding follows the structure of a typical OSGi bundle projec
```
|- src/main
|------- feature
|---------- feature.xml Your OSGI feature file
|------- java Your Java code
|---------- org/openhab/[...]
|---- feature
|-------- feature.xml Your OSGI feature file
|---- java Your Java code
|-------- org/openhab/[...]
|- src/main/resources/ESH-INF
|---- binding
|------- binding.xml Binding name, description, author and other meta data
|-----config Configuration description files when not in things files
|------- *.xml
|-------- binding.xml Binding name, description, author and other meta data
|---- config Configuration description files when not in things files
|-------- *.xml
|---- i18n Your localized binding texts
|------- *_<local>.properties
|-------- *_<local>.properties
|---- thing One or more xml files with thing descriptions
|------- *.xml
|-------- *.xml
|- src/test
|------- java It's easy to write unit tests and fellow developers will thank you
|---------- org/openhab/[...]
|------- resources Any resource files used in your unit tests, like test data
|---------- [...]
|---- java It's easy to write unit tests and fellow developers will thank you
|-------- org/openhab/[...]
|---- resources Any resource files used in your unit tests, like test data
|-------- [...]
|- NOTICE License information
| 3rd party content has to be given in the NOTICE file
|- pom.xml Build system file: Describe your dependencies here
@ -90,7 +90,7 @@ The rules are defined at https://github.com/openhab/static-code-analysis/tree/ma
```java
public static <T> boolean isEqual(GenericsType<T> g1, GenericsType<T> g2){
return g1.get().equals(g2.get());
return g1.get().equals(g2.get());
}
```
@ -98,7 +98,7 @@ public static <T> boolean isEqual(GenericsType<T> g1, GenericsType<T> g2){
Warnings that cannot be circumvented should be suppressed by using the `@SuppressWarnings` annotation.
* Your classes are generally organised within an internal package
```
```java
org.openhab.binding.coolbinding.internal
org.openhab.binding.coolbinding.internal.handler
org.openhab.binding.coolbinding.internal.discovery
@ -113,8 +113,8 @@ Remember that classes that are meant to be used by scripts or other bindings mus
```java
@Component(service=MyCoolService.class)
public class MyCoolService {
@Reference
private @NonNullByDefault({}) ItemRegistry itemRegistry;
@Reference
private @NonNullByDefault({}) ItemRegistry itemRegistry;
}
```
@ -134,19 +134,25 @@ Data-transfer-objects (DTOs map from Json/XML to Java classes) do not require Ja
## D. Language Levels and Libraries
1. openHAB generally targets the long time supported Java 8 and Java 11 releases with the following restrictions:
* To allow optimized runtimes, the set of Java packages to be used is further restricted to [Compact Profile 2](http://www.oracle.com/technetwork/java/embedded/resources/tech/compact-profiles-overview-2157132.html)
2. The [OSGi R6](http://www.osgi.org/Download/Release6) release with OSGI Compendium R7 is targeted, and newer features should not be used.
3. slf4j is used for logging.
* To allow optimized runtimes, the set of Java packages to be used is further restricted to [Compact Profile 2](https://www.oracle.com/technetwork/java/embedded/resources/tech/compact-profiles-overview-2157132.html).
2. The [OSGi Core Release 7](https://osgi.org/download/r7/osgi.core-7.0.0.pdf) with [OSGI Compendium Release 7](https://osgi.org/download/r7/osgi.cmpn-7.0.0.pdf) is targeted, and newer features should not be used.
3. [slf4j](http://slf4j.org) is used for logging.
You might also have the need to use other libraries for specific use cases like XML processing, networking etc.
See [Default libraries](#default-libraries) for more details.
## E. Runtime Behavior
1. Overridden methods from abstract classes or interfaces are expected to return fast unless otherwise stated in their JavaDoc. Expensive operations should therefore rather be scheduled as a job.
1. Creation of threads must be avoided. Instead, resort into using existing schedulers which use pre-configured thread pools. If there is no suitable scheduler available, start a discussion in the forum about it rather than creating a thread by yourself. For periodically executed jobs that do not require a fixed rate [scheduleWithFixedDelay](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html#scheduleWithFixedDelay(java.lang.Runnable,%20long,%20long,%20java.util.concurrent.TimeUnit)) should be preferred over [scheduleAtFixedRate](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledExecutorService.html#scheduleAtFixedRate(java.lang.Runnable,%20long,%20long,%20java.util.concurrent.TimeUnit)).
1. Bundles need to cleanly start and stop without throwing exceptions or malfunctioning. This can be tested by manually starting and stopping the bundle from the console (```stop <bundle-id>``` resp. ```start <bundle-id>```).
1. Bundles must not require any substantial CPU time. Test this e.g. using "top" or VisualVM and compare CPU utilization with your bundle stopped vs. started.
1. Overridden methods from abstract classes or interfaces are expected to return fast unless otherwise stated in their JavaDoc.
Expensive operations should therefore rather be scheduled as a job.
2. Creation of threads must be avoided.
Instead, resort into using existing schedulers which use pre-configured thread pools.
If there is no suitable scheduler available, start a discussion in the forum about it rather than creating a thread by yourself.
For periodically executed jobs that do not require a fixed rate [scheduleWithFixedDelay](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledExecutorService.html#scheduleWithFixedDelay(java.lang.Runnable,%20long,%20long,%20java.util.concurrent.TimeUnit)) should be preferred over [scheduleAtFixedRate](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledExecutorService.html#scheduleAtFixedRate(java.lang.Runnable,%20long,%20long,%20java.util.concurrent.TimeUnit)).
3. Bundles need to cleanly start and stop without throwing exceptions or malfunctioning.
This can be tested by manually starting and stopping the bundle from the console (```stop <bundle-id>``` resp. ```start <bundle-id>```).
4. Bundles must not require any substantial CPU time.
Test this e.g. using "top" or VisualVM and compare CPU utilization with your bundle stopped vs. started.
## F. Logging
@ -159,7 +165,7 @@ Please remember that every logging statement adds to code size and runtime cost.
```java
class MyCoolClass {
private final Logger logger = LoggerFactory.getLogger(MyCoolClass.class);
private final Logger logger = LoggerFactory.getLogger(MyCoolClass.class);
}
```
@ -167,9 +173,9 @@ class MyCoolClass {
```java
void myFun() {
String someValue = "abc";
int someInt = 12;
logger.log("Current value is {} and int is {}", someValue, someInt);
String someValue = "abc";
int someInt = 12;
logger.log("Current value is {} and int is {}", someValue, someInt);
}
```
@ -179,11 +185,11 @@ Configuration errors by users should only print log messages about what's wrong.
```java
void myFun() {
try {
doSomething();
} catch (IOException e) {
logger.warn("Explain what went wrong and how to avoid it. You can have arguments {}.", someVariable, e);
}
try {
doSomething();
} catch (IOException e) {
logger.warn("Explain what went wrong and how to avoid it. You can have arguments {}.", someVariable, e);
}
}
```
@ -191,9 +197,9 @@ void myFun() {
```java
void myFun() {
logger.trace("Enter myfun"); // DONT, DONT, really DONT do that
doSomething();
logger.trace("Leave myfun"); // DONT, DONT, really DONT do that
logger.trace("Enter myfun"); // DONT, DONT, really DONT do that
doSomething();
logger.trace("Leave myfun"); // DONT, DONT, really DONT do that
}
```
@ -201,8 +207,8 @@ void myFun() {
```java
void myFun() {
logger.debug("And now the thing goes online"); // DONT, DONT, really DONT do that
updateState(ThingState.ONLINE);
logger.debug("And now the thing goes online"); // DONT, DONT, really DONT do that
updateState(ThingState.ONLINE);
}
```
@ -287,10 +293,10 @@ The compiler will force you to check if `myField` is null, before using it:
```java
private void myFunction() {
final MyType myField = this.myField; // You need a local copy of the field for thread safety.
if (myField != null) {
myField.soSomething();
}
final MyType myField = this.myField; // You need a local copy of the field for thread safety.
if (myField != null) {
myField.soSomething();
}
}
```