<%@page contentType="text/html;charset=UTF-8" pageEncoding="ISO-8859-1" session="true"
%><%@page errorPage="Exception.jsp"
%><%@page import="com.fujitsu.iflow.common.DOMUtils"
%><%@page import="com.fujitsu.iflow.common.JSConversions"
%><%@page import="com.fujitsu.iflow.model.bpm.BPMSession"
%><%@page import="com.fujitsu.iflow.model.bpmcore.BPMSessionImpl"
%><%@page import="com.fujitsu.iflow.model.util.QuickForm"
%><%@page import="com.fujitsu.iflow.model.util.URLEncoder"
%><%@page import="com.fujitsu.iflow.model.workflow.Arrow"
%><%@page import="com.fujitsu.iflow.model.workflow.BranchSpec"
%><%@page import="com.fujitsu.iflow.model.workflow.ConditionSpec"
%><%@page import="com.fujitsu.iflow.model.workflow.DataItemRef"
%><%@page import="com.fujitsu.iflow.model.workflow.DirectoryServices"
%><%@page import="com.fujitsu.iflow.model.workflow.Filter"
%><%@page import="com.fujitsu.iflow.model.workflow.FormRef"
%><%@page import="com.fujitsu.iflow.model.workflow.JavaAction"
%><%@page import="com.fujitsu.iflow.model.workflow.JavaActionSet"
%><%@page import="com.fujitsu.iflow.model.workflow.Node"
%><%@page import="com.fujitsu.iflow.model.workflow.Plan"
%><%@page import="com.fujitsu.iflow.model.workflow.PlanVersionHistoryElement"
%><%@page import="com.fujitsu.iflow.model.workflow.TimerAction"
%><%@page import="com.fujitsu.iflow.model.workflow.TimerDef"
%><%@page import="com.fujitsu.iflow.model.workflow.TriggerDef"
%><%@page import="com.fujitsu.iflow.model.workflow.WFSession"
%><%@page import="com.fujitsu.iflow.model.workflow.WFObjectFactory"
%><%@page import="java.awt.Point"
%><%@page import="java.io.Writer"
%><%@page import="java.util.Arrays"
%><%@page import="java.util.Enumeration"
%><%@page import="java.util.Hashtable"
%><%@page import="org.w3c.dom.Element"
%><%@page import="org.w3c.dom.NodeList"
%><%
    request.setCharacterEncoding("UTF-8");request.getParameterNames(); //Need dummy call for WL9.1
    BPMSession bps = (BPMSession) session.getAttribute("BPMSession");
    if (bps == null) {
        %><jsp:include page="PasswordPanel.jsp" flush="true"/><%
        return;
    }

    selectedPlanID = (String)request.getParameter("planID");
    if (selectedPlanID == null) {
        // Try with 'planId' - becoz when request comes from XPDLGenerator.
        selectedPlanID = (String)request.getParameter("planId");
        if (selectedPlanID == null)
            throw new Exception("ProcessDefintion.jsp requires the process definition id to be specified as a 'planID' paramater.  No such parameter was found on this invocation.");
    }

    long planId = Integer.parseInt(selectedPlanID);
    Plan selPlan = bps.getPlan(planId);
    String desc = selPlan.getDesc();
    String iden = selPlan.getPlanIdentifier();
    showEditButtons = selPlan.isInEditMode();
    session.setAttribute("TabIndex","0");
//set URL
    StringBuffer reqURL = request.getRequestURL();
    reqURL.append("?");
    if (request.getQueryString() != null) {
        reqURL.append(request.getQueryString());
    }
%>

<!-- added for floating menu
<%
    String editMode = (String) request.getParameter("editMode");
    String isEditableStr = (String) request.getParameter("isEditable");

    boolean isEditMode = false;
    if(editMode!=null && editMode.equalsIgnoreCase("true")) isEditMode = true;

    boolean isEditable = false;
    if(isEditableStr!=null && isEditableStr.equalsIgnoreCase("true")) isEditable = true;

    String xpdlURL = "XPDLGenerator.jsp?planId="+planId + "&fromConsole=true";
    String bpelURL = "BPELGenerator.jsp?planId="+planId;
    String exportXpdlURL = "ExportXPDL.jsp?planId="+planId+"&type=xpdl";
    String graphicalURL = "PDGraphic.jsp?planId="+planId;
     String commandURL = "TemplateCommands.jsp?pdId="+planId+"&mode=";

%>
-->


<HTML>
<HEAD>
<title>Interstage Business Process Manager | Process Definition</TITLE>
<jsp:include page="StyleSheet.jsp" flush="true"/>
<script language="javascript" src="styles/clockscripts.js"></script>
<style>
.divdhtmlcontent{display:none;}
.divdhtmlcontentshow{display:show;}
</style>
</HEAD>
<body class="bodyClass" onLoad="goforit();">

<% session.setAttribute("TabIndex","2");  /*should be a parameter to HEADER*/%>
<jsp:include page="Header.jsp" flush="true"/>
      <jsp:include page="TemplateMenu.jsp">
      <jsp:param name="planId" value="<%=String.valueOf(selPlan.getId()) %>" />
      <jsp:param name="editMode" value="<%= String.valueOf(selPlan.isInEditMode()) %>" />
      <jsp:param name="referralURL" value="<%=reqURL.toString() %>" />
      </jsp:include>
<table border="0" cellpadding="2" cellspacing="1" class="tableClass"
           bgcolor="#CCCCCC" align="center" width="90%">
    <tr class="headrow"><td colspan="4"><font class="arialfonts" color="#FFFFFF">
        <b>Process Definition Attributes</b></font></td></tr>
    <%
    writeAll(out, 1, "Name",  selPlan.getName(),  AS_TEXT, "name");
    writeAll(out, 1, "Title", selPlan.getTitle(), AS_TEXT, "title");
    writeAll(out, 1, "Desc", desc, AS_TEXT, "desc");
    writeAll(out, 1, "Identifier", iden, AS_TEXT, "iden");
    writeLink1(out, "ASAP", selPlan.getPlanURI(), getSubtext(bps, selPlan));
    writeLink1(out, "WSDL", selPlan.getPlanURI() + "&wsdl", null);
    writeLink1(out, "Context", "contextData.jsp?pdid="+planId, null);
    writeLink1(out, "Result", "resultData.jsp?pdid="+planId, null);
    writeLink1(out, "Registry", "ServReg.jsp", null);
    writeAll(out, 1, "Owner", selPlan.getOwner(), AS_TEXT, null);
    writeAll(out, 1, "O-Script", selPlan.getProcOwnerRoleScript(), AS_SCRIPT, "oscript");
    writeAction1(out, "Owner<br>Action", selPlan.getProcOwnerRoleJavaActionSet());
    writeAll(out, 1, "Init", selPlan.getInitScript(), AS_SCRIPT, "init");
    writeAction1(out, "Init<br>Action", selPlan.getInitJavaActionSet());
    writeAll(out, 1, "Commit", selPlan.getCommitScript(), AS_SCRIPT, "commit");
    writeAction1(out, "Commit<br>Action", selPlan.getCommitJavaActionSet());
    TriggerDef[] trigs = selPlan.getTriggers();
    for (int i=0; i<trigs.length; i++) {
        writeTrigger(out, "Trig "+i, trigs[i]);
    }
    Node[] allNodes = selPlan.getNodes();
%>
    </table>
    <%out.flush();%>
<br>
    <table border="0" cellpadding="2" cellspacing="1" class="tableClass"
           bgcolor="#CCCCCC" align="center" width="90%">
    <tr class="headrow"><td colspan="4"><font class="arialfonts" color="#FFFFFF">
        <b>Groups (Current members in this server)</b></font></td></tr>
<%

    // First we have to get the set of unique roles.
    Hashtable ht = new Hashtable();
    int last = allNodes.length;
    for (int i=0; i<last; i++)
    {
        Node aNode = allNodes[i];
        if (aNode.supportRole())
        {
            String roleName = aNode.getRole();
            ht.put(roleName, roleName);
        }
    }

    Enumeration it = ht.elements();
    WFSession wfSession = ((BPMSessionImpl)bps)._wfs;
    DirectoryServices ds = WFObjectFactory.getDirectoryServices(wfSession,wfSession.getUserName(),(String) session.getAttribute("password"));
    while (it.hasMoreElements()) {
        String roleName = (String) it.nextElement();
        String[] members = null;
        try {
            members = ds.getUserList(roleName);
        }
        catch (Exception e) {
            // recently it appears this funciton has changed, and it throws an exception
            // if the user group does not exist.  Should instead return empty set.
            // ignore exception and assume empty set instead.
        }
        if (members == null) {
            members = new String[0];
        }
        StringBuffer sb = new StringBuffer();
        if (members.length>0) {
            sb.append(members[0]);
            for (int i=1; i<members.length; i++) {
                sb.append(", ");
                sb.append(members[i]);
            }
            writeAll(out, 1, roleName, sb.toString(), AS_TEXT, null);
        }
        else {
            writeAll(out, 1, roleName, "<b><font color=\"red\">UNDEFINED GROUP:</font></b>  Need to define in your user directory, or change the role assignments.", AS_HTML, null);
        }
    }
%>
    </table>
    <%out.flush();%>
<br>
    <%

    NodeComparator nc = new NodeComparator();
    Arrays.sort(allNodes, nc);

    last = allNodes.length;
    for (int i=0; i<last; i++)
    {
        out.flush();
        Node aNode = allNodes[i];
        int nodeType = aNode.getType();
        String nodeTypeName = "Unknown";
        String customNodeType = "Unknown";
        boolean formsOK = false;
        long nodeId = aNode.getNodeId();
        switch (nodeType)
        {
            case Node.TYPE_START:
                nodeTypeName = "Start Node";
                break;
            case Node.TYPE_EXIT:
                nodeTypeName = "Exit Node";
                break;
            case Node.TYPE_ACTIVITY:
                nodeTypeName = "Activity Node";
                formsOK = true;
                break;
            case Node.TYPE_AND:
                nodeTypeName = "And Node";
                break;
            case Node.TYPE_CONDITION:
                nodeTypeName = "Condition Node";
                if(aNode.isCustomNodeType())
                {   
                    customNodeType = aNode.getCustomNodeType();
                    if(customNodeType.equals("com.fujitsu.iflow.gui.planview.UIComplexCondition"))
            {
                nodeTypeName = "Complex Condition Custom Node";
            }
        }                
                break;
            case Node.TYPE_OR:
                nodeTypeName = "Or Node";
                if(aNode.isCustomNodeType())
                {                
                    customNodeType = aNode.getCustomNodeType();
                    if(customNodeType.equals("com.fujitsu.iflow.gui.planview.UICustomWebService"))
                    {
                        nodeTypeName = "Web Service Custom Node";
                    } 
                    else if(customNodeType.equals("com.fujitsu.iflow.gui.planview.UICustomEmail"))
                    {
                        nodeTypeName = "Email Custom Node";
                    } 
                    else if(customNodeType.equals("com.fujitsu.iflow.gui.planview.UICustomDB"))
                    {
                        nodeTypeName = "Database Custom Node";
                    } 
                }                
                break;
            case Node.TYPE_SUB_PROCESS:
                nodeTypeName = "Subprocess Node";
                break;
            case Node.TYPE_DELAY:
                nodeTypeName = "Time Delay Node";
                break;
            case Node.TYPE_CHAINED_PROCESS:
                nodeTypeName = "Chained Subprocess Node";
                break;
            case Node.TYPE_VOTING_ACTIVITY:
                nodeTypeName = "Voting Activity Node";
                formsOK = true;
                break;
            case Node.TYPE_REMOTE_SUB_PROCESS:
                nodeTypeName = "Remote Subprocess Node";
                break;
        }
    %>
    <table border="0" cellpadding="2" cellspacing=1 class="tableClass"
           bgcolor="#CCCCCC" align="center" width="90%">
    <tr class="headrow">
        <td align="left" width="50%"><font class="arialfonts" color="#FFFFFF">
            <b><%=nodeId%>: <%QuickForm.writeHtml(out,aNode.getName());%></b></font></td>
        <td align="right" width="50%">
            <font face="verdana" size="1" color="#FFFFFF">
        <b>
        <a href="javascript:void(0);" onClick="document.getElementById('a<%=i%>').className='divdhtmlcontentshow';document.getElementById('minus<%=i%>').className='divdhtmlcontentshow';document.getElementById('add<%=i%>').className='divdhtmlcontent';">
            <div id="add<%=i%>" class="divdhtmlcontent"><font face="verdana" size="1" color="#FFFFFF">[&gt;&gt;&gt;MORE]</font>
            </div>
            </a>
        <a href="javascript:void(0);" onClick="document.getElementById('a<%=i%>').className='divdhtmlcontent';document.getElementById('minus<%=i%>').className='divdhtmlcontent';document.getElementById('add<%=i%>').className='divdhtmlcontentshow';">
            <div id="minus<%=i%>"><font face="verdana" size="1" color="#FFFFFF">[&lt;&lt;&lt;LESS]</font>
            </div>
            </a>
        </b></font>
        </td></tr>
    </table>

    <div id="a<%=i%>" class="divdhtmlcontentshow">
    <table border="0" cellpadding="2" cellspacing=1 class="tableClass"
           bgcolor="#CCCCCC" align="center" width="90%">
    <%//following line needed to force columns to be the right width%>
    <tr><td width="50"></td><td width="50"></td><td width="50"></td>
    <% if (showEditButtons) {%> <td width="640"></td><td width="10"></td> <%} else {%> <td width="650"></td> <%}%>
    </tr>
    <%
        writeAll(out, 1, "Type:", nodeTypeName, AS_TEXT, null);
        writeAll(out, 1, "Desc:", aNode.getDesc(), AS_TEXT, "ndesc&node="+nodeId);
        Point aPoint = aNode.getPosition();
        writeAll(out, 1, "Position:", "(" + aPoint.x+ ", " + aPoint.y + ")", AS_TEXT, "npos&node="+nodeId);

        String webServerURL = bps.getServerOption("TWFServerBaseURL");
        if (webServerURL == null) {
            throw new Exception("Error, the configuration variable 'TWFServerBaseURL' has not been configured and the ProcessDefinition page needs it.");
        }
        webServerURL = webServerURL.trim();
        if (!webServerURL.endsWith("/")) {
            webServerURL += "/";
        }
        if (aNode.supportForm())
        {
            FormRef[] frs = aNode.getForms();
            int last2 = frs.length;
            for (int j=0; j<last2; j++)
            {
                FormRef fr = frs[j];
                writeAll(out, 1, "Form "+j, fr.getName(), AS_TEXT, "fname&aux="+j+"&node="+nodeId);
                String formPath = fr.getPath();
                if (formPath == null) {
                    formPath = "MISSING FORM PATH";
                }

                String formURL = null;
                int repospos = formPath.lastIndexOf("FormsRepository");
                int qfpos = formPath.lastIndexOf("QuickForms");
                if (repospos >= 0) {
                    String relPath = formPath.substring(repospos+16).replace('\\', '/');
                    formURL = webServerURL + "QuickForms/";
                    StringBuffer bufURL = new StringBuffer();
                    QuickForm.urlEncode(bufURL,relPath);
                    formURL = formURL + bufURL.toString();
                }
                else if (qfpos>=0) {
                    String relPath = formPath.substring(qfpos+11).replace('\\', '/');
                    formURL = webServerURL + "QuickForms/";
                    StringBuffer bufURL = new StringBuffer();
                    QuickForm.urlEncode(bufURL,relPath);
                    formURL = formURL + bufURL.toString();
                }
                if (formURL != null) {
                    StringBuffer htmlImage = new StringBuffer();
                    htmlImage.append("<a href=\"");
                    htmlImage.append(formURL);
                    htmlImage.append("\">");
                    htmlImage.append(formPath);
                    htmlImage.append("</a>");
                    writeAll(out, 1, "", htmlImage.toString(),
                            AS_HTML, "fpath&aux="+j+"&node="+nodeId);
                }
                else {
                    writeAll(out, 1, "", formPath, AS_TEXT, "fpath&aux="+j+"&node="+nodeId);
                }
            }
        }
        if (aNode.supportRole())
        {
            writeAll(out, 1, "Role:", aNode.getRole(), AS_TEXT, "role&node="+nodeId);
        }
        if (aNode.supportRoleScript())
        {
            writeAll(out, 1, "R-Script:", aNode.getRoleScript(), AS_SCRIPT, "rscript&node="+nodeId);
        }
        if (aNode.supportRoleJavaActionSet())
        {
            writeAction1(out, "Role<br>Action", aNode.getRoleJavaActionSet());
        }
        if (aNode.supportPrologueScript() && supportScripts(aNode)) {
            writeAll(out, 1, "Prolog:", aNode.getPrologueScript(), AS_SCRIPT, "prol&node="+nodeId);
        }
        if (aNode.supportPrologueJavaActionSet())
        {
            writeAction1(out, "Prologue<br>Action", aNode.getPrologueJavaActionSet());
        }
        if (aNode.supportSubProcess())
        {
            writeSub2(out, "Sub:", aNode.getSubPlanId(), aNode.getSubPlanName());
        }
        if (aNode.supportChainedProcess())
        {
            writeSub2(out, "Chained:", aNode.getChainedPlanId(), aNode.getChainedPlanName());
        }
        if (aNode.supportRemoteSubProcess())
        {
            writeAll(out, 1, "Remote:", aNode.getSubPlanURI(), AS_SCRIPT, null);
        }
        if (aNode.supportEpilogueScript() && supportScripts(aNode))
        {
            writeAll(out, 1, "Epilog:", aNode.getEpilogueScript(), AS_SCRIPT, "epil&node="+nodeId);
        }
        if (aNode.supportEpilogueJavaActionSet())
        {
            writeAction1(out, "Epilogue<br>Action", aNode.getEpilogueJavaActionSet());
        }
        ConditionSpec cs = null;
        if (aNode.supportConditionSpec())
        {
             cs = aNode.getConditionSpec();
        }

        Arrow[] az = aNode.getOutgoingArrows();
        int last2 = az.length;
        for (int j=0; j<last2; j++)
        {
            Arrow aArrow = az[j];
            long arrowId = aArrow.getArrowId();
            Point startPoint = aArrow.getStartPoint();
            Point endPoint = aArrow.getEndPoint();
            Point[] pz = aArrow.getPoints();
            if (pz == null) {
                pz = new Point[0];
            }
            Node target = aArrow.getTargetNode();
            writeAll(out, 1, "Arrow "+j, aArrow.getArrowId()+": "+aArrow.getName(), AS_HEADER, "aname&arrow="+arrowId);
            writeAll(out, 2, "Target:", target.getNodeId()+": "+target.getName(), AS_TEXT, null);
            writeAll(out, 2, "Desc:", aArrow.getDesc(), AS_TEXT, null);
            StringBuffer pointList = new StringBuffer();
            pointList.append("(");
            pointList.append(startPoint.x);
            pointList.append(", ");
            pointList.append(startPoint.y);
            pointList.append(");");
            int last3 = pz.length;
            for (int k=0; k<last3; k++) {
                pointList.append("(");
                pointList.append(pz[k].x);
                pointList.append(", ");
                pointList.append(pz[k].y);
                pointList.append(");");
            }
            pointList.append("(");
            pointList.append(endPoint.x);
            pointList.append(", ");
            pointList.append(endPoint.y);
            pointList.append(")");

            writeAll(out, 2, "Points:", pointList.toString(), AS_TEXT, "points&arrow="+arrowId);
            if (cs != null)
            {
                BranchSpec bs = cs.getBranchSpec(aArrow.getName());
                String compOp = " ?? ";
                switch (bs.getComparisonOperator())
                {
                    case BranchSpec.EQUAL_OP:
                        compOp = " == ";
                        break;
                    case BranchSpec.NOT_EQUALS_OP:
                        compOp = " != ";
                        break;
                    case BranchSpec.LESS_THAN_OP:
                        compOp = " &lt; ";
                        break;
                    case BranchSpec.LESS_THAN_OR_EQUALS_OP:
                        compOp = " &lt;= ";
                        break;
                    case BranchSpec.GREATER_THAN_OP:
                        compOp = " &gt; ";
                        break;
                    case BranchSpec.GREATER_THAN_OR_EQUALS_OP:
                        compOp = " &gt;= ";
                        break;
                }
                StringBuffer res = new StringBuffer();
                res.append(cs.getConditionAttribute());
                res.append(compOp);
                JSConversions.quote4JS(res, bs.getValue());
                if (bs.isDefault())
                {
                    res.append(" (default)");
                }
                writeAll(out, 2, "Condition:",   res.toString(), AS_TEXT, null);
            }
        }
        if (aNode.supportTimer())
        {
            TimerDef[] tz = aNode.getTimers();
            int last4 = tz.length;
            for (int j=0; j<last4; j++)
            {
                TimerDef aTimer = tz[j];
                TimerAction[] taz = aTimer.getTimerActions();
                writeAll(out, 1, "Timer "+j, aTimer.getId()+": "+aTimer.getName(), AS_HEADER, null);
                writeAll(out, 2, "Desc:", aTimer.getDescription(), AS_TEXT, null);
                writeAll(out, 2, "Type:", Integer.toString(aTimer.getType()), AS_TEXT, null);
                writeAll(out, 2, "Time:", aTimer.getTime(), AS_TEXT, null);
                int last5 = taz.length;
                for (int k=0; k<last5; k++)
                {
                    TimerAction aAction = taz[k];
                    writeAll(out, 2, Integer.toString(k)+" Name:", Integer.toString(aAction.getType()), AS_TEXT, null);
                    writeAll(out, 2, Integer.toString(k)+" Script:", aAction.getScriptAction(), AS_TEXT, null);
                    writeAll(out, 2, Integer.toString(k)+" Esc:",    aAction.getEscalateActionNameList(), AS_TEXT, null);
                    writeAll(out, 2, Integer.toString(k)+" Grp:", aAction.getEscalateActionGroupList(), AS_TEXT, null);
                    writeAll(out, 2, Integer.toString(k)+" Mail:", aAction.getSendMailActionFrom(), AS_TEXT, null);
                    writeAll(out, 2, Integer.toString(k)+" To:", aAction.getSendMailActionTo(), AS_TEXT, null);
                    writeAll(out, 2, Integer.toString(k)+" Sub:", aAction.getSendMailActionSubject(), AS_TEXT, null);
                    writeAll(out, 2, Integer.toString(k)+" CC:", aAction.getSendMailActionCc(), AS_TEXT, null);
                    writeAll(out, 2, Integer.toString(k)+" BCC:", aAction.getSendMailActionBcc(), AS_TEXT, null);
                    writeAll(out, 2, Integer.toString(k)+" JA:", aAction.getJavaActionSet(), AS_TEXT, null);
                }
            }
        }
    out.write("</table><br></div>");
    } // FOR ENDS HERE
%>

<br>
    <table border="0" cellpadding="2" cellspacing=1 class="tableClass"
           bgcolor="#CCCCCC" align="center" width="90%">
    <tr class="headrow"><td colspan="10"><font class="arialfonts" color="#FFFFFF">
        <b>Process Definition Variables: User Defined Attributes</b></font></td></tr>
    <tr class="evenrow">
    <td></td>
    <td><font face="verdana" size="1">Type</font></td>
    <td><font face="verdana" size="1">Name</font></td>
    <td><font face="verdana" size="1">Initial Value</font></td>
    <td><font face="verdana" size="1">Worklist</font></td>
    <td><font face="verdana" size="1">Read-Only</font></td>
    <td><font face="verdana" size="1">Analytics</font></td>
    <td><font face="verdana" size="1">Cubes</font></td>
    <td><font face="verdana" size="1">Aggregates</font></td>
    <td><font face="verdana" size="1">Trackable</font></td>
    </tr>
    <%
    DataItemRef[] dirz = selPlan.getDataItemRefs();
    last = dirz.length;
    for (int i=0; i<last; i++)
    {
        DataItemRef dir = dirz[i];
        String wlData = "";
        if (dir.isWorkListUDA()) {
            wlData = "Worklist";
        }
        String roData = "";
        if (dir.isReadOnly()) {
            roData = "Read-Only";
        }
        String trackData = "";
        if (dir.isUdaTracking()) {
            trackData = "Tracked";
        }
        %>
        <tr class="oddrow"><td><font face=verdana size=1><%= i %>:</font></td>
        <td><font face=verdana size=1><%= dir.getType() %></font></td>
        <td><font face=verdana size=1><% QuickForm.writeHtmlWithNBSPs(out, dir.getName()); %></font></td>
        <td><font face=verdana size=1>
        <%
                String value = dir.getValue();
                String type = dir.getType();
                if(type.equals(DataItemRef.TYPE_DATE)){
                    writeDateLong(out,Long.parseLong(value));
                }
                else {
                    writeGuardLength(out, value);
                }

        %></font></td>
        <td><%= wlData %></td>
        <td><%= roData %></td>
        <td>
        <%
            if (dir.getDimension()) {
                %>Dimension<%
            }
            if (dir.getMeasure()) {
                %>Measure<%
            }
        %></td>
        <td><% QuickForm.writeHtml(out, dir.getCubeNames());%></td>
        <td><% QuickForm.writeHtml(out, dir.getAggregates());%></td>
        <td><%= trackData %></td>
        </tr>
        <%
    }
    %>
    </table>

<table width="90%" border="0" align="center" cellpadding="0" cellspacing="0">
    <td align="right">
        <a href="<% QuickForm.writeHtml(out, commandURL); %>Copy"><img src="images/but_copy.gif" border="0"></a><a href="<%QuickForm.writeHtml(out, commandURL); %>Delete"><img src="images/but_delete.gif" border="0"></a>
    </td>
  </table>


</BODY>
</HTML>

<%!

    boolean showEditButtons =false;
    String  selectedPlanID = null;

    final int AS_SCRIPT = 1;
    final int AS_TEXT = 2;
    final int AS_HEADER = 3;
    final int AS_HTML = 4;


    public
    void
    writeAll(Writer out, int level, String name, String value, int format, String loc)
         throws Exception
    {
        //suppress null values when not editing
        if (!showEditButtons) {
            if (value==null) {
                return;
            }
            if (value.length()==0) {
                return;
            }
        }
        out.write("<tr>");
        int leftOver = 740;
        if (showEditButtons) {
            leftOver -= 10;
        }
        if (level > 1) {
            out.write("<td class=\"evenrow\" width=\"50\"></td>");
            leftOver -= 50;
            if (level > 2) {
                out.write("<td class=\"evenrow\" width=\"50\"></td>");
                leftOver -= 50;
            }
        }
        out.write("<td class=\"oddrow\" width=\"50\"><font face=verdana size=1>");
        out.write(name);
        out.write("</font></td>\n    <td  class=\"TxtField\" colspan=\"");
        out.write(Integer.toString(4-level));
        out.write("\" width=\"");
        out.write(Integer.toString(leftOver));
        out.write("\"><font face=verdana size=1>");
        if (value == null)
        {
            out.write("<i>null</i>");
        }
        else if (format == AS_SCRIPT)
        {
            out.write("</font>");
            writeScript(out, value);
            out.write("<font face=verdana size=1>");
        }
        else if (format == AS_TEXT)
        {
            QuickForm.writeHtmlWithLineBreaks(out, value);
        }
        else if (format == AS_HEADER)
        {
            out.write("<b>");
            QuickForm.writeHtmlWithLineBreaks(out, value);
            out.write("</b>");
        }
        else if (format == AS_HTML)
        {
            out.write(value);
        }
        else
        {
            QuickForm.writeHtmlWithLineBreaks(out, "unknown format");
        }
        out.write("</font>");
        if (showEditButtons)
        {
            out.write("</td><td width=\"10\" bgcolor=\"#FFFFFF\">");
            if (loc!=null) {
                out.write("<a href=\"EditPD.jsp?pdId=");
                out.write(selectedPlanID);
                out.write("&mode=");
                out.write(loc);
                out.write("\"><img border=\"0\" src=\"images/edit_sm.gif\"></a>");
            }
        }
        out.write("</td></tr>\n");
        out.flush();
    }

    public
    void
    writeLink1(Writer out, String name, String value, String subtext)
         throws Exception
    {
        out.write("<tr><td class=\"oddrow\" width=\"50\"><font face=verdana size=1>");
        out.write(name);
        out.write("</font></td>\n    <td  class=\"TxtField\" colspan=\"3\"><font face=verdana size=1>");
        if (value == null) {
            out.write("<i>null</i>");
        }
        else {
            out.write("<a href=\"");
            QuickForm.writeHtml(out, value);
            out.write("\">");
            QuickForm.writeHtml(out, value);
            out.write("</a>");
        }
        if (subtext != null) {
            out.write("<br>");
            out.write(subtext);
        }
        out.write("</font></td></tr>\n");
        out.flush();
    }

    public
    void
    writeAction1(Writer out, String name, JavaActionSet jas)
        throws Exception
    {
        if (jas == null) {
            writeAll(out, 1, name, null, AS_TEXT, null);
            return;
        }
        JavaAction[] jaa = jas.getJavaActions();
        if (jaa == null) {
            writeAll(out, 1, name, null, AS_TEXT, null);
            return;
        }
        int count = jas.getActionCount();
        for (int i=0; i<count; i++) {
            JavaAction ja = jaa[i];


            out.write("<tr><td class=\"oddrow\" width=\"50\">");
            out.write(name);
            out.write(" ");
            out.write(Integer.toString(i));
            out.write("</td>\n    <td  class=\"TxtField\" colspan=\"3\" width=\"");
            if (showEditButtons) {
                out.write("740");
            }
            else {
                out.write("750");
            }
            out.write("\"><table class=\"tableClass\"><tr><td><b>Name:</b></td><td>");
            QuickForm.writeHtml(out, ja.getActionName());
            out.write("</td></tr>\n<tr><td><b>Description:</b></td><td>");
            QuickForm.writeHtml(out, ja.getActionDescription());
            out.write("</td></tr>\n<tr><td><b>Path:</b></td><td>");
            QuickForm.writeHtml(out, ja.getClassPath());
            out.write("</td></tr>\n<tr><td><b>Class:</b></td><td>");
            QuickForm.writeHtml(out, ja.getClassName());
            out.write("</td></tr>\n<tr><td><b>Method:</b></td><td>");
            QuickForm.writeHtml(out, ja.getMethodName());
            out.write("</td></tr>\n<tr><td><b>Return:</b></td><td>");
            QuickForm.writeHtml(out, ja.getReturnValueUDAName());
            String params = ja.getArgumentsUDANames();
            if (params.indexOf("<E>")!=0) {
                out.write("</td></tr>\n<tr><td><b>Params:</b></td><td bgcolor=\"#FFFF88\">");
                QuickForm.writeHtml(out, params);
            }
            else {
                String parseable = "<g>"+params+"</g>";
                Element dom = DOMUtils.convertStringToDom(parseable);
                NodeList nl = dom.getChildNodes();
                int nllen = nl.getLength();
                for (int iii=0; iii<nllen; iii++) {
                    org.w3c.dom.Node nnParent = nl.item(iii);
                    String val = DOMUtils.textValueOf(nnParent, false);
                    out.write("</td></tr>\n<tr><td><b>Param ");
                    out.write(Integer.toString(iii));
                    out.write(":</b></td><td>");
                    QuickForm.writeHtml(out, val);
                }
            }
            out.write("</td></tr>\n<tr><td><b>Name:</b></td><td>");
            QuickForm.writeHtml(out, ja.getActionName());
            out.write("</td></tr>\n<tr><td><b>Bean:</b></td><td>");
            QuickForm.writeHtml(out, ja.getBeanName());
            out.write("</td></tr>\n<tr><td><b>B-Method:</b></td><td>");
            QuickForm.writeHtml(out, ja.getBeanName());
            out.write("</td></tr>\n<tr><td><b>B-Args:</b></td><td>");
            QuickForm.writeHtml(out, ja.getBeanMethodArgumentsUDANames());
            out.write("</td></tr></table>");
            if (showEditButtons) {
                out.write("</td><td width=\"10\" bgcolor=\"#FFFFFF\">");
            }
            out.write("</td></tr>\n");
        }
        out.flush();
    }

    public
    void
    writeHeader2(Writer out, String name, String value)
        throws Exception
    {
        writeAll(out, 2, name, value, AS_HEADER, null);
    }

    public
    void
    writeSub2(Writer out, String name, long id, String value)
        throws Exception
    {
        out.write("<tr><td class=\"evenrow\" width=\"50\"></td><td class=\"oddrow\">");
        out.write(name);
        out.write("</td>\n    <td  class=\"TxtField\" colspan=\"2\"><a href=\"ProcessDefinition.jsp?planID=");
        out.write(Long.toString(id));
        out.write("\">");
        out.write(Long.toString(id));
        out.write(": ");
        if (value == null) {
            out.write("<i>null</i>");
        }
        else {
            QuickForm.writeHtml(out, value);
        }
        out.write("</a></td></tr>\n");
        out.flush();
    }

%>

<%!

    public
    void
    writeDateLong(Writer out, long dateLong)
        throws Exception
    {
        if (dateLong==-1) {
            return;
        }
        out.write("<script> showDate('");
        out.write(Long.toString(dateLong));
        out.write("'); </script>");
    }

    /**
    * writes out a value, putting in returns arbitrarily every 80 characters.
    * this is really gross, but it avoid some pretty aweful browser layout
    * problems.
    */
    public void
    writeGuardLength(Writer out, String msg)
        throws Exception
    {
        if (msg.length() < 60) {
            QuickForm.writeHtml(out, msg);
            return;
        }
        int pos = 0;
        int len = msg.length();
        while (pos+40<=len) {
            String part = msg.substring(pos, pos+40);
            QuickForm.writeHtml(out, part);
            // if there were not any spaces, then add a return
            if (part.indexOf(" ")<0) {
                out.write("\n");
            }
            pos += 40;
        }
        String lastPart = msg.substring(pos);
        QuickForm.writeHtml(out, lastPart);
    }


    /***************8
     * the only issue with printing scripts is that if you use the (pre) tag, and
     * if the script is very very long, it warps the whole table.  So this continues
     * to use the (pre) tag, but arbitrarily truncates the scripts if the line gets
     * longer than 80 characters.
     */
    public
    void
    writeScript(Writer out, String script)
        throws Exception
    {
        out.write("<tt>");
        int last = script.length();
        int start = 0;
        boolean beginningOfLine = true;
        for (int pos=0; pos < last; pos++) {
            char c = script.charAt(pos);

            // handle the indent spaces
            if (beginningOfLine) {
                if (c == ' ' || c=='\t') {
                    out.write("&nbsp;");
                    continue;
                }
                beginningOfLine = false;
            }

            // look for and handle end of line
            if (c == '\n') {
                String line = script.substring(start, pos);
                QuickForm.writeHtml(out, line);
                out.write("<br>\n");
                start = pos+1;
                beginningOfLine = true;
                continue;
            }

            // handle case where line is too long
            if (pos - start > 80) {
                String line = script.substring(start, pos);
                QuickForm.writeHtml(out, line);
                out.write("<br>\n");
                start = pos;
                continue;
            }
        }

        //remainder of script
        String line = script.substring(start, last);
        QuickForm.writeHtml(out, line);
        out.write("</tt>");
    }

    public 
    boolean 
    supportScripts(Node aNode)
    {
        String customNodeType = "Unknown";
        boolean supportsScripts = true;
        if(aNode.isCustomNodeType())
        {                
            try 
            {
                customNodeType = aNode.getCustomNodeType();
            } catch(Exception e){}
            if(customNodeType.equals("com.fujitsu.iflow.gui.planview.UICustomWebService") ||
                customNodeType.equals("com.fujitsu.iflow.gui.planview.UICustomEmail") || 
                customNodeType.equals("com.fujitsu.iflow.gui.planview.UICustomDB"))
            {
            supportsScripts = false;
        } 
        }
        return supportsScripts;
    }

    private
    void
    writeTrigger(Writer out, String label, TriggerDef trig)
        throws Exception
    {
        StringBuffer sit = new StringBuffer();
        sit.append("id: ");
        sit.append(Long.toString(trig.getId()));
        sit.append("\ntype: ");
        sit.append(Integer.toString(trig.getType()));
        sit.append("\nstate: ");
        sit.append(Integer.toString(trig.getState()));
        if (trig.isActive()) {
            sit.append("\nactive: true");
        }
        else {
            sit.append("\nactive: false");
        }
        sit.append("\nname: ");
        sit.append(trig.getName());
        sit.append("\ndescription:");
        sit.append(trig.getDescription());
        String[] conds = trig.getControlConditions();
        for (int i=0; i<conds.length; i++) {
            sit.append("\ncontrolCondition:");
            sit.append(conds[i]);
        }
        writeAll(out, 1, label, sit.toString(), AS_TEXT, null);
        int ac = trig.getActionCount();
        for (int actNo=0; actNo<ac; actNo++) {
            String[] param = trig.getActionParams(actNo);
            for (int i=0; i<param.length; i++) {
                writeAll(out, 2, "Params "+actNo+" "+i, param[i], AS_TEXT, null);
            }
            writeAll(out, 2, "Condition"+actNo, trig.getActionCondition(actNo), AS_TEXT, null);
        }

        Hashtable dMap = trig.getDataMap();
        Enumeration e1 = dMap.keys();
        while (e1.hasMoreElements()) {
            String key1 = (String) e1.nextElement();
            String value1 = (String) dMap.get(key1);
            writeAll(out, 2, "Data", key1 + " = " + value1, AS_TEXT, null);
        }
        Hashtable cMap = trig.getCorrelationMap();
        Enumeration e2 = cMap.keys();
        while (e2.hasMoreElements()) {
            String key2 = (String) e2.nextElement();
            String value2 = (String) dMap.get(key2);
            writeAll(out, 2, "Corr", key2 + " == " + value2, AS_TEXT, null);
        }
    }

    private
    String
    getSubtext(
        BPMSession bps,
        Plan selPlan)
        throws Exception
    {
        PlanVersionHistoryElement[] planHistory = bps.getPlanVersionHistory(selPlan.getName());

        long planId = -1;
        // Look for a published plan.
        for(int i=0; i< planHistory.length; i++) {
            if (planHistory[i].getState() == Plan.STATE_PUBLISHED) {
                planId = planHistory[i].getPlanId();
                break;
            }
        }

        if (planId != -1) {
            // There is a published plan
            if (planId == Long.parseLong(selectedPlanID)) {
                // Current plan is a published plan. So no subtext needed.
                return null;
            }
            else {
                // Subtext needed.
                return "(The published version of this process definition hides this process definition for ASAP and WSDL interactions)";
            }
        }
        else {
            // There is no published plan. Check if there is any "Draft" plan for this user with a higher version number
            String requestUser = bps.getUserName();
            for(int i=0; i< planHistory.length; i++) {
                if (planHistory[i].getState() == Plan.STATE_DRAFT &&
                    requestUser.equals(planHistory[i].getOwner()))
                {
                    if (isHigherVersion(planHistory[i].getMajorVersion(), planHistory[i].getMinorVersion(), selPlan)) {
                        // Subtext needed
                        return "(The latest version of this process definition hides this process definition for ASAP and WSDL interactions)";
                    }
                }
            }
            // No higher version found. No comment needed.
            return null;
        }
    }

    private
    boolean
    isHigherVersion(
        int majorVersion,
        int minorVersion,
        Plan selPlan)
        throws Exception
    {
        String selPlanVersion = selPlan.getVersion();
        int selPlanMajorVersion = Integer.parseInt(selPlanVersion.substring(0,selPlanVersion.indexOf(".")));
        int selPlanMinorVersion = Integer.parseInt(selPlanVersion.substring(selPlanVersion.indexOf(".")+1));

        if (majorVersion > selPlanMajorVersion) return true;
        if (majorVersion == selPlanMajorVersion) {
            if (minorVersion > selPlanMinorVersion)
            return true;
        }
        return false;
    }

    /**
    *   This comparator is used to sort the process definition list into ascending order
    *   relatively to their ID.
    */
    class PlanIDComparator implements java.util.Comparator
    {
        public int compare(Object obj1, Object obj2)
        {
            if ( obj1 == null || obj2 == null ||
                !(obj1 instanceof Plan) || !(obj2 instanceof Plan) )
                return 0;
            Plan plan1 = (Plan)obj1;
            Plan plan2 = (Plan)obj2;
            if ( plan1.getId() < plan2.getId() ) return -1;
            else return 1;
        }
    }

    // This comparitor is used to sort the activities into a reasonable
    // order.  It figures out how many hops the node is away from the
    // start node.  Then for all the nodes in the same number of
    // hops, it takes into account X & Y locations, closer to upper
    // left corner the earlier it will be in the list.

    class NodeComparator implements java.util.Comparator
    {
        NodeComparator() {}

        Hashtable jumpsFromStart = new Hashtable();

        public int compare(Object a, Object b) {
            Node nia = (Node) a;
            Node nib = (Node) b;
            Point pa = nia.getPosition();
            int vala = pa.x + 2*pa.y + 10000*findJumpsFromStart(nia);
            Point pb = nib.getPosition();
            int valb = pb.x + 2*pb.y + 10000*findJumpsFromStart(nib);
            if (vala < valb) {
                return -1;
            }
            if (vala == valb) {
                return 0;
            }
            return 1;
        }

        int findJumpsFromStart(Node ni) {
            // first check to see if we already knew the result
            Long id = new Long(ni.getNodeId());
            Integer storedVal = (Integer) jumpsFromStart.get(id);
            if (storedVal != null) {
                return storedVal.intValue();
            }

            // check to see if this is the start node
            int nodeType = ni.getType();
            if (nodeType == Node.TYPE_START) {
                jumpsFromStart.put(id, new Integer(0));
                return 0;
            }

            // prevent infinite loops
            jumpsFromStart.put(id, new Integer(-1));

            // now start search
            Arrow ai[] = ni.getIncomingArrows();
            int last = ai.length;
            for (int j=0; j<last; j++) {
                Arrow aij = ai[j];
                Node ni2 = aij.getSourceNode();
                int t = findJumpsFromStart(ni2);
                if (t >= 0) {
                    jumpsFromStart.put(id, new Integer(t+1));
                    return t+1;
                }
            }

            // if we get here, then a full depth search has not found
            // a start node, which means we are disconnected from
            // the start node, so return a high number
            jumpsFromStart.put(id, new Integer(100));
            return 100;
        }
    }


%>
