Skip to content

Commit

Permalink
Merge pull request #39 from SAP/add-javadoc
Browse files Browse the repository at this point in the history
Add JavaDoc
  • Loading branch information
Johannes-Schneider authored Aug 12, 2022
2 parents 713d940 + 012612f commit 18a919d
Show file tree
Hide file tree
Showing 28 changed files with 989 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* A static access point for the default {@link ServiceBindingAccessor}. The statically stored instance inside this
* class can both be retrieved ({@link DefaultServiceBindingAccessor#getInstance()}) <bold>and</bold> manipulated
* ({@link DefaultServiceBindingAccessor#setInstance(ServiceBindingAccessor)}). Applications might want to overwrite the
* default instance during startup to tweak the default behavior of libraries that are relying on it. <br>
* <bold>Please note:</bold> It is considered best practice to offer APIs that accept a dedicated
* {@link ServiceBindingAccessor} instance instead of using the globally available instance stored inside this class.
* For example, libraries that are using {@link ServiceBindingAccessor}s should offer APIs such as the following:
*
* <pre>
* public ReturnType doSomethingWithServiceBindings( @Nonnull final ServiceBindingAccessor accessor );
* </pre>
*
* If that is, for some reason, not feasible, only then should this static default instance be used.
*/
public final class DefaultServiceBindingAccessor
{
@Nonnull
Expand All @@ -28,12 +43,33 @@ private DefaultServiceBindingAccessor()
throw new IllegalStateException("This utility class must not be instantiated.");
}

/**
* Returns the statically stored {@link ServiceBindingAccessor} instance. This instance can be changed at any time
* by using {@link DefaultServiceBindingAccessor#setInstance(ServiceBindingAccessor)}. <br>
* By default, the returned {@link ServiceBindingAccessor} will be assembled in the following way:
* <ol>
* <li>Use the {@link ServiceLoader} to find implementations of {@link ServiceBindingAccessor}.</li>
* <li>Combine instances of the found implementations using the {@link ServiceBindingMerger} (the merging strategy
* used is {@link ServiceBindingMerger#KEEP_EVERYTHING}).</li>
* <li>Wrap the resulting instance of {@link ServiceBindingMerger} into a {@link SimpleServiceBindingCache}.</li>
* </ol>
*
* @return The statically stored {@link ServiceBindingAccessor} instance.
*/
@Nonnull
public static ServiceBindingAccessor getInstance()
{
return instance;
}

/**
* Overwrites the statically stored {@link ServiceBindingAccessor} instance.
*
* @param accessor
* The {@link ServiceBindingAccessor} instance that should be returned by
* {@link DefaultServiceBindingAccessor#getInstance()}. If {@code accessor} is {@code null}, the default
* instance will be used (see {@link DefaultServiceBindingAccessor#getInstance()} for more details).
*/
public static void setInstance( @Nullable final ServiceBindingAccessor accessor )
{
if( accessor != null ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,19 @@

import com.sap.cloud.environment.servicebinding.api.exception.ServiceBindingAccessException;

/**
* Represents a source for {@link ServiceBinding}s.
*/
@FunctionalInterface
public interface ServiceBindingAccessor
{
/**
* Retrieves all {@link ServiceBinding}s that are accessible for this {@link ServiceBindingAccessor}.
*
* @return All accessible {@link ServiceBinding}s.
* @throws ServiceBindingAccessException
* Thrown if anything went wrong while loading the {@link ServiceBinding}s.
*/
@Nonnull
List<ServiceBinding> getServiceBindings()
throws ServiceBindingAccessException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,31 @@

import javax.annotation.Nonnull;

/**
* A {@link ServiceBindingAccessor} that merges the result of multiple other {@link ServiceBindingAccessor}s. This is
* done in the following manner:
* <ol>
* <li>Create an empty {@link java.util.Set} of {@link ServiceBinding}s - this is the final result that should be
* returned by {@link #getServiceBindings()}.</li>
* <li>For each delegate {@link ServiceBindingAccessor}:</li>
* <ol>
* <li>Call {@link ServiceBindingAccessor#getServiceBindings()}.</li>
* <li>For each {@link ServiceBinding}:</li>
* <ol>
* <li>Check whether the given {@link ServiceBinding} already exists<b>*</b> in the result {@link java.util.Set}.</li>
* <li>If the {@link ServiceBinding} does not yet exist, add it to the result.</li>
* </ol>
* </ol>
* </ol>
* <b>*:</b> This class uses the {@link EqualityComparer} to determine whether a given {@link ServiceBinding} already
* exists in the result {@link java.util.Set}.
*/
public class ServiceBindingMerger implements ServiceBindingAccessor
{
/**
* A {@link EqualityComparer} that always evaluates to {@code false}. Therefore, all {@link ServiceBinding}s will be
* included in the combined result set.
*/
@Nonnull
public static final EqualityComparer KEEP_EVERYTHING = ( a, b ) -> false;

Expand All @@ -21,6 +44,17 @@ public class ServiceBindingMerger implements ServiceBindingAccessor
@Nonnull
private final EqualityComparer equalityComparer;

/**
* Initializes a new {@link ServiceBindingMerger} instance. It will use the given {@code equalityComparer} to
* combine the individual {@link ServiceBinding}s returned from the given {@code accessors}.
*
* @param accessors
* The {@link ServiceBindingAccessor}s that should be used to get the actual {@link ServiceBinding}s
* from.
* @param equalityComparer
* The {@link EqualityComparer} to check whether a given {@link ServiceBinding} is already part of the
* combined result set.
*/
public ServiceBindingMerger(
@Nonnull final Collection<ServiceBindingAccessor> accessors,
@Nonnull final EqualityComparer equalityComparer )
Expand Down Expand Up @@ -56,9 +90,23 @@ public List<ServiceBinding> getServiceBindings()
return existingBindings.stream().anyMatch(contained -> equalityComparer.areEqual(contained, newBinding));
}

/**
* Represents a method object that is capable of comparing two instances of {@link ServiceBinding}. An instance of
* this interface will be used when checking whether a given {@link ServiceBinding} is already contained in the
* combined set of {@link ServiceBinding}s.
*/
@FunctionalInterface
public interface EqualityComparer
{
/**
* Determines whether the given {@link ServiceBinding} instances ({@code a} and {@code b}) are equal.
*
* @param a
* The first {@link ServiceBinding} instance.
* @param b
* The second {@link ServiceBinding} instance.
* @return {@code true} if {@code a} and {@code b} are equal, {@code false} otherwise.
*/
boolean areEqual( @Nonnull final ServiceBinding a, @Nonnull final ServiceBinding b );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@

import com.sap.cloud.environment.servicebinding.api.exception.ServiceBindingAccessException;

/**
* A {@link ServiceBindingAccessor} that caches the result of an other {@link ServiceBindingAccessor} for a certain
* amount of time.
*/
public class SimpleServiceBindingCache implements ServiceBindingAccessor
{
@Nonnull
Expand Down Expand Up @@ -51,6 +55,13 @@ public class SimpleServiceBindingCache implements ServiceBindingAccessor
@Nullable
private LocalDateTime lastCacheRenewal = null;

/**
* Initializes a new {@link SimpleServiceBindingCache} instance that retrieves {@link ServiceBinding}s from the
* given {@code delegateAccessor} and caches them for 5 minutes.
*
* @param delegateAccessor
* The {@link ServiceBindingAccessor} to retrieve the {@link ServiceBinding}s from.
*/
public SimpleServiceBindingCache( @Nonnull final ServiceBindingAccessor delegateAccessor )
{
this(delegateAccessor, DEFAULT_CACHE_DURATION, DEFAULT_LOCAL_DATE_TIME_SUPPLIER);
Expand All @@ -66,6 +77,15 @@ public SimpleServiceBindingCache( @Nonnull final ServiceBindingAccessor delegate
this.localDateTimeSupplier = localDateTimeSupplier;
}

/**
* Initializes a new {@link SimpleServiceBindingCache} instance that retrieves {@link ServiceBinding}s from the
* given {@code delegateAccessor} and caches them for the given {@code cacheDuration}.
*
* @param delegateAccessor
* The {@link ServiceBindingAccessor} to retrieve the {@link ServiceBinding}s from.
* @param cacheDuration
* The cahing {@link Duration}.
*/
public SimpleServiceBindingCache(
@Nonnull final ServiceBindingAccessor delegateAccessor,
@Nonnull final Duration cacheDuration )
Expand Down Expand Up @@ -133,6 +153,9 @@ private boolean isExpired( @Nonnull final Temporal now )
return cacheDuration.minus(durationSinceLastCacheRenewal).isNegative();
}

/**
* Invalidate the cache.
*/
public void invalidate()
{
logger.debug("Invalidating service binding cache.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,47 @@

import javax.annotation.Nonnull;

/**
* A {@link RuntimeException} that is thrown if anything goes wrong while accessing
* {@link com.sap.cloud.environment.servicebinding.api.ServiceBinding}s.
*/
public class ServiceBindingAccessException extends RuntimeException
{
private static final long serialVersionUID = 8589108462580396260L;

public ServiceBindingAccessException()
{
}

/**
* Initializes a new {@link ServiceBindingAccessException} instance with a dedicated {@code message}.
*
* @param message
* The exception message.
*/
public ServiceBindingAccessException( @Nonnull final String message )
{
super(message);
}

public ServiceBindingAccessException( @Nonnull final String message, @Nonnull final Throwable cause )
/**
* Initializes a new {@link ServiceBindingAccessException} instance with a dedicated {@code cause}.
*
* @param cause
* The exception cause.
*/
public ServiceBindingAccessException( @Nonnull final Throwable cause )
{
super(message, cause);
super(cause);
}

public ServiceBindingAccessException( @Nonnull final Throwable cause )
/**
* Initializes a new {@link ServiceBindingAccessException} instance with a dedicated {@code message} and
* {@code cause}.
*
* @param message
* The exception message.
* @param cause
* The exception cause.
*/
public ServiceBindingAccessException( @Nonnull final String message, @Nonnull final Throwable cause )
{
super(cause);
super(message, cause);
}
}
Loading

0 comments on commit 18a919d

Please sign in to comment.