Skip to content

Commit

Permalink
Merge pull request #5 from aditosoftware/reactive
Browse files Browse the repository at this point in the history
ReactiveBuilder for RxJava
  • Loading branch information
jboesl authored Nov 21, 2018
2 parents e753ed8 + d9607eb commit e442aec
Show file tree
Hide file tree
Showing 23 changed files with 1,217 additions and 4 deletions.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<groupId>de.adito.propertly</groupId>
<artifactId>propertly.parent</artifactId>
<packaging>pom</packaging>
<version>0.4.3-SNAPSHOT</version>
<version>1.0.0</version>

<name>${project.groupId}:${project.artifactId}</name>
<description>a listenable hierarchical data model</description>
Expand Down Expand Up @@ -56,6 +56,7 @@

<modules>
<module>propertly.core</module>
<module>propertly.reactive</module>
<module>propertly.serialization</module>
</modules>

Expand Down Expand Up @@ -114,7 +115,6 @@
<version>3.0.1</version>
<configuration>
<failOnError>false</failOnError>
<additionalparam>-Xdoclint:none</additionalparam>
</configuration>
</plugin>

Expand Down
2 changes: 1 addition & 1 deletion propertly.core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>de.adito.propertly</groupId>
<artifactId>propertly.parent</artifactId>
<version>0.4.3-SNAPSHOT</version>
<version>1.0.0</version>
</parent>

<artifactId>propertly.core</artifactId>
Expand Down
63 changes: 63 additions & 0 deletions propertly.reactive/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>de.adito.propertly</groupId>
<artifactId>propertly.parent</artifactId>
<version>1.0.0</version>
</parent>

<artifactId>propertly.reactive</artifactId>

<dependencies>
<dependency>
<groupId>de.adito.propertly</groupId>
<artifactId>propertly.core</artifactId>
<version>${project.version}</version>
</dependency>

<!-- RxJava 2 -->
<dependency>
<groupId>io.reactivex.rxjava2</groupId>
<artifactId>rxjava</artifactId>
<version>2.2.3</version>
</dependency>

<!-- Utility for RxJava 2 -->
<dependency>
<groupId>de.adito.util</groupId>
<artifactId>reactive</artifactId>
<version>1.0.2</version>
</dependency>

<!-- Mockito -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.23.0</version>
<scope>test</scope>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Export-Package>
de.adito.propertly.reactive.api
</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>


</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package de.adito.propertly.reactive.api.builder;

import io.reactivex.Observable;
import org.jetbrains.annotations.NotNull;

import java.util.Optional;

/**
* Common Interface for all Propertly-Observables constructed by PropertlyObservableBuilder
*
* @see PropertlyObservableBuilder
* @author w.glanzer, 09.11.2018
*/
public interface IBuilderObservable<V>
{

/**
* Constructs the underlying observable.
* The Value is an Optional of the "real" value, because RxJava
* does not allow to return NULL inside one Observable.
* The returned Observable is not distincted automatically.
*
* @return the observable, not <tt>null</tt>
*/
@NotNull
Observable<Optional<V>> toObservable();

/**
* Constructs the underlying observable.
* The Value is the outboxed value of {@link IBuilderObservable##toObservable()},
* previously filtered by {@link Optional#isPresent()}.
* Use this with care - you will not be notified with NULL-Value-Changes (e.g. propertyValueChange with newValue=NULL).
* The returned Observable is not distincted automatically.
*
* @return the observable, not <tt>null</tt>
*/
@NotNull
Observable<V> toObservableUnsafe();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package de.adito.propertly.reactive.api.builder;

import de.adito.propertly.core.spi.*;
import io.reactivex.Observable;
import org.jetbrains.annotations.NotNull;

import java.util.*;

/**
* A PropertyListObservable is a wrapper around an Observable with
* a list of properties in it.
*
* @param <S> PropertyPitProvider all properties belong to
* @param <T> Value-Type of all properties
* @author w.glanzer, 09.11.2018
*/
public interface IBuilderPropertyListObservable<S extends IPropertyPitProvider, T> extends IBuilderObservable<List<IProperty<S, T>>>
{

/**
* Constructs an Observable that contains the values of all
* properties in this PropertyListObservable. <br>
* The resulting Observable is not distincted automatically.<br>
* All properties are observed, so the Observable will get notified if any of the
* containing properties changes.
* <b>It does not contain any NULL-Values</b>. If you have the need to, use {@link IBuilderPropertyListObservable#emitValues(boolean)}
*
* @return the Observable, not <tt>null</tt>
* @see IBuilderPropertyListObservable#emitDistinctedValues()
*/
@NotNull
default Observable<Optional<List<T>>> emitValues()
{
return emitValues(false);
}

/**
* Constructs an Observable that contains the values of all
* properties in this PropertyListObservable. <br>
* The resulting Observable is not distincted automatically. <br>
* All properties are observed, so the Observable will get notified if any of the
* containing properties changes.
*
* @param pIncludeNullValues <tt>true</tt>, if the inner list should contain NULL-Values, if a property has <tt>null</tt> as a value
* @return the Observable, not <tt>null</tt>
* @see IBuilderPropertyListObservable#emitDistinctedValues(boolean)
*/
@NotNull
Observable<Optional<List<T>>> emitValues(boolean pIncludeNullValues);

/**
* Constructs an Observable that contains the values of all
* properties in this PropertyListObservable. <br>
* The resulting Observable <b>will be distincted automatically</b><br>
* All properties are observed, so the Observable will get notified if any of the
* containing properties changes. <br>
* <b>It does not contain any NULL-Values</b>. If you have the need to, use {@link IBuilderPropertyListObservable#emitDistinctedValues(boolean)}
*
* @return the Observable, not <tt>null</tt>
*/
@NotNull
default Observable<Optional<List<T>>> emitDistinctedValues()
{
return emitValues()
.distinctUntilChanged();
}

/**
* Constructs an Observable that contains the values of all
* properties in this PropertyListObservable. <br>
* The resulting Observable <b>will be distincted automatically</b><br>
* All properties are observed, so the Observable will get notified if any of the
* containing properties changes.
*
* @param pIncludeNullValues <tt>true</tt>, if the inner list should contain NULL-Values, if a property has <tt>null</tt> as a value
* @return the Observable, not <tt>null</tt>
*/
@NotNull
default Observable<Optional<List<T>>> emitDistinctedValues(boolean pIncludeNullValues)
{
return emitValues(pIncludeNullValues)
.distinctUntilChanged();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package de.adito.propertly.reactive.api.builder;

import de.adito.propertly.core.spi.*;
import io.reactivex.Observable;
import org.jetbrains.annotations.NotNull;

import java.util.Optional;

/**
* A BuilderPropertyObservable is a wrapper around an Observable that
* contains a single Property as value. <br>
* It will trigger, if propertyNameChanged/propertyValueChanged is fired
*
* @param <S> PropertyPitProvider this property belongs to
* @param <T> Value-Type of the property
* @author w.glanzer, 09.11.2018
*/
public interface IBuilderPropertyObservable<S extends IPropertyPitProvider, T> extends IBuilderObservable<IProperty<S, T>>
{

/**
* Constructs an Observable that contains an Optional representing
* the value of the underlying property. <br>
* The Optional will be empty, if the property has NULL as value. <br>
* This Observable is not distincted automatically.
*
* @return the Observable, not <tt>null</tt>
*/
@NotNull
Observable<Optional<T>> emitValue();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package de.adito.propertly.reactive.api.builder;

import de.adito.propertly.core.spi.*;
import io.reactivex.Observable;
import org.jetbrains.annotations.NotNull;

import java.util.*;

/**
* a BuilderPropertyPitObservable is a Observable that
* contains a PropertyPitProvider as value and will trigger,
* if propertyAdded/propertyOrderChanged/propertyRemoved is fired
*
* @param <P> Parent of the containing PropertyPitProvider
* @param <S> Self-Type of the containing PropertyPitProvider
* @param <T> Value-Type the containing PropertyPitProvider can contain
* @author w.glanzer, 09.11.2018
*/
public interface IBuilderPropertyPitObservable<P extends IPropertyPitProvider, S extends IPropertyPitProvider<P, S, T>, T>
extends IBuilderObservable<S>
{

/**
* Emits a single Property, identified by the given PropertyDescription. <br>
* If the property is not found in this pit, the resulting BuilderPropertyObservable will be empty. <br>
* The PropertyObservable will trigger, if the property will be added/changed/removed
*
* @param pDescription Description to identify the property to observe on
* @param <T2> Value-Type of the property and it's description
* @return the IBuilderPropertyObservable, not <tt>null</tt>
*/
@NotNull <T2> IBuilderPropertyObservable<S, T2> emitProperty(@NotNull IPropertyDescription<? super S, T2> pDescription);

/**
* Emits a child PropertyPitProvider, identified by the given PropertyDescription. <br>
* If the property is not found in this pit, the resulting BuilderPropertyPitObservable will be empty <br>
* The PropertyPitObservable will trigger, if the property that contains the searched pit will be added/changed/removed or
* the pit itself does something like propertyAdded/propertyOrderChanged/propertyRemoved.
*
* @param pDescription Description to identify the property (with an PropertyPitProvider as value-type) to observe on
* @param <S2> Value-Type of the property -> It has to be a subtype of PropertyPitProvider!
* @return IBuilderPropertyPitObservable, not <tt>null</tt>
*/
@NotNull <P2 extends IPropertyPitProvider, S2 extends IPropertyPitProvider<P2, S2, T2>, T2>
IBuilderPropertyPitObservable<P2, S2, T2> emitPropertyPit(@NotNull IPropertyDescription<? super S, S2> pDescription);

/**
* Emits all properties this PropertyPitProvider has.
*
* @return IBuilderPropertyListObservable, not <tt>null</tt>
*/
@NotNull
IBuilderPropertyListObservable<S, T> emitProperties();

/**
* Emits all values of all properties this PropertyPit has.
* It calls {@link IBuilderPropertyPitObservable#emitProperties()} first, to retrieve a list of all properties,
* and then emits their values with {@link IBuilderPropertyListObservable#emitValues()}
* The resulting Observable is not distincted automatically.
* <b>It does not contain any NULL-Values</b>. If you have the need to, use {@link IBuilderPropertyPitObservable#emitPropertyValues(boolean)}
*
* @return the Observable containing all values as list, not <tt>null</tt>
*/
@NotNull
default Observable<Optional<List<T>>> emitPropertyValues()
{
return emitProperties().emitValues();
}

/**
* Emits all values of all properties this PropertyPit has.
* It calls {@link IBuilderPropertyPitObservable#emitProperties()} first, to retrieve a list of all properties,
* and then emits their values with {@link IBuilderPropertyListObservable#emitValues()}
* The resulting Observable is not distincted automatically.
*
* @param pIncludeNullValues <tt>true</tt>, if the inner list should contain NULL-Values, if a property has <tt>null</tt> as a value
* @return the Observable containing all values as list, not <tt>null</tt>
*/
@NotNull
default Observable<Optional<List<T>>> emitPropertyValues(boolean pIncludeNullValues)
{
return emitProperties().emitValues(pIncludeNullValues);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package de.adito.propertly.reactive.api.builder;

import de.adito.propertly.core.spi.*;
import de.adito.propertly.reactive.impl.InternalObservableFactory;
import de.adito.propertly.reactive.impl.builder.*;
import org.jetbrains.annotations.NotNull;

/**
* Builder for all {@link IBuilderObservable}s, the main entrypoint for
* interacting with the API of "propertly.reactive"
*
* @author w.glanzer, 08.11.2018
*/
public class PropertlyObservableBuilder
{

private PropertlyObservableBuilder()
{
}

/**
* Creates an PropertyPitObservable from a PropertyPitProvider.
*
* @param pPropertyPitProvider Source, to start building the reactive chain
* @return IBuilderPropertyPitProvider, not <tt>null</tt>
*/
@NotNull
public static <P extends IPropertyPitProvider, S extends IPropertyPitProvider<P, S, T>, T>
IBuilderPropertyPitObservable<P, S, T> create(@NotNull IPropertyPitProvider<P, S, T> pPropertyPitProvider)
{
return new BuilderPropertyPitObservable<>(InternalObservableFactory.propertyPit((S) pPropertyPitProvider, false), false);
}

/**
* Creates an PropertyObservable from a Property.
*
* @param pProperty Source, to start building the reactive chain
* @return IBuilderPropertyObservable, not <tt>null</tt>
*/
@NotNull
public static <P extends IPropertyPitProvider, V> IBuilderPropertyObservable<P, V> create(@NotNull IProperty<P, V> pProperty)
{
return new BuilderPropertyObservable<>(InternalObservableFactory.property(pProperty, false), false);
}

}
Loading

0 comments on commit e442aec

Please sign in to comment.