package fr.jcgay.notification.notifier.additional;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import fr.jcgay.notification.DiscoverableNotifier;
import fr.jcgay.notification.MultipleSendNotificationException;
import fr.jcgay.notification.Notification;
import fr.jcgay.notification.Notifier;
import org.slf4j.Logger;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
public class AdditionalNotifier implements DiscoverableNotifier {
private static final Logger LOGGER = getLogger(AdditionalNotifier.class);
private final Set<DiscoverableNotifier> secondary;
private final DiscoverableNotifier primary;
private final boolean notifyWithSecondaryNotifiers;
public AdditionalNotifier(DiscoverableNotifier primary, Set<DiscoverableNotifier> secondary) {
checkArgument(!secondary.isEmpty());
this.primary = checkNotNull(primary);
this.secondary = secondary;
this.notifyWithSecondaryNotifiers = Boolean.valueOf(System.getProperty("notifyAll"));
}
@Override
public Notifier init() {
List<Exception> errors = new ArrayList<Exception>();
safeInit(primary, errors);
if (notifyWithSecondaryNotifiers) {
for (DiscoverableNotifier notifier : secondary) {
safeInit(notifier, errors);
}
}
failIfNotEmpty(errors);
return this;
}
@Override
public boolean tryInit() {
return false;
}
@Override
public void send(Notification notification) {
List<Exception> errors = new ArrayList<Exception>();
safeSend(primary, notification, errors);
if (notifyWithSecondaryNotifiers) {
for (DiscoverableNotifier notifier : secondary) {
safeSend(notifier, notification, errors);
}
}
failIfNotEmpty(errors);
}
@Override
public void close() {
List<Exception> errors = new ArrayList<Exception>();
safeClose(primary, errors);
if (notifyWithSecondaryNotifiers) {
for (DiscoverableNotifier notifier : secondary) {
safeClose(notifier, errors);
}
}
failIfNotEmpty(errors);
}
@Override
public boolean isPersistent() {
if (notifyWithSecondaryNotifiers) {
boolean result = primary.isPersistent();
for (DiscoverableNotifier notifier : secondary) {
result |= notifier.isPersistent();
}
return result;
}
return primary.isPersistent();
}
public static void safeClose(DiscoverableNotifier notifier, List<Exception> errors) {
try {
notifier.close();
} catch (RuntimeException e) {
LOGGER.debug("Error closing {}.", notifier, e);
errors.add(e);
}
}
private static void failIfNotEmpty(List<Exception> errors) {
if (!errors.isEmpty()) {
throw new MultipleSendNotificationException(errors);
}
}
private static void safeSend(DiscoverableNotifier notifier, Notification notification, List<Exception> errors) {
try {
notifier.send(notification);
} catch (RuntimeException e) {
LOGGER.debug("Error sending notification {} with {}.", notification, notifier, e);
errors.add(e);
}
}
public static void safeInit(DiscoverableNotifier notifier, List<Exception> errors) {
try {
notifier.init();
} catch (RuntimeException e) {
LOGGER.debug("Error initializing {}.", notifier, e);
errors.add(e);
}
}
@Override
public int hashCode() {
return Objects.hashCode(secondary, primary, notifyWithSecondaryNotifiers);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
final AdditionalNotifier other = (AdditionalNotifier) obj;
return Objects.equal(this.secondary, other.secondary)
&& Objects.equal(this.primary, other.primary)
&& Objects.equal(this.notifyWithSecondaryNotifiers, other.notifyWithSecondaryNotifiers);
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("secondary", secondary)
.add("primary", primary)
.add("notifyWithSecondaryNotifiers", notifyWithSecondaryNotifiers)
.toString();
}
}