001 /* 002 * Copyright 2011 Christian Kumpe http://kumpe.de/christian/java 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package de.kumpe.hadooptimizer.impl; 017 018 import java.io.Serializable; 019 import java.util.Collection; 020 import java.util.concurrent.CopyOnWriteArrayList; 021 022 import org.apache.commons.logging.Log; 023 import org.apache.commons.logging.LogFactory; 024 025 import de.kumpe.hadooptimizer.EvaluationResult; 026 import de.kumpe.hadooptimizer.Halter; 027 import de.kumpe.hadooptimizer.Stoppable; 028 029 /** 030 * The {@link ReportingHalterWrapper} passed the {@link EvaluationResult}s to 031 * each registered {@link Reporter} and then delegates the halt-decision the the 032 * specified {@link Halter}. 033 * 034 * @param <I> 035 * the individuals' type 036 * 037 * @author <a href="http://kumpe.de/christian/java">Christian Kumpe</a> 038 */ 039 public final class ReportingHalterWrapper<I> extends 040 NeedsRandomWrapperBase<Halter<I>> implements Halter<I>, Stoppable { 041 private static final long serialVersionUID = 1L; 042 private static final Log log = LogFactory 043 .getLog(ReportingHalterWrapper.class); 044 045 /** 046 * The {@link ReportingHalterWrapper.Reporter} is used by the 047 * {@link ReportingHalterWrapper} to report about the passed 048 * evaluation-results every cycle. 049 * 050 * @param <I> 051 * the individuals' type 052 * 053 * @author <a href="http://kumpe.de/christian/java">Christian Kumpe</a> 054 */ 055 public interface Reporter<I> extends Serializable { 056 void report(Collection<EvaluationResult<I>> evaluationResults); 057 } 058 059 private Collection<Reporter<I>> reporters = new CopyOnWriteArrayList<Reporter<I>>(); 060 061 /** 062 * Creates a new {@link ReportingHalterWrapper} with the specified 063 * {@link Halter} delegate. 064 * 065 * @param delegate 066 * the {@link Halter} to which the halt-decision is delegated 067 */ 068 public ReportingHalterWrapper(final Halter<I> delegate) { 069 super(delegate); 070 071 if (log.isDebugEnabled()) { 072 log.debug("Constructing new ReportingHalterWrapper with delegate=" 073 + delegate); 074 } 075 } 076 077 @Override 078 public boolean halt(final Collection<EvaluationResult<I>> evaluationResults) { 079 for (final Reporter<I> reporter : reporters) { 080 reporter.report(evaluationResults); 081 } 082 return delegate.halt(evaluationResults); 083 } 084 085 @Override 086 public void stop() { 087 if (delegate instanceof Stoppable) { 088 ((Stoppable) delegate).stop(); 089 } 090 } 091 092 /** 093 * Adds a {@link Reporter}. 094 * 095 * @param reporter 096 * the {@link Reporter} to add; it will not check if the reporter 097 * is already registered 098 */ 099 public void addReporter(final Reporter<I> reporter) { 100 if (log.isTraceEnabled()) { 101 log.trace("Adding reporter: " + reporter); 102 } 103 104 reporters.add(reporter); 105 } 106 107 /** 108 * Remove a {@link Reporter}. 109 * 110 * @param reporter 111 * the {@link Reporter} to remove; it will only remove the first 112 * occurrence of the specified reporter 113 */ 114 public void removeReporter(final Reporter<I> reporter) { 115 if (log.isTraceEnabled()) { 116 log.trace("Removing reporter: " + reporter); 117 } 118 reporters.remove(reporter); 119 } 120 121 @Override 122 public String toString() { 123 return "ReportingHalterWrapper [delegate=" + delegate + ", reporters=" 124 + reporters + "]"; 125 } 126 }