/**
*#########################################################################
*
* 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, Greenstone Digital Library, University of Waikato
*
* Copyright (C) 1999 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.cdm;
import java.util.*;
import org.greenstone.gatherer.DebugStream;
import org.greenstone.gatherer.Gatherer;
import org.greenstone.gatherer.metadata.MetadataElement;
import org.greenstone.gatherer.metadata.MetadataTools;
import org.greenstone.gatherer.util.StaticStrings;
import org.greenstone.gatherer.util.XMLTools;
import org.w3c.dom.*;
/** This class encapsulates a single indexing pair.
* @author John Thompson, Greenstone Digital Library, University of Waikato
* @version 2.3d
*/
public class Index
implements Comparable, DOMProxyListEntry {
/** An values of items in the index level enumeration. */
static protected final String LEVEL[] = {StaticStrings.DOCUMENT_STR, StaticStrings.SECTION_STR, StaticStrings.PARAGRAPH_STR};
private ArrayList sources = null;
/** The level of this index (if old sckool MG). */
private int level = -1;
/** The element this index is based upon. */
private Element element = null;
/** The unique, if cryptic, identifier of an index. */
private String id = null;
/** Default constructor, which should only be used during DOMProxyListModel creation. */
public Index() {
}
/** Constructor. */
public Index(Element element) {
this.element = element;
}
/** Constructor for a newly assigned index. */
public Index(ArrayList sources) {
this.sources = sources;
// Create a new element
this.element = CollectionConfiguration.createElement(StaticStrings.INDEX_ELEMENT);
// For each source add a content element
int size = sources.size();
for(int i = 0; i < size; i++) {
Element content_element = CollectionConfiguration.createElement(StaticStrings.CONTENT_ELEMENT);
Object source_object = sources.get(i);
if (source_object instanceof MetadataElement) {
// System.err.println("Constructing new Index with MetadataElement source...");
content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, ((MetadataElement) source_object).getFullName());
}
else {
// System.err.println("Constructing new Index with String source...");
content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, source_object.toString());
}
element.appendChild(content_element);
content_element = null;
}
}
/** Constructor for a newly assigned index with specified level (old skool). */
public Index(int level, ArrayList sources) {
this(sources);
this.level = level;
element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, LEVEL[level]);
}
public Index(String level, ArrayList sources) {
this(sources);
for(int i = 0; i < LEVEL.length; i++) {
if(LEVEL[i].equalsIgnoreCase(level)) {
this.level = i;
}
}
element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, LEVEL[this.level]);
}
/** Method to compare two indexes.
* @param object The other index as an Object.
* @return An int which indicates how the indexes compare.
* @see java.lang.String
*/
public int compareTo(Object object) {
if(object == null) {
return -1;
}
String id = getID();
return id.compareTo(((Index)object).getID());
}
public DOMProxyListEntry create(Element element) {
return new Index(element);
}
/** Method to test for the equality of two indexes.
* @param object The other index as an Object.
* @return A boolean which is true if the two indexes are equal, false otherwise.
*/
public boolean equals(Object object) {
return (compareTo(object) == 0);
}
public Element getElement() {
return element;
}
/** Method to get the value of level.
* @return the level as a int
*/
public int getLevel() {
if(level == -1 && element != null) {
String level_str = element.getAttribute(StaticStrings.LEVEL_ATTRIBUTE);
for(int i = 0; level == -1 && i < LEVEL.length; i++) {
if(level_str.equals(LEVEL[i])) {
level = i;
}
}
level_str = null;
}
return level;
}
public String getID() {
if(element == null) {
id="";
}
else if(id == null) {
StringBuffer id_buffer = new StringBuffer();
// Write level information, if any.
int level = getLevel();
if(0 <= level && level < 3) {
id_buffer.append(LEVEL[level]);
id_buffer.append(StaticStrings.COLON_CHARACTER);
}
// Write data information. Retrieve each of the content sources and add them in a comma separated list.
ArrayList sources = getSources();
int sources_size = sources.size();
for(int i = 0; i < sources_size; i++) {
Object source_object = sources.get(i);
if (source_object instanceof MetadataElement) {
String full_element_name = ((MetadataElement)source_object).getFullName();
if(full_element_name.startsWith(StaticStrings.EXTRACTED_NAMESPACE) && full_element_name.indexOf(StaticStrings.NS_SEP, StaticStrings.EXTRACTED_NAMESPACE.length()) == -1) {
id_buffer.append(full_element_name.substring(StaticStrings.EXTRACTED_NAMESPACE.length()));
}
else {
id_buffer.append(full_element_name);
}
}
else {
id_buffer.append(source_object.toString());
}
id_buffer.append(StaticStrings.COMMA_CHARACTER);
}
sources = null;
if (id_buffer.length()==0) {
id = "";
} else {
id = id_buffer.substring(0, id_buffer.length() - 1);
}
}
return id;
}
/** Retrieve the sources of this index.
* @return the sources as an ArrayList
*/
public ArrayList getSources() {
if(sources == null) {
sources = new ArrayList();
NodeList content_elements = element.getElementsByTagName(StaticStrings.CONTENT_ELEMENT);
int content_elements_length = content_elements.getLength();
for(int i = 0; i < content_elements_length; i++) {
Element content_element = (Element) content_elements.item(i);
String metadata_element_name_full = (String) content_element.getAttribute(StaticStrings.NAME_ATTRIBUTE);
MetadataElement metadata_element = MetadataTools.getMetadataElementWithName(metadata_element_name_full);
if (metadata_element != null) {
sources.add(metadata_element);
}
else {
sources.add(metadata_element_name_full);
}
}
content_elements = null;
}
return sources;
}
public boolean isAssigned() {
return (element != null && !element.getAttribute(StaticStrings.ASSIGNED_ATTRIBUTE).equals(StaticStrings.FALSE_STR));
}
public void setAssigned(boolean assigned) {
if(element != null) {
element.setAttribute(StaticStrings.ASSIGNED_ATTRIBUTE, (assigned ? StaticStrings.TRUE_STR : StaticStrings.FALSE_STR));
}
}
public void setElement(Element element) {
this.element = element;
this.level = -1;
this.id = null;
this.sources = null;
}
/** Method to set the level of this index which can only be used for the default index.
* @param new_level the new level as an int
*/
public void setLevel(int new_level) {
// System.err.println("SetLevel(" + new_level + ")");
if(element != null && element.getNodeName().equals(StaticStrings.INDEX_DEFAULT_ELEMENT)) {
if (0 <= new_level && new_level < 3) {
element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, LEVEL[new_level]);
} else {
element.setAttribute(StaticStrings.LEVEL_ATTRIBUTE, "");
}
this.id = null; // Regenerate ID.
this.level = new_level;
}
else {
DebugStream.println("Error! Called setLevel() of index other than the default.");
}
}
/** Method to set the sources for this index which can only be used for the default index.
* @param sources an ArrayList of source names
*/
public void setSources(ArrayList sources) {
if(element != null && element.getNodeName().equals(StaticStrings.INDEX_DEFAULT_ELEMENT)) {
// Erase old sources
XMLTools.clear(element);
// For each entry in the sources array add a new content element.
int size = sources.size();
for(int i = 0; i < size; i++) {
Element content_element = element.getOwnerDocument().createElement(StaticStrings.CONTENT_ELEMENT);
Object source_object = sources.get(i);
if (source_object instanceof MetadataElement) {
String name = ((MetadataElement) source_object).getFullName();
content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, name);
name = null;
}
else {
//DebugStream.println("Found String as source: " + source_object.toString());
content_element.setAttribute(StaticStrings.NAME_ATTRIBUTE, source_object.toString());
}
source_object = null;
element.appendChild(content_element);
content_element = null;
}
this.id = null; // Regenerate ID.
this.sources = sources;
}
else {
DebugStream.println("Error! Called setSource() of index other than the default.");
}
}
/** Method to turn this object into a string representation ready to be placed in the collection configuration file.
* @return A String containing the information of this class.
*/
public String toString() {
StringBuffer text_buffer = new StringBuffer("");
// Generate language dependant id (include extracted metadata namespace)
// Write level information, if any.
int level = getLevel();
if(0 <= level && level < 3) {
text_buffer.append(LEVEL[level]);
text_buffer.append(StaticStrings.COLON_CHARACTER);
}
// Write data information. Retrieve each of the content sources and add them in a comma separated list.
ArrayList sources = getSources();
int sources_size = sources.size();
for(int i = 0; i < sources_size; i++) {
String source_name = (sources.get(i)).toString();
text_buffer.append(source_name);
if(i < sources_size - 1) {
text_buffer.append(StaticStrings.COMMA_CHARACTER);
}
}
sources = null;
return text_buffer.toString();
}
}