/*
* 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_OFF;
/**
* 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
/////////////////////////////////////////////////////////////////////////
}