package org.intermine.web;

/*
 * Copyright (C) 2002-2004 FlyMine
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  See the LICENSE file for more
 * information or http://www.gnu.org/copyleft/lesser.html.
 *
 */

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.LinkedHashMap;

import org.intermine.metadata.Model;

public class PathQuery
{
    protected Model model;
    protected Map nodes = new LinkedHashMap();
    protected List view = new ArrayList();
    
    public PathQuery(Model model) {
        this.model = model;
    }

    public Model getModel() {
        return model;
    }

    public void setNodes(Map nodes) {
        this.nodes = nodes;
    }

    public Map getNodes() {
        return nodes;
    }

    public void setView(List view) {
        this.view = view;
    }

    public List getView() {
        return view;
    }

    /**
     * Add a node to the query using a path, adding parent nodes if necessary
     * @param path the path for the new Node
     * @return the RightNode that was added to the qNodes Map
     */
    public RightNode addNode(String path) {
        RightNode node;
        if (path.lastIndexOf(".") == -1) {
            node = new RightNode(path);
        } else {
            String prefix = path.substring(0, path.lastIndexOf("."));
            if (nodes.containsKey(prefix)) {
                RightNode parent = (RightNode) nodes.get(prefix);
                String fieldName = path.substring(path.lastIndexOf(".") + 1);
                node = new RightNode(parent, fieldName, model);
            } else {
                addNode(prefix);
                return addNode(path);
            }
        }
        nodes.put(path, node);
        return node;
    }

    public Object clone() {
        PathQuery query = new PathQuery(model);
        for (Iterator i = nodes.entrySet().iterator(); i.hasNext();) {
            Map.Entry entry = (Map.Entry) i.next();
            query.getNodes().put(entry.getKey(), clone((RightNode) entry.getValue()));
        }
        query.getView().addAll(view);
        return query;
    }

    public RightNode clone(RightNode node) {
        RightNode newNode;
        RightNode parent = (RightNode) nodes.get(node.getPrefix());
        if (parent == null) {
            newNode = new RightNode(node.getType());
        } else {
            newNode = new RightNode(parent, node.getFieldName(), model);
            newNode.setType(node.getType());
        }
        for (Iterator i = node.getConstraints().iterator(); i.hasNext();) {
            Constraint constraint = (Constraint) i.next();
            newNode.getConstraints().add(new Constraint(constraint.getOp(), constraint.getValue()));
        }
        return newNode;
    }

    public String toString() {
        return nodes + " " + view;
    }
}

@@ -490,16 +490,92 @@
 Model;%0A%0A
+/**%0A * Class to represent a path-based query%0A * @author Mark Woodbridge%0A */%0A
 public c
@@ -715,339 +715,841 @@
 %0A   
- %0A    public PathQuery(Model model) %7B%0A        this.model = model;%0A    %7D%0A%0A    public Model getModel() %7B%0A        return model;%0A    %7D%0A%0A    public void setNodes(Map nodes) %7B%0A        this.nodes = nodes;%0A    %7D%0A%0A    public Map getNodes() %7B%0A        return nodes;%0A    %7D%0A%0A    public void setView(List view) %7B%0A        this.view = view;%0A    %7D%0A
+%0A    /**%0A     * Constructor%0A     * @param model the Model on which to base this query%0A     */%0A    public PathQuery(Model model) %7B%0A        this.model = model;%0A    %7D%0A%0A    /**%0A     * Gets the value of model%0A     * @return the value of model%0A     */%0A    public Model getModel() %7B%0A        return model;%0A    %7D%0A%0A    /**%0A     * Sets the value of nodes%0A     * @param nodes the value of nodes%0A     */%0A    public void setNodes(Map nodes) %7B%0A        this.nodes = nodes;%0A    %7D%0A%0A    /**%0A     * Gets the value of nodes%0A     * @return the value of nodes%0A     */%0A    public Map getNodes() %7B%0A        return nodes;%0A    %7D%0A%0A    /**%0A     * Sets the value of view%0A     * @param view the value of view%0A     */%0A    public void setView(List view) %7B%0A        this.view = view;%0A    %7D%0A%0A    /**%0A     * Gets the value of view%0A     * @return the value of view%0A     */
 %0A   
@@ -2460,32 +2460,103 @@
 rn node;%0A    %7D%0A%0A
+    /**%0A     * Clone this PathQuery%0A     * @return a PathQuery%0A     */%0A
     public Objec
@@ -2894,32 +2894,143 @@
 n query;%0A    %7D%0A%0A
+    /**%0A     * Clone a RightNode%0A     * @param node a RightNode%0A     * @return a copy of the RightNode%0A     */%0A
     public Right
@@ -3660,80 +3660,7 @@
    %7D
-%0A%0A    public String toString() %7B%0A        return nodes + %22 %22 + view;%0A    %7D
 %0A%7D%0A

Correct style