Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Help with Generic tree data structure 1

Status
Not open for further replies.

advait75

Programmer
Oct 5, 2002
48
IN
Hi,
I am trying to develop a Java class which acts as a recipe calculator. What it is supposed to do is that if I give 'Capuccino' as an input parameter, the class should calculate how much milk, how much sugar etc goes into that coffee. The class should return every item that goes into the coffee, and the qty of the item also. I thought that the best way to do so would be to use a tree structure, because there may be 2 or levels under each item also.
Can someone please help or advice?
 
I would use beans to represent your specific recipes, eg :

So start off with a Coffee interface :

Code:
public interface Coffee {
	public int getMilk();
	public void setMilk(int milk);
	public int getSuagrs();
	public void setSugars(int sugars);	
	
}

and then implement your Cappucino object :

Code:
public class Cappucino implements Coffee {
	private int sugars = 1;
	private int milk = 1;
	
	public void setMilk(int milk) {
		this.milk = milk;
	}
	
	public int getMilk() {
		return milk;
	}

	public void setSugars(int sugars) {
		this.sugars = sugars;
	}
	
	public int getSugars() {
		return sugars;
	}

}

and to test it :

Code:
public class Recipe {

	public static void main(String args[]) {
	
		if (args[0].equals("Cappucino")) {
		
			Coffee c = new Cappucino();
			int sugars = c.getSugars();
			int milk = c.getMilk();
			
			System.err.println("Cappucinos have " +sugars +" suagars, and " +milk +" milk);
		} else {
			System.err.println("Drink not recognised : " +args[0]);
		}
	
	}

}
 
Sedj,
Thanks for the response. I guess I didn't give you enough info to solve the problem. I cannot have individual classes for each product that i want a recipe for. I have a Bill Of Material table which contains the parent item, child items and qty of each child item.
E.g
Parent Item Child Item qty
Cappucino Milk 1
Cappucino Sugar 2
Cappucino Espresso 2
Espresso Coffee beans 3
So you see there are items, and sub-child items. So my class has to return these values in the form of a tree, so that I can display the tree to the user like this-
User chooses to see the tree for 20 Capuccinos-
Cappucino
|
|
Milk 20
Sugar 40
Espresso
|
|
Coffee beans 60
So you see the tree structure. I cannot use a binary tree because there may be more than 3 branches, so I have to usea generic tree.



 
How are you displaying the data, via the web or via a Swing GUI ?
 
Sedj,
i am displaying the data via the web. I'm using a DHTML Fold menu which will be populated with the data received from the class.
 
Sedj,
Thanks for taking the time to help me. I'm really sorry, but I'm fairly new to Java. With the example that I have given and the resource that you have given(the link), can you show me how to solve my problem?
 
Well, where is this data coming from ? A text file, or database, or what ?

Will you be able to present the data in an XML format ?
 
Sedj,
Sorry for not replying immediately. The data is coming from a database with a table structure as described in my 2nd post. I want to present the data to the user via the web. Therefore, I was thinking of using a DHTML tree menu, whose branches will be populated based on the results returned from the class. Is there are a better way to output via the web?
 
Sedj,
Also please remember that the class that is created which does all the calculation and finds how much of each item is used, should be re-usable by other code also. It shouldn't be developed only to satisfy this need of displaying the result in the form of a tree structure.
So if other code wants to get back a result, parameters can be sent to this class and a data object is returned.
 
You are attempting to transform relational data into a hierachical form - this is by no means a trivial issue. You need an intermediary to ease the transition from db-->web, and I suggest extracting the data into a DOM object. This would then be fairly easy to traverse and output in HTML form.

The pseudo code for this will be :

- Use JDBC to connect to the database, and exract a ResultSet
- Loop the ResultSet, parsing the data into a DOM object.
- Return the ResultSet to whatever calling program
- Build the HTML tree by traversing the DOM object

Here is a DOM tutorial to get you started :
 
Sedj,
Thanks for your help. But I have one silly question-how do I store the data that I get in the resultset in the form of a tree like structure with parent and child items, and also child items under child items (like the figure I drew in an earlier post), using a DOM object?
Can you please give me some sample code, to pass my resultset into the DOM object?
 
I can't write all the code for you because I have not got the time, and this is not a "write my code for me" kind of forum.

DOM has methods to add nodes/elements to a tree, and to add children to those elements and so on. I suggest you take a look at the link I posted earlier, and spend some time looking at the examples and tutorials. There is no easy way to do what you wish - you'll just have to spend some time getting to grips with it.

Good Luck.

--------------------------------------------------
Free Database Connection Pooling Software
 
Sedj,
Thanks for your help. I will go through the examples and see what I can do.
 
Okey dokey - have a play around for a day or 2, and if you are still having problems, come back with the code you've got stuck with, and we'll have another look !

Cheers

--------------------------------------------------
Free Database Connection Pooling Software
 
Sedj,
I managed to get the DOM object in memory, with the data that I want. How do I output it in a nice tree format now, via the web. I have the DOM in memory.
 
You need something to traverse the DOM, writing out your data. The below code is taken from "Java and XML" by Brett McLauglin (oreilly), and will serialize a DOM to an output stream. I would suggest you look at it, work out how if works, and then modify to produce your required HTML/JavaScript output.

Use it like this :

Code:
Document doc = // your DOM object
DOMSerializer ds = new DOMSerializer();
ds.serialize(doc, System.out);

Code:
/*--

 Copyright (C) 2001 Brett McLaughlin.
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:

 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions, and the following disclaimer.

 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions, and the disclaimer that follows
    these conditions in the documentation and/or other materials
    provided with the distribution.

 3. The name "Java and XML" must not be used to endorse or promote products
    derived from this software without prior written permission.  For
    written permission, please contact brett@newInstance.com.

 In addition, we request (but do not require) that you include in the
 end-user documentation provided with the redistribution and/or in the
 software itself an acknowledgement equivalent to the following:
     "This product includes software developed for the
      'Java and XML' book, by Brett McLaughlin (O'Reilly & Associates)."

 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 SUCH DAMAGE.

 */

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * <b><code>DOMSerializer</code></b> will take a DOM
 *   tree and serialize that tree.
 */
public class DOMSerializer {

    /** Indentation to use */
    private String indent;

    /** Line separator to use */
    private String lineSeparator;

    /**
     * <p> This initializes the needed settings. </p>
     */
    public DOMSerializer() {
        indent = "";
        lineSeparator = "\n";
    }

    /**
     * <p> This sets the indentation to use. </p>
     *
     * @param indent the indentation <code>String</code> to use.
     */
    public void setIndent(String indent) {
        this.indent = indent;
    }

    /**
     * <p> This sets the line separator to use. </p>
     *
     * @param lineSeparator line separator to use.
     */
    public void setLineSeparator(String lineSeparator) {
        this.lineSeparator = lineSeparator;
    }

    /**
     * <p> This serializes a DOM tree to the supplied
     *  <code>OutputStream</code>.</p>
     *
     * @param doc DOM tree to serialize.
     * @param out <code>OutputStream</code> to write to.
     */
    public void serialize(Document doc, OutputStream out)
        throws IOException {

        Writer writer = new OutputStreamWriter(out);
        serialize(doc, writer);
    }

    /**
     * <p> This serializes a DOM tree to the supplied
     *  <code>OutputStream</code>.</p>
     *
     * @param doc DOM tree to serialize.
     * @param file <code>File</code> to write to.
     */
    public void serialize(Document doc, File file)
        throws IOException {

        Writer writer = new FileWriter(file);
        serialize(doc, writer);
    }

    /**
     * <p> This serializes a DOM tree to the supplied
     *  <code>OutputStream</code>.</p>
     *
     * @param doc DOM tree to serialize.
     * @param writer <code>Writer</code> to write to.
     */
    public void serialize(Document doc, Writer writer)
        throws IOException {

        // Start serialization recursion with no indenting
        serializeNode(doc, writer, "");
        writer.flush();
    }

    /**
     * <p> This will serialize a DOM <code>Node</code> to
     *   the supplied <code>Writer</code>. </p>
     *
     * @param node DOM <code>Node</code> to serialize.
     * @param writer <code>Writer</code> to write to.
     * @param indentLevel current indentation.
     */
    public void serializeNode(Node node, Writer writer,
                              String indentLevel)
        throws IOException {

        // Determine action based on node type
        switch (node.getNodeType()) {
            case Node.DOCUMENT_NODE:
                writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
                writer.write(lineSeparator);

                // recurse on each child
                NodeList nodes = node.getChildNodes();
                if (nodes != null) {
                    for (int i=0; i<nodes.getLength(); i++) {
                        serializeNode(nodes.item(i), writer, "");
                    }
                }
                /*
                Document doc = (Document)node;
                serializeNode(doc.getDocumentElement(), writer, "");
                */
                break;

            case Node.ELEMENT_NODE:
                String name = node.getNodeName();
                writer.write(indentLevel + "<" + name);
                NamedNodeMap attributes = node.getAttributes();
                for (int i=0; i<attributes.getLength(); i++) {
                    Node current = attributes.item(i);
                    writer.write(" " + current.getNodeName() +
                                 "=\"" + current.getNodeValue() +
                                 "\"");
                }
                writer.write(">");

                // recurse on each child
                NodeList children = node.getChildNodes();
                if (children != null) {
                    if ((children.item(0) != null) &&
                        (children.item(0).getNodeType() ==
                        Node.ELEMENT_NODE)) {

                        writer.write(lineSeparator);
                    }
                    for (int i=0; i<children.getLength(); i++) {
                        serializeNode(children.item(i), writer,
                            indentLevel + indent);
                    }
                    if ((children.item(0) != null) &&
                        (children.item(children.getLength()-1)
                                .getNodeType() ==
                        Node.ELEMENT_NODE)) {

                        writer.write(indentLevel);
                    }
                }

                writer.write("</" + name + ">");
                writer.write(lineSeparator);
                break;

            case Node.TEXT_NODE:
                writer.write(node.getNodeValue());
                break;

            case Node.CDATA_SECTION_NODE:
                writer.write("<![CDATA[" +
                             node.getNodeValue() + "]]>");
                break;

            case Node.COMMENT_NODE:
                writer.write(indentLevel + "<!-- " +
                             node.getNodeValue() + " -->");
                writer.write(lineSeparator);
                break;

            case Node.PROCESSING_INSTRUCTION_NODE:
                writer.write("<?" + node.getNodeName() +
                             " " + node.getNodeValue() +
                             "?>");
                writer.write(lineSeparator);
                break;

            case Node.ENTITY_REFERENCE_NODE:
                writer.write("&" + node.getNodeName() + ";");
                break;

            case Node.DOCUMENT_TYPE_NODE:
                DocumentType docType = (DocumentType)node;
                writer.write("<!DOCTYPE " + docType.getName());
                //if (docType.getPublicId() != null)  {
                //    System.out.print(" PUBLIC \"" +
                //        docType.getPublicId() + "\" ");
                //} else {
                //    writer.write(" SYSTEM ");
                //}
                //writer.write("\"" + docType.getSystemId() + "\">");
                writer.write(lineSeparator);
                break;
        }
    }
}

--------------------------------------------------
Free Database Connection Pooling Software
 
Sedj,
I'm sorry for disturbing you so much. Once I submit this code this evening, i promise I wont trouble you.
Anyway, I got my data out of the DOM Object like this-
<?xml version="1.0" encoding="UTF-8"?>
<Parent>
<RecipeItem>
<CHILD_ITEMCODE>11003</CHILD_ITEMCODE>
<NAME>Espresso shot</NAME>
<QUANTITY>10</QUANTITY>
<UOM>PCS</UOM>
<SubRecipeItem>
<CHILD_ITEMCODE>MDC-55</CHILD_ITEMCODE>
<NAME>Water Plain</NAME>
<QUANTITY>0.45</QUANTITY>
<UOM>LITRES</UOM>
</SubRecipeItem>
<SubRecipeItem>
<CHILD_ITEMCODE>MDI-FP-14</CHILD_ITEMCODE>
<NAME>Coffee Beans</NAME>
<QUANTITY>0.115</QUANTITY>
<UOM>KG</UOM>
</SubRecipeItem>
</RecipeItem>
<RecipeItem>
<CHILD_ITEMCODE>MDC-19</CHILD_ITEMCODE>
<NAME>Stirrer</NAME>
<QUANTITY>10</QUANTITY>
<UOM>PCS</UOM>
</RecipeItem>
<RecipeItem>
<CHILD_ITEMCODE>MDC-21</CHILD_ITEMCODE>
<NAME>Tissue (1 Pkt x 100)</NAME>
<QUANTITY>0.1</QUANTITY>
<UOM>PCS</UOM>
</RecipeItem>
<RecipeItem>
<CHILD_ITEMCODE>MDC-26</CHILD_ITEMCODE>
<NAME>Tray Mat Half</NAME>
<QUANTITY>10</QUANTITY>
<UOM>PCS</UOM>
</RecipeItem>
<RecipeItem>
<CHILD_ITEMCODE>MDC-51</CHILD_ITEMCODE>
<NAME>Cup Regular Hot 250ml Paper</NAME>
<QUANTITY>10</QUANTITY>
<UOM>PCS</UOM>
</RecipeItem>
<RecipeItem>
<CHILD_ITEMCODE>MDI-FP-12</CHILD_ITEMCODE>
<NAME>Cinnamon Powder</NAME>
<QUANTITY>0.01</QUANTITY>
<UOM>KG</UOM>
</RecipeItem>
<RecipeItem>
<CHILD_ITEMCODE>MDI-FP-20</CHILD_ITEMCODE>
<NAME>Sachet Java Green Sugar</NAME>
<QUANTITY>20</QUANTITY>
<UOM>PCS</UOM>
</RecipeItem>
<RecipeItem>
<CHILD_ITEMCODE>MDI-FP-22</CHILD_ITEMCODE>
<NAME>Milk</NAME>
<QUANTITY>1.4</QUANTITY>
<UOM>LITRES</UOM>
</RecipeItem>
<RecipeItem>
<CHILD_ITEMCODE>MDI-FP-31</CHILD_ITEMCODE>
<NAME>Syrup - Da Vinci Amaretto</NAME>
<QUANTITY>0.15</QUANTITY>
<UOM>LITRES</UOM>
</RecipeItem>
<RecipeItem>
<CHILD_ITEMCODE>MDI-FP-68</CHILD_ITEMCODE>
<NAME>Chocolate Fudge Cookie</NAME>
<QUANTITY>10</QUANTITY>
<UOM>PCS</UOM>
</RecipeItem>
</Parent>
I still don't understand how to go through the nodes and display it to the user via the web in the format as I have shown in my earlier posts.
Thanks for everything again.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top