// Path: puree/src/main/java/com/cookpad/puree/PureeFilter.java
// @ParametersAreNonnullByDefault
// public interface PureeFilter {
// 
//     @Nullable
//     String apply(String jsonLog);
// }
// 
// Path: puree/src/main/java/com/cookpad/puree/PureeLogger.java
// @ParametersAreNonnullByDefault
// public class PureeLogger {
//     private final PureeSerializer pureeSerializer;
// 
//     final Map<Class<?>, List<PureeOutput>> sourceOutputMap = new HashMap<>();
// 
//     final PureeStorage storage;
// 
//     final ScheduledExecutorService executor;
// 
//     public PureeLogger(Map<Class<?>, List<PureeOutput>> sourceOutputMap, PureeSerializer pureeSerializer, PureeStorage storage,
//             ScheduledExecutorService executor) {
//         this.sourceOutputMap.putAll(sourceOutputMap);
//         this.pureeSerializer = pureeSerializer;
//         this.storage = storage;
//         this.executor = executor;
// 
//         forEachOutput(new PureeLogger.Consumer<PureeOutput>() {
//             @Override
//             public void accept(@Nonnull PureeOutput value) {
//                 value.initialize(PureeLogger.this);
//             }
//         });
//     }
// 
//     public void send(Object log) {
//         List<PureeOutput> outputs = getRegisteredOutputPlugins(log);
//         for (PureeOutput output : outputs) {
//             output.receive(serializeLog(log));
//         }
//     }
// 
//     public PureeStorage getStorage() {
//         return storage;
//     }
// 
//     public ScheduledExecutorService getExecutor() {
//         return executor;
//     }
// 
//     public Records getBufferedLogs() {
//         return storage.selectAll();
//     }
// 
//     public void discardBufferedLogs() {
//         storage.clear();
//     }
// 
//     public void truncateBufferedLogs(int truncateThresholdInRows) {
//         storage.truncateBufferedLogs(truncateThresholdInRows);
//     }
// 
//     public void flush() {
//         forEachOutput(new PureeLogger.Consumer<PureeOutput>() {
//             @Override
//             public void accept(@Nonnull PureeOutput value) {
//                 value.flush();
//             }
//         });
//     }
// 
//     /**
//      * Serialize a {@link Object} into a json string representation.
//      *
//      * @param log {@link Object}.
//      * @return serialized json object.
//      */
//     @Nonnull
//     public String serializeLog(Object log) {
//         return pureeSerializer.serialize(log);
//     }
// 
//     @Nonnull
//     public List<PureeOutput> getRegisteredOutputPlugins(Object log) {
//         return getRegisteredOutputPlugins(log.getClass());
//     }
// 
//     @Nonnull
//     public List<PureeOutput> getRegisteredOutputPlugins(Class<?> logClass) {
//         List<PureeOutput> outputs = sourceOutputMap.get(logClass);
//         if (outputs == null) {
//             throw new NoRegisteredOutputPluginException("No output plugin registered for " + logClass);
//         }
//         return outputs;
//     }
// 
//     public interface Consumer<T> {
// 
//         void accept(@Nonnull T value);
//     }
// 
//     public void forEachOutput(Consumer<PureeOutput> f) {
//         for (List<PureeOutput> outputs : new HashSet<>(sourceOutputMap.values())) {
//             for (PureeOutput output : outputs) {
//                 f.accept(output);
//             }
//         }
//     }
// 
//     public static class NoRegisteredOutputPluginException extends IllegalStateException {
// 
//         public NoRegisteredOutputPluginException(String detailMessage) {
//             super(detailMessage);
//         }
//     }
// }
// 
// Path: puree/src/main/java/com/cookpad/puree/storage/PureeStorage.java
// public interface PureeStorage {
// 
//     public void insert(String type, String jsonLog);
//     public Records select(String type, int logsPerRequest);
//     public Records selectAll();
//     public void delete(Records records);
//     public void truncateBufferedLogs(int maxRecords);
//     public void clear();
//     public boolean lock();
//     public void unlock();
// }


import com.cookpad.puree.PureeFilter;
import com.cookpad.puree.PureeLogger;
import com.cookpad.puree.storage.PureeStorage;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
package com.cookpad.puree.outputs;




@ParametersAreNonnullByDefault
public abstract class PureeOutput {
    protected OutputConfiguration conf;
    protected PureeStorage storage;
    protected List<PureeFilter> filters = new ArrayList<>();

    public void registerFilter(PureeFilter filter) {
        filters.add(filter);
    }

    public PureeOutput withFilters(PureeFilter... filters) {
        Collections.addAll(this.filters, filters);
        return this;
    }

    public PureeOutput withFilters(Collection<PureeFilter> filters) {
        this.filters.addAll(filters);
        return this;
    }


// Path: puree/src/main/java/com/cookpad/puree/PureeFilter.java
// @ParametersAreNonnullByDefault
// public interface PureeFilter {
// 
//     @Nullable
//     String apply(String jsonLog);
// }
// 
// Path: puree/src/main/java/com/cookpad/puree/PureeLogger.java
// @ParametersAreNonnullByDefault
// public class PureeLogger {
//     private final PureeSerializer pureeSerializer;
// 
//     final Map<Class<?>, List<PureeOutput>> sourceOutputMap = new HashMap<>();
// 
//     final PureeStorage storage;
// 
//     final ScheduledExecutorService executor;
// 
//     public PureeLogger(Map<Class<?>, List<PureeOutput>> sourceOutputMap, PureeSerializer pureeSerializer, PureeStorage storage,
//             ScheduledExecutorService executor) {
//         this.sourceOutputMap.putAll(sourceOutputMap);
//         this.pureeSerializer = pureeSerializer;
//         this.storage = storage;
//         this.executor = executor;
// 
//         forEachOutput(new PureeLogger.Consumer<PureeOutput>() {
//             @Override
//             public void accept(@Nonnull PureeOutput value) {
//                 value.initialize(PureeLogger.this);
//             }
//         });
//     }
// 
//     public void send(Object log) {
//         List<PureeOutput> outputs = getRegisteredOutputPlugins(log);
//         for (PureeOutput output : outputs) {
//             output.receive(serializeLog(log));
//         }
//     }
// 
//     public PureeStorage getStorage() {
//         return storage;
//     }
// 
//     public ScheduledExecutorService getExecutor() {
//         return executor;
//     }
// 
//     public Records getBufferedLogs() {
//         return storage.selectAll();
//     }
// 
//     public void discardBufferedLogs() {
//         storage.clear();
//     }
// 
//     public void truncateBufferedLogs(int truncateThresholdInRows) {
//         storage.truncateBufferedLogs(truncateThresholdInRows);
//     }
// 
//     public void flush() {
//         forEachOutput(new PureeLogger.Consumer<PureeOutput>() {
//             @Override
//             public void accept(@Nonnull PureeOutput value) {
//                 value.flush();
//             }
//         });
//     }
// 
//     /**
//      * Serialize a {@link Object} into a json string representation.
//      *
//      * @param log {@link Object}.
//      * @return serialized json object.
//      */
//     @Nonnull
//     public String serializeLog(Object log) {
//         return pureeSerializer.serialize(log);
//     }
// 
//     @Nonnull
//     public List<PureeOutput> getRegisteredOutputPlugins(Object log) {
//         return getRegisteredOutputPlugins(log.getClass());
//     }
// 
//     @Nonnull
//     public List<PureeOutput> getRegisteredOutputPlugins(Class<?> logClass) {
//         List<PureeOutput> outputs = sourceOutputMap.get(logClass);
//         if (outputs == null) {
//             throw new NoRegisteredOutputPluginException("No output plugin registered for " + logClass);
//         }
//         return outputs;
//     }
// 
//     public interface Consumer<T> {
// 
//         void accept(@Nonnull T value);
//     }
// 
//     public void forEachOutput(Consumer<PureeOutput> f) {
//         for (List<PureeOutput> outputs : new HashSet<>(sourceOutputMap.values())) {
//             for (PureeOutput output : outputs) {
//                 f.accept(output);
//             }
//         }
//     }
// 
//     public static class NoRegisteredOutputPluginException extends IllegalStateException {
// 
//         public NoRegisteredOutputPluginException(String detailMessage) {
//             super(detailMessage);
//         }
//     }
// }
// 
// Path: puree/src/main/java/com/cookpad/puree/storage/PureeStorage.java
// public interface PureeStorage {
// 
//     public void insert(String type, String jsonLog);
//     public Records select(String type, int logsPerRequest);
//     public Records selectAll();
//     public void delete(Records records);
//     public void truncateBufferedLogs(int maxRecords);
//     public void clear();
//     public boolean lock();
//     public void unlock();
// }


// Path: puree/src/main/java/com/cookpad/puree/outputs/PureeOutput.java
import com.cookpad.puree.PureeFilter;
import com.cookpad.puree.PureeLogger;
import com.cookpad.puree.storage.PureeStorage;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;

package com.cookpad.puree.outputs;




@ParametersAreNonnullByDefault
public abstract class PureeOutput {
    protected OutputConfiguration conf;
    protected PureeStorage storage;
    protected List<PureeFilter> filters = new ArrayList<>();

    public void registerFilter(PureeFilter filter) {
        filters.add(filter);
    }

    public PureeOutput withFilters(PureeFilter... filters) {
        Collections.addAll(this.filters, filters);
        return this;
    }

    public PureeOutput withFilters(Collection<PureeFilter> filters) {
        this.filters.addAll(filters);
        return this;
    }


    public List<PureeFilter> getFilters() {