/* * $Id$ * * Copyright (c) 2000-2003 by Rodney Kinney * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License (LGPL) as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, copies are available * at http://www.opensource.org. */ package VASSAL.build.module; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import VASSAL.build.AbstractBuildable; import VASSAL.build.Buildable; import VASSAL.build.GameModule; import VASSAL.command.Command; import VASSAL.command.CommandEncoder; import VASSAL.configure.StringConfigurer; import VASSAL.tools.SequenceEncoder; public class EventLog extends AbstractBuildable implements CommandEncoder, GameComponent { public static final String EVENT_LIST = "Events"; //$NON-NLS-1$ private List<Event> myEvents; private List<Event> savedEvents; public void addTo(Buildable b) { GameModule mod = GameModule.getGameModule(); mod.addCommandEncoder(this); mod.getGameState().addGameComponent(this); mod.getPrefs().addOption(new StringConfigurer(EVENT_LIST, null)); myEvents = new ArrayList<Event>(); savedEvents = new ArrayList<Event>(); for (Event e : decodedEvents((String) mod.getPrefs().getValue(EVENT_LIST))) myEvents.add(e); } public void clearSaved() { savedEvents.clear(); } public void store(Event e) { savedEvents.add(e); } public void log(Event e) { myEvents.add(e); GameModule.getGameModule() .getPrefs() .getOption(EVENT_LIST) .setValue(encodedEvents(myEvents)); } public Command decode(String s) { if (s.startsWith(EVENT_LIST)) { return new StoreEvents(this, s.substring(EVENT_LIST.length())); } else { return null; } } public String encode(Command c) { if (c instanceof StoreEvents) { return EVENT_LIST + ((StoreEvents) c).getEvents(); } else { return null; } } public void setup(boolean starting) { if (!starting) { clearSaved(); } } public Command getRestoreCommand() { return new StoreEvents(this, encodedEvents(savedEvents)); } /** * Decodes a <code>String</code> into a sequence of <code>Event</code>s. * * @param s the event string * @return the events represented by the string */ public static Iterable<Event> decodedEvents(final String s) { return new Iterable<Event>() { public Iterator<Event> iterator() { return new Iterator<Event>() { private final SequenceEncoder.Decoder se = new SequenceEncoder.Decoder(s, '|'); public boolean hasNext() { return se.hasMoreTokens(); } public Event next() { final SequenceEncoder.Decoder sub = new SequenceEncoder.Decoder(se.nextToken(), ','); return new Event(Long.parseLong(sub.nextToken()), sub.nextToken(), sub.nextToken()); } public void remove() { throw new UnsupportedOperationException(); } }; } }; } /** Use {@link #decodedEvents()} instead. */ @Deprecated public static Enumeration<Event> decodeEvents(String s) { ArrayList<Event> l = new ArrayList<Event>(); SequenceEncoder.Decoder se = new SequenceEncoder.Decoder(s, '|'); while (se.hasMoreTokens()) { SequenceEncoder.Decoder sub = new SequenceEncoder.Decoder(se.nextToken(), ','); l.add(new Event(Long.parseLong(sub.nextToken()), sub.nextToken(), sub.nextToken())); } return Collections.enumeration(l); } /** * Encodes a sequence of <code>Event</code>s into a <code>String</code>. * * @param events the sequence of events * @return the string representing the events */ public static String encodedEvents(Iterable<Event> events) { final SequenceEncoder se = new SequenceEncoder('|'); for (Event e : events) { final SequenceEncoder sub = new SequenceEncoder(','); sub.append(e.getTime()) .append(e.getUser()) .append(e.getAction()); se.append(sub.getValue()); } return se.getValue(); } /** Use {@link #encodedEvents(Iterable<Event>)} instead. */ @Deprecated public static String encodeEvents(Enumeration<?> e) { final SequenceEncoder se = new SequenceEncoder('|'); while (e.hasMoreElements()) { final Event evt = (Event) e.nextElement(); final SequenceEncoder sub = new SequenceEncoder(','); sub.append(evt.getTime()) .append(evt.getUser()) .append(evt.getAction()); se.append(sub.getValue()); } return se.getValue(); } public static class Event { private long time; private String user; private String action; public Event(long time, String user, String action) { this.time = time; this.user = user; this.action = action; } public long getTime() { return time; } public String getUser() { return user; } public String getAction() { return action; } } public static class StoreEvents extends Command { private EventLog log; private String events; public StoreEvents(EventLog log, String events) { this.log = log; this.events = events; } public String getEvents() { return events; } public void executeCommand() { log.clearSaved(); for (Event e : decodedEvents(events)) log.store(e); } public Command myUndoCommand() { return null; } } public String[] getAttributeNames() { return new String[0]; } public void setAttribute(String name, Object value) { } public String getAttributeValueString(String name) { return null; } }