/* * JFugue - API for Music Programming * Copyright (C) 2003-2008 David Koelle * * http://www.jfugue.org * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or any later version. * * 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ package org.jfugue; import java.util.EventListener; import javax.swing.event.EventListenerList; /** * You may notice that there is no parse() method in the Parser class! That's * because the parse() method may take any type of parameter, as well as any * number of parameters, so it isn't something that can declared ahead of time. * * @author David Koelle * */ public class Parser { public Parser() { progressListenerList = new EventListenerList(); listenerList = new EventListenerList(); // The Parser could add itself as a ParserProgressListener. } // Logging methods /////////////////////////////////////////// /** * Pass this value to setTracing( ) to turn tracing off. Tracing is off by * default. */ public static final int TRACING_OFF = 0; /** * Pass this value to setTracing( ) to turn tracing on. Tracing is off by * default. */ public static final int TRACING_ON = 1; private int tracing = TRACING_ON; /** * Turns tracing on or off. If you're having trouble with your music string, * or if you've added new tokens to the parser, turn tracing on to make sure * that your new tokens are parsed correctly. * * @param tracing * the state of tracing - on or off */ public void setTracing(int tracing) { this.tracing = tracing; } /** * Returns the current state of tracing. * * @return the state of tracing */ public int getTracing() { return this.tracing; } /** * Displays the passed String. * * @param s * the String to display */ protected void trace(Object... sentenceFragments) { if (TRACING_ON == getTracing()) { StringBuilder buddy = new StringBuilder(); for (int i = 0; i < sentenceFragments.length; i++) { buddy.append(sentenceFragments[i]); } System.out.println(buddy.toString()); } } // // ParserProgressListener methods ///////////////////////////////////////////////////////////////////////// /** List of ParserProgressListeners */ protected EventListenerList progressListenerList; /** * Adds a <code>ParserListener</code>. The listener will receive events when * the parser interprets music string tokens. * * @param listener * the listener that is to be notified of parser events */ public void addParserProgressListener(ParserProgressListener l) { progressListenerList.add(ParserProgressListener.class, l); } /** * Removes a <code>ParserListener</code>. * * @param listener * the listener to remove */ public void removeParserProgressListener(ParserProgressListener l) { progressListenerList.remove(ParserProgressListener.class, l); } protected void clearParserProgressListeners() { EventListener[] l = progressListenerList .getListeners(ParserProgressListener.class); int numListeners = l.length; for (int i = 0; i < numListeners; i++) { progressListenerList.remove(ParserProgressListener.class, (ParserProgressListener) l[i]); } } /** * Tells all ParserProgressListener interfaces that progress has occurred. */ protected void fireProgressReported(String description, long partComplete, long whole) { Object[] listeners = progressListenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ParserProgressListener.class) { ((ParserProgressListener) listeners[i + 1]) .progressReported(description, partComplete, whole); } } } // // ParserListener methods ///////////////////////////////////////////////////////////////////////// /** List of ParserListeners */ protected EventListenerList listenerList; /** * Adds a <code>ParserListener</code>. The listener will receive events when * the parser interprets music string tokens. * * @param listener * the listener that is to be notified of parser events */ public void addParserListener(ParserListener l) { listenerList.add(ParserListener.class, l); } /** * Removes a <code>ParserListener</code>. * * @param listener * the listener to remove */ public void removeParserListener(ParserListener l) { listenerList.remove(ParserListener.class, l); } protected void clearParserListeners() { EventListener[] l = listenerList.getListeners(ParserListener.class); int numListeners = l.length; for (int i = 0; i < numListeners; i++) { listenerList.remove(ParserListener.class, (ParserListener) l[i]); } } /** Tells all ParserListeners that a voice event has been parsed. */ protected void fireVoiceEvent(Voice event) { Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ParserListener.class) { ((ParserListener) listeners[i + 1]).voiceEvent(event); } } } /** Tells all ParserListeners that a tempo event has been parsed. */ protected void fireTempoEvent(Tempo event) { Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ParserListener.class) { ((ParserListener) listeners[i + 1]).tempoEvent(event); } } } /** Tells all ParserListeners that an instrument event has been parsed. */ protected void fireInstrumentEvent(Instrument event) { Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ParserListener.class) { ((ParserListener) listeners[i + 1]).instrumentEvent(event); } } } /** Tells all ParserListeners that a layer event has been parsed. */ protected void fireLayerEvent(Layer event) { Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ParserListener.class) { ((ParserListener) listeners[i + 1]).layerEvent(event); } } } /** Tells all ParserListeners that a time event has been parsed. */ protected void fireTimeEvent(Time event) { Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ParserListener.class) { ((ParserListener) listeners[i + 1]).timeEvent(event); } } } /** Tells all ParserListeners that a key signature event has been parsed. */ protected void fireKeySignatureEvent(KeySignature event) { Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ParserListener.class) { ((ParserListener) listeners[i + 1]).keySignatureEvent(event); } } } /** Tells all ParserListeners that a measure event has been parsed. */ protected void fireMeasureEvent(Measure event) { Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ParserListener.class) { ((ParserListener) listeners[i + 1]).measureEvent(event); } } } /** Tells all ParserListeners that a controller event has been parsed. */ protected void fireControllerEvent(Controller event) { Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ParserListener.class) { ((ParserListener) listeners[i + 1]).controllerEvent(event); } } } /** Tells all ParserListeners that a controller event has been parsed. */ protected void fireChannelPressureEvent(ChannelPressure event) { Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ParserListener.class) { ((ParserListener) listeners[i + 1]).channelPressureEvent(event); } } } /** Tells all ParserListeners that a controller event has been parsed. */ protected void firePolyphonicPressureEvent(PolyphonicPressure event) { Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ParserListener.class) { ((ParserListener) listeners[i + 1]) .polyphonicPressureEvent(event); } } } /** Tells all ParserListeners that a controller event has been parsed. */ protected void firePitchBendEvent(PitchBend event) { Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ParserListener.class) { ((ParserListener) listeners[i + 1]).pitchBendEvent(event); } } } /** Tells all ParserListeners that a note event has been parsed. */ protected void fireNoteEvent(Note event) { Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ParserListener.class) { ((ParserListener) listeners[i + 1]).noteEvent(event); } } } /** * Tells all ParserListeners that a sequential note event has been parsed. */ protected void fireSequentialNoteEvent(Note event) { Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ParserListener.class) { ((ParserListener) listeners[i + 1]).sequentialNoteEvent(event); } } } /** Tells all ParserListeners that a parallel note event has been parsed. */ protected void fireParallelNoteEvent(Note event) { Object[] listeners = listenerList.getListenerList(); for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ParserListener.class) { ((ParserListener) listeners[i + 1]).parallelNoteEvent(event); } } } // // End ParserListener methods ///////////////////////////////////////////////////////////////////////// }