manifoldcf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kwri...@apache.org
Subject svn commit: r1603199 [2/4] - in /manifoldcf/trunk: ./ connectors/alfresco/connector/src/test/java/org/apache/manifoldcf/crawler/connectors/alfresco/tests/ connectors/cmis/connector/src/test/java/org/apache/manifoldcf/crawler/connectors/cmis/tests/ conn...
Date Tue, 17 Jun 2014 15:17:36 GMT
Modified: manifoldcf/trunk/framework/crawler-ui/src/main/webapp/editjob.jsp
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/crawler-ui/src/main/webapp/editjob.jsp?rev=1603199&r1=1603198&r2=1603199&view=diff
==============================================================================
--- manifoldcf/trunk/framework/crawler-ui/src/main/webapp/editjob.jsp (original)
+++ manifoldcf/trunk/framework/crawler-ui/src/main/webapp/editjob.jsp Tue Jun 17 15:17:34 2014
@@ -78,14 +78,17 @@
 
 	// Setup default fields
 	String connectionName = "";
-	String outputName = "";
-	String[] transformationNames = new String[0];
-	String[] transformationDescriptions = new String[0];
 	String description = "";
 	int type = IJobDescription.TYPE_SPECIFIED;
-	OutputSpecification outputSpecification = new OutputSpecification();
 	DocumentSpecification documentSpecification = new DocumentSpecification();
-	OutputSpecification[] transformationSpecifications = new OutputSpecification[0];
+	
+	// Pipeline data
+	String[] pipelineConnectionNames = new String[0];
+	String[] pipelineDescriptions = new String[0];
+	boolean[] pipelineIsOutputs = new boolean[0];
+	int[] pipelinePrerequisites = new int[0];
+	OutputSpecification[] pipelineSpecifications = new OutputSpecification[0];
+	
 	ArrayList scheduleRecords = new ArrayList();
 
 	EnumeratedValues dayOfWeek = null;
@@ -123,21 +126,24 @@
 	{
 		// Set up values
 		description = job.getDescription();
-		outputName = job.getOutputConnectionName();
 		connectionName = job.getConnectionName();
-		transformationNames = new String[job.countPipelineStages()];
-		transformationDescriptions = new String[job.countPipelineStages()];
-		transformationSpecifications = new OutputSpecification[job.countPipelineStages()];
+		
+		pipelineConnectionNames = new String[job.countPipelineStages()];
+		pipelineDescriptions = new String[job.countPipelineStages()];
+		pipelineIsOutputs = new boolean[job.countPipelineStages()];
+		pipelinePrerequisites = new int[job.countPipelineStages()];
+		pipelineSpecifications = new OutputSpecification[job.countPipelineStages()];
 		for (int j = 0; j < job.countPipelineStages(); j++)
 		{
-			transformationNames[j] = job.getPipelineStageConnectionName(j);
-			transformationDescriptions[j] = job.getPipelineStageDescription(j);
-			transformationSpecifications[j] = job.getPipelineStageSpecification(j);
+			pipelineConnectionNames[j] = job.getPipelineStageConnectionName(j);
+			pipelineDescriptions[j] = job.getPipelineStageDescription(j);
+			pipelineIsOutputs[j] = job.getPipelineStageIsOutputConnection(j);
+			pipelinePrerequisites[j] = job.getPipelineStagePrerequisite(j);
+			pipelineSpecifications[j] = job.getPipelineStageSpecification(j);
 		}
 		type = job.getType();
 		startMethod = job.getStartMethod();
 		hopcountMode = job.getHopcountMode();
-		outputSpecification = job.getOutputSpecification();
 		documentSpecification = job.getSpecification();
 		// Fill in schedule records from job
 		for (int j = 0; j < job.getScheduleRecordCount(); j++)
@@ -173,18 +179,12 @@
 	List<Integer> sequenceArray = new ArrayList<Integer>();
 	
 	IRepositoryConnection connection = null;
-	IOutputConnection outputConnection = null;
 	if (connectionName.length() > 0)
 	{
 		connection = connMgr.load(connectionName);
 		model = RepositoryConnectorFactory.getConnectorModel(threadContext,connection.getClassName());
 		relationshipTypes = RepositoryConnectorFactory.getRelationshipTypes(threadContext,connection.getClassName());
 	}
-	if (outputName.length() > 0)
-	{
-		outputConnection = outputMgr.load(outputName);
-	}
-	ITransformationConnection[] transformationConnections = transformationMgr.loadMultiple(transformationNames);
 
 	// Set up the predefined tabs
 	tabsArray.add(Messages.getString(pageContext.getRequest().getLocale(),"editjob.Name"));
@@ -205,28 +205,16 @@
 	}
 
 	// Get the names of the various Javascript methods we'll need to call
-	String outputCheckMethod = "checkOutputSpecification";
-	String outputSaveCheckMethod = "checkOutputSpecificationForSave";
 	String checkMethod = "checkSpecification";
 	String saveCheckMethod = "checkSpecificationForSave";
-	String[] transformationCheckMethods = new String[transformationConnections.length];
-	String[] transformationCheckForSaveMethods = new String[transformationConnections.length];
-	for (int j = 0; j < transformationConnections.length; j++)
+	String[] pipelineCheckMethods = new String[pipelineConnectionNames.length];
+	String[] pipelineCheckForSaveMethods = new String[pipelineConnectionNames.length];
+	for (int j = 0; j < pipelineConnectionNames.length; j++)
 	{
-		transformationCheckMethods[j] = "unknown";
-		transformationCheckForSaveMethods[j] = "unknown";
+		pipelineCheckMethods[j] = "unknown";
+		pipelineCheckForSaveMethods[j] = "unknown";
 	}
 	
-	if (outputConnection != null)
-	{
-		IOutputConnector outputConnector = OutputConnectorFactory.getConnectorNoCheck(outputConnection.getClassName());
-		if (outputConnector != null)
-		{
-			outputCheckMethod = outputConnector.getFormCheckJavascriptMethodName(1+transformationNames.length);
-			outputSaveCheckMethod = outputConnector.getFormPresaveCheckJavascriptMethodName(1+transformationNames.length);
-		}
-	}
-
 	if (connection != null)
 	{
 		IRepositoryConnector connector = RepositoryConnectorFactory.getConnectorNoCheck(connection.getClassName());
@@ -237,13 +225,33 @@
 		}
 	}
 
-	for (int j = 0; j < transformationConnections.length; j++)
+	for (int j = 0; j < pipelineConnectionNames.length; j++)
 	{
-		ITransformationConnector transformationConnector = TransformationConnectorFactory.getConnectorNoCheck(transformationConnections[j].getClassName());
-		if (transformationConnector != null)
+		if (pipelineIsOutputs[j])
+		{
+			IOutputConnection outputConnection = outputMgr.load(pipelineConnectionNames[j]);
+			if (outputConnection != null)
+			{
+				IOutputConnector outputConnector = OutputConnectorFactory.getConnectorNoCheck(outputConnection.getClassName());
+				if (outputConnector != null)
+				{
+					pipelineCheckMethods[j] = outputConnector.getFormCheckJavascriptMethodName(1+j);
+					pipelineCheckForSaveMethods[j] = outputConnector.getFormPresaveCheckJavascriptMethodName(1+j);
+				}
+			}
+		}
+		else
 		{
-			transformationCheckMethods[j] = transformationConnector.getFormCheckJavascriptMethodName(1+j);
-			transformationCheckForSaveMethods[j] = transformationConnector.getFormPresaveCheckJavascriptMethodName(1+j);
+			ITransformationConnection transformationConnection = transformationMgr.load(pipelineConnectionNames[j]);
+			if (transformationConnection != null)
+			{
+				ITransformationConnector transformationConnector = TransformationConnectorFactory.getConnectorNoCheck(transformationConnection.getClassName());
+				if (transformationConnector != null)
+				{
+					pipelineCheckMethods[j] = transformationConnector.getFormCheckJavascriptMethodName(1+j);
+					pipelineCheckForSaveMethods[j] = transformationConnector.getFormPresaveCheckJavascriptMethodName(1+j);
+				}
+			}
 		}
 	}
 
@@ -332,18 +340,13 @@
 				document.editjob.description.focus();
 				return;
 			}
-			if (window.<%=outputSaveCheckMethod%>)
-			{
-				if (<%=outputSaveCheckMethod%>() == false)
-					return;
-			}
 <%
-	for (int j = 0; j < transformationCheckForSaveMethods.length; j++)
+	for (int j = 0; j < pipelineCheckForSaveMethods.length; j++)
 	{
 %>
-			if (window.<%=transformationCheckForSaveMethods[j]%>)
+			if (window.<%=pipelineCheckForSaveMethods[j]%>)
 			{
-				if (<%=transformationCheckForSaveMethods[j]%>() == false)
+				if (<%=pipelineCheckForSaveMethods[j]%>() == false)
 					return;
 			}
 <%
@@ -371,28 +374,40 @@
 		postFormNew();
 	}
 
-	function InsertPipelineStage(n)
+	function InsertPipelineStageTransformation(n)
+	{
+		if (editjob.transformation_connectionname.value == "")
+		{
+			alert("<%=Messages.getBodyJavascriptString(pageContext.getRequest().getLocale(),"editjob.SelectATransformationStageConnectionName")%>");
+			editjob.transformation_connectionname.focus();
+			return;
+		}
+		eval("document.editjob.pipeline_"+n+"_op.value = 'InsertTransformation'");
+		postFormSetAnchor("pipeline_"+(n+1)+"_tag");
+	}
+
+	function InsertPipelineStageOutput(n)
 	{
-		if (editjob.pipeline_connectionname.value == "")
+		if (editjob.output_connectionname.value == "")
 		{
-			alert("<%=Messages.getBodyJavascriptString(pageContext.getRequest().getLocale(),"editjob.SelectAPipelineStageConnectionName")%>");
-			editjob.pipeline_connectionname.focus();
+			alert("<%=Messages.getBodyJavascriptString(pageContext.getRequest().getLocale(),"editjob.SelectAnOutputStageConnectionName")%>");
+			editjob.output_connectionname.focus();
 			return;
 		}
-		eval("document.editjob.pipeline_"+n+"_op.value = 'Insert'");
+		eval("document.editjob.pipeline_"+n+"_op.value = 'InsertOutput'");
 		postFormSetAnchor("pipeline_"+(n+1)+"_tag");
 	}
 
-	function AppendPipelineStage()
+	function AppendPipelineStageOutput()
 	{
-		if (editjob.pipeline_connectionname.value == "")
+		if (editjob.output_connectionname.value == "")
 		{
-			alert("<%=Messages.getBodyJavascriptString(pageContext.getRequest().getLocale(),"editjob.SelectAPipelineStageConnectionName")%>");
-			editjob.pipeline_connectionname.focus();
+			alert("<%=Messages.getBodyJavascriptString(pageContext.getRequest().getLocale(),"editjob.SelectAnOutputStageConnectionName")%>");
+			editjob.output_connectionname.focus();
 			return;
 		}
-		document.editjob.pipeline_op.value="Add";
-		postFormSetAnchor("pipeline_tag");
+		document.editjob.output_op.value="Add";
+		postFormSetAnchor("output_tag");
 	}
 	
 	function DeletePipelineStage(n)
@@ -460,19 +475,13 @@
 			return false;
 		if (!checkSchedule())
 			return false;
-		// Check the output connector part
-		if (window.<%=outputCheckMethod%>)
-		{
-			if (<%=outputCheckMethod%>() == false)
-				return false;
-		}
 <%
-	for (int j = 0; j < transformationCheckMethods.length; j++)
+	for (int j = 0; j < pipelineCheckMethods.length; j++)
 	{
 %>
-		if (window.<%=transformationCheckMethods[j]%>)
+		if (window.<%=pipelineCheckMethods[j]%>)
 		{
-			if (<%=transformationCheckMethods[j]%>() == false)
+			if (<%=pipelineCheckMethods[j]%>() == false)
 				return false;
 		}
 <%
@@ -583,29 +592,6 @@
 	//-->
 	</script>
 <%
-	if (outputConnection != null)
-	{
-		IOutputConnector outputConnector = outputConnectorPool.grab(outputConnection);
-		if (outputConnector != null)
-		{
-			try
-			{
-				outputConnector.outputSpecificationHeader(new org.apache.manifoldcf.ui.jsp.JspWrapper(out,adminprofile),pageContext.getRequest().getLocale(),outputSpecification,1,tabsArray);
-			}
-			finally
-			{
-				outputConnectorPool.release(outputConnection,outputConnector);
-			}
-		}
-		Integer outputConnectionSequenceNumber = new Integer(1+transformationConnections.length);
-		while (sequenceArray.size() < tabsArray.size())
-		{
-			sequenceArray.add(outputConnectionSequenceNumber);
-		}
-	}
-%>
-
-<%
 	if (connection != null)
 	{
 		IRepositoryConnector repositoryConnector = repositoryConnectorPool.grab(connection);
@@ -629,24 +615,50 @@
 %>
 
 <%
-	for (int j = 0; j < transformationConnections.length; j++)
+	for (int j = 0; j < pipelineConnectionNames.length; j++)
 	{
-		ITransformationConnector transformationConnector = transformationConnectorPool.grab(transformationConnections[j]);
-		if (transformationConnector != null)
+		if (pipelineIsOutputs[j])
 		{
-			try
+			IOutputConnection outputConnection = outputMgr.load(pipelineConnectionNames[j]);
+			if (outputConnection != null)
 			{
-				transformationConnector.outputSpecificationHeader(new org.apache.manifoldcf.ui.jsp.JspWrapper(out,adminprofile),pageContext.getRequest().getLocale(),transformationSpecifications[j],1+j,tabsArray);
+				IOutputConnector outputConnector = outputConnectorPool.grab(outputConnection);
+				if (outputConnector != null)
+				{
+					try
+					{
+						outputConnector.outputSpecificationHeader(new org.apache.manifoldcf.ui.jsp.JspWrapper(out,adminprofile),pageContext.getRequest().getLocale(),pipelineSpecifications[j],1+j,tabsArray);
+					}
+					finally
+					{
+						outputConnectorPool.release(outputConnection,outputConnector);
+					}
+				}
 			}
-			finally
+		}
+		else
+		{
+			ITransformationConnection transformationConnection = transformationMgr.load(pipelineConnectionNames[j]);
+			if (transformationConnection != null)
 			{
-				transformationConnectorPool.release(transformationConnections[j],transformationConnector);
+				ITransformationConnector transformationConnector = transformationConnectorPool.grab(transformationConnection);
+				if (transformationConnector != null)
+				{
+					try
+					{
+						transformationConnector.outputSpecificationHeader(new org.apache.manifoldcf.ui.jsp.JspWrapper(out,adminprofile),pageContext.getRequest().getLocale(),pipelineSpecifications[j],1+j,tabsArray);
+					}
+					finally
+					{
+						transformationConnectorPool.release(transformationConnection,transformationConnector);
+					}
+				}
 			}
 		}
-		Integer transformationConnectionSequenceNumber = new Integer(1+j);
+		Integer connectionSequenceNumber = new Integer(1+j);
 		while (sequenceArray.size() < tabsArray.size())
 		{
-			sequenceArray.add(transformationConnectionSequenceNumber);
+			sequenceArray.add(connectionSequenceNumber);
 		}
 	}
 	
@@ -993,7 +1005,7 @@
 	// Connection tab
 	if (tabName.equals(Messages.getString(pageContext.getRequest().getLocale(),"editjob.Connection")) && tabSequenceInt == -1)
 	{
-		int displaySequence = 0;
+		int rowCounter = 0;
 
 %>
 		  <table class="displaytable">
@@ -1004,16 +1016,20 @@
 					<table class="formtable">
 						<tr class="formheaderrow">
 							<td class="formcolumnheader">
-								<input name="pipeline_count" type="hidden" value="<%=transformationNames.length%>"/>
+								<input name="pipeline_count" type="hidden" value="<%=pipelineConnectionNames.length%>"/>
 							</td>
 							<td class="formcolumnheader"><nobr><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.StageNumber")%></nobr></td>
+							<td class="formcolumnheader"><nobr><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.StageType")%></nobr></td>
+							<td class="formcolumnheader"><nobr><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.StagePrecedent")%></nobr></td>
 							<td class="formcolumnheader"><nobr><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.StageDescription")%></nobr></td>
 							<td class="formcolumnheader"><nobr><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.StageConnectionName")%></nobr></td>
 						</tr>
-						<tr class="<%=((displaySequence % 2)==0)?"evenformrow":"oddformrow"%>">
+						<tr class="<%=((rowCounter++ % 2)==0)?"evenformrow":"oddformrow"%>">
+							<td class="formcolumncell"></td>
+							<td class="formcolumncell">1.</td>
+							<td class="formcolumncell"><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.Repository")%></td>
+							<td class="formcolumncell"></td>
 							<td class="formcolumncell"></td>
-							<td class="formcolumncell"><%=(++displaySequence)%>.</td>
-							<td class="formcolumncell"><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.RepositoryStage")%></td>
 							<td class="formcolumncell">
 <%
 		if (connectionName.length() == 0)
@@ -1042,96 +1058,151 @@
 							</td>
 						</tr>
 <%
-		for (int j = 0; j < transformationNames.length; j++)
+		// A map of stage number to reference count
+		Map<Integer,Integer> referenceCounts = new HashMap<Integer,Integer>();
+		// A list of precedents to pick from, displayed at the end
+		List<Integer> precedents = new ArrayList<Integer>();
+		// Repository connection is always allowed
+		precedents.add(new Integer(-1));
+		Set<String> alreadyPresent = new HashSet<String>();
+		for (int j = 0; j < pipelineConnectionNames.length; j++)
+		{
+			if (pipelineIsOutputs[j])
+				alreadyPresent.add(pipelineConnectionNames[j]);
+			else
+				precedents.add(new Integer(j));
+			if (pipelinePrerequisites[j] != -1)
+			{
+				Integer thisOne = new Integer(pipelinePrerequisites[j]);
+				Integer x = referenceCounts.get(thisOne);
+				if (x == null)
+					referenceCounts.put(thisOne,new Integer(1));
+				else
+					referenceCounts.put(thisOne,new Integer(x.intValue() + 1));
+			}
+		}
+		for (int j = 0; j < pipelineConnectionNames.length; j++)
 		{
-			String transformationName = transformationNames[j];
-			String transformationDescription = transformationDescriptions[j];
-			if (transformationDescription == null)
-				transformationDescription = "";
+			String pipelineConnectionName = pipelineConnectionNames[j];
+			String pipelineDescription = pipelineDescriptions[j];
+			if (pipelineDescription == null)
+				pipelineDescription = "";
+			String pipelineType = pipelineIsOutputs[j]?Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.Output"):Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.Transformation");
 %>
-						<tr class="<%=((displaySequence % 2)==0)?"evenformrow":"oddformrow"%>">
+						<tr class="<%=((rowCounter++ % 2)==0)?"evenformrow":"oddformrow"%>">
 							<td class="formcolumncell">
 								<input name="pipeline_<%=j%>_op" type="hidden" value="Continue"/>
 								<a name="pipeline_<%=j%>_tag"/>
-								<input type="button" value="<%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.Delete")%>" alt='<%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.Deletestage")%>' onclick="javascript:DeletePipelineStage(<%=j%>);"/>
-								<input type="button" value="<%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.InsertBefore")%>" alt='<%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.Insertnewstagehere")%>' onclick="javascript:InsertPipelineStage(<%=j%>);"/>
+<%
+			// We don't want to leave orphans around.  If the pipeline stage is an output, we can delete it ONLY if:
+			// -- the precedent is -1, OR
+			// -- the precedent is not -1 BUT more than one stage refers to the precedent
+			if (!pipelineIsOutputs[j] || pipelinePrerequisites[j] == -1 || referenceCounts.get(new Integer(pipelinePrerequisites[j])).intValue() > 1)
+			{
+%>
+								<input type="button" value="<%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.Delete")%>" alt='<%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.Deletepipelinestage")%>' onclick="javascript:DeletePipelineStage(<%=j%>);"/>
+<%
+			}
+			if (transformationList.length > 0)
+			{
+%>
+								<input type="button" value="<%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.InsertTransformationBefore")%>" alt='<%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.Insertnewtransformationhere")%>' onclick="javascript:InsertPipelineStageTransformation(<%=j%>);"/>
+<%
+			}
+			if (outputList.length != alreadyPresent.size())
+			{
+%>
+								<input type="button" value="<%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.InsertOutputBefore")%>" alt='<%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.Insertnewoutputhere")%>' onclick="javascript:InsertPipelineStageOutput(<%=j%>);"/>
+<%
+			}
+%>
+							</td>
+							<td class="formcolumncell"><%=(j+2)%>.</td>
+							<td class="formcolumncell"><%=pipelineType%>
+								<input name="pipeline_<%=j%>_isoutput" type="hidden" value='<%=pipelineIsOutputs[j]?"true":"false"%>'/>
+							</td>
+							<td class="formcolumncell"><%=(pipelinePrerequisites[j] + 2)%>.
+								<input name="pipeline_<%=j%>_precedent" type="hidden" value="<%=pipelinePrerequisites[j]%>"/>
 							</td>
-							<td class="formcolumncell"><%=(++displaySequence)%>.</td>
 							<td class="formcolumncell">
-								<input name="pipeline_<%=j%>_description" type="text" size="30" value="<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(transformationDescription)%>"/>
+								<input name="pipeline_<%=j%>_description" type="text" size="30" value="<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(pipelineDescription)%>"/>
 							</td>
 							<td class="formcolumncell">
-								<nobr><%=org.apache.manifoldcf.ui.util.Encoder.bodyEscape(transformationName)%></nobr>
-								<input name="pipeline_<%=j%>_connectionname" type="hidden" value="<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(transformationName)%>"/>
+								<nobr><%=org.apache.manifoldcf.ui.util.Encoder.bodyEscape(pipelineConnectionName)%></nobr>
+								<input name="pipeline_<%=j%>_connectionname" type="hidden" value="<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(pipelineConnectionName)%>"/>
 							</td>
 						</tr>
 <%
 		}
-%>
-						<tr class="<%=((displaySequence % 2)==0)?"evenformrow":"oddformrow"%>">
-							<td class="formcolumncell">
-<%
 		if (transformationList.length > 0)
 		{
 %>
-								<input type="button" value="<%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.InsertBefore")%>" alt='<%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.Insertnewstagehere")%>' onclick="javascript:AppendPipelineStage();"/>
-<%
-		}
-%>
+						<tr class="formrow"><td class="formseparator" colspan="4"><hr/></td></tr>
+						<tr class="formrow">
+							<td class="formcolumncell">
+								<a name="transformation_tag"/>
 							</td>
-							<td class="formcolumncell"><%=(++displaySequence)%>.</td>
-							<td class="formcolumncell"><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.OutputStage")%></td>
+							<td class="formcolumncell"></td>
+							<td class="formcolumncell"><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.Transformation")%></td>
+							<td class="formcolumncell"></td>
 							<td class="formcolumncell">
+								<input name="transformation_description" type="text" size="30" value=""/>
+							</td>
+							<td class="formcolumncell">
+								<select name="transformation_connectionname" size="1">
+									<option selected="selected" value="">-- <%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.NoneSelected")%> --</option>
 <%
-		if (outputName.length() == 0)
-		{
-%>
-								<select name="outputname" size="1">
-									<option <%="".equals(outputName)?"selected=\"selected\"":""%> value="">-- <%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.NoneSelected")%> --</option>
-<%
-			for (IOutputConnection conn : outputList)
+			for (ITransformationConnection conn : transformationList)
 			{
 %>
-									<option <%=conn.getName().equals(outputName)?"selected=\"selected\"":""%> value='<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(conn.getName())%>'><%=org.apache.manifoldcf.ui.util.Encoder.bodyEscape(conn.getName())%></option>
+									<option value='<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(conn.getName())%>'><%=org.apache.manifoldcf.ui.util.Encoder.bodyEscape(conn.getName())%></option>
 <%
 			}
 %>
 								</select>
-<%
-		}
-		else
-		{
-%>
-								<input type="hidden" name="outputname" value='<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(outputName)%>'/><%=org.apache.manifoldcf.ui.util.Encoder.bodyEscape(outputName)%>
-<%
-		}
-%>
 							</td>
 						</tr>
 <%
-		if (transformationList.length > 0)
+		}
+		if (outputList.length != alreadyPresent.size())
 		{
 %>
 						<tr class="formrow"><td class="formseparator" colspan="4"><hr/></td></tr>
 						<tr class="formrow">
 							<td class="formcolumncell">
-								<input name="pipeline_op" type="hidden" value="Continue"/>
-								<a name="pipeline_tag"/>
+								<a name="output_tag"/>
+								<input type="button" value='<%=Messages.getAttributeString(pageContext.getRequest().getLocale(),"editjob.AddOutput")%>' alt='<%=Messages.getAttributeString(pageContext.getRequest().getLocale(),"editjob.AddAnOutput")%>' onclick="javascript:AppendPipelineStageOutput();"/>
+								<input name="output_op" type="hidden" value="Continue"/>
 							</td>
+							<td class="formcolumncell"></td>
+							<td class="formcolumncell"><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.Output")%></td>
 							<td class="formcolumncell">
+								<select name="output_precedent" size="1">
+<%
+			for (Integer pre : precedents)
+			{
+%>
+									<option value="<%=pre%>"><%=(pre.intValue()+2)%></option>
+<%
+			}
+%>
+								</select>
 							</td>
 							<td class="formcolumncell">
-								<input name="pipeline_description" type="text" size="30" value=""/>
+								<input name="output_description" type="text" size="30" value=""/>
 							</td>
 							<td class="formcolumncell">
-								<select name="pipeline_connectionname" size="1">
+								<select name="output_connectionname" size="1">
 									<option selected="selected" value="">-- <%=Messages.getBodyString(pageContext.getRequest().getLocale(),"editjob.NoneSelected")%> --</option>
 <%
-			for (ITransformationConnection conn : transformationList)
+			for (IOutputConnection conn : outputList)
 			{
+				if (!alreadyPresent.contains(conn.getName()))
+				{
 %>
 									<option value='<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(conn.getName())%>'><%=org.apache.manifoldcf.ui.util.Encoder.bodyEscape(conn.getName())%></option>
 <%
+				}
 			}
 %>
 								</select>
@@ -1177,19 +1248,20 @@
 	else
 	{
 %>
-		  <input type="hidden" name="outputname" value='<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(outputName)%>'/>
 		  <input type="hidden" name="connectionname" value='<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(connectionName)%>'/>
-		  <input type="hidden" name="pipeline_count" value="<%=transformationNames.length%>"/>
+		  <input type="hidden" name="pipeline_count" value="<%=pipelineConnectionNames.length%>"/>
 <%
-		for (int j = 0; j < transformationNames.length; j++)
+		for (int j = 0; j < pipelineConnectionNames.length; j++)
 		{
-			String transformationName = transformationNames[j];
-			String transformationDescription = transformationDescriptions[j];
-			if (transformationDescription == null)
-				transformationDescription = "";
-%>
-		  <input type="hidden" name="pipeline_<%=j%>_connectionname" value="<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(transformationName)%>"/>
-		  <input type="hidden" name="pipeline_<%=j%>_description" value="<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(transformationDescription)%>"/>
+			String pipelineConnectionName = pipelineConnectionNames[j];
+			String pipelineDescription = pipelineDescriptions[j];
+			if (pipelineDescription == null)
+				pipelineDescription = "";
+%>
+		  <input name="pipeline_<%=j%>_isoutput" type="hidden" value='<%=pipelineIsOutputs[j]?"true":"false"%>'/>
+		  <input name="pipeline_<%=j%>_precedent" type="hidden" value="<%=pipelinePrerequisites[j]%>"/>
+		  <input type="hidden" name="pipeline_<%=j%>_connectionname" value="<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(pipelineConnectionName)%>"/>
+		  <input type="hidden" name="pipeline_<%=j%>_description" value="<%=org.apache.manifoldcf.ui.util.Encoder.attributeEscape(pipelineDescription)%>"/>
 <%
 		}
 %>
@@ -1656,25 +1728,6 @@
 	      }
 	}
 
-	if (outputConnection != null)
-	{
-		IOutputConnector outputConnector = outputConnectorPool.grab(outputConnection);
-		if (outputConnector != null)
-		{
-			try
-			{
-				outputConnector.outputSpecificationBody(new org.apache.manifoldcf.ui.jsp.JspWrapper(out,adminprofile),pageContext.getRequest().getLocale(),outputSpecification,1+transformationConnections.length,tabSequenceInt,tabName);
-			}
-			finally
-			{
-				outputConnectorPool.release(outputConnection,outputConnector);
-			}
-%>
-		  <input type="hidden" name="outputpresent" value="true"/>
-<%
-		}
-	}
-
 	if (connection != null)
 	{
 		IRepositoryConnector repositoryConnector = repositoryConnectorPool.grab(connection);
@@ -1694,18 +1747,46 @@
 		}
 	}
 	
-	for (int j = 0; j < transformationConnections.length; j++)
+	boolean outputPresent = false;
+	for (int j = 0; j < pipelineConnectionNames.length; j++)
 	{
-		ITransformationConnector transformationConnector = transformationConnectorPool.grab(transformationConnections[j]);
-		if (transformationConnector != null)
+		if (pipelineIsOutputs[j])
 		{
-			try
+			outputPresent = true;
+			IOutputConnection outputConnection = outputMgr.load(pipelineConnectionNames[j]);
+			if (outputConnection != null)
 			{
-				transformationConnector.outputSpecificationBody(new org.apache.manifoldcf.ui.jsp.JspWrapper(out,adminprofile),pageContext.getRequest().getLocale(),transformationSpecifications[j],1+j,tabSequenceInt,tabName);
+				IOutputConnector outputConnector = outputConnectorPool.grab(outputConnection);
+				if (outputConnector != null)
+				{
+					try
+					{
+						outputConnector.outputSpecificationBody(new org.apache.manifoldcf.ui.jsp.JspWrapper(out,adminprofile),pageContext.getRequest().getLocale(),pipelineSpecifications[j],1+j,tabSequenceInt,tabName);
+					}
+					finally
+					{
+						outputConnectorPool.release(outputConnection,outputConnector);
+					}
+				}
 			}
-			finally
+		}
+		else
+		{
+			ITransformationConnection transformationConnection = transformationMgr.load(pipelineConnectionNames[j]);
+			if (transformationConnection != null)
 			{
-				transformationConnectorPool.release(transformationConnections[j],transformationConnector);
+				ITransformationConnector transformationConnector = transformationConnectorPool.grab(transformationConnection);
+				if (transformationConnector != null)
+				{
+					try
+					{
+						transformationConnector.outputSpecificationBody(new org.apache.manifoldcf.ui.jsp.JspWrapper(out,adminprofile),pageContext.getRequest().getLocale(),pipelineSpecifications[j],1+j,tabSequenceInt,tabName);
+					}
+					finally
+					{
+						transformationConnectorPool.release(transformationConnection,transformationConnector);
+					}
+				}
 			}
 		}
 	}
@@ -1715,7 +1796,7 @@
 			<tr><td class="separator" colspan="4"><hr/></td></tr>
 			<tr><td class="message" colspan="4"><nobr>
 <%
-	if (connectionName.length() > 0 && outputName.length() > 0)
+	if (connectionName.length() > 0 && outputPresent)
 	{
 %>
 			<input type="button" value="<%=Messages.getAttributeString(pageContext.getRequest().getLocale(),"editjob.Save")%>" onClick="javascript:Save()" alt="<%=Messages.getAttributeString(pageContext.getRequest().getLocale(),"editjob.SaveThisJob")%>"/>

Modified: manifoldcf/trunk/framework/crawler-ui/src/main/webapp/execute.jsp
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/crawler-ui/src/main/webapp/execute.jsp?rev=1603199&r1=1603198&r2=1603199&view=diff
==============================================================================
--- manifoldcf/trunk/framework/crawler-ui/src/main/webapp/execute.jsp (original)
+++ manifoldcf/trunk/framework/crawler-ui/src/main/webapp/execute.jsp Tue Jun 17 15:17:34 2014
@@ -884,16 +884,11 @@
 					// Figure out what got posted.
 					String x = variableContext.getParameter("connectionpresent");
 					boolean connectionPresent = (x != null && x.equals("true"));
-					x = variableContext.getParameter("outputpresent");
-					boolean outputPresent = (x != null && x.equals("true"));
 					
 					// Gather the rest of the data.
 					x = variableContext.getParameter("description");
 					if (x != null)
 						job.setDescription(x);
-					x = variableContext.getParameter("outputname");
-					if (x != null)
-						job.setOutputConnectionName(x);
 					x = variableContext.getParameter("connectionname");
 					if (x != null)
 						job.setConnectionName(x);
@@ -916,9 +911,11 @@
 						for (int j = 0; j < count; j++)
 						{
 							// Gather everything first; we'll look at edits later
+							int precedent = Integer.parseInt(variableContext.getParameter("pipeline_"+j+"_precedent"));
+							boolean isOutput = variableContext.getParameter("pipeline_"+j+"_isoutput").equals("true");
 							String connectionName = variableContext.getParameter("pipeline_"+j+"_connectionname");
 							String description = variableContext.getParameter("pipeline_"+j+"_description");
-							job.addPipelineStage(connectionName, description);
+							job.addPipelineStage(precedent, isOutput, connectionName, description);
 						}
 					}
 
@@ -1165,9 +1162,6 @@
 					IRepositoryConnection connection = null;
 					if (job.getConnectionName() != null && job.getConnectionName().length() > 0)
 						connection = connManager.load(job.getConnectionName());
-					IOutputConnection outputConnection = null;
-					if (job.getOutputConnectionName() != null && job.getOutputConnectionName().length() > 0)
-						outputConnection = outputManager.load(job.getOutputConnectionName());
 					
 					if (connection != null)
 					{
@@ -1191,30 +1185,6 @@
 						}
 					}
 					
-					if (outputPresent && outputConnection != null)
-					{
-						IOutputConnector outputConnector = outputConnectorPool.grab(outputConnection);
-						if (outputConnector != null)
-						{
-							try
-							{
-								String error = outputConnector.processSpecificationPost(variableContext,pageContext.getRequest().getLocale(),job.getOutputSpecification(),1+job.countPipelineStages());
-								if (error != null)
-								{
-									variableContext.setParameter("text",error);
-									variableContext.setParameter("target","listjobs.jsp");
-%>
-									<jsp:forward page="error.jsp"/>
-<%
-								}
-							}
-							finally
-							{
-								outputConnectorPool.release(outputConnection,outputConnector);
-							}
-						}
-					}
-					
 					if (connectionPresent && connection != null)
 					{
 						IRepositoryConnector repositoryConnector = repositoryConnectorPool.grab(connection);
@@ -1242,32 +1212,62 @@
 					// Process all pipeline stages
 					for (int j = 0; j < job.countPipelineStages(); j++)
 					{
-						ITransformationConnection transformationConnection = transformationManager.load(job.getPipelineStageConnectionName(j));
-						if (transformationConnection != null)
+						if (job.getPipelineStageIsOutputConnection(j))
 						{
-							ITransformationConnector transformationConnector = transformationConnectorPool.grab(transformationConnection);
-							if (transformationConnector != null)
+							IOutputConnection outputConnection = outputManager.load(job.getPipelineStageConnectionName(j));
+							if (outputConnection != null)
 							{
-								try
+								IOutputConnector outputConnector = outputConnectorPool.grab(outputConnection);
+								if (outputConnector != null)
 								{
-									String error = transformationConnector.processSpecificationPost(variableContext,pageContext.getRequest().getLocale(),job.getPipelineStageSpecification(j),1+j);
-									if (error != null)
+									try
 									{
-										variableContext.setParameter("text",error);
-										variableContext.setParameter("target","listjobs.jsp");
+										String error = outputConnector.processSpecificationPost(variableContext,pageContext.getRequest().getLocale(),job.getPipelineStageSpecification(j),1+j);
+										if (error != null)
+										{
+											variableContext.setParameter("text",error);
+											variableContext.setParameter("target","listjobs.jsp");
 %>
 									<jsp:forward page="error.jsp"/>
 <%
+										}
+									}
+									finally
+									{
+										outputConnectorPool.release(outputConnection,outputConnector);
 									}
 								}
-								finally
+							}
+						}
+						else
+						{
+							ITransformationConnection transformationConnection = transformationManager.load(job.getPipelineStageConnectionName(j));
+							if (transformationConnection != null)
+							{
+								ITransformationConnector transformationConnector = transformationConnectorPool.grab(transformationConnection);
+								if (transformationConnector != null)
 								{
-									transformationConnectorPool.release(transformationConnection,transformationConnector);
+									try
+									{
+										String error = transformationConnector.processSpecificationPost(variableContext,pageContext.getRequest().getLocale(),job.getPipelineStageSpecification(j),1+j);
+										if (error != null)
+										{
+											variableContext.setParameter("text",error);
+											variableContext.setParameter("target","listjobs.jsp");
+%>
+									<jsp:forward page="error.jsp"/>
+<%
+										}
+									}
+									finally
+									{
+										transformationConnectorPool.release(transformationConnection,transformationConnector);
+									}
 								}
 							}
 						}
 					}
-					
+
 					// Now, after gathering is complete, consider doing changes to the pipeline.
 					int currentStage = 0;
 					for (int j = 0; j < job.countPipelineStages(); j++)
@@ -1276,26 +1276,36 @@
 						x = variableContext.getParameter("pipeline_"+j+"_op");
 						if (x != null && x.equals("Delete"))
 						{
-							// Delete this pipeline stage
+							// Delete this pipeline stage (and rewire other stages according to rules)
 							job.deletePipelineStage(currentStage);
 						}
-						else if (x != null && x.equals("Insert"))
+						else if (x != null && x.equals("InsertTransformation"))
 						{
 							// Insert a new stage before this one
-							String connectionName = variableContext.getParameter("pipeline_connectionname");
-							String description = variableContext.getParameter("pipeline_description");
-							job.insertPipelineStage(currentStage++,connectionName,description);
+							String connectionName = variableContext.getParameter("transformation_connectionname");
+							String description = variableContext.getParameter("transformation_description");
+							job.insertPipelineStage(currentStage,false,connectionName,description);
+							currentStage++;
+						}
+						else if (x != null && x.equals("InsertOutput"))
+						{
+							// Insert a new stage before this one
+							String connectionName = variableContext.getParameter("output_connectionname");
+							String description = variableContext.getParameter("output_description");
+							job.insertPipelineStage(currentStage,true,connectionName,description);
+							currentStage++;
 						}
 						else
 							currentStage++;
 					}
-					x = variableContext.getParameter("pipeline_op");
+					x = variableContext.getParameter("output_op");
 					if (x != null && x.equals("Add"))
 					{
 						// Append a new stage at the end
-						String connectionName = variableContext.getParameter("pipeline_connectionname");
-						String description = variableContext.getParameter("pipeline_description");
-						job.addPipelineStage(connectionName,description);
+						int precedent = Integer.parseInt(variableContext.getParameter("output_precedent"));
+						String connectionName = variableContext.getParameter("output_connectionname");
+						String description = variableContext.getParameter("output_description");
+						job.addPipelineStage(precedent,true,connectionName,description);
 					}
 					
 					if (op.equals("Continue"))

Modified: manifoldcf/trunk/framework/crawler-ui/src/main/webapp/listjobs.jsp
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/crawler-ui/src/main/webapp/listjobs.jsp?rev=1603199&r1=1603198&r2=1603199&view=diff
==============================================================================
--- manifoldcf/trunk/framework/crawler-ui/src/main/webapp/listjobs.jsp (original)
+++ manifoldcf/trunk/framework/crawler-ui/src/main/webapp/listjobs.jsp Tue Jun 17 15:17:34 2014
@@ -84,11 +84,22 @@
 				<td class="columnheader"><nobr><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"listjobs.ScheduleType")%></nobr></td>
 			</tr>
 <%
-	int i = 0;
-	while (i < jobs.length)
+	for (int i = 0; i < jobs.length; i++)
 	{
-		IJobDescription jd = jobs[i++];
+		IJobDescription jd = jobs[i];
 
+		StringBuilder sb = new StringBuilder();
+		for (int j = 0; j < jd.countPipelineStages(); j++)
+		{
+			if (jd.getPipelineStageIsOutputConnection(j))
+			{
+				if (sb.length() > 0)
+					sb.append(",");
+				sb.append(jd.getPipelineStageConnectionName(j));
+			}
+		}
+		String outputConnectionNames = sb.toString();
+		
 		String jobType = "";
 		switch (jd.getType())
 		{
@@ -112,7 +123,7 @@
 			</nobr>
 		    </td>
 		    <td class="columncell"><%=org.apache.manifoldcf.ui.util.Encoder.bodyEscape(jd.getDescription())%></td>
-		    <td class="columncell"><%=org.apache.manifoldcf.ui.util.Encoder.bodyEscape(jd.getOutputConnectionName())%></td>
+		    <td class="columncell"><%=org.apache.manifoldcf.ui.util.Encoder.bodyEscape(outputConnectionNames)%></td>
 		    <td class="columncell"><%=org.apache.manifoldcf.ui.util.Encoder.bodyEscape(jd.getConnectionName())%></td>
 		    <td class="columncell"><%=jobType%></td>
 		</tr>

Modified: manifoldcf/trunk/framework/crawler-ui/src/main/webapp/viewjob.jsp
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/crawler-ui/src/main/webapp/viewjob.jsp?rev=1603199&r1=1603198&r2=1603199&view=diff
==============================================================================
--- manifoldcf/trunk/framework/crawler-ui/src/main/webapp/viewjob.jsp (original)
+++ manifoldcf/trunk/framework/crawler-ui/src/main/webapp/viewjob.jsp Tue Jun 17 15:17:34 2014
@@ -143,22 +143,8 @@
 		int priority = job.getPriority();
 
 		String connectionName = job.getConnectionName();
-		String outputName = job.getOutputConnectionName();
-		String[] transformationNames = new String[job.countPipelineStages()];
-		String[] transformationDescriptions = new String[job.countPipelineStages()];
-		for (int j = 0; j < job.countPipelineStages(); j++)
-		{
-			transformationNames[j] = job.getPipelineStageConnectionName(j);
-			String transformationDescription = job.getPipelineStageDescription(j);
-			if (transformationDescription == null)
-				transformationDescription = "";
-			transformationDescriptions[j] = transformationDescription;
-		}
-
 		IRepositoryConnection connection = connManager.load(connectionName);
-		IOutputConnection outputConnection = outputManager.load(outputName);
-		ITransformationConnection[] transformationConnections = transformationManager.loadMultiple(transformationNames);
-
+		
 		int model = RepositoryConnectorFactory.getConnectorModel(threadContext,connection.getClassName());
 		String[] relationshipTypes = RepositoryConnectorFactory.getRelationshipTypes(threadContext,connection.getClassName());
 		Map hopCountFilters = job.getHopCountFilters();
@@ -169,7 +155,7 @@
 		//threadContext.save("OutputConnection",outputConnection);
 		//threadContext.save("DocumentSpecification",job.getSpecification());
 		//threadContext.save("RepositoryConnection",connection);
-		int displaySequence = 0;
+		int rowCounter = 0;
 
 %>
 		<table class="displaytable">
@@ -189,31 +175,32 @@
 					<table class="formtable">
 						<tr class="formheaderrow">
 							<td class="formcolumnheader"><nobr><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"viewjob.StageNumber")%></nobr></td>
+							<td class="formcolumnheader"><nobr><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"viewjob.StageType")%></nobr></td>
+							<td class="formcolumnheader"><nobr><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"viewjob.StagePrecedent")%></nobr></td>
 							<td class="formcolumnheader"><nobr><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"viewjob.StageDescription")%></nobr></td>
 							<td class="formcolumnheader"><nobr><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"viewjob.StageConnectionName")%></nobr></td>
 						</tr>
-						<tr class="<%=((displaySequence % 2)==0)?"evenformrow":"oddformrow"%>">
-							<td class="formcolumncell"><%=(++displaySequence)%>.</td>
-							<td class="formcolumncell"><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"viewjob.RepositoryStage")%></td>
+						<tr class="<%=((rowCounter++ % 2)==0)?"evenformrow":"oddformrow"%>">
+							<td class="formcolumncell">1.</td>
+							<td class="formcolumncell"><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"viewjob.Repository")%></td>
+							<td class="formcolumncell"></td>
+							<td class="formcolumncell"></td>
 							<td class="formcolumncell"><%=org.apache.manifoldcf.ui.util.Encoder.bodyEscape(connectionName)%></td>
 						</tr>
 <%
-		for (int j = 0; j < transformationNames.length; j++)
+		for (int j = 0; j < job.countPipelineStages(); j++)
 		{
 %>
-						<tr class="<%=((displaySequence % 2)==0)?"evenformrow":"oddformrow"%>">
-							<td class="formcolumncell"><%=(++displaySequence)%>.</td>
-							<td class="formcolumncell"><%=org.apache.manifoldcf.ui.util.Encoder.bodyEscape(transformationDescriptions[j])%></td>
-							<td class="formcolumncell"><%=org.apache.manifoldcf.ui.util.Encoder.bodyEscape(transformationNames[j])%></td>
+						<tr class="<%=((rowCounter++ % 2)==0)?"evenformrow":"oddformrow"%>">
+							<td class="formcolumncell"><%=(j+2)%>.</td>
+							<td class="formcolumncell"><%=job.getPipelineStageIsOutputConnection(j)?Messages.getBodyString(pageContext.getRequest().getLocale(),"viewjob.Output"):Messages.getBodyString(pageContext.getRequest().getLocale(),"viewjob.Transformation")%></td>
+							<td class="formcolumncell"><%=(job.getPipelineStagePrerequisite(j)+2)%>.</td>
+							<td class="formcolumncell"><%=(job.getPipelineStageDescription(j)!=null)?org.apache.manifoldcf.ui.util.Encoder.bodyEscape(job.getPipelineStageDescription(j)):""%></td>
+							<td class="formcolumncell"><%=org.apache.manifoldcf.ui.util.Encoder.bodyEscape(job.getPipelineStageConnectionName(j))%></td>
 						</tr>
 <%
 		}
 %>
-						<tr class="<%=((displaySequence % 2)==0)?"evenformrow":"oddformrow"%>">
-							<td class="formcolumncell"><%=(++displaySequence)%>.</td>
-							<td class="formcolumncell"><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"viewjob.OutputStage")%></td>
-							<td class="formcolumncell"><%=org.apache.manifoldcf.ui.util.Encoder.bodyEscape(outputName)%></td>
-						</tr>
 					</table>
 				</td>
 			</tr>
@@ -692,25 +679,27 @@
 
 		}
 %>
-
 			<tr>
 				<td class="separator" colspan="4"><hr/></td>
 			</tr>
 			<tr>
+				<td class="message" colspan="4">1.</td>
+			</tr>
+			<tr>
 				<td colspan="4">
 <%
-		if (outputConnection != null)
+		if (connection != null)
 		{
-			IOutputConnector outputConnector = outputConnectorPool.grab(outputConnection);
-			if (outputConnector != null)
+			IRepositoryConnector repositoryConnector = repositoryConnectorPool.grab(connection);
+			if (repositoryConnector != null)
 			{
 				try
 				{
-					outputConnector.viewSpecification(new org.apache.manifoldcf.ui.jsp.JspWrapper(out,adminprofile),pageContext.getRequest().getLocale(),job.getOutputSpecification(),1+transformationConnections.length);
+					repositoryConnector.viewSpecification(new org.apache.manifoldcf.ui.jsp.JspWrapper(out,adminprofile),pageContext.getRequest().getLocale(),job.getSpecification(),0);
 				}
 				finally
 				{
-					outputConnectorPool.release(outputConnection,outputConnector);
+					repositoryConnectorPool.release(connection,repositoryConnector);
 				}
 			}
 		}
@@ -718,19 +707,39 @@
 				</td>
 			</tr>
 <%
-		if (transformationConnections.length > 0)
+		for (int j = 0; j < job.countPipelineStages(); j++)
 		{
 %>
 			<tr>
 				<td class="separator" colspan="4"><hr/></td>
 			</tr>
 			<tr>
+				<td class="message" colspan="4"><%=(j+2)%>.</td>
+			</tr>
+			<tr>
 				<td colspan="4">
 <%
-			for (int j = 0; j < transformationConnections.length; j++)
+			OutputSpecification os = job.getPipelineStageSpecification(j);
+			if (job.getPipelineStageIsOutputConnection(j))
 			{
-				OutputSpecification os = job.getPipelineStageSpecification(j);
-				ITransformationConnector transformationConnector = transformationConnectorPool.grab(transformationConnections[j]);
+				IOutputConnection thisConnection = outputManager.load(job.getPipelineStageConnectionName(j));
+				IOutputConnector outputConnector = outputConnectorPool.grab(thisConnection);
+				if (outputConnector != null)
+				{
+					try
+					{
+						outputConnector.viewSpecification(new org.apache.manifoldcf.ui.jsp.JspWrapper(out,adminprofile),pageContext.getRequest().getLocale(),os,1+j);
+					}
+					finally
+					{
+						outputConnectorPool.release(thisConnection,outputConnector);
+					}
+				}
+			}
+			else
+			{
+				ITransformationConnection thisConnection = transformationManager.load(job.getPipelineStageConnectionName(j));
+				ITransformationConnector transformationConnector = transformationConnectorPool.grab(thisConnection);
 				if (transformationConnector != null)
 				{
 					try
@@ -739,7 +748,7 @@
 					}
 					finally
 					{
-						transformationConnectorPool.release(transformationConnections[j],transformationConnector);
+						transformationConnectorPool.release(thisConnection,transformationConnector);
 					}
 				}
 			}
@@ -753,30 +762,6 @@
 				<td class="separator" colspan="4"><hr/></td>
 			</tr>
 			<tr>
-				<td colspan="4">
-<%
-		if (connection != null)
-		{
-			IRepositoryConnector repositoryConnector = repositoryConnectorPool.grab(connection);
-			if (repositoryConnector != null)
-			{
-				try
-				{
-					repositoryConnector.viewSpecification(new org.apache.manifoldcf.ui.jsp.JspWrapper(out,adminprofile),pageContext.getRequest().getLocale(),job.getSpecification(),0);
-				}
-				finally
-				{
-					repositoryConnectorPool.release(connection,repositoryConnector);
-				}
-			}
-		}
-%>
-				</td>
-			</tr>
-			<tr>
-				<td class="separator" colspan="4"><hr/></td>
-			</tr>
-			<tr>
 				<td class="message" colspan="4">
 					<nobr>
 						<a href='<%="editjob.jsp?jobid="+jobID%>' alt="<%=Messages.getAttributeString(pageContext.getRequest().getLocale(),"viewjob.EditThisJob")%>"><%=Messages.getBodyString(pageContext.getRequest().getLocale(),"viewjob.Edit")%></a>

Modified: manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/DefineJob.java
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/DefineJob.java?rev=1603199&r1=1603198&r2=1603199&view=diff
==============================================================================
--- manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/DefineJob.java (original)
+++ manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/DefineJob.java Tue Jun 17 15:17:34 2014
@@ -38,7 +38,7 @@ public class DefineJob
   {
     if (args.length != 13)
     {
-      System.err.println("Usage: DefineJob <description> <connection_name> <output_name> <type> <start_method> <hopcount_method> <recrawl_interval> <expiration_interval> <reseed_interval> <job_priority> <hop_filters> <filespec_xml> <outputspec_xml>");
+      System.err.println("Usage: DefineJob <description> <connection_name> <type> <start_method> <hopcount_method> <recrawl_interval> <expiration_interval> <reseed_interval> <job_priority> <hop_filters> <filespec_xml>");
       System.err.println("<type> is one of: continuous or specified");
       System.err.println("<start_method> is one of: windowbegin, windowinside, disable");
       System.err.println("<hopcount_method> is one of: accurate, nodelete, neverdelete");
@@ -48,23 +48,20 @@ public class DefineJob
       System.err.println("<job_priority> is the job priority (and integer between 0 and 10)");
       System.err.println("<hop_filters> is a comma-separated list of tuples, of the form 'linktype=maxhops'");
       System.err.println("<filespec_xml> is the document specification XML, its form dependent on the connection type");
-      System.err.println("<outputspec_xml> is the output specification XML, its form dependent on the output connection type");
       System.exit(-1);
     }
 
     String description = args[0];
     String connectionName = args[1];
-    String outputConnectionName = args[2];
-    String typeString = args[3];
-    String startString = args[4];
-    String hopcountString = args[5];
-    String recrawlInterval = args[6];
-    String expirationInterval = args[7];
-    String reseedInterval = args[8];
-    String jobPriority = args[9];
-    String hopFilters = args[10];
-    String filespecXML = args[11];
-    String outputspecXML = args[12];
+    String typeString = args[2];
+    String startString = args[3];
+    String hopcountString = args[4];
+    String recrawlInterval = args[5];
+    String expirationInterval = args[6];
+    String reseedInterval = args[7];
+    String jobPriority = args[8];
+    String hopFilters = args[9];
+    String filespecXML = args[10];
 
     try
     {
@@ -75,7 +72,6 @@ public class DefineJob
 
       desc.setDescription(description);
       desc.setConnectionName(connectionName);
-      desc.setOutputConnectionName(outputConnectionName);
 
       if (typeString.equals("continuous"))
         desc.setType(IJobDescription.TYPE_CONTINUOUS);
@@ -123,8 +119,6 @@ public class DefineJob
       }
       
       desc.getSpecification().fromXML(filespecXML);
-      if (outputspecXML.length() > 0)
-        desc.getOutputSpecification().fromXML(outputspecXML);
       
       // Now, save
       jobManager.save(desc);

Modified: manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/ListJobs.java
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/ListJobs.java?rev=1603199&r1=1603198&r2=1603199&view=diff
==============================================================================
--- manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/ListJobs.java (original)
+++ manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/ListJobs.java Tue Jun 17 15:17:34 2014
@@ -41,7 +41,7 @@ public class ListJobs
       System.err.println("Usage: ListJobs");
       System.err.println("");
       System.err.println("The result will be printed to standard out, will be UTF-8 encoded, and will contain the following columns:");
-      System.err.println("    identifier,description,connection,outputconnection,startmode,runmode,hopcountmode,priority,rescaninterval,expirationinterval,reseedinterval,outputspecification");
+      System.err.println("    identifier,description,connection,startmode,runmode,hopcountmode,priority,rescaninterval,expirationinterval,reseedinterval");
       System.exit(1);
     }
 
@@ -57,20 +57,18 @@ public class ListJobs
       {
         IJobDescription job = jobs[i++];
 
-        //identifier,description,connection,outputconnection,startmode,runmode,hopcountmode,priority,rescaninterval,expirationinterval,reseedinterval,outputspecification
+        //identifier,description,connection,startmode,runmode,hopcountmode,priority,rescaninterval,expirationinterval,reseedinterval
 
         UTF8Stdout.println(job.getID().toString()+","+
           ((job.getDescription()==null)?"":commaEscape(job.getDescription()))+","+
           commaEscape(job.getConnectionName())+","+
-          commaEscape(job.getOutputConnectionName())+","+
           startModeMap(job.getStartMethod())+","+
           runModeMap(job.getType())+","+
           hopcountModeMap(job.getHopcountMode())+","+
           Integer.toString(job.getPriority())+","+
           presentInterval(job.getInterval())+","+
           presentInterval(job.getExpiration())+","+
-          presentInterval(job.getReseedInterval())+","+
-          ((job.getOutputSpecification()==null)?"":commaEscape(job.getOutputSpecification().toXML())));
+          presentInterval(job.getReseedInterval()));
       }
       System.err.println("Job list done");
     }

Modified: manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/interfaces/IJobDescription.java
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/interfaces/IJobDescription.java?rev=1603199&r1=1603198&r2=1603199&view=diff
==============================================================================
--- manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/interfaces/IJobDescription.java (original)
+++ manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/interfaces/IJobDescription.java Tue Jun 17 15:17:34 2014
@@ -81,32 +81,36 @@ public interface IJobDescription
   */
   public String getConnectionName();
 
-  /** Set the output connection name.
-  *@param connectionName is the output connection name.
-  */
-  public void setOutputConnectionName(String connectionName);
-
-  /** Get the output connection name.
-  *@return the output connection name.
-  */
-  public String getOutputConnectionName();
-
   /** Clear pipeline connections.
   */
   public void clearPipeline();
   
   /** Add a pipeline connection.
+  *@param prerequisiteStage is the prerequisite stage number for this connection, or -1 if there is none.
+  *@param isOutput is true if the pipeline stage is an output connection.
   *@param pipelineStageConnectionName is the name of the pipeline connection to add.
   *@param pipelineStageDescription is a description of the pipeline stage being added.
   *@return the empty output specification for this pipeline stage.
   */
-  public OutputSpecification addPipelineStage(String pipelineStageConnectionName, String pipelineStageDescription);
+  public OutputSpecification addPipelineStage(int prerequisiteStage, boolean isOutput, String pipelineStageConnectionName, String pipelineStageDescription);
   
   /** Get a count of pipeline connections.
   *@return the current number of pipeline connections.
   */
   public int countPipelineStages();
   
+  /** Get the prerequisite stage number for a pipeline stage.
+  *@param index is the index of the pipeline stage to get.
+  *@return the preceding stage number for that stage, or -1 if there is none.
+  */
+  public int getPipelineStagePrerequisite(int index);
+  
+  /** Check if a pipeline stage is an output connection.
+  *@param index is the index of the pipeline stage to check.
+  *@return true if it is an output connection.
+  */
+  public boolean getPipelineStageIsOutputConnection(int index);
+  
   /** Get a specific pipeline connection name.
   *@param index is the index of the pipeline stage whose connection name to get.
   *@return the name of the connection.
@@ -136,7 +140,7 @@ public interface IJobDescription
   *@param pipelineStageDescription is the description.
   *@return the newly-created output specification.
   */
-  public OutputSpecification insertPipelineStage(int index, String pipelineStageConnectionName, String pipelineStageDescription);
+  public OutputSpecification insertPipelineStage(int index, boolean isOutput, String pipelineStageConnectionName, String pipelineStageDescription);
   
   /** Set the job type.
   *@param type is the type (as an integer).
@@ -231,13 +235,6 @@ public interface IJobDescription
   */
   public Long getReseedInterval();
 
-  // Output specification
-
-  /** Get the output specification (which can be modified).
-  *@return the specification.
-  */
-  public OutputSpecification getOutputSpecification();
-
   // Document specification
 
   /** Get the document specification (which can be modified).

Modified: manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/JobDescription.java
URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/JobDescription.java?rev=1603199&r1=1603198&r2=1603199&view=diff
==============================================================================
--- manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/JobDescription.java (original)
+++ manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/jobs/JobDescription.java Tue Jun 17 15:17:34 2014
@@ -42,7 +42,6 @@ public class JobDescription implements I
   protected boolean isNew = true;
   protected Long id = null;
   protected String description = null;
-  protected String outputConnectionName = null;
   protected String connectionName = null;
   protected final List<PipelineStage> pipelineStages = new ArrayList<PipelineStage>();
   protected int type = TYPE_CONTINUOUS;
@@ -67,9 +66,6 @@ public class JobDescription implements I
   // Default reseed interval for continuous crawling
   protected Long reseedInterval = new Long(60L * 60L * 1000L);    // 1 hour is the default
 
-  // Output specification
-  protected OutputSpecification outputSpecification = new OutputSpecification();
-
   // Document specification
   protected DocumentSpecification documentSpecification = new DocumentSpecification();
 
@@ -96,15 +92,16 @@ public class JobDescription implements I
     JobDescription rval = new JobDescription();
     rval.id = id;
     rval.isNew = isNew;
-    rval.outputConnectionName = outputConnectionName;
-    // Direct modification of this object is possible - so it also has to know if it is read-only!!
-    rval.outputSpecification = outputSpecification.duplicate(readOnly);
     rval.connectionName = connectionName;
     // Direct modification of this object is possible - so it also has to know if it is read-only!!
     rval.documentSpecification = documentSpecification.duplicate(readOnly);
     for (PipelineStage pipelineStage : pipelineStages)
     {
-      rval.pipelineStages.add(new PipelineStage(pipelineStage.getConnectionName(),pipelineStage.getDescription(),pipelineStage.getSpecification().duplicate(readOnly)));
+      rval.pipelineStages.add(new PipelineStage(pipelineStage.getPrerequisiteStage(),
+        pipelineStage.getIsOutput(),
+        pipelineStage.getConnectionName(),
+        pipelineStage.getDescription(),
+        pipelineStage.getSpecification().duplicate(readOnly)));
     }
     rval.description = description;
     rval.type = type;
@@ -145,7 +142,10 @@ public class JobDescription implements I
     if (readOnly)
       return;
     readOnly = true;
-    outputSpecification.makeReadOnly();
+    for (PipelineStage pipelineStage : pipelineStages)
+    {
+      pipelineStage.getSpecification().makeReadOnly();
+    }
     documentSpecification.makeReadOnly();
   }
 
@@ -207,26 +207,6 @@ public class JobDescription implements I
     return description;
   }
 
-  /** Set the output connection name.
-  *@param connectionName is the connection name.
-  */
-  @Override
-  public void setOutputConnectionName(String connectionName)
-  {
-    if (readOnly)
-      throw new IllegalStateException("Attempt to change read-only object");
-    this.outputConnectionName = connectionName;
-  }
-
-  /** Get the output connection name.
-  *@return the output connection name.
-  */
-  @Override
-  public String getOutputConnectionName()
-  {
-    return outputConnectionName;
-  }
-
   /** Set the connection name.
   *@param connectionName is the connection name.
   */
@@ -257,16 +237,18 @@ public class JobDescription implements I
   }
   
   /** Add a pipeline connection.
+  *@param prerequisiteStage is the prerequisite stage number for this connection, or -1 if there is none.
+  *@param isOutput is true if the pipeline stage is an output connection.
   *@param pipelineStageConnectionName is the name of the pipeline connection to add.
   *@param pipelineStageDescription is a description of the pipeline stage being added.
   *@return the empty output specification for this pipeline stage.
   */
   @Override
-  public OutputSpecification addPipelineStage(String pipelineStageConnectionName, String pipelineStageDescription)
+  public OutputSpecification addPipelineStage(int prerequisiteStage, boolean isOutput, String pipelineStageConnectionName, String pipelineStageDescription)
   {
     if (readOnly)
       throw new IllegalStateException("Attempt to change read-only object");
-    PipelineStage ps = new PipelineStage(pipelineStageConnectionName,pipelineStageDescription);
+    PipelineStage ps = new PipelineStage(prerequisiteStage,isOutput,pipelineStageConnectionName,pipelineStageDescription);
     pipelineStages.add(ps);
     return ps.getSpecification();
   }
@@ -284,15 +266,47 @@ public class JobDescription implements I
   *@param pipelineStageDescription is the description.
   *@return the newly-created output specification.
   */
-  public OutputSpecification insertPipelineStage(int index, String pipelineStageConnectionName, String pipelineStageDescription)
+  @Override
+  public OutputSpecification insertPipelineStage(int index, boolean isOutput, String pipelineStageConnectionName, String pipelineStageDescription)
   {
     if (readOnly)
       throw new IllegalStateException("Attempt to change read-only object");
-    PipelineStage ps = new PipelineStage(pipelineStageConnectionName,pipelineStageDescription);
+    // What we do here depends on the kind of stage we're inserting.
+    // Both kinds take the current stage's prerequisite as their own.  But what happens to the current stage will
+    // differ as to whether its reference changes or not.
+    PipelineStage currentStage = pipelineStages.get(index);
+    PipelineStage ps = new PipelineStage(currentStage.getPrerequisiteStage(),isOutput,pipelineStageConnectionName,pipelineStageDescription);
     pipelineStages.add(index,ps);
+    // Adjust stage back-references
+    int stage = index + 1;
+    while (stage < pipelineStages.size())
+    {
+      pipelineStages.get(stage).adjustForInsert(index,isOutput);
+      stage++;
+    }
     return ps.getSpecification();
   }
   
+  /** Get the prerequisite stage number for a pipeline stage.
+  *@param index is the index of the pipeline stage to get.
+  *@return the preceding stage number for that stage, or -1 if there is none.
+  */
+  @Override
+  public int getPipelineStagePrerequisite(int index)
+  {
+    return pipelineStages.get(index).getPrerequisiteStage();
+  }
+  
+  /** Check if a pipeline stage is an output connection.
+  *@param index is the index of the pipeline stage to check.
+  *@return true if it is an output connection.
+  */
+  @Override
+  public boolean getPipelineStageIsOutputConnection(int index)
+  {
+    return pipelineStages.get(index).getIsOutput();
+  }
+
   /** Get a specific pipeline connection name.
   *@param index is the index of the pipeline stage whose connection name to get.
   *@return the name of the connection.
@@ -329,7 +343,12 @@ public class JobDescription implements I
   @Override
   public void deletePipelineStage(int index)
   {
-    pipelineStages.remove(index);
+    PipelineStage ps = pipelineStages.remove(index);
+    int stage = index;
+    while (stage < pipelineStages.size())
+    {
+      pipelineStages.get(stage).adjustForDelete(index,ps.getPrerequisiteStage());
+    }
   }
 
   /** Set the job type.
@@ -511,15 +530,6 @@ public class JobDescription implements I
     return reseedInterval;
   }
 
-  /** Get the output specification.
-  *@return the output specification object.
-  */
-  @Override
-  public OutputSpecification getOutputSpecification()
-  {
-    return outputSpecification;
-  }
-
   /** Get the document specification.
   *@return the document specification object.
   */
@@ -636,29 +646,59 @@ public class JobDescription implements I
 
   protected static class PipelineStage
   {
+    protected int prerequisiteStage;
+    protected final boolean isOutput;
     protected final String connectionName;
     protected final String description;
     protected final OutputSpecification specification;
     
-    public PipelineStage(String connectionName, String description)
+    public PipelineStage(int prerequisiteStage, boolean isOutput, String connectionName, String description)
     {
+      this.prerequisiteStage = prerequisiteStage;
+      this.isOutput = isOutput;
       this.connectionName = connectionName;
       this.description = description;
       this.specification = new OutputSpecification();
     }
 
-    public PipelineStage(String connectionName, String description, OutputSpecification spec)
+    public PipelineStage(int prerequisiteStage, boolean isOutput, String connectionName, String description, OutputSpecification spec)
     {
+      this.prerequisiteStage = prerequisiteStage;
+      this.isOutput = isOutput;
       this.connectionName = connectionName;
       this.description = description;
       this.specification = spec;
     }
     
+    public void adjustForInsert(int index, boolean isOutput)
+    {
+      if (prerequisiteStage > index || (prerequisiteStage == index && !isOutput))
+        prerequisiteStage++;
+    }
+    
+    public void adjustForDelete(int index, int prerequisite)
+    {
+      if (prerequisiteStage > index)
+        prerequisiteStage--;
+      else if (prerequisiteStage == index)
+        prerequisiteStage = prerequisite;
+    }
+    
     public OutputSpecification getSpecification()
     {
       return specification;
     }
     
+    public int getPrerequisiteStage()
+    {
+      return prerequisiteStage;
+    }
+    
+    public boolean getIsOutput()
+    {
+      return isOutput;
+    }
+    
     public String getConnectionName()
     {
       return connectionName;



Mime
View raw message