// ConcatSequencesImpl.java
//
// Created: February 2008
//
// Copyright 2008 Martin Senger
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//


package org.jmoby.tutorial.service;

import net.jmoby.samples.ConcatSequencesSkel;
import org.biomoby.shared.MobyException;
import org.biomoby.shared.parser.MobyPackage;
import org.biomoby.shared.parser.MobyJob;
import org.biomoby.shared.datatypes.*;

import org.apache.commons.lang.BooleanUtils;

/**
 * A simple services that concatenates input sequences. It can have up
 * to three inputs. It can be used to illustrate that a MoSeS-based
 * service can accept several more specialized primary inputs and
 * correctly assign them their fallback type (a type the service was
 * registered for). <p>
 *
 * @author <A HREF="mailto:martin.senger@gmail.com">Martin Senger</A>
 * @version $Id: ConcatSequencesImpl.java,v 1.2 2008/03/03 11:34:17 senger Exp $
 */
public class ConcatSequencesImpl
    extends ConcatSequencesSkel {

    /**************************************************************************
     * This is a mandatory method to be implemented.
     *************************************************************************/
    public void processIt (MobyJob request,
			   MobyJob response,
			   MobyPackage outputContext)
	throws MobyException {

	// primary inputs (any of them, or all, may be empty)
	GenericSequence seq1 = get_seq1 (request);
	GenericSequence seq2 = get_seq2 (request);
	GenericSequence seq3 = get_seq3 (request);

	// secondary input (an empty input means 'false')
	boolean onlyLength =
	    BooleanUtils.toBoolean (getParameter_return_only_length (request));

	// build the result
	int totalLength = 0;
	StringBuilder buf = new StringBuilder();
	totalLength += addOneInput (seq1, buf);
	totalLength += addOneInput (seq2, buf);
	totalLength += addOneInput (seq3, buf);

	GenericSequence result = new GenericSequence();
	result.set_SequenceString (onlyLength ? "" : buf.toString());
	result.set_Length (new MobyInteger (totalLength));

	set_result (response, result);
    }

    /**************************************************************************
     * Add the string from 'seq' into 'buf', and return the length of
     * 'seq' (or zero). The 'seq' can be null.
     *************************************************************************/
    static long addOneInput (GenericSequence seq,
			     StringBuilder buf)
	throws MobyException {

	// if we have a non-empty input...
	if (seq == null)
	    return 0;

	// ...extract what we got
	String seqString = seq.get_SequenceString();

	// ...concatenate sequence string and get its length
	long seqLength = 0;
	if (seqString == null) {
	    try {
		seqLength = seq.getMoby_Length().getIntValue();
	    } catch (NullPointerException e) {
	    }
	} else {
	    buf.append (seqString);
	    seqLength = seqString.length();
	}

	// ...and return the sequence length
	return seqLength;
    }

}

