// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3) deadcode 
// Source File Name:   StructuredDocumentProcessor.java

package com.ptc.windchill.pdmlink.doc.server.processors;

import com.ptc.core.HTMLtemplateutil.server.processors.*;
import java.io.*;
import java.net.URL;
import java.util.*;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;
import wt.doc.*;
import wt.enterprise.BasicTemplateProcessor;
import wt.fc.*;
import wt.htmlutil.HtmlUtil;
import wt.htmlutil.TemplateOutputStream;
import wt.httpgw.*;
import wt.identity.DisplayIdentity;
import wt.lifecycle.State;
import wt.pds.PDSObjectInput;
import wt.session.*;
import wt.templateutil.processor.*;
import wt.templateutil.table.*;
import wt.util.*;
import wt.vc.*;
import wt.vc.baseline.ManagedBaseline;
import wt.vc.config.*;
import wt.vc.wip.*;
import wt.visitor.PathNode;

public class StructuredDocumentProcessor extends ExpandCollapseSectionProcessor
    implements Externalizable
{

    public StructuredDocumentProcessor()
    {
        identifier = 0;
        topDoc = null;
        topDocMaster = null;
        configSpec = null;
        locale = null;
        docCookie = null;
        treeModel = null;
        rowDataObjects = null;
        topDocIsNull = false;
        isInitializingTreeTable = false;
    }

    public void writeExternal(ObjectOutput output)
        throws IOException
    {
        output.writeLong(0x1cb93348b29c6cd5L);
        super.writeExternal(output);
    }

    public void readExternal(ObjectInput input)
        throws IOException, ClassNotFoundException
    {
        long readSerialVersionUID = input.readLong();
        readVersion(this, input, readSerialVersionUID, false, false);
    }

    protected boolean readVersion(StructuredDocumentProcessor thisObject, ObjectInput input, long readSerialVersionUID, boolean passThrough, boolean superDone)
        throws IOException, ClassNotFoundException
    {
        boolean success = true;
        if(readSerialVersionUID == 0x1cb93348b29c6cd5L)
        {
            if(!superDone)
                super.readExternal(input);
        } else
        {
            success = readOldVersion(input, readSerialVersionUID, passThrough, superDone);
            if(input instanceof PDSObjectInput)
                EvolvableHelper.requestRewriteOfEvolvedBlobbedObject();
        }
        return success;
    }

    private boolean readOldVersion(ObjectInput input, long readSerialVersionUID, boolean passThrough, boolean superDone)
        throws IOException, ClassNotFoundException
    {
        boolean success = true;
        if(readSerialVersionUID != 0x3b7e613e796c1195L)
            if(!superDone)
            {
                success = super.readVersion(this, input, readSerialVersionUID, false, false);
                if(success && !passThrough && readSerialVersionUID != 0x5c76dbfc74a584b3L)
                    readVersion(this, input, input.readLong(), false, true);
            } else
            {
                throw new InvalidClassException(CLASSNAME, "Local class not compatible: stream classdesc externalizationVersionUID=" + readSerialVersionUID + " local class externalizationVersionUID=" + 0x1cb93348b29c6cd5L);
            }
        return success;
    }

    public void initializeTreeTable(Properties parameters, Locale locale, OutputStream os)
        throws WTException, WTPropertyVetoException
    {
        if(VERBOSE)
            System.out.println("initializeTreeTable:  Starting to get the tree setup.");
        try
        {
            Properties formProperties = getFormData();
            isInitializingTreeTable = true;
            this.locale = locale;
            PrintWriter out = TemplateOutputStream.getPrintWriter(os, locale);
            WTDocument context_doc = (WTDocument)getContextObj();
            String context_oid = context_doc.getPersistInfo().getObjectIdentifier().toString();
            if(VERBOSE)
                System.out.println("***** Context Object is: name = " + context_doc.getName() + " oid = " + context_oid + " Document version info = " + VersionControlHelper.getVersionIdentifier(context_doc).getValue() + "." + VersionControlHelper.getIterationIdentifier(context_doc).getValue());
            String checkin = formProperties.getProperty("checkin");
            if(checkin != null && checkin.equals("true"))
            {
                switchCookies(formProperties);
            } else
            {
                checkin = "false";
                WTDocumentConfigSpec form_config = null;
                if(getFormData().getProperty("DOC_CONFIG_SPEC") != null)
                    form_config = getConfigSpec(getFormData().getProperty("DOC_CONFIG_SPEC"));
                Vector rowDataObj = (Vector)getCookie().get("rowDataObjects");
                WTDocumentConfigSpec cookie_config = (WTDocumentConfigSpec)getCookie().get("configSpec");
                boolean latest_config = true;
                if(cookie_config != null && (cookie_config.getActive() instanceof BaselineConfigSpec))
                    latest_config = false;
                if(VERBOSE && !latest_config)
                    System.out.println("***** Config Spec in cookie is Baseline " + cookie_config.getActive());
                if(rowDataObj != null && rowDataObj.size() > 0 && form_config == null && latest_config)
                {
                    Object data = rowDataObj.elementAt(0);
                    if(data instanceof WTDocument)
                    {
                        WTDocument top_doc = (WTDocument)data;
                        String top_oid = top_doc.getPersistInfo().getObjectIdentifier().toString();
                        if(VERBOSE)
                            System.out.println("***** Top Node Object is: name = " + top_doc.getName() + " oid = " + top_oid + " Document version info = " + VersionControlHelper.getVersionIdentifier(top_doc).getValue() + "." + VersionControlHelper.getIterationIdentifier(top_doc).getValue());
                        if(context_oid.equals(top_oid))
                        {
                            if(VERBOSE)
                                System.out.println("***** Checking to see if the top doc and context doc are out of sync.");
                            boolean context_ckout = WorkInProgressHelper.isCheckedOut(context_doc, SessionMgr.getPrincipal());
                            boolean top_ckout = WorkInProgressHelper.isCheckedOut(top_doc, SessionMgr.getPrincipal());
                            if(context_ckout != top_ckout)
                            {
                                if(VERBOSE)
                                    System.out.println("***** Top node doc and context doc are not in sync by check out/in status.");
                                rowDataObjects = getRowDataObjects();
                                treeModel = (TreeModel)getCookie().get("treeModel");
                                Integer nextNodeIdentity = (Integer)getCookie().get("nextNodeIdentity");
                                identifier = nextNodeIdentity.intValue();
                                refreshForAssociation(top_doc, context_doc);
                                if(VERBOSE)
                                    System.out.println("***** Identifier = " + identifier);
                                getCookie().put("rowDataObjects", rowDataObjects);
                                getCookie().put("treeModel", treeModel);
                                getCookie().put("nextNodeIdentity", new Integer(identifier));
                                saveCookies();
                            }
                        } else
                        if(VERBOSE)
                            System.out.println("***** Top node doc and context doc are not the same.");
                    }
                } else
                if(VERBOSE)
                    System.out.println("***** Either no cookie, change of cookie, or baseline config spec.  Don't check if out of sync context doc and top doc.");
            }
            if(VERBOSE)
                printOutCookie("StrucDocProc.initTreeTable:  Starting to test whether new or existing structure, here is current cookie.", "StrucDocProc.initTreeTable:  ");
            if(needNewCookie(formProperties))
            {
                if((context_doc instanceof Workable) && WorkInProgressHelper.isCheckedOut(context_doc, SessionMgr.getPrincipal()) && WorkInProgressHelper.isWorkingCopy(context_doc))
                {
                    WTDocument orig = (WTDocument)WorkInProgressHelper.service.originalCopyOf(context_doc);
                    switchCookies(orig);
                    if(needNewCookie(formProperties))
                    {
                        if(VERBOSE)
                            System.out.println("StructuredDocumentProcessor.initializeTreeTable:  This is a checked out Document but it isn't after a checkout, so need to start new display.");
                        getNewCookie();
                        configSpec = getConfigSpec();
                        rowDataObjects = getRowDataObjects();
                        expand(getTopDoc());
                    } else
                    {
                        if(VERBOSE)
                            printOutCookie("StrucDocProc.initTreeTable:  After checkout and switch cookie, here is current cookie.", "StrucDocProc.initTreeTable:  ");
                        rowDataObjects = (Vector)getCookie().get("rowDataObjects");
                        treeModel = (TreeModel)getCookie().get("treeModel");
                        Integer nextNodeIdentity = (Integer)getCookie().get("nextNodeIdentity");
                        identifier = nextNodeIdentity.intValue();
                        refreshForAssociation(orig, context_doc);
                    }
                } else
                {
                    if(VERBOSE)
                        System.out.println("StructuredDocumentProcessor.initializeTreeTable:  New Display (either first display or redoing the display because of new Configuration).");
                    getNewCookie();
                    configSpec = getConfigSpec();
                    rowDataObjects = getRowDataObjects();
                    expand(getTopDoc());
                }
            } else
            if(formProperties != null)
            {
                if(VERBOSE)
                    System.out.println("StructuredDocumentProcessor.initializeTreeTable:  Follow-on Display (adding to an existing display).");
                if(DISABLE_CACHE)
                {
                    if(VERBOSE)
                        System.out.println(">>> VERBOSE : " + CLASSNAME + " : " + "Entering CACHE DISABLED.");
                    refreshForAssociation(context_doc, context_doc);
                    if(VERBOSE)
                        printOutCookie("CACHE DISABLED : ", "CACHE DISABLED : ");
                    if(VERBOSE)
                        System.out.println(">>> VERBOSE : " + CLASSNAME + " : " + "Exiting CACHE DISABLED.");
                }
                Integer nextNodeIdentity = (Integer)getCookie().get("nextNodeIdentity");
                identifier = nextNodeIdentity.intValue();
                if(formProperties.getProperty("treeNode") != null)
                {
                    String treeAction = null;
                    String treeIdentity = null;
                    if(formProperties != null)
                    {
                        treeAction = formProperties.getProperty("treeNode");
                        treeIdentity = formProperties.getProperty("identity");
                    }
                    boolean actionIsOpening = "open".equals(treeAction);
                    if(treeIdentity != null)
                    {
                        int treeIdentityInt = Integer.parseInt(treeIdentity);
                        TreeTableNode targetNode = null;
                        int targetIndex = 0;
                        Vector vTempData = getRowDataObjects();
                        int i = 1;
                        do
                        {
                            if(i >= vTempData.size())
                                break;
                            TreeTableNode currentNode = (TreeTableNode)vTempData.elementAt(i);
                            if(currentNode.getIdentifier() == treeIdentityInt)
                            {
                                targetNode = currentNode;
                                targetIndex = i;
                                break;
                            }
                            i++;
                        } while(true);
                        expand(targetNode, targetIndex, actionIsOpening, false);
                    }
                } else
                if(formProperties.getProperty("tableSelectionAction") != null)
                {
                    String tableSelectionAction = formProperties.getProperty("tableSelectionAction");
                    if(VERBOSE)
                        System.out.println("StructuredDocumentProcessor tableSelectionAction = " + tableSelectionAction);
                    if(tableSelectionAction.equals("ExpandOne") || tableSelectionAction.equals("ExpandAll") || tableSelectionAction.equals("Collapse"))
                    {
                        boolean actionIsOpening = tableSelectionAction.equals("ExpandOne") || tableSelectionAction.equals("ExpandAll");
                        boolean actionIsRecursive = tableSelectionAction.equals("ExpandAll") || tableSelectionAction.equals("Collapse");
                        Enumeration keys = formProperties.keys();
                        do
                        {
                            if(!keys.hasMoreElements())
                                break;
                            String name = (String)keys.nextElement();
                            if(name.startsWith("checkbox__"))
                            {
                                String item = formProperties.getProperty(name);
                                if(VERBOSE)
                                    System.out.println(">> TABLE ACTION ITEM : " + item);
                                int targetIndex = getNodeIndex(item);
                                if(targetIndex != -1)
                                {
                                    TreeTableNode targetNode = getNode(targetIndex);
                                    if(targetNode != null)
                                    {
                                        if(VERBOSE)
                                            System.out.println(">> Starting to expand Node : " + targetNode + " Index : " + targetIndex + "Is Opening : " + actionIsOpening + " Recursive : " + actionIsRecursive);
                                        targetIndex = expand(targetNode, targetIndex, actionIsOpening, actionIsRecursive);
                                        formProperties.remove(name);
                                    } else
                                    if(VERBOSE)
                                        System.out.println(">> TABLE ACTION ITEM NODE is NULL");
                                } else
                                if(VERBOSE)
                                    System.out.println(">> TABLE ACTION ITEM NODE is returning NO_NODE - no such index in rowDataObjects");
                            }
                        } while(true);
                    } else
                    if(tableSelectionAction.equals("Reset"))
                    {
                        if(VERBOSE)
                            System.out.println(">>> VERBOSE : " + CLASSNAME + " : " + "Entering Table Selection Action RESET / REFRESH.");
                        Vector vRowData = new Vector(getRowDataObjects());
                        treeModel = getTreeModel();
                        if(treeModel != null)
                        {
                            identifier = 1;
                            TreeTableNode tmpNode = (TreeTableNode)treeModel.getRoot();
                            if(context_doc != null && tmpNode != null)
                            {
                                if(VERBOSE)
                                    System.out.println(">>> VERBOSE : " + CLASSNAME + " : " + "RESET : Starting call to refreshTreeNode.");
                                refreshTreeNode(context_doc, tmpNode, true);
                                if(VERBOSE)
                                    System.out.println(">>> VERBOSE : " + CLASSNAME + " : " + "RESET : Finished call to refreshTreeNode");
                            } else
                            if(VERBOSE)
                                System.out.println(">>> VERBOSE : " + CLASSNAME + " : " + "RESET : Context Doc was null, or TreeTableNode was null - do nothing.");
                        }
                        getCookie().put("rowDataObjects", rowDataObjects);
                        getCookie().put("treeModel", treeModel);
                        getCookie().put("nextNodeIdentity", new Integer(identifier));
                        saveCookies();
                        Vector currentRowData = new Vector(getRowDataObjects());
                        int i = 1;
                        for(int n = vRowData.size(); i < n; i++)
                        {
                            Object obj = vRowData.elementAt(i);
                            if(obj instanceof WTDocument)
                                continue;
                            TreeTableNode oldNode = (TreeTableNode)obj;
                            int x = 0;
                            for(int y = currentRowData.size(); x < y; x++)
                            {
                                Object obj2 = currentRowData.elementAt(x);
                                if(obj2 instanceof WTDocument)
                                    continue;
                                TreeTableNode currentNode = (TreeTableNode)obj2;
                                if(oldNode.getIdentifier() != currentNode.getIdentifier())
                                    continue;
                                boolean actionIsOpen = oldNode.getIsOpen();
                                if(rowDataObjects.contains(currentNode))
                                    expand(currentNode, currentNode.getIdentifier(), actionIsOpen, false);
                            }

                        }

                        getCookie().put("rowDataObjects", rowDataObjects);
                        getCookie().put("treeModel", treeModel);
                        getCookie().put("nextNodeIdentity", new Integer(identifier));
                        saveCookies();
                        if(VERBOSE)
                            printOutCookie("RESET : ", "RESET : ");
                        if(VERBOSE)
                            System.out.println(">>> VERBOSE : " + CLASSNAME + " : " + "Exiting Table Selection Action RESET / REFRESH.");
                    } else
                    if(tableSelectionAction.equals("RefreshForAssociation"))
                    {
                        if(VERBOSE)
                            System.out.println("StructuredDocumentProcessor.initializeTreeTable:  refresh tree model when something in the data changes.");
                        String oldOid = formProperties.getProperty("oldOid");
                        String newOid = formProperties.getProperty("newOid");
                        refreshForAssociation(oldOid, newOid);
                    }
                }
            }
            TreeTableModel tableModel = new TreeTableModel();
            tableModel.setRowDataObjects(rowDataObjects);
            tableModel.setLocale(locale);
            int columnIndex = 0;
            String columnList = parameters.getProperty("COLUMNS");
            Vector columnVector = new Vector();
            if(columnList == null || columnList.length() == 0 || columnList.equals(""))
                throw new WTException("com.ptc.windchill.pdmlink.doc.server.processors.processorsResource", "94", null);
            StringTokenizer tokenizer = new StringTokenizer(columnList, ",");
            int tokenCount = tokenizer.countTokens();
            boolean needToRemoveOrganizationIdentifier = !SHOW_ORGID;
            for(int i = 0; i < tokenCount; i++)
            {
                boolean keep = true;
                String nextToken = tokenizer.nextToken().trim();
                if(needToRemoveOrganizationIdentifier && nextToken.equals("organizationUniqueIdentifier"))
                    keep = false;
                if(keep)
                {
                    columnVector.addElement(nextToken);
                    columnIndex++;
                }
            }

            String moveFrom = (new Integer(columnIndex + 2)).toString();
            String moveTo = null;
            tableModel.setTableColumns(columnVector);
            PDMLinkHTMLTable table = new PDMLinkHTMLTable();
            List multiSelectActionList = new ArrayList();
            table.setMultiSelectActionNavBarName("DocumentStructure_MultiSelectActions");
            multiSelectActionList.add("CopyDocUfid");
            multiSelectActionList.add("AddToProjectUfid");
            multiSelectActionList.add("CONTAINERMOVE_STRUCT_BROWSER");
            multiSelectActionList.add("ExpandOne");
            multiSelectActionList.add("ExpandAll");
            multiSelectActionList.add("Collapse");
            multiSelectActionList.add("DocumentDownload");
            multiSelectActionList.add("AddToBaseline");
            table.setMultiSelectActionList(multiSelectActionList);
            List actionList = new ArrayList();
            table.setActionNavBarName("DocumentStructure_TableActions");
            actionList.add("Reset");
            table.setActionList(actionList);
            table.setTableModel(tableModel);
            table.setLocale(locale);
            table.setFormData(parameters);
            table.setTableColumnModel(new DefaultHTMLTableColumnModel());
            table.setPresentCheckBox(true);
            table.createDefaultColumnsFromModel();
            table.setOutputStream(os);
            table.setState(getState());
            table.setName("DocumentStructureTable");
            table.init(null, null, null, null, null);
            String tags[] = {
                "TABLE"
            };
            table.setTagList(tags);
            ServletSessionCookie cookie = getCookie();
            cookie.put("rowDataObjects", rowDataObjects);
            cookie.put("treeModel", treeModel);
            cookie.put("nextNodeIdentity", new Integer(identifier));
            cookie.put("RETURN_URL", getState().getRequestObj().getFullURL());
            saveCookies();
            if(VERBOSE)
                printOutCookie("StrucDocProc.initTreeTable:  After init tree and saving the cookie, here is the cookie that is active.", "StrucDocProc.initTreeTable:  ");
            getHTMLTableService().setHtmlTable(table);
            out.flush();
        }
        catch(WTException e)
        {
            DefaultTemplateProcessor.addToFeedbackCookie(e, getState());
        }
        if(VERBOSE)
            System.out.println("end of the initializeTreeTable");
    }

    public void outputConfigSpecSelector(Properties parameters, Locale locale, OutputStream os)
        throws WTException, IOException
    {
        String uniqueConfigWindow = "configspec" + getTimeStamp();
        String mainWindow = "main" + getTimeStamp();
        PrintWriter out = TemplateOutputStream.getPrintWriter(os, locale);
        out.print("<Form name=\"RefreshConfiguration\" method=\"post\" action=\"");
        getCurrentUrl(parameters, locale, os);
        out.println("\">");
        out.println("<INPUT TYPE=\"hidden\" NAME=\"DocOid\" VALUE=\"?\">");
        out.println("</Form>");
        out.println("<Form name=\"SelectConfiguration\">");
        out.print("<P><B>");
        out.print(getResourceString("36", locale, "com.ptc.windchill.pdmlink.doc.server.processors.processorsResource", "36"));
        out.println(":&nbsp;</B>");
        out.println("<Select " + HtmlUtil.createTrlIdAttribute("PDML", "configSpec", "DropDown", "doc_mgmt_Config_Select") + " Name=\"Configuration\" onchange=\"submitConfiguration()\">");
        String trailId = HtmlUtil.createTrlIdAttribute("PDML", "configSpec", "DropDown", "doc_mgmt_Config_Id");
        out.print("<Option " + trailId + " Value=0 Selected>");
        out.print(getConfigurationIdentity(locale));
        out.println("</Option>");
        trailId = HtmlUtil.createTrlIdAttribute("PDML", "configSpec", "DropDown", "---");
        out.print("<Option " + trailId + " Value=0>");
        out.print("---");
        out.println("</Option>");
        trailId = HtmlUtil.createTrlIdAttribute("PDML", "configSpec", "DropDown", "doc_mgmt_Choose_Latest_Config_Spec");
        out.print("<Option " + trailId + " Value=\"javascript:launchWindow('");
        getChooseConfigSpecURL(parameters, locale, os, "ChooseLatestDocConfigSpec");
        out.print("&cookieName=" + getCookieName() + "&RETURN_WINDOW=" + mainWindow + "','");
        out.print(uniqueConfigWindow);
        out.print("', 'resizable=yes,scrollbars=yes,menubar=no,toolbar=no,location=no,status=yes,height=425,width=850')");
        out.print("\">");
        out.print(getResourceString("37", locale, "com.ptc.windchill.pdmlink.doc.server.processors.processorsResource", "37"));
        out.println("</Option>");
        trailId = HtmlUtil.createTrlIdAttribute("PDML", "configSpec", "DropDown", "doc_mgmt_Baseline_Config_Spec");
        out.print("<Option " + trailId + " Value=\"javascript:launchWindow('");
        getChooseConfigSpecURL(parameters, locale, os, "ChooseBaselineDocConfigSpec");
        out.print("&cookieName=" + getCookieName() + "&RETURN_WINDOW=" + mainWindow + "','");
        out.print(uniqueConfigWindow);
        out.print("', 'resizable=yes,scrollbars=yes,menubar=no,toolbar=no,location=no,status=yes,height=425,width=850')");
        out.print("\">");
        out.print(getResourceString("38", locale, "com.ptc.windchill.pdmlink.doc.server.processors.processorsResource", "38"));
        out.println("</Option>");
        out.println("</Select></P></Form>");
        out.println("<SCRIPT LANGUAGE=JavaScript>");
        out.println("<!--");
        out.println("var configwindow = null;");
        out.println("function submitConfiguration()");
        out.println("{");
        out.println("  var cform = window.document.SelectConfiguration;");
        out.println("  if (window.document.SelectConfiguration.Configuration.value!=0){");
        out.println("    window.name='" + mainWindow + "'");
        out.println("    submitLink('SelectConfiguration','Configuration');");
        out.println("  }");
        out.println("  setTimeout('window.document.SelectConfiguration.Configuration.selectedIndex=0',10);");
        out.println("}");
        out.println("-->");
        out.println("</SCRIPT>");
        out.flush();
    }

    public void outputEncodedConfigSpec(Properties parameters, Locale locale, OutputStream os)
        throws WTException, IOException
    {
        PrintWriter out = TemplateOutputStream.getPrintWriter(os, locale);
        out.print(getEncodedConfigSpec(getConfigSpec()));
        out.flush();
    }

    public void outputReportSelector(Properties parameters, Locale locale, OutputStream os)
        throws WTException, IOException
    {
        if(!enableReportMenuPicks())
            return;
        PrintWriter out = getPrintWriter(os, locale);
        String link = "";
        String label = WTMessage.getLocalizedMessage("com.ptc.windchill.pdmlink.doc.server.processors.processorsResource", "39", null, locale);
        String style = null;
        String formName = "ReportSelector";
        if(parameters != null)
        {
            label = splitString(parameters.getProperty("label", label));
            style = parameters.getProperty("style");
        }
        WTDocumentConfigSpec config_spec = null;
        WTDocument top_doc = null;
        try
        {
            config_spec = getConfigSpec();
            top_doc = getTopDoc();
        }
        catch(WTPropertyVetoException wtpve)
        {
            out.println(label);
        }
        if(config_spec != null && top_doc != null)
            try
            {
                Properties props = new Properties();
                props.put("oid", top_doc.toString());
                URL url = GatewayURL.buildAuthenticatedURL("wt.enterprise.URLProcessor", "URLTemplateAction", props);
                link = link + getTrailComplFormStart(formName);
                try
                {
                    link = link + getHiddenFieldHTML("config_spec", Encoder.encode(config_spec));
                }
                catch(IOException ioe)
                {
                    if(VERBOSE)
                    {
                        System.err.println("outputReportSelector() - error encoding the config spec: ");
                        ioe.printStackTrace();
                    }
                }
                try
                {
                    link = link + getHiddenFieldHTML("doc", getReferenceString(top_doc));
                }
                catch(WTException wte)
                {
                    if(VERBOSE)
                    {
                        System.err.println("outputReportSelector() - error retrieving the object reference: ");
                        wte.printStackTrace(System.err);
                    }
                }
                link = link + "<TABLE BORDER=\"0\" CELLPADDING=\"0\" CELLSPACING=\"0\"><TR><TD CLASS=f-label>";
                link = link + "<b>" + label + ":</b>" + "&nbsp;" + "</TD><TD>" + "<SELECT " + HtmlUtil.createTrlIdAttribute("PDML", "relatedReports", "DropDown", "doc_mgmt_30") + " name='action'>";
                link = getReportMenuPicks(link);
                link = link + "</SELECT>";
                link = link + "&nbsp;";
                link = link + "</TD><TD>";
                out.print(link);
                out.flush();
                UtilProcessorService utilService = new UtilProcessorService();
                utilService.setState(getState());
                Properties buttonProps = new Properties();
                buttonProps.put("resourceClass", "com.ptc.windchill.pdmlink.doc.server.processors.processorsResource");
                buttonProps.put("resourceKey", "GENERATE_REPORT_BUTTON_LABEL");
                buttonProps.put("buttonURL", "javascript:submitLink('ReportSelector','action')");
                utilService.getButton(buttonProps, locale, os);
                out.flush();
                out.print("</TD></TR></TABLE>");
                out.print(getFormEnd());
                out.flush();
            }
            catch(WTException wte)
            {
                out.println(label);
            }
    }

    public String getReportMenuPicks(String reportSelector)
    {
        return "";
    }

    public boolean enableReportMenuPicks()
    {
        return false;
    }

    public void getDelim(Properties parameters, Locale locale, OutputStream os)
    {
        if(DELIM != null && DELIM.length() > 0)
        {
            PrintWriter out = getPrintWriter(os, locale);
            out.print(DELIM);
            out.flush();
        }
    }

    public void getTreeDocsValues(Properties parameters, Locale locale, OutputStream os)
        throws WTException
    {
        StringBuffer treeDocs = new StringBuffer("");
        rowDataObjects = (Vector)getCookie().get("rowDataObjects");
        int size = rowDataObjects.size();
        for(int i = 0; i < size; i++)
        {
            if(!(rowDataObjects.elementAt(i) instanceof TreeTableNode))
                continue;
            TreeTableNode currentNode = (TreeTableNode)rowDataObjects.elementAt(i);
            int id = currentNode.getIdentifier();
            Object an_object = currentNode.getCentralObject();
            if(!(an_object instanceof WTDocument) && !(an_object instanceof WTDocumentMaster))
                continue;
            String reference = BasicTemplateProcessor.getReferenceString((WTObject)an_object);
            if(!treeDocs.equals(""))
                treeDocs.append(DELIM);
            treeDocs.append(id + DELIM + reference);
        }

        PrintWriter out = getPrintWriter(os, locale);
        out.print(treeDocs.toString());
        out.flush();
    }

    public void getContextDoc(Properties parameters, Locale locale, OutputStream os)
        throws WTException
    {
        WTObject obj = (WTObject)getContextObj();
        if(obj != null)
        {
            ReferenceFactory factory = new ReferenceFactory();
            String context_obj = factory.getReferenceString(ObjectReference.newObjectReference(obj.getPersistInfo().getObjectIdentifier()));
            PrintWriter out = getPrintWriter(os, locale);
            out.print(context_obj);
            out.flush();
        }
    }

    private void expand()
        throws WTException, WTPropertyVetoException
    {
        ConfigSpec oldSpec = getConfigSpec();
        getNewCookie();
        configSpec = null;
        rowDataObjects = null;
        rowDataObjects = getRowDataObjects();
        if(oldSpec != null)
            getCookie().put("configSpec", oldSpec);
        expand(getTopDoc());
    }

    private Vector remove(Vector vec, TreeTableNode node)
    {
        if(vec.contains(node))
        {
            vec.removeElement(node);
            if(node.getIsOpen())
            {
                for(Enumeration children = node.children(); children.hasMoreElements();)
                {
                    TreeTableNode subNode = (TreeTableNode)children.nextElement();
                    vec = remove(vec, subNode);
                }

            }
        }
        return vec;
    }

    protected String getEncodedConfigSpec(ConfigSpec configSpec)
        throws WTException, IOException
    {
        return Encoder.encode(configSpec);
    }

    protected String getTrailComplFormStart(String name)
    {
        return "<FORM NAME=\"" + name + "\">";
    }

    protected String getFormEnd()
    {
        return "</FORM>";
    }

    protected static String getHiddenFieldHTML(String name, String value)
    {
        return "<INPUT TYPE=\"hidden\" NAME=\"" + name + "\" VALUE=\"" + value + "\">";
    }

    protected static String splitString(String string_to_split)
    {
        if(string_to_split != null)
            string_to_split = string_to_split.replace("&".toCharArray()[0], ' ');
        return string_to_split;
    }

    protected void saveCookies()
    {
        getState().getCookieManager().saveCookies();
    }

    protected ServletSessionCookie getCookie()
    {
        if(docCookie == null)
        {
            String cookieName = getCookieName();
            docCookie = getState().getCookieManager().getCookie(cookieName);
        }
        return docCookie;
    }

    protected ServletSessionCookie getNewCookie()
    {
        String cookieName = getCookieName();
        if(VERBOSE)
            System.out.println("getNewCookie:  New cookie name = " + cookieName);
        getState().getCookieManager().removeCookie(cookieName);
        docCookie = getState().getCookieManager().newCookie(cookieName);
        return docCookie;
    }

    protected String getCookieName()
    {
        return getCookieName(getContextObj());
    }

    protected String getCookieName(Object doc)
    {
        return "DocStructure-" + doc;
    }

    protected void switchCookies(Properties formProperties)
    {
        String oldOid = formProperties.getProperty("oldOid");
        ReferenceFactory factory = new ReferenceFactory();
        if(oldOid != null && !oldOid.equalsIgnoreCase("undefined"))
        {
            if(VERBOSE)
                System.out.println("switchCookies:  Old oid = " + oldOid);
            WTDocument old_doc = null;
            try
            {
                old_doc = (WTDocument)factory.getReference(oldOid).getObject();
                if(VERBOSE)
                    System.out.println("switchCookies:  Document retrieved.");
            }
            catch(WTException wte)
            {
                if(VERBOSE)
                    System.out.println("switchCookies:  Exception on getting the document let the new cookie be created and restart the structure display.");
                return;
            }
            switchCookies(old_doc);
        }
    }

    protected void switchCookies(WTDocument old_doc)
    {
        String old_cookie_name = getCookieName(old_doc);
        ServletSessionCookie old_cookie = getState().getCookieManager().getCookie(old_cookie_name);
        Vector rowDataObj = (Vector)old_cookie.get("rowDataObjects");
        if(VERBOSE)
            System.out.println("switchCookie:  Old cookie name = " + old_cookie_name);
        if(rowDataObj != null)
        {
            if(VERBOSE)
                System.out.println("switchCookie:  Cookie retrieved, start switching to new.");
            ServletSessionCookie new_cookie = getCookie();
            if(new_cookie == null)
                new_cookie = getNewCookie();
            TreeModel tmodel = (TreeModel)old_cookie.get("treeModel");
            Integer nextNodeIdentity = (Integer)old_cookie.get("nextNodeIdentity");
            new_cookie.put("rowDataObjects", rowDataObj);
            new_cookie.put("treeModel", tmodel);
            new_cookie.put("nextNodeIdentity", nextNodeIdentity);
            saveCookies();
            return;
        }
        if(VERBOSE)
            System.out.println("switchCookie:  oldOid is null or undefined so let the new cookie be created and restart the structure display.");
    }

    protected WTDocumentConfigSpec getConfigSpec()
        throws WTException
    {
        if(configSpec == null)
            if(getFormData().getProperty("DOC_CONFIG_SPEC") != null)
            {
                configSpec = getConfigSpec(getFormData().getProperty("DOC_CONFIG_SPEC"));
                getCookie().put("configSpec", configSpec);
            } else
            if(getCookie().get("configSpec") != null && (getCookie().get("configSpec") instanceof ConfigSpec))
            {
                configSpec = (WTDocumentConfigSpec)getCookie().get("configSpec");
            } else
            {
                configSpec = getDefaultConfigSpec();
                getCookie().put("configSpec", configSpec);
            }
        return configSpec;
    }

    protected WTDocumentConfigSpec getDefaultConfigSpec()
        throws WTException
    {
        return (WTDocumentConfigSpec)ConfigHelper.service.getConfigSpecFor((WTDocument)getContextObj());
    }

    protected WTDocumentConfigSpec getConfigSpec(String encodedConfigSpec)
        throws WTException
    {
        return (WTDocumentConfigSpec)Encoder.decode(encodedConfigSpec);
        ClassNotFoundException cnfe;
        cnfe;
        throw new WTException(cnfe);
        IOException ioe;
        ioe;
        throw new WTException(ioe);
    }

    protected String getConfigurationIdentity(Locale locale)
        throws WTException
    {
        String identity = null;
        WTDocumentConfigSpec docConfigSpec = getConfigSpec();
        if(docConfigSpec.isStandardActive())
        {
            String insertString = "";
            WTDocumentStandardConfigSpec standardConfigSpec = docConfigSpec.getStandard();
            if(standardConfigSpec.getLifeCycleState() != null)
                insertString = insertString + standardConfigSpec.getLifeCycleState().getLocalizedMessage(locale);
            boolean hasParameter = !insertString.equals("");
            if(hasParameter)
            {
                Object inserts[] = {
                    insertString
                };
                if(standardConfigSpec.isWorkingIncluded())
                    identity = WTMessage.getLocalizedMessage("com.ptc.windchill.pdmlink.doc.server.processors.processorsResource", "43", inserts, locale);
                else
                    identity = WTMessage.getLocalizedMessage("com.ptc.windchill.pdmlink.doc.server.processors.processorsResource", "44", inserts, locale);
            } else
            {
                Object inserts[] = null;
                if(standardConfigSpec.isWorkingIncluded())
                    identity = WTMessage.getLocalizedMessage("com.ptc.windchill.pdmlink.doc.server.processors.processorsResource", "41", inserts, locale);
                else
                    identity = WTMessage.getLocalizedMessage("com.ptc.windchill.pdmlink.doc.server.processors.processorsResource", "42", inserts, locale);
            }
        } else
        if(docConfigSpec.isBaselineActive())
        {
            BaselineConfigSpec baselineConfigSpec = docConfigSpec.getBaseline();
            ManagedBaseline baseline = (ManagedBaseline)baselineConfigSpec.getBaseline();
            Object inserts[] = {
                baseline.getName()
            };
            identity = WTMessage.getLocalizedMessage("com.ptc.windchill.pdmlink.doc.server.processors.processorsResource", "45", inserts, locale);
        }
        return identity;
    }

    protected Vector getRowDataObjects()
    {
        if(rowDataObjects == null)
        {
            rowDataObjects = (Vector)getCookie().get("rowDataObjects");
            if(rowDataObjects == null)
                rowDataObjects = new Vector();
        }
        return rowDataObjects;
    }

    protected TreeModel getTreeModel()
    {
        TreeModel treeModel = (TreeModel)getCookie().get("treeModel");
        return treeModel;
    }

    protected void getChooseConfigSpecURL(Properties parameters, Locale locale, OutputStream os, String action)
        throws WTException
    {
        Properties props = new Properties();
        props.put("method", "generateForm");
        props.put("action", action);
        props.put("oid", getReferenceString((WTObject)getContextObj()));
        props.put("fullyQualified", "true");
        PrintWriter out = TemplateOutputStream.getPrintWriter(os, locale);
        out.print(getURLProcessorLink(props));
    }

    protected WTDocument getTopDoc()
        throws WTException, WTPropertyVetoException
    {
        WTDocument selectedTopDoc = null;
        ConfigSpec updatedSpec = null;
        if(topDoc != null)
            return topDoc;
        if(topDocIsNull)
            return null;
        if(getContextObj() instanceof WTDocument)
        {
            topDoc = (WTDocument)getContextObj();
            if(getConfigSpec() instanceof WTDocumentConfigSpec)
                updatedSpec = getConfigSpec().getActive();
            if(!(updatedSpec instanceof WTDocumentStandardConfigSpec))
                selectedTopDoc = getTopDoc((WTDocumentMaster)topDoc.getMaster());
            else
                selectedTopDoc = topDoc;
            if(VERBOSE)
                System.out.println("getTopDoc() topDoc: " + topDoc + " CS specific selectedTopDoc:" + selectedTopDoc);
            if(selectedTopDoc == null)
            {
                topDocIsNull = true;
                topDoc = null;
                if(isInitializingTreeTable)
                {
                    WTMessage message = new WTMessage("com.ptc.windchill.pdmlink.doc.server.processors.processorsResource", "46", null);
                    DefaultTemplateProcessor.addToFeedbackCookie(message, getState());
                }
            } else
            if(!PersistenceHelper.isEquivalent(topDoc, selectedTopDoc) && !isCheckedOutEqual(topDoc, selectedTopDoc))
            {
                topDoc = selectedTopDoc;
                if(isInitializingTreeTable)
                {
                    WTMessage message = new WTMessage("com.ptc.windchill.pdmlink.doc.server.processors.processorsResource", "47", null);
                    DefaultTemplateProcessor.addToFeedbackCookie(message, getState());
                }
            }
        }
        return topDoc;
    }

    protected WTDocument getTopDoc(WTDocumentMaster docMaster, ConfigSpec spec)
        throws WTException
    {
        ObjectVector master_vector = new ObjectVector();
        master_vector.addElement(docMaster);
        QueryResult qr = ConfigHelper.service.filteredIterationsOf(new QueryResult(master_vector), spec);
        WTDocument doc = null;
        if(qr.size() == 1)
            doc = (WTDocument)qr.nextElement();
        return doc;
    }

    protected WTDocument getTopDoc(WTDocumentMaster docMaster)
        throws WTException
    {
        WTDocument selectedTopDoc = null;
        selectedTopDoc = getTopDoc(docMaster, ((ConfigSpec) (getConfigSpec())));
        return selectedTopDoc;
    }

    protected WTDocumentMaster getTopDocMaster()
    {
        if(topDocMaster != null)
            return topDocMaster;
        if(getContextObj() instanceof WTDocument)
        {
            topDoc = (WTDocument)getContextObj();
            topDocMaster = (WTDocumentMaster)topDoc.getMaster();
        } else
        if(getContextObj() instanceof WTDocumentMaster)
            topDocMaster = (WTDocumentMaster)getContextObj();
        return topDocMaster;
    }

    protected WTDocumentConfigSpec getTopConfigSpec()
        throws WTException, WTPropertyVetoException
    {
        if(configSpec != null)
            return configSpec;
        if(getContextObj() instanceof WTDocument)
            configSpec = getConfigSpec();
        else
        if(getContextObj() instanceof WTDocumentMaster)
            configSpec = getConfigSpec();
        return configSpec;
    }

    protected void expand(WTDocument doc)
        throws WTException, WTPropertyVetoException
    {
        if(doc == null)
        {
            rowDataObjects = new Vector();
            rowDataObjects.addElement(getTopDocMaster());
            int targetIndex = 0;
            return;
        } else
        {
            Enumeration docResults = getUsesWTDocs(doc);
            boolean hasChildren = docResults.hasMoreElements();
            boolean isOpen = true;
            boolean isLastSibling = true;
            TreeTableNode rootTreeNode = null;
            rootTreeNode = new TreeTableNode(hasChildren, isOpen, isLastSibling, identifier++, doc);
            treeModel = new DefaultTreeModel(rootTreeNode);
            rowDataObjects = new Vector(1);
            rowDataObjects.addElement(doc);
            int targetIndex = 0;
            targetIndex = addDocs(docResults, rootTreeNode, targetIndex);
            return;
        }
    }

    protected int expand(TreeTableNode targetNode, int targetIndex, boolean actionIsOpening, boolean actionIsRecursive)
        throws WTException, WTPropertyVetoException
    {
        if(VERBOSE)
            System.out.println("Start/End of the expand targetIndex = " + targetIndex + " actionIsOpening = " + actionIsOpening + " actionIsRecursive = " + actionIsRecursive);
        return expand(new PathNode((Persistable)targetNode.getCentralObject(), null), targetNode, targetIndex, actionIsOpening, actionIsRecursive);
    }

    protected int expand(PathNode toPathNode, TreeTableNode targetNode, int targetIndex, boolean actionIsOpening, boolean actionIsRecursive)
        throws WTException, WTPropertyVetoException
    {
        if(VERBOSE)
        {
            System.out.println(">> Entering expand to PathNode");
            System.out.println("Start of the expand toPathNode = " + toPathNode.nodeIdentity.getDisplayIdentifier().getLocalizedMessage(Locale.US));
            Object central = targetNode.getCentralObject();
            String name = "unknown name";
            if(central instanceof WTDocument)
                name = ((WTDocument)central).getName();
            else
            if(central instanceof WTDocumentMaster)
                name = ((WTDocumentMaster)central).getName();
            System.out.println("                    targetNode = " + name);
            System.out.println("                    targetIndex = " + targetIndex + " actionIsOpening = " + actionIsOpening + " actionIsRecursive = " + actionIsRecursive);
        }
        Enumeration children = targetNode.children();
        targetNode.setIsOpen(actionIsOpening);
        do
        {
            if(!children.hasMoreElements())
                break;
            TreeTableNode currentNode = (TreeTableNode)children.nextElement();
            if(actionIsOpening)
            {
                if(!rowDataObjects.contains(currentNode))
                {
                    if(VERBOSE)
                        System.out.println("*** EXPAND DOES NOT HAVE THIS IN THE ROWSET : " + currentNode.getIdentifier());
                    rowDataObjects.insertElementAt(currentNode, ++targetIndex);
                    if(VERBOSE)
                        System.out.println("*** TARGET INDEX ASSIGNED : " + targetIndex);
                    if(VERBOSE)
                        System.out.println("*** IDENTIFIER ASSIGNED : " + currentNode.getIdentifier());
                    if((currentNode.getCentralObject() instanceof WTDocument) && !currentNode.getChildrenAreFeteched())
                    {
                        WTDocument doc = (WTDocument)currentNode.getCentralObject();
                        Enumeration result = getUsesWTDocs(doc);
                        currentNode.setHasChildren(result.hasMoreElements());
                        currentNode.setIsOpen(false);
                        TreeTableNode subTreeNode;
                        for(; result.hasMoreElements(); currentNode.add(subTreeNode))
                        {
                            Persistable items[] = (Persistable[])result.nextElement();
                            Vector newVector = new Vector(items.length);
                            newVector.addElement(items[1]);
                            WTDocumentUsageLink link = (WTDocumentUsageLink)items[0];
                            newVector.addElement(link);
                            boolean hasChildren = true;
                            boolean isOpen = false;
                            boolean isLastSibling = !result.hasMoreElements();
                            subTreeNode = new TreeTableNode(hasChildren, isOpen, isLastSibling, identifier++, newVector);
                        }

                        currentNode.setChildrenAreFeteched(true);
                    }
                    if(actionIsRecursive)
                        targetIndex = expand(new PathNode((Persistable)currentNode.getCentralObject(), toPathNode), currentNode, targetIndex, actionIsOpening, actionIsRecursive);
                } else
                {
                    targetIndex++;
                }
            } else
            if(rowDataObjects.contains(currentNode))
            {
                if(actionIsRecursive)
                    targetIndex = expand(new PathNode((Persistable)currentNode.getCentralObject(), toPathNode), currentNode, targetIndex, actionIsOpening, actionIsRecursive);
                rowDataObjects = remove(rowDataObjects, currentNode);
            }
        } while(true);
        return targetIndex;
    }

    protected void addDocs(Enumeration docResults, Enumeration subResult, TreeTableNode subTreeNode)
    {
        TreeTableNode subSubTreeNode;
        for(; subResult.hasMoreElements(); subTreeNode.add(subSubTreeNode))
        {
            Persistable subItems[] = (Persistable[])subResult.nextElement();
            Vector subVector = new Vector(subItems.length);
            subVector.addElement(subItems[1]);
            subVector.addElement(subItems[0]);
            boolean hasChildren = false;
            boolean isOpen = false;
            boolean isLastSibling = !subResult.hasMoreElements();
            subSubTreeNode = new TreeTableNode(hasChildren, isOpen, isLastSibling, identifier++, subVector);
        }

        subTreeNode.setChildrenAreFeteched(true);
    }

    protected int addDocs(Enumeration docResults, TreeTableNode rootTreeNode, int targetIndex)
        throws WTException, WTPropertyVetoException
    {
        while(docResults.hasMoreElements()) 
        {
            Persistable items[] = (Persistable[])docResults.nextElement();
            Vector newVector = new Vector(items.length);
            newVector.addElement(items[1]);
            WTDocumentUsageLink link = (WTDocumentUsageLink)items[0];
            newVector.addElement(link);
            if(items[1] instanceof WTDocument)
            {
                WTDocument subDoc = (WTDocument)items[1];
                Enumeration subResult = getUsesWTDocs(subDoc);
                boolean hasChildren = subResult.hasMoreElements();
                boolean isOpen = false;
                boolean isLastSibling = !docResults.hasMoreElements();
                TreeTableNode subTreeNode = new TreeTableNode(hasChildren, isOpen, isLastSibling, identifier++, newVector);
                rootTreeNode.add(subTreeNode);
                rowDataObjects.insertElementAt(subTreeNode, ++targetIndex);
                addDocs(docResults, subResult, subTreeNode);
            } else
            {
                WTDocumentMaster subDocMaster = (WTDocumentMaster)items[1];
                boolean hasChildren = false;
                boolean isOpen = false;
                boolean isLastSibling = !docResults.hasMoreElements();
                TreeTableNode subTreeNode = new TreeTableNode(hasChildren, isOpen, isLastSibling, identifier++, newVector);
                rootTreeNode.add(subTreeNode);
                rowDataObjects.insertElementAt(subTreeNode, ++targetIndex);
            }
        }
        return targetIndex;
    }

    protected int getNodeIndex(String item)
        throws WTException
    {
        if(item.startsWith("HtmlTable_TreeTableNode_"))
        {
            return getNodeIndex(Integer.parseInt(item.substring(NODE_VALUE_PREFIX_LEN)));
        } else
        {
            TreeTableNode currentNode = (TreeTableNode)treeModel.getRoot();
            return currentNode.getIdentifier();
        }
    }

    protected int getNodeIndex(int targetIdentifier)
        throws WTException
    {
        for(int i = 0; i < rowDataObjects.size(); i++)
        {
            if(!(rowDataObjects.elementAt(i) instanceof TreeTableNode))
                continue;
            TreeTableNode currentNode = (TreeTableNode)rowDataObjects.elementAt(i);
            if(currentNode.getIdentifier() == targetIdentifier)
                return i;
        }

        return -1;
    }

    protected TreeTableNode getNode(int targetIndex)
    {
        TreeTableNode node = null;
        if(targetIndex < rowDataObjects.size() && (rowDataObjects.elementAt(targetIndex) instanceof TreeTableNode))
            node = (TreeTableNode)rowDataObjects.elementAt(targetIndex);
        else
        if(targetIndex < rowDataObjects.size() && (rowDataObjects.elementAt(targetIndex) instanceof WTDocument))
            node = (TreeTableNode)treeModel.getRoot();
        return node;
    }

    protected Enumeration getUsesWTDocs(WTDocument doc)
        throws WTException, WTPropertyVetoException
    {
        Enumeration docQueryResults = null;
        docQueryResults = WTDocumentHelper.service.getOrderedUsesWTDocuments(doc, getTopConfigSpec());
        return docQueryResults;
    }

    private static String getTimeStamp()
    {
        Date currentDate = new Date();
        Long currentTime = new Long(currentDate.getTime());
        String timeStamp = currentTime.toString();
        return timeStamp;
    }

    private boolean isCheckedOutEqual(Workable ckedOut, Workable working)
    {
        boolean flag = false;
        try
        {
            if(WorkInProgressHelper.isCheckedOut(ckedOut, SessionHelper.manager.getPrincipal()))
            {
                Workable orig = WorkInProgressHelper.service.originalCopyOf(working);
                flag = PersistenceHelper.isEquivalent(ckedOut, orig);
            }
        }
        catch(WTException wte)
        {
            return flag;
        }
        return flag;
    }

    protected void refreshTreeNode(WTDocument doc, TreeTableNode node, boolean topNode)
        throws WTException, WTPropertyVetoException
    {
        rowDataObjects = getRowDataObjects();
        int layers = recursiveRemoveDocs(node, 0);
        if(VERBOSE)
            System.out.println("*** RefreshTreeNode: Removed documents to depth of " + layers);
        int nodeIndex = -1;
        if(topNode)
        {
            nodeIndex = 0;
            rowDataObjects.removeElementAt(nodeIndex);
            rowDataObjects.insertElementAt(doc, nodeIndex);
        } else
        {
            nodeIndex = rowDataObjects.indexOf(node);
            if(VERBOSE)
                System.out.println(">> REFRESH TREE NODE : NODE INDEX : " + nodeIndex);
            if(nodeIndex == -1)
                return;
            rowDataObjects.removeElementAt(nodeIndex);
            rowDataObjects.insertElementAt(node, nodeIndex);
        }
        recursiveRefresh(doc, node, layers, nodeIndex);
    }

    private int recursiveRefresh(WTDocument doc, TreeTableNode node, int layers, int nodeIndex)
        throws WTException, WTPropertyVetoException
    {
        Enumeration docResults = getUsesWTDocs(doc);
        node.setHasChildren(docResults.hasMoreElements());
        node.setIsOpen(true);
        int depth = --layers;
        TreeTableNode subTreeNode;
        for(; docResults.hasMoreElements(); node.add(subTreeNode))
        {
            Persistable items[] = (Persistable[])docResults.nextElement();
            Vector newVector = new Vector(items.length);
            newVector.addElement(items[1]);
            WTDocumentUsageLink link = (WTDocumentUsageLink)items[0];
            WTDocument child_doc = null;
            WTDocumentMaster master_doc = null;
            if(items[1] instanceof WTDocument)
            {
                child_doc = (WTDocument)items[1];
                if(VERBOSE)
                    System.out.println("Refresh child document " + child_doc.getName() + " at layer = " + depth);
            } else
            {
                master_doc = (WTDocumentMaster)items[1];
                if(VERBOSE)
                    System.out.println("Refresh child master document " + master_doc.getName() + " at layer = " + depth);
            }
            newVector.addElement(link);
            boolean hasChildren = false;
            if(child_doc != null)
                hasChildren = WTDocumentHelper.service.hasUses(child_doc);
            else
                hasChildren = false;
            boolean isOpen = false;
            boolean isLastSibling = !docResults.hasMoreElements();
            subTreeNode = new TreeTableNode(hasChildren, isOpen, isLastSibling, identifier++, newVector);
            if(nodeIndex > -1)
                rowDataObjects.insertElementAt(subTreeNode, ++nodeIndex);
            if(hasChildren && depth > 0)
            {
                nodeIndex = recursiveRefresh(child_doc, subTreeNode, depth, nodeIndex);
                subTreeNode.setChildrenAreFeteched(true);
                continue;
            }
            if(!hasChildren)
                continue;
            TreeTableNode grandKidNode;
            for(Enumeration grandkids_result = getUsesWTDocs(child_doc); grandkids_result.hasMoreElements(); subTreeNode.add(grandKidNode))
            {
                Persistable grandkid_items[] = (Persistable[])grandkids_result.nextElement();
                Vector grandkid = new Vector(grandkid_items.length);
                grandkid.addElement(grandkid_items[1]);
                WTDocumentUsageLink grandkid_link = (WTDocumentUsageLink)grandkid_items[0];
                grandkid.addElement(grandkid_link);
                boolean hasKids = true;
                boolean isKidOpen = false;
                boolean isKidLastSibling = !grandkids_result.hasMoreElements();
                grandKidNode = new TreeTableNode(hasKids, isKidOpen, isKidLastSibling, identifier++, grandkid);
            }

            subTreeNode.setChildrenAreFeteched(true);
        }

        return nodeIndex;
    }

    private int recursiveRemoveDocs(TreeTableNode node, int layers)
    {
        int current_layers = layers + 1;
        int nodeIndex = rowDataObjects.indexOf(node);
        int childCount = node.getChildCount();
        for(int i = childCount - 1; i >= 0; i--)
        {
            TreeTableNode childNode = (TreeTableNode)node.getChildAt(i);
            int grandchild_count = childNode.getChildCount();
            boolean grandchild_open = childNode.getIsOpen();
            if(grandchild_count > 0 && grandchild_open)
            {
                int depth = recursiveRemoveDocs(childNode, current_layers);
                if(depth > current_layers)
                {
                    if(VERBOSE)
                        System.out.println("Descended to depth of " + depth + " removing nodes in the tree.");
                    current_layers = depth;
                }
            }
            int childIndex = rowDataObjects.indexOf(childNode);
            node.remove(i);
            if(childIndex > -1)
                rowDataObjects.removeElement(childNode);
        }

        return current_layers;
    }

    public void getURLProcessorLinkForObj(Properties parameters, Locale locale, OutputStream os)
        throws WTException
    {
        PrintWriter out = getPrintWriter(os, locale);
        String methodName = "URLTemplateAction";
        boolean fullyQualified = false;
        String contextOid = null;
        String contextClass = null;
        Persistable context_obj = (Persistable)getContextObj();
        contextClass = getContextClassName();
        if(context_obj != null)
            contextOid = (new ReferenceFactory()).getReferenceString(context_obj);
        if(parameters != null)
        {
            if(VERBOSE)
                System.err.println("getURLProcessorLinkForObj : parameters != null");
            String currentKey = null;
            String value = null;
            Enumeration enum = parameters.keys();
            do
            {
                if(!enum.hasMoreElements())
                    break;
                currentKey = (String)enum.nextElement();
                value = parameters.getProperty(currentKey);
                if(VERBOSE)
                    System.err.println("getURLProcessorLinkForObj : currentKey = " + currentKey + "   value = " + value);
                if(value == null)
                    parameters.remove(currentKey);
                else
                if(currentKey.equalsIgnoreCase("method"))
                {
                    if(VERBOSE)
                        System.err.println("getURLProcessorLinkForObj : methodName = " + methodName);
                    methodName = value;
                    parameters.remove(currentKey);
                } else
                if(currentKey.equalsIgnoreCase("fullyQualified"))
                {
                    if(value.equalsIgnoreCase("true"))
                        fullyQualified = true;
                    parameters.remove(currentKey);
                    if(VERBOSE)
                        System.err.println("getURLProcessorLinkForObj : fullyQualified = " + fullyQualified);
                } else
                if(value.equals(""))
                    parameters.remove(currentKey);
            } while(true);
            if(contextOid != null)
                parameters.put("OID", contextOid);
            else
            if(contextClass != null)
                parameters.put("class", contextClass);
        }
        out.print(getURLProcessorLink(methodName, parameters, fullyQualified));
        out.flush();
    }

    private String getURLProcessorLink(Properties parameters)
        throws WTException
    {
        String methodName = "URLTemplateAction";
        boolean installed = true;
        boolean fullyQualified = false;
        if(parameters != null)
        {
            String installed_key = parameters.getProperty("installed_key", null);
            if(installed_key != null)
                installed = InstalledProperties.isInstalled(installed_key);
            if(VERBOSE)
                System.err.println("getURLProcessorLink : parameters != null");
            String currentKey = null;
            String value = null;
            Enumeration enum = parameters.keys();
            do
            {
                if(!enum.hasMoreElements())
                    break;
                currentKey = (String)enum.nextElement();
                value = parameters.getProperty(currentKey);
                if(VERBOSE)
                    System.err.println("getURLProcessorLink : currentKey = " + currentKey + "   value = " + value);
                if(value == null)
                    parameters.remove(currentKey);
                else
                if(currentKey.equalsIgnoreCase("method"))
                {
                    if(VERBOSE)
                        System.err.println("getURLProcessorLink : methodName = " + methodName);
                    methodName = value;
                    parameters.remove(currentKey);
                } else
                if(currentKey.equalsIgnoreCase("fullyQualified"))
                {
                    if(value.equalsIgnoreCase("true"))
                        fullyQualified = true;
                    parameters.remove(currentKey);
                    if(VERBOSE)
                        System.err.println("getURLProcessorLink : fullyQualified = " + fullyQualified);
                } else
                if(value.equals(""))
                    parameters.remove(currentKey);
            } while(true);
        }
        String url = getURLProcessorLink(methodName, parameters, fullyQualified);
        url = convertURLToExtForm(url);
        return url;
    }

    private String convertURLToExtForm(String inUrl)
    {
        StringBuffer outUrl = new StringBuffer(inUrl);
        int startInd = 0;
        for(int tokInd = outUrl.toString().indexOf("%3A"); tokInd != -1; tokInd = outUrl.toString().indexOf("%3A", tokInd + 3))
            outUrl.replace(tokInd, tokInd + 3, ":");

        return outUrl.toString();
    }

    public void getBaselineCookie(Properties properties, Locale locale, OutputStream os)
        throws WTException
    {
        PrintWriter out = getPrintWriter(os, locale);
        out.println(getHiddenFieldHTML(BASELINE_COOKIE, getCookieName()));
        out.print("<INPUT TYPE=\"hidden\" NAME=\"RETURN_URL\" VALUE=\"");
        getCurrentUrl(properties, locale, os);
        out.println("\">");
        out.flush();
    }

    public void getBodyTag(Properties parameters, Locale locale, OutputStream os)
        throws WTException, WTPropertyVetoException
    {
        String onloadAction = getFormData().getProperty("onloadAction");
        if(getCookie().get("AddToBaseline") != null)
        {
            wt.httpgw.URLFactory urlFactory = getState().getURLFactory();
            HashMap map = new HashMap();
            map.put("action", "AddToBaseline");
            ReferenceFactory rf = new ReferenceFactory();
            WTReference ref = rf.getReference((Persistable)getContextObj());
            map.put("oid", rf.getReferenceString(ref));
            map.put(BASELINE_COOKIE, getCookieName());
            try
            {
                URL url = GatewayServletHelper.buildAuthenticatedURL(urlFactory, "wt.enterprise.URLProcessor", "generateForm", map);
                String gwURL = url.toExternalForm();
                String jsURL = WindowUtils.getLaunchWindowURLWrapper(gwURL, "addToBaseLine", "wfWindowOpen", 650, 400);
                parameters.setProperty("onLoadJavascript", jsURL);
            }
            catch(WTException wte)
            {
                wte.printStackTrace();
            }
        }
        getCookie().remove("AddToBaseline");
        UtilProcessorService utps = new UtilProcessorService();
        utps.setState(getState());
        utps.getBodyTag(parameters, locale, os);
    }

    private void refreshForAssociation(String oldOid, String newOid)
        throws WTPropertyVetoException, WTException, VersionControlException
    {
        ReferenceFactory factory = new ReferenceFactory();
        if(!oldOid.equalsIgnoreCase("undefined") && !newOid.equalsIgnoreCase("undefined"))
        {
            WTDocument old_doc = (WTDocument)factory.getReference(oldOid).getObject();
            WTDocument new_doc = (WTDocument)factory.getReference(newOid).getObject();
            refreshForAssociation(old_doc, new_doc);
        }
    }

    private void refreshForAssociation(WTDocument old_doc, WTDocument new_doc)
        throws WTPropertyVetoException, WTException, VersionControlException
    {
        if(VERBOSE)
            System.out.println(">>> VERBOSE : " + CLASSNAME + " : " + "Entering REFRESH for ASSOCIATION.");
        if(DISABLE_CACHE)
        {
            Vector vRowData = new Vector(getRowDataObjects());
            treeModel = getTreeModel();
            if(treeModel != null)
            {
                identifier = 1;
                TreeTableNode tmpNode = (TreeTableNode)treeModel.getRoot();
                WTDocument context_doc = (WTDocument)getContextObj();
                if(context_doc != null && tmpNode != null)
                {
                    if(VERBOSE)
                        System.out.println(">>> VERBOSE : " + CLASSNAME + " : " + "RESET : Starting call to refreshTreeNode.");
                    refreshTreeNode(context_doc, tmpNode, true);
                    if(VERBOSE)
                        System.out.println(">>> VERBOSE : " + CLASSNAME + " : " + "RESET : Finished call to refreshTreeNode");
                } else
                if(VERBOSE)
                    System.out.println(">>> VERBOSE : " + CLASSNAME + " : " + "RESET : Context Doc was null, or TreeTableNode was null - do nothing.");
            }
            getCookie().put("rowDataObjects", rowDataObjects);
            getCookie().put("treeModel", treeModel);
            getCookie().put("nextNodeIdentity", new Integer(identifier));
            saveCookies();
            Vector currentRowData = new Vector(getRowDataObjects());
            int i = 1;
            for(int n = vRowData.size(); i < n; i++)
            {
                Object obj = vRowData.elementAt(i);
                if(obj instanceof WTDocument)
                    continue;
                TreeTableNode oldNode = (TreeTableNode)obj;
                int x = 0;
                for(int y = currentRowData.size(); x < y; x++)
                {
                    Object obj2 = currentRowData.elementAt(x);
                    if(obj2 instanceof WTDocument)
                        continue;
                    TreeTableNode currentNode = (TreeTableNode)obj2;
                    if(oldNode.getIdentifier() != currentNode.getIdentifier())
                        continue;
                    boolean actionIsOpen = oldNode.getIsOpen();
                    if(rowDataObjects.contains(currentNode))
                        expand(currentNode, currentNode.getIdentifier(), actionIsOpen, false);
                }

            }

            getCookie().put("rowDataObjects", rowDataObjects);
            getCookie().put("treeModel", treeModel);
            getCookie().put("nextNodeIdentity", new Integer(identifier));
            saveCookies();
            if(VERBOSE)
                printOutCookie("REFRESH : ", "REFRESH : ");
        } else
        {
            String old_doc_num = old_doc.getNumber();
            if(VERBOSE)
                System.out.println("Document in refresh = " + old_doc.getName() + " number = " + old_doc_num + " Doc oid = " + old_doc.getPersistInfo().getObjectIdentifier() + " Document version info = " + VersionControlHelper.getVersionIdentifier(old_doc).getValue() + "." + VersionControlHelper.getIterationIdentifier(old_doc).getValue());
            TreeTableNode rootNode = (TreeTableNode)getTreeModel().getRoot();
            Enumeration breadthFirst = rootNode.breadthFirstEnumeration();
            boolean match_found = false;
            boolean top_node = true;
            do
            {
                if(!breadthFirst.hasMoreElements())
                    break;
                TreeTableNode nextNode = (TreeTableNode)breadthFirst.nextElement();
                Persistable nextObj = (Persistable)nextNode.getCentralObject();
                String old_number = null;
                if(nextObj instanceof WTDocument)
                    old_number = ((WTDocument)nextObj).getNumber();
                else
                if(nextObj instanceof WTDocumentMaster)
                    old_number = ((WTDocumentMaster)nextObj).getNumber();
                if(VERBOSE)
                {
                    System.out.print("Checking obj = " + old_number + " document oid = " + nextObj.getPersistInfo().getObjectIdentifier());
                    if(nextObj instanceof WTDocument)
                        System.out.println(" Document version info = " + VersionControlHelper.getVersionIdentifier((WTDocument)nextObj).getValue() + "." + VersionControlHelper.getIterationIdentifier((WTDocument)nextObj).getValue());
                    if(nextObj instanceof WTDocumentMaster)
                        System.out.println(" Document Master copy");
                }
                if(PersistenceHelper.isEquivalent(nextObj, old_doc) || old_doc_num.equals(old_number))
                {
                    match_found = true;
                    if(VERBOSE)
                        System.out.println("Matching node found.");
                    Object userObject = nextNode.getUserObject();
                    if(userObject instanceof Vector)
                    {
                        if(VERBOSE)
                            System.out.println("Object is a vector.");
                        Vector userVector = (Vector)userObject;
                        userVector.setElementAt(new_doc, 0);
                    } else
                    if(userObject instanceof WTDocument)
                    {
                        if(VERBOSE)
                            System.out.println("Object is a document.");
                        nextNode.setUserObject(new_doc);
                    }
                    refreshTreeNode(new_doc, nextNode, top_node);
                }
                if(top_node)
                    top_node = false;
            } while(true);
            if(!match_found)
            {
                if(VERBOSE)
                    System.out.println("Refreshing just the changed assocition didn't work, so refreshing the entire tree.");
                expand();
            }
        }
        if(VERBOSE)
            System.out.println(">>> VERBOSE : " + CLASSNAME + " : " + "Exiting REFRESH for ASSOCIATION.");
    }

    private void printOutCookie(String message, String contextMessage)
    {
        ServletSessionCookie cookie = getCookie();
        System.out.println("*****");
        System.out.println(message);
        System.out.println("Cookie name = " + getCookieName());
        System.out.println("*****");
        Vector rowDataObj = (Vector)cookie.get("rowDataObjects");
        if(rowDataObj != null && rowDataObj.size() > 0)
        {
            System.out.println(contextMessage + "Row Data Objects = ");
            for(int i = 0; i < rowDataObj.size(); i++)
            {
                Object data = rowDataObj.elementAt(i);
                System.out.println(contextMessage + data + " of type " + data.getClass());
            }

        } else
        {
            System.out.println(contextMessage + "Row Data Objects is null or empty.");
        }
        System.out.println("");
        TreeModel tmodel = (TreeModel)cookie.get("treeModel");
        if(tmodel != null)
        {
            System.out.println(contextMessage + "Tree table model is = ");
            TreeTableNode rootNode = (TreeTableNode)tmodel.getRoot();
            Enumeration breadthFirst = rootNode.breadthFirstEnumeration();
            boolean top_node = true;
            do
            {
                if(!breadthFirst.hasMoreElements())
                    break;
                TreeTableNode nextNode = (TreeTableNode)breadthFirst.nextElement();
                Persistable nextObj = (Persistable)nextNode.getCentralObject();
                Object userObject = nextNode.getUserObject();
                if(userObject instanceof Vector)
                {
                    System.out.println(contextMessage + "Object is a vector.");
                    Vector userVector = (Vector)userObject;
                    int i = 0;
                    while(i < userVector.size()) 
                    {
                        System.out.println(contextMessage + userVector.elementAt(i));
                        i++;
                    }
                } else
                if(userObject instanceof WTDocument)
                {
                    WTDocument doc = (WTDocument)userObject;
                    try
                    {
                        System.out.println(contextMessage + "Object is a document. name = " + doc.getName() + " oid = " + doc.getPersistInfo().getObjectIdentifier() + " Document version info = " + VersionControlHelper.getVersionIdentifier(doc).getValue() + "." + VersionControlHelper.getIterationIdentifier(doc).getValue());
                    }
                    catch(VersionControlException vce)
                    {
                        System.out.println(contextMessage + "Object is a document. name = " + doc.getName() + " oid = " + doc.getPersistInfo().getObjectIdentifier());
                    }
                }
            } while(true);
        } else
        {
            System.out.println(contextMessage + "Tree table model is null.");
        }
        System.out.println("");
        Integer nextNodeIdentity = (Integer)cookie.get("nextNodeIdentity");
        if(nextNodeIdentity != null)
            System.out.println(contextMessage + "Next node identity in cookie is " + nextNodeIdentity.toString());
        else
            System.out.println(contextMessage + "Next node identity in cookie is null.");
        System.out.println("");
        WTDocumentConfigSpec cookie_config = (WTDocumentConfigSpec)cookie.get("configSpec");
        if(cookie_config != null)
            System.out.println(contextMessage + "Config Spec in cookie = " + cookie_config.getActive());
        else
            System.out.println(contextMessage + "No config spec in the cookie.");
        try
        {
            if(getFormData().getProperty("DOC_CONFIG_SPEC") != null)
            {
                WTDocumentConfigSpec form_config = getConfigSpec(getFormData().getProperty("DOC_CONFIG_SPEC"));
                if(form_config != null)
                    System.out.println(contextMessage + "Config Spec in form data = " + form_config.getActive());
                else
                    System.out.println(contextMessage + "Config Spec in form data is null.");
            } else
            {
                System.out.println(contextMessage + "Config Spec in form data is null.");
            }
        }
        catch(WTException wte)
        {
            System.out.println(contextMessage + "Config Spec in form data is not retrievable, throws exception on attempting to retrieve");
        }
        System.out.println("*****");
    }

    private boolean needNewCookie(Properties formProperties)
    {
        rowDataObjects = (Vector)getCookie().get("rowDataObjects");
        treeModel = (TreeModel)getCookie().get("treeModel");
        String config_spec = formProperties.getProperty("DOC_CONFIG_SPEC");
        return rowDataObjects == null || treeModel == null || config_spec != null;
    }

    static Class _mthclass$(String x0)
    {
        return Class.forName(x0);
        ClassNotFoundException x1;
        x1;
        throw (new NoClassDefFoundError()).initCause(x1);
    }

    private static final String RESOURCE = "com.ptc.windchill.pdmlink.doc.server.processors.processorsResource";
    private static final String CLASSNAME;
    public static final String CONFIG_SPEC = "DOC_CONFIG_SPEC";
    static final long serialVersionUID = 1L;
    public static final long EXTERNALIZATION_VERSION_UID = 0x1cb93348b29c6cd5L;
    protected static final long OLD_FORMAT_VERSION_UID = 0x3b7e613e796c1195L;
    int identifier;
    protected static final String ROWDATAOBJECTS = "rowDataObjects";
    private static final String TREEMODEL = "treeModel";
    private static final String NEXTNODEIDENTITY = "nextNodeIdentity";
    private static final String CONFIGSPEC = "configSpec";
    private static final String RELATED_REPORTS = "relatedReports";
    protected static final String NODE_VALUE_PREFIX = "HtmlTable_TreeTableNode_";
    protected static final int NODE_VALUE_PREFIX_LEN = "HtmlTable_TreeTableNode_".length();
    private static final String COLLAPSE = "Collapse";
    private static final String EXPAND_ONE = "ExpandOne";
    private static final String EXPAND_ALL = "ExpandAll";
    private static final String COPYDOCUFID = "CopyDocUfid";
    private static final String ADDTOPROJECTUFID = "AddToProjectUfid";
    protected static final String CONTAINERMOVE = "CONTAINERMOVE_STRUCT_BROWSER";
    private static final String DOWNLOAD_DOCUMENTS = "DocumentDownload";
    protected static final String ADD_TO_BASELINE = "AddToBaseline";
    private static final String RESET = "Reset";
    private static final String REMOVE_CHILDREN = "RemoveChildren";
    private static final String REFRESH_FOR_ASSOCIATION = "RefreshForAssociation";
    public static final String ID_SEPARATOR = "&";
    private static final String OID = "oid";
    private static final int NO_NODE = -1;
    private WTDocument topDoc;
    private WTDocumentMaster topDocMaster;
    private WTDocumentConfigSpec configSpec;
    private Locale locale;
    protected ServletSessionCookie docCookie;
    private TreeModel treeModel;
    private Vector rowDataObjects;
    private boolean topDocIsNull;
    private boolean isInitializingTreeTable;
    protected static String BASELINE_COOKIE = "baselineCookie";
    protected static boolean SHOW_ORGID = false;
    protected static boolean VERBOSE = false;
    protected static String DELIM;
    protected static boolean DISABLE_CACHE = false;

    static 
    {
        CLASSNAME = (com.ptc.windchill.pdmlink.doc.server.processors.StructuredDocumentProcessor.class).getName();
        try
        {
            WTProperties properties = WTProperties.getLocalProperties();
            VERBOSE = properties.getProperty("com.ptc.windchill.pdmlink.doc.client.verbose", false);
            SHOW_ORGID = properties.getProperty("wt.org.OrganizationOwned.displayOrganization", false);
            DELIM = properties.getProperty("wt.doc.hiddenFieldDelimiter", ";;;qqq");
            if(getPreferenceValue("/com/ptc/windchill/pdmlink/doc/server/processors", "DisableDocumentStructureCache").trim().equals("true"))
                DISABLE_CACHE = true;
        }
        catch(Throwable t)
        {
            System.err.println("com.ptc.windchill.pdmlink.doc.server.processors.StructuredDocumentProcessor : Error reading com.ptc.windchill.pdmlink.doc.client.* properties");
            t.printStackTrace(System.err);
            throw new ExceptionInInitializerError(t);
        }
    }
}
