/**
 *#########################################################################
 *
 * A component of the Gatherer application, part of the Greenstone digital
 * library suite from the New Zealand Digital Library Project at the
 * University of Waikato, New Zealand.
 *
 * Author: John Thompson, New Zealand Digital Library, University of Waikato
 *
 * Copyright (C) 2004 New Zealand Digital Library Project
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *########################################################################
 */
package org.greenstone.gatherer.shell;
import java.util.HashMap;
import java.util.StringTokenizer;
import org.greenstone.gatherer.util.StaticStrings;

/** This class wraps around a pseudo-XML message we have recieved from an external script, and allows access to the element name, attributes etc via method calls. */
public class GShellElement {
    private boolean is_closed = false;
    private HashMap attributes;
    private String element_name;
    /** Create a new element around the message string. The string is expected to start with < and end with > */
    /** this is a hack - why aren't we using proper XML parsing?? */
    public GShellElement(String message) {
	// Remove the angle brackets
	message = message.substring(1, message.length() - 1);
	// Tokenize the message
	StringTokenizer tokenizer = new StringTokenizer(message);
	// The first token is the element name - be aware it may start with the close tag indicator
	element_name = tokenizer.nextToken();
	if(element_name.startsWith(StaticStrings.URL_SEPARATOR_CHARACTER)) {
	    element_name = element_name.substring(1);
	    is_closed = true;
	}
	// Now while we have remaining tokens
	while(tokenizer.hasMoreTokens()) {
	    int index = -1;
	    // The next token might be a attribute=value pair or it could be the close tag indicator
	    String token = tokenizer.nextToken();
	    if(token.equals(StaticStrings.URL_SEPARATOR_CHARACTER)) {
		is_closed = true;
	    }
	    else if(token.length() > 3 && (index = token.indexOf(StaticStrings.EQUALS_CHARACTER)) != -1) {
		String attribute_name = token.substring(0, index);
		String attribute_value = token.substring(index + 1);
		// Value may end in a /
		if(attribute_value.endsWith(StaticStrings.URL_SEPARATOR_CHARACTER)) {
		    is_closed = true;
		    attribute_value = attribute_value.substring(0, attribute_value.length() - 1);
		}
		// We may have to strip ' marks off value - if it starts with ' and doesn't end with ' we read in more tokens until we get an ending '
		if(attribute_value.startsWith(StaticStrings.SINGLE_QUOTE_CHARACTER)) {
		    while (!attribute_value.endsWith(StaticStrings.SINGLE_QUOTE_CHARACTER) && tokenizer.hasMoreTokens()) {
			attribute_value += " "+tokenizer.nextToken();
		    }
		    if (attribute_value.endsWith(StaticStrings.SINGLE_QUOTE_CHARACTER)) {
			attribute_value = attribute_value.substring(1, attribute_value.length() - 1);
		    }
		}
		if(attributes == null) {
		    attributes = new HashMap();
		}
		attributes.put(attribute_name, attribute_value);
		attribute_value = null;
		attribute_name = null;
	    }
	    token = null;
	}
	tokenizer = null;
    }

    public String getAttribute(String attribute_name) {
	String result = null;
	if(attributes != null) {
	    result = (String) attributes.get(attribute_name);
	}
	if(result == null) {
	    result = "";
	}
	return result;
    }

    public String getElementName() {
	return element_name;
    }

    public boolean isClosed() {
	return is_closed;
    }
}

