001/*
002 * jPOS Project [http://jpos.org]
003 * Copyright (C) 2000-2026 jPOS Software SRL
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018
019package org.jpos.transaction.participant;
020
021import org.jdom2.Element;
022import org.jpos.core.ConfigurationException;
023import org.jpos.transaction.GroupSelector;
024import org.jpos.util.LogEvent;
025import org.jpos.util.Logger;
026
027import java.io.Serializable;
028
029/**
030 * BeanShell-backed {@link GroupSelector} that evaluates a {@code <select>} script
031 * to choose the next participant group, falling back to {@link #defaultSelect}
032 * when the script returns {@code null}.
033 *
034 * @author  AMarques
035 */
036public class BSHGroupSelector extends BSHTransactionParticipant implements GroupSelector {
037    /** Default constructor; no instance state to initialise. */
038    public BSHGroupSelector() {}
039
040    /** Compiled BSH method invoked to determine the active group. */
041    protected BSHMethod selectMethod;
042    
043    public void setConfiguration(Element e) throws ConfigurationException {
044        super.setConfiguration(e);
045        try {
046            selectMethod = BSHMethod.createBshMethod(e.getChild("select"));
047        } catch (Exception ex) {
048            throw new ConfigurationException(ex.getMessage(), ex);
049        }
050    }    
051    
052    public String select(long id, java.io.Serializable context) {
053        LogEvent ev = new LogEvent(this, "select");
054        String result = null;
055        if (selectMethod != null) {
056            try {
057                result = (String) executeMethod(selectMethod, id, context, ev, "result");
058            } catch (Exception ex) {
059                ev.addMessage(ex);
060            }
061        } 
062        if (result == null) {
063            result = defaultSelect(id, context);
064        }
065        ev.addMessage("result", result);
066        Logger.log(ev);
067        return result;
068    }
069    
070    /**
071     * Hook returning the default group when the BSH script returns {@code null}.
072     * Subclasses may override to provide deterministic fallback selection.
073     *
074     * @param id transaction id
075     * @param context transaction context
076     * @return default group identifier (empty string by default)
077     */
078    public String defaultSelect(long id, Serializable context) {
079        return "";
080    }
081        
082}