/* ************************************************************************* * * * * Copyright (c) 2004 Peter Cappello * * * * Permission is hereby granted, free of charge, to any person obtaining * * a copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to * * the following conditions: * * * * The above copyright notice and this permission notice shall be * * included in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * * * ************************************************************************* */ /** * Demonstrates a non-Java client invoking a Jicos Task, in this case, the * Fibonacci sequence. * * @author Peter Cappello * @author Andy Pippin */ package edu.ucsb.cs.jicos.examples.external.fibonacci; import edu.ucsb.cs.jicos.services.*; import edu.ucsb.cs.jicos.services.tasks.*; import edu.ucsb.cs.jicos.services.external.ExternalData; import edu.ucsb.cs.jicos.services.external.ExternalRequest; import edu.ucsb.cs.jicos.services.external.XmlDocument; import edu.ucsb.cs.jicos.services.external.XmlConverter; import edu.ucsb.cs.jicos.services.external.services.CollectorHttp; import edu.ucsb.cs.jicos.services.external.services.ExternalRequestProcessor; final public class Fibonacci extends Task implements XmlConverter { // //-- Constants ------------------------------------------------------- private static final int DEFAULT_Number = 8; // //-- Variables ------------------------------------------------------- private int n; // //-- Constructors ---------------------------------------------------- /** * Constructs a Fibonacci task with the given number. * * @param n The nth Fibonacci number to return. */ public Fibonacci(int n) { this.n = n; } /** * Perform this task. * * @param environment The Jicos environment of the task. * @return A result, or a new (composition) Task. */ public Object execute( Environment environment ) { if (n < 2) { return new Integer( 1 ); } else { compute( new Fibonacci( n - 1 ) ); compute( new Fibonacci( n - 2 ) ); return new AddInteger(); } } /** * Set the nth Fibonacci number to compute. * * @param n The nth Fibonacci number */ public void setN( int n ) { this.n = n; } /** * Get the nth Fibnonacci number that this task is going to compute. * * @return The nth Fibnonacci number for this task. */ public int getN() { return (this.n); } // //-- For External Results -------------------------------------------- /** * Default, no-argument constructor necessary for Class.newInstance(). */ public Fibonacci() { this.n = 0; } /** * Convert the class to XML-encoded rstring representation. * * @param prefix Precede each line of text with this string. * @return XML represetation. */ public String toXml( String prefix ) { String xml = null; String pre = (null != prefix) ? prefix : ""; xml = pre + "\r\n" + pre + " " + this.n + "\r\n" + pre + "\r\n" ; return (xml); } /** * Populate the instance from the data given. * * @param externalData Data from the external client. * @return Success (true), or failure (false). */ public boolean fromXml( ExternalData externalData ) { boolean success = false; String n = null; if (null != (n = externalData.getValue( "/Fibonacci/n" ))) { try { setN( Integer.parseInt( n ) ); success = true; } catch (NumberFormatException formatException) { // ignore } } return (success); } /** * Create the input object from the data given. * * @param externalData Data from the external client. * @return The input object, if any, or null. */ public Object createInput( ExternalData externalData ) { return ((Object) null); } /** * Create the Shared object from the data given. * * @param externalData Data from the external client. * @return The Shared object, if any, or null. */ public Shared createShared( ExternalData externalData ) { return ((Shared) null); } /** * Get the XSLT Style sheet used to transform a result of this task to HTML. * * @param styleSheetType * The type of XSLT style sheet. * @return A DOM object that represents the Style sheet, or null * if not defined for this type. */ public org.w3c.dom.Document getStyleSheet( int styleSheetType ) { return( null ); } /** * Given the Object from Jicos, that is the result of the computation, * create the appropriate XmlDocument to be returned to the client * (via the Collector). * * @param result * @return An XmlDocument representing the result to be returned. * @throws Exception Variety of reasons. */ public XmlDocument createResult( Object result ) throws Exception { String xml = null; if (null == result) { throw new NullPointerException( "Result cannot be null" ); } else { int FofN = ((Integer) result).intValue(); // This contains extra attributes necessary for SOAP. xml = "\r\n" + "\r\n" + " \r\n" + " " + this.n + "\r\n" + " " + FofN + "\r\n" + " \r\n" + "\r\n" ; } return (new XmlDocument( xml )); } /** * Manual create the HTML that would be returned by the CollectorHttp. * Since there is no over-riding function for getStyleSheet(int), the * default stylesheet (null) will be returned. * * @param xmlResult The XML representation of the result from Jicos. * @param hostPort The "hostname:port" of the CollectorHttp. * @return The HTML string without the HTTP header to be returned. */ public String toHtmlString( XmlDocument xmlResult, String hostPort ) { String strFib = null; // Fix the hostname/port. if (null == hostPort) { hostPort = "localhost"; } // Get the result if it exists. if (null != xmlResult) { strFib = xmlResult.getValue( "/ExternalResponse/Fibonacci/FofN" ); if ("".equals( strFib )) { strFib = null; } } int number = this.n; if (0 >= number) { number = DEFAULT_Number; } String html = "\r\n" + "\r\n" + " Fibonacci Solver\r\n" + "\r\n" + "\r\n" + CollectorHttp.jicosHtmlHeader() + "

Fibonacci Solver

\r\n" + "\r\n" ; // If there is an answer, format it. if( null != strFib ) { html = html + "\r\n" + "\r\n" + "Previous Result:
\r\n" + "
\r\n" + "\r\n" + " \r\n" + " \r\n" + " \r\n" + " \r\n" + "
Fibonacci( " + this.n + " ) = " + strFib + "
\r\n" + "
\r\n" + "
\r\n" ; } // A request for a Fibonacci number. html = html + "\r\n" + "\r\n" + "\r\n" + "

\r\n" + "
\r\n" + "\r\n" + "
\r\n" + "\r\n" + " \r\n" + " \r\n" + " \r\n" + "
\r\n" + " \r\n" + " \r\n" + " \r\n" + " \r\n" + " \r\n" + " \r\n" + "
Number:" + "
\r\n" + "
\r\n" + "
\r\n" + "

\r\n" + "\r\n" + CollectorHttp.createResponseSelect( null ) + "\r\n" + "
\r\n" + "\r\n" + "\r\n" + CollectorHttp.jicosHtmlFooter() + "\r\n" + "\r\n" ; return (html); } }