src.com.ibm.as400.util.html.HTMLTree Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jt400-jdk8 Show documentation
Show all versions of jt400-jdk8 Show documentation
The Open Source version of the IBM Toolbox for Java
///////////////////////////////////////////////////////////////////////////////
//
// JTOpen (IBM Toolbox for Java - OSS version)
//
// Filename: HTMLTree.java
//
// The source code contained herein is licensed under the IBM Public License
// Version 1.0, which has been approved by the Open Source Initiative.
// Copyright (C) 1997-2002 International Business Machines Corporation and
// others. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
package com.ibm.as400.util.html;
import java.util.Vector;
import java.util.Date;
import java.text.Collator; // @A1A
import java.beans.PropertyChangeSupport;
import java.beans.PropertyChangeListener;
import javax.servlet.http.HttpServletRequest;
import com.ibm.as400.access.Trace;
import com.ibm.as400.access.ExtendedIllegalStateException;
/**
* The HTMLTree class represents an HTML hierarchical tree of HTML elements.
*
*
* This example creates an HTMLTree object with five elements.
* The first three elements will be added directly to the HTMLTree and the remaining two
* elements will extend off one of the first three elements.
*
*
*
*
* // Create a URLParser object.
* URLParser urlParser = new URLParser(myHttpServletRequest.getRequestURI());
*
* // Create parent HTMLTreeElements.
* HTMLTreeElement parentElement = new HTMLTreeElement();
* parentElement.setTextUrl(new HTMLHyperlink("http://myWebPage", "My Web Page"));
*
* HTMLTreeElement parentElement2 = new HTMLTreeElement();
* parentElement2.setText(new HTMLText("Parent Element 2"));
*
* HTMLTreeElement parentElement3 = new HTMLTreeElement();
* parentElement3.setText(new HTMLText("Parent Element 3"));
*
* // Create children HTMLTreeElements.
* HTMLTreeElement childElement1 = new HTMLTreeElement();
* childElement1.setTextUrl(new HTMLHyperlink("http://anotherWebPage", "Another Web Page"));
* parentElement.addElement(childElement1);
*
* // Create a child of the first Child Element.
* HTMLTreeElement subChildElement1 = new HTMLTreeElement();
* subChildElement1.setText(new HTMLHyperlink("http://myHomePage", "Home"));
*
* // Add the sub-child to the parent child element.
* childElement1.addElement(subChildElement1);
*
* // Set the URL link for the Expand/Collapsed Icon.
* ServletHyperlink iconUrl = new ServletHyperlink(urlParser.getURI());
* iconUrl.setHttpServletResponse(resp);
* parentElement.setIconUrl(iconUrl);
* parentElement2.setIconUrl(iconUrl);
* parentElement3.setIconUrl(iconUrl);
*
* // Add the parent elements to the tree.
* tree.addElement(parentElement);
* tree.addElement(parentElement2);
* tree.addElement(parentElement3);
*
*
*
* When the HTMLTree is first viewed in a browser, none of the elements in the tree will be
* expanded, so the tree will look like this:
*
*
*
*
* +
*
*
* My Web Page
*
*
*
*
*
* Parent Element 2
*
*
*
*
*
*
* Parent Element 3
*
*
*
*
*
* When the elements in the HTMLTree are expanded by traversing the hierarchy, the tree will look like:
*
*
*
*
* -
*
*
* My Web Page
*
*
*
*
*
* -
*
*
* Another Web Page
*
*
*
*
*
*
*
* Home
*
*
*
*
*
*
*
*
*
*
* Parent Element 2
*
*
*
*
*
*
* Parent Element 3
*
*
*
*
*
* HTMLTree objects generate the following events:
*
* - ElementEvent - The events fired are:
*
* - elementAdded
*
- elementRemoved
*
* - PropertyChangeEvent
*
*
* @see com.ibm.as400.util.html.HTMLTreeElement
* @see com.ibm.as400.util.html.URLParser
**/
public class HTMLTree implements HTMLTagElement, java.io.Serializable
{
private static final String copyright = "Copyright (C) 1997-2002 International Business Machines Corporation and others.";
static final long serialVersionUID = 4170861562301214202L;
private HTMLVector branches_; //@P2C
private HttpServletRequest request_;
private boolean sort_ = true; // @A1A
transient private Collator collator_; // @A1A @B2C
transient private PropertyChangeSupport changes_; //@P2C
transient private Vector elementListeners_; // The list of element listeners @P2C
/**
* Constructs a default HTMLTree object.
**/
public HTMLTree()
{
super();
// @B2A
// If the locale is Korean, then this throws
// an ArrayIndexOutOfBoundsException. This is
// a bug in the JDK. The workarond in that case
// is just to use String.compareTo().
try // @B2A
{
collator_ = Collator.getInstance (); // @B2A
collator_.setStrength (Collator.PRIMARY); // @B2A
}
catch (Exception e) // @B2A
{
collator_ = null; // @B2A
}
branches_ = new HTMLVector(); //@P2C
}
/**
* Constructs an HTMLTree object with the specified HttpServletRequest.
* The request is the mechanism used to provide continuity while expanding
* and collapsing the tree.
* @param request
**/
public HTMLTree(HttpServletRequest request)
{
this();
setHttpServletRequest(request);
}
/**
* Adds an HTMLTreeElement to the tree.
*
* @param element The HTMLTreeElement.
**/
public void addElement(HTMLTreeElement element)
{
if (element == null)
throw new NullPointerException("element");
//@B3D
branches_.addElement(element);
if (elementListeners_ != null) fireElementEvent(ElementEvent.ELEMENT_ADDED); //@P2C
}
/**
* Adds an addElementListener.
* The specified addElementListeners elementAdded method will
* be called each time a RadioFormInput is added to the group.
* The addElementListener object is added to a list of addElementListeners
* managed by this RadioFormInputGroup. It can be removed with removeElementListener.
*
* @see #removeElementListener
*
* @param listener The ElementListener.
**/
public void addElementListener(ElementListener listener)
{
if (listener == null)
throw new NullPointerException ("listener");
if (elementListeners_ == null) elementListeners_ = new Vector(); //@P2A
elementListeners_.addElement(listener);
}
/**
* Adds a PropertyChangeListener. The specified
* PropertyChangeListener's propertyChange
* method is called each time the value of any
* bound property is changed.
*
* @see #removePropertyChangeListener
* @param listener The PropertyChangeListener.
**/
public void addPropertyChangeListener(PropertyChangeListener listener)
{
if (listener == null)
throw new NullPointerException("listener");
if (changes_ == null) changes_ = new PropertyChangeSupport(this); //@P2A
changes_.addPropertyChangeListener(listener);
}
/**
* Deserializes and initializes transient data.
**/
private void readObject(java.io.ObjectInputStream in)
throws java.io.IOException, ClassNotFoundException
{
// @B2A
// If the locale is Korean, then this throws
// an ArrayIndexOutOfBoundsException. This is
// a bug in the JDK. The workarond in that case
// is just to use String.compareTo().
try // @B2A
{
collator_ = Collator.getInstance (); // @B2A
collator_.setStrength (Collator.PRIMARY); // @B2A
}
catch (Exception e) // @B2A
{
collator_ = null; // @B2A
}
in.defaultReadObject();
//@P2D changes_ = new PropertyChangeSupport(this);
//@P2D elementListeners = new Vector();
}
/**
* Removes an HTMLTreeElement from the tree.
*
* @param element The HTMLTreeElement.
**/
public void removeElement(HTMLTreeElement element)
{
if (element == null)
throw new NullPointerException("element");
//@B3D
if (branches_.removeElement(element) && elementListeners_ != null) //@P2C
fireElementEvent(ElementEvent.ELEMENT_REMOVED);
}
/**
* Removes this ElementListener from the internal list.
* If the ElementListener is not on the list, nothing is done.
*
* @see #addElementListener
*
* @param listener The ElementListener.
**/
public void removeElementListener(ElementListener listener)
{
if (listener == null)
throw new NullPointerException ("listener");
if (elementListeners_ != null) elementListeners_.removeElement(listener); //@P2C
}
/**
* Removes the PropertyChangeListener from the internal list.
* If the PropertyChangeListener is not on the list, nothing is done.
*
* @see #addPropertyChangeListener
* @param listener The PropertyChangeListener.
**/
public void removePropertyChangeListener(PropertyChangeListener listener)
{
if (listener == null)
throw new NullPointerException("listener");
if (changes_ != null) changes_.removePropertyChangeListener(listener); //@P2C
}
/**
* Fires the element event.
**/
private void fireElementEvent(int evt)
{
Vector targets;
targets = (Vector) elementListeners_.clone();
ElementEvent elementEvt = new ElementEvent(this, evt);
for (int i = 0; i < targets.size(); i++)
{
ElementListener target = (ElementListener)targets.elementAt(i);
if (evt == ElementEvent.ELEMENT_ADDED)
target.elementAdded(elementEvt);
else if (evt == ElementEvent.ELEMENT_REMOVED)
target.elementRemoved(elementEvt);
}
}
/**
* Returns the HttpServletRequest.
*
* @return The request.
**/
public HttpServletRequest getHttpServletRequest()
{
return request_;
}
/**
* Returns the Collator.
*
* @return The collator.
**/
public Collator getCollator() // @B2A
{
return collator_;
}
/**
* Returns a comment tag.
* This method should not be called. There is no XSL-FO support for this class.
* @return The comment tag.
**/
public String getFOTag() //@C1A
{
Trace.log(Trace.ERROR, "Attempting to getFOTag() for an object that doesn't support it.");
return "";
}
/**
* Returns the HTMLTree tag.
*
* @return The tag.
**/
public String getTag()
{
//@B3D
if (request_ == null)
throw new ExtendedIllegalStateException("request", ExtendedIllegalStateException.PROPERTY_NOT_SET );
// Get the hashcode parameter from the HTTP request.
String hcStr = request_.getParameter("hashcode"); // @B1C
StringBuffer buf1 = new StringBuffer("\n");
if (sort_) sort(collator_, branches_); // @A1A @B2C @P2C
int size = branches_.getCount(); //@P2A
Object[] data = branches_.getData(); //@P2A
for (int i=0; i\n");
return buf1.toString();
}
/**
* Sets the collator. The collator allows the tree to perform
* locale-sensitive String comparisons when sorting the tree elements.
*
* @param collator The Collator.
**/
public void setCollator(Collator collator) // @B2A
{
if (collator == null)
throw new NullPointerException("collator");
Collator old = collator_;
collator_ = collator;
if (changes_ != null) changes_.firePropertyChange("collator", old, collator_); //@P2C
}
/**
* Sets the Http servlet request. The request is the mechanism
* used to provide continuity while expanding and collapsing the tree.
*
* @param request The Http servlet request.
**/
public void setHttpServletRequest(HttpServletRequest request)
{
if (request == null)
throw new NullPointerException("request");
HttpServletRequest old = request_;
request_ = request;
if (changes_ != null) changes_.firePropertyChange("request", old, request_); //@P2C
}
/**
* Sorts the elements within the HTMLTree.
*
* @param sort true if the elements are sorted; false otherwise.
* The default is true.
**/
public void sort(boolean sort) // @A1A
{
sort_ = sort;
}
/**
* Sorts a vector of objects.
*
* @param collator The Collator, or null if the default Collator should be used.
* @param list The objects.
*
* @return The sorted Vector.
**/
public static Vector sort (Collator collator, Vector list) // @A1A @B2C @B4C @P2C
{
heapSort(collator, list); // @B2A
return list;
}
/**
* Method used to perform a heap sort,
* which is faster than a quick sort and
* a bubble sort.
*
* @param collator The collator.
* @param sortlist The list to sort.
**/
private static void heapSort(Collator collator, Vector sortlist) // @B2A
{
int numberOfEntries = sortlist.size();
int i;
Object temp = null;
if (numberOfEntries > 0)
{
// convert table list map into a heap
for (i = (numberOfEntries/2); i != 0; i--)
{
adjustList(collator, sortlist,i,numberOfEntries);
}
// sort table list
for (i = (numberOfEntries - 1); i != 0; i--)
{
// swap first and last entries in heap to get largest remaining
// table name correctly placed
temp = sortlist.elementAt(i);
sortlist.setElementAt(sortlist.elementAt(0),i);
sortlist.setElementAt(temp,0);
// create new heap with the remaining nodes
adjustList(collator, sortlist,1,i);
}
}
}
/**
* Utility routine used by heap sort
**/
private static void adjustList(Collator collator, Vector sortlist, int rootIndex, int maxIndex) // @B2A
{
Object rootItem = sortlist.elementAt(rootIndex-1);
int j = rootIndex * 2;
Object itemAtJ = null;
Object itemAtJLess1 = null;
boolean done = false;
// traverse tree
while ((j <= maxIndex) && (done == false))
{
itemAtJLess1 = sortlist.elementAt(j-1);
if (j < maxIndex)
{
itemAtJ = sortlist.elementAt(j);
// find greater table name of left and right child
if (sortCompare(collator, itemAtJLess1, itemAtJ) < 0)
{
j++;
itemAtJLess1 = itemAtJ;
}
}
// if root table name is greater than max child
if (sortCompare(collator, rootItem, itemAtJLess1) >= 0)
done = true;
// root table name less than max child
else
{
// move max child up tree
sortlist.setElementAt(sortlist.elementAt(j-1),(j/2)-1);
// move to next level
j = j * 2;
}
}
// place original root in proper place
sortlist.setElementAt(rootItem,(j/2)-1);
}
/**
* Compares two objects for the sort.
*
* @param objectI The ith object.
* @param objectJ The jth object.
* @return a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater
* than the second.
**/
private static int sortCompare (Collator collator, Object objectI, Object objectJ) // @A1A
{
Object valueI;
Object valueJ;
// When the object is a HTMLTreeElement or FileTreeElement the
// sort must be done against the name or viewable text
// of the element otherwise nothing will be sorted properly.
if (objectI instanceof FileTreeElement)
{ // @B2C
valueI = ((FileTreeElement)objectI).getFile().getName();
valueJ = ((FileTreeElement)objectJ).getFile().getName();
}
else if (objectI instanceof HTMLTreeElement) // @B2C
{
valueI = ((HTMLTreeElement)objectI).getText();
valueJ = ((HTMLTreeElement)objectJ).getText();
}
else
{
valueI = objectI.toString();
valueJ = objectJ.toString();
}
// Check for nulls.
if (valueI == null)
valueI = "";
if (valueJ == null)
valueJ = "";
int comparison = 0;
// If they are equal, then use the next column.
if (collator != null) // Otherwise, do the comparison using this column.
comparison = collator.compare (valueI.toString(), valueJ.toString()); // @B2C
else
comparison = valueI.toString().compareTo(valueJ.toString()); // @B2C
// Return the value.
return comparison;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy