001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org 019 */ 020 021package org.biojava.utils; 022 023import java.io.PrintStream; 024import java.util.EventListener; 025 026/** 027 * Interface for objects which listen to ChangeEvents. 028 * 029 * @author Thomas Down 030 * @author Matthew Pocock 031 * @author Keith James 032 * @since 1.1 033 */ 034 035public interface ChangeListener extends EventListener { 036 /** 037 * Convenience implementation which vetoes every change of which it is 038 * notified. You could add this to an object directly to stop it changing 039 * in any way, or alternatively you could add it for a specific ChangeType 040 * to stop that single item from altering. 041 */ 042 final static ChangeListener ALWAYS_VETO = new AlwaysVetoListener(); 043 044 /** 045 * Convenience implementation that echoes all events to out. 046 */ 047 final static ChangeListener LOG_TO_OUT = new LoggingListener(System.out); 048 049 /** 050 * <p> 051 * Called before a change takes place. 052 * </p> 053 * 054 * <p> 055 * This is your chance to stop the change by throwing a ChangeVetoException. 056 * This method does not indicate that the change will definitely take place, 057 * so it is not recomended that you take any positive action within this 058 * handler. 059 * </p> 060 * 061 * @param cev 062 * An event encapsulating the change which is about 063 * to take place. 064 * @exception ChangeVetoException Description of Exception 065 * @throws 066 * ChangeVetoException if the receiver does not wish 067 * this change to occur at this 068 * time. 069 */ 070 071 void preChange(ChangeEvent cev) throws ChangeVetoException; 072 073 074 /** 075 * <p> 076 * Called when a change has just taken place. 077 * </p> 078 * 079 * <p> 080 * This method is the place to perform any behavior in response to the 081 * change event. 082 * </p> 083 * 084 * @param cev 085 * An event encapsulating the change which has 086 * occured. 087 */ 088 089 void postChange(ChangeEvent cev); 090 091 /** 092 * An implementation that always vetoes everything. 093 * 094 * @author Thomas Down 095 * @author Matthew Pocock 096 * @since 1.1 097 */ 098 099 static class AlwaysVetoListener implements ChangeListener { 100 101 /** 102 * Private constructor. 103 */ 104 protected AlwaysVetoListener() { 105 } 106 107 public void preChange(ChangeEvent cev) throws ChangeVetoException { 108 throw new ChangeVetoException( 109 cev, 110 "This object has been locked" 111 ); 112 } 113 114 /** 115 * @throws AssertionFailure if this is called, as preChange should have 116 * vetoed any change already 117 */ 118 public void postChange(ChangeEvent cev) { 119 throw new AssertionFailure( 120 new ChangeVetoException( 121 cev, 122 "This object has been locked" )); 123 } 124 } 125 126 /** 127 * A listener that remembers the ChangeEvent of the last change. Mostly for 128 * debugging. 129 * @author Mark Schreiber 130 * @since 1.5 131 */ 132 133 public class ChangeEventRecorder extends ChangeAdapter{ 134 private ChangeEvent event; 135 136 public ChangeEvent getEvent(){return this.event;} 137 138 public void preChange(ChangeEvent cev) throws ChangeVetoException { 139 event = cev; 140 } 141 } 142 143 /** 144 * A listener that writes information about the event stream to a PrintStream. 145 * 146 * @author Matthew Pocock 147 * @since 1.1 148 */ 149 public class LoggingListener implements ChangeListener { 150 private PrintStream out; 151 private String prefix; 152 153 /** 154 * Create a LoggingListener that will log all events to 'out'. 155 * 156 * @param out the PrintStream to log events to 157 */ 158 public LoggingListener(PrintStream out) { 159 this.out = out; 160 this.prefix = null; 161 } 162 163 /** 164 * Create a LoggingListener that will log all events to 'out' with a prefix. 165 * 166 * @param out the PrintStream to log events to 167 * @param prefix the prefix to attach to each line of the log 168 */ 169 public LoggingListener(PrintStream out, String prefix) { 170 this.out = out; 171 this.prefix = prefix; 172 } 173 174 public void preChange(ChangeEvent cev) throws ChangeVetoException { 175 if(prefix != null) { 176 out.print(prefix); 177 } 178 out.println("preChange for event " + cev); 179 } 180 181 public void postChange(ChangeEvent cev) { 182 if(prefix != null) { 183 out.print(prefix); 184 } 185 out.println("postChange for event " + cev); 186 } 187 } 188} 189