Java tutorial
/* * File: $HeadURL$ * Version: $LastChangedRevision$ * Date: $Date$ * Author: $LastChangedBy$ * * JVoiceXML - A free VoiceXML implementation. * * Copyright (C) 2005-2010 JVoiceXML group - http://jvoicexml.sourceforge.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) 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 * 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ package org.jvoicexml.interpreter.event; import org.apache.commons.lang3.StringEscapeUtils; import org.jvoicexml.event.error.SemanticError; import org.jvoicexml.interpreter.EventStrategy; import org.jvoicexml.interpreter.FormInterpretationAlgorithm; import org.jvoicexml.interpreter.FormItem; import org.jvoicexml.interpreter.JVoiceXmlSession; import org.jvoicexml.interpreter.VoiceXmlInterpreter; import org.jvoicexml.interpreter.VoiceXmlInterpreterContext; import org.jvoicexml.interpreter.datamodel.DataModel; import org.jvoicexml.profile.Profile; import org.jvoicexml.profile.TagStrategyExecutor; import org.jvoicexml.xml.VoiceXmlNode; import org.jvoicexml.xml.vxml.AbstractCatchElement; import org.jvoicexml.xml.vxml.Catch; /** * Basic methods of an {@link EventStrategy} that can be processed by the * {@link JVoiceXmlEventHandler}. * * <p> * Typically, an {@link AbstractEventStrategy} is responsible to handle events * for a single {@link FormItem}. * </p> * * @author Dirk Schnelle-Walka * @version $Revision$ */ abstract class AbstractEventStrategy implements EventStrategy { /** Base hash code. */ private static final int HASH_CODE_BASE = 3; /** Multiplier for hash code generation. */ private static final int HASH_CODE_MULTIPLIER = 5; /** The VoiceXML interpreter context. */ private final VoiceXmlInterpreterContext context; /** The VoiceXML interpreter. */ private final VoiceXmlInterpreter interpreter; /** The current FIA. */ private FormInterpretationAlgorithm fia; /** The current form item. */ private FormItem item; /** The child node with which to continue. */ private final VoiceXmlNode node; /** The event type. */ private final String event; /** The count. */ private final int count; /** * Constructs a new object. */ AbstractEventStrategy() { context = null; interpreter = null; fia = null; item = null; node = null; event = null; count = 0; } /** * Constructs a new object. * * @param ctx * the VoiceXML interpreter context. * @param ip * the VoiceXML interpreter. * @param algorithm * the FIA, maybe <code>null</code>. If a <code>null</code> value * is provided the strategy obtains the current FIA from the * interpreter in the processing state. * @param formItem * the current form item, maybe <code>null</code>. If a * <code>null</code> value is provided, the strategy tries to * obtain the current item from the FIA in the processing state. * @param n * the child node with which to continue. * @param type * the event type. */ protected AbstractEventStrategy(final VoiceXmlInterpreterContext ctx, final VoiceXmlInterpreter ip, final FormInterpretationAlgorithm algorithm, final FormItem formItem, final VoiceXmlNode n, final String type) { context = ctx; interpreter = ip; fia = algorithm; item = formItem; node = n; event = type; if (node == null) { count = 1; } else { final String countAttribute = node.getAttribute(Catch.ATTRIBUTE_COUNT); if (countAttribute == null) { count = 1; } else { count = Integer.valueOf(countAttribute); } } } /** * Retrieve the context property. * * @return The VoiceXML interpreter context. */ protected final VoiceXmlInterpreterContext getVoiceXmlInterpreterContext() { return context; } /** * Retrieve the interpreter property. * * @return The VoiceXML interpreter. */ protected final VoiceXmlInterpreter getVoiceXmlInterpreter() { return interpreter; } /** * Retrieve the FIA. * * @return The current FIA. */ protected final FormInterpretationAlgorithm getFormInterpretationAlgorithm() { // If there was no FIA, try to obtain one from the interpreter. if (fia == null) { if (interpreter == null) { return null; } fia = interpreter.getFormInterpretationAlgorithm(); } return fia; } /** * Retrieves the tag strategy executor. If a FIA is present the executor is * obtained from the FIA, a new one is created otherwise. * * @return the tag strategy executor. * @since 0.7 */ protected TagStrategyExecutor getTagStrategyExecutor() { if (fia == null) { final JVoiceXmlSession session = (JVoiceXmlSession) context.getSession(); final Profile profile = session.getProfile(); return new TagStrategyExecutor(profile); } else { return fia.getTagStrategyExecutor(); } } /** * Retrieves the form item that caused the event. * * @return The current form item. */ protected FormItem getCurrentFormItem() { if (item == null) { FormInterpretationAlgorithm algorithm = getFormInterpretationAlgorithm(); if (algorithm == null) { return null; } item = algorithm.getFormItem(); } return item; } /** * Retrieves the assocaited form item. This may be different to what is * returned by {@link #getCurrentFormItem()}. * * @return associated form item, <code>null</code> if there is none. */ public FormItem getFormItem() { return item; } /** * Retrieves the child node with which to continue. * * @return The child node with which to continue. */ protected final VoiceXmlNode getVoiceXmlNode() { return node; } /** * {@inheritDoc} */ public final String getEventType() { return event; } /** * {@inheritDoc} */ public final int getCount() { return count; } /** * {@inheritDoc} */ @Override public final boolean isActive() throws SemanticError { if (!(node instanceof AbstractCatchElement)) { return true; } final AbstractCatchElement catchElement = (AbstractCatchElement) node; final String cond = catchElement.getCond(); if (cond == null) { return true; } final DataModel model = context.getDataModel(); final String unescapedCond = StringEscapeUtils.unescapeXml(cond); return model.evaluateExpression(unescapedCond, Boolean.class); } /** * {@inheritDoc} * * @since 0.7 */ @Override public boolean equals(final Object obj) { if (obj == null) { return false; } if (!(obj instanceof AbstractEventStrategy)) { return false; } final AbstractEventStrategy strategy = (AbstractEventStrategy) obj; if (context != strategy.context) { if ((context != null) && !context.equals(strategy.context)) { return false; } } if (interpreter != strategy.interpreter) { if ((interpreter != null) && !interpreter.equals(strategy.interpreter)) { return false; } } if (fia != strategy.fia) { if ((fia != null) && !fia.equals(strategy.fia)) { return false; } } if (item != strategy.item) { if ((item != null) && !item.equals(strategy.item)) { return false; } } if (node != strategy.node) { if ((node != null) && !node.equals(strategy.node)) { return false; } } if (event != strategy.event) { if ((event != null) && !event.equals(strategy.event)) { return false; } } return count == strategy.count; } /** * {@inheritDoc} * * @since 0.6 */ @Override public int hashCode() { int hash = HASH_CODE_BASE; hash *= HASH_CODE_MULTIPLIER; if (context != null) { hash += context.hashCode(); } hash *= HASH_CODE_MULTIPLIER; if (interpreter != null) { hash += interpreter.hashCode(); } hash *= HASH_CODE_MULTIPLIER; if (fia != null) { hash += fia.hashCode(); } hash *= HASH_CODE_MULTIPLIER; if (item != null) { hash += item.hashCode(); } hash *= HASH_CODE_MULTIPLIER; if (node != null) { hash += node.hashCode(); } hash *= HASH_CODE_MULTIPLIER; return hash + count; } }