diff --git a/engine/src/main/java/org/apache/hop/pipeline/transform/TransformErrorMeta.java b/engine/src/main/java/org/apache/hop/pipeline/transform/TransformErrorMeta.java index ca06324bf2..ea0848614f 100644 --- a/engine/src/main/java/org/apache/hop/pipeline/transform/TransformErrorMeta.java +++ b/engine/src/main/java/org/apache/hop/pipeline/transform/TransformErrorMeta.java @@ -21,7 +21,9 @@ import lombok.Getter; import lombok.Setter; import org.apache.hop.core.changed.ChangedFlag; +import org.apache.hop.core.exception.HopException; import org.apache.hop.core.exception.HopRuntimeException; +import org.apache.hop.core.exception.HopXmlException; import org.apache.hop.core.row.IRowMeta; import org.apache.hop.core.row.IValueMeta; import org.apache.hop.core.row.RowMeta; @@ -31,6 +33,8 @@ import org.apache.hop.core.variables.IVariables; import org.apache.hop.core.xml.XmlHandler; import org.apache.hop.metadata.api.HopMetadataProperty; +import org.apache.hop.metadata.serializer.memory.MemoryMetadataProvider; +import org.apache.hop.metadata.serializer.xml.XmlMetadataUtil; import org.w3c.dom.Node; /** This class contains the metadata to handle proper error handling on a transform level. */ @@ -155,40 +159,25 @@ public TransformErrorMeta clone() { } } - public String getXml() { - return XmlHandler.openTag(TransformErrorMeta.XML_ERROR_TAG) - + XmlHandler.addTagValue( - TransformErrorMeta.XML_SOURCE_TRANSFORM_TAG, - sourceTransform != null ? sourceTransform.getName() : "") - + XmlHandler.addTagValue( - TransformErrorMeta.XML_TARGET_TRANSFORM_TAG, - targetTransform != null ? targetTransform.getName() : "") - + XmlHandler.addTagValue("is_enabled", enabled) - + XmlHandler.addTagValue("nr_valuename", nrErrorsValueName) - + XmlHandler.addTagValue("descriptions_valuename", errorDescriptionsValueName) - + XmlHandler.addTagValue("fields_valuename", errorFieldsValueName) - + XmlHandler.addTagValue("codes_valuename", errorCodesValueName) - + XmlHandler.addTagValue("max_errors", maxErrors) - + XmlHandler.addTagValue("max_pct_errors", maxPercentErrors) - + XmlHandler.addTagValue("min_pct_rows", minPercentRows) - + XmlHandler.closeTag(TransformErrorMeta.XML_ERROR_TAG); + public String getXml() throws HopException { + return XmlHandler.aroundTag(XML_ERROR_TAG, XmlMetadataUtil.serializeObjectToXml(this)); } - public TransformErrorMeta(Node node, List transforms) { - sourceTransform = - TransformMeta.findTransform( - transforms, XmlHandler.getTagValue(node, TransformErrorMeta.XML_SOURCE_TRANSFORM_TAG)); - targetTransform = - TransformMeta.findTransform( - transforms, XmlHandler.getTagValue(node, TransformErrorMeta.XML_TARGET_TRANSFORM_TAG)); - enabled = "Y".equals(XmlHandler.getTagValue(node, "is_enabled")); - nrErrorsValueName = XmlHandler.getTagValue(node, "nr_valuename"); - errorDescriptionsValueName = XmlHandler.getTagValue(node, "descriptions_valuename"); - errorFieldsValueName = XmlHandler.getTagValue(node, "fields_valuename"); - errorCodesValueName = XmlHandler.getTagValue(node, "codes_valuename"); - maxErrors = XmlHandler.getTagValue(node, "max_errors"); - maxPercentErrors = XmlHandler.getTagValue(node, "max_pct_errors"); - minPercentRows = XmlHandler.getTagValue(node, "min_pct_rows"); + @Getter + public static class Transforms { + private List transforms; + } + + public TransformErrorMeta(Node node, List transforms) throws HopXmlException { + // The deSerializeFromXml call searches for a List field called 'transforms' in the provided + // Object. + // Normally this is the transform metadata but here we wrap it a tiny class. + // + Transforms parentObject = new Transforms(); + parentObject.transforms = transforms; + + XmlMetadataUtil.deSerializeFromXml( + parentObject, null, node, TransformErrorMeta.class, this, new MemoryMetadataProvider()); } public IRowMeta getErrorRowMeta(IVariables variables) { diff --git a/engine/src/test/java/org/apache/hop/pipeline/ModPartitionerTest.java b/engine/src/test/java/org/apache/hop/pipeline/ModPartitionerTest.java index 0232daf382..5562f78fa9 100644 --- a/engine/src/test/java/org/apache/hop/pipeline/ModPartitionerTest.java +++ b/engine/src/test/java/org/apache/hop/pipeline/ModPartitionerTest.java @@ -21,9 +21,12 @@ import java.util.List; import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.xml.XmlHandler; import org.apache.hop.junit.rules.RestoreHopEngineEnvironmentExtension; +import org.apache.hop.metadata.serializer.xml.XmlMetadataUtil; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.w3c.dom.Node; @ExtendWith(RestoreHopEngineEnvironmentExtension.class) class ModPartitionerTest { @@ -37,4 +40,14 @@ void testSerialization() throws HopException { assertNotNull(tester); tester.testSerialization(); } + + @Test + void testSerializationRoundTrip() throws HopException { + ModPartitioner test = new ModPartitioner(); + test.setFieldName("field1"); + + String xml = XmlHandler.aroundTag("p", XmlMetadataUtil.serializeObjectToXml(test)); + + Node node = XmlHandler.loadXmlString(xml, "p"); + } } diff --git a/engine/src/test/java/org/apache/hop/pipeline/transform/TransformErrorMetaTest.java b/engine/src/test/java/org/apache/hop/pipeline/transform/TransformErrorMetaTest.java index 66d3bec890..6e2848f3cd 100644 --- a/engine/src/test/java/org/apache/hop/pipeline/transform/TransformErrorMetaTest.java +++ b/engine/src/test/java/org/apache/hop/pipeline/transform/TransformErrorMetaTest.java @@ -19,14 +19,30 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.ArrayList; +import java.util.List; +import org.apache.hop.core.annotations.Transform; +import org.apache.hop.core.plugins.PluginRegistry; +import org.apache.hop.core.plugins.TransformPluginType; import org.apache.hop.core.row.IRowMeta; import org.apache.hop.core.row.IValueMeta; import org.apache.hop.core.variables.IVariables; import org.apache.hop.core.variables.Variables; +import org.apache.hop.core.xml.XmlHandler; +import org.apache.hop.pipeline.transform.transforms.FakeMeta; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.w3c.dom.Node; class TransformErrorMetaTest { + @BeforeEach + void setUp() throws Exception { + PluginRegistry registry = PluginRegistry.getInstance(); + registry.registerPluginClass( + FakeMeta.class.getName(), TransformPluginType.class, Transform.class); + } @Test void testGetErrorRowMeta() { @@ -57,4 +73,38 @@ void testGetErrorRowMeta() { assertEquals(IValueMeta.TYPE_STRING, result.getValueMeta(3).getType()); assertEquals("errorCodes", result.getValueMeta(3).getName()); } + + @Test + void testSerialization() throws Exception { + List transforms = new ArrayList<>(); + TransformMeta t1 = new TransformMeta("t1", new FakeMeta()); + transforms.add(t1); + TransformMeta t2 = new TransformMeta("t1", new FakeMeta()); + transforms.add(t2); + + TransformErrorMeta meta = new TransformErrorMeta(); + meta.setSourceTransform(t1); + meta.setTargetTransform(t2); + meta.setEnabled(true); + meta.setMaxErrors("400"); + meta.setMinPercentRows("100"); + meta.setMaxPercentErrors("25"); + meta.setErrorFieldsValueName("errorFields"); + meta.setErrorCodesValueName("errorCodes"); + meta.setErrorDescriptionsValueName("errorDescriptions"); + + String xml = meta.getXml(); + Node node = XmlHandler.loadXmlString(xml, TransformErrorMeta.XML_ERROR_TAG); + TransformErrorMeta copy = new TransformErrorMeta(node, transforms); + + assertEquals(meta.getSourceTransform(), copy.getSourceTransform()); + assertEquals(meta.getTargetTransform(), copy.getTargetTransform()); + assertTrue(copy.isEnabled()); + assertEquals("400", copy.getMaxErrors()); + assertEquals("100", copy.getMinPercentRows()); + assertEquals("25", copy.getMaxPercentErrors()); + assertEquals("errorFields", copy.getErrorFieldsValueName()); + assertEquals("errorCodes", copy.getErrorCodesValueName()); + assertEquals("errorDescriptions", copy.getErrorDescriptionsValueName()); + } } diff --git a/plugins/misc/testing/src/main/java/org/apache/hop/testing/xp/LocationMouseDoubleClickExtensionPoint.java b/plugins/misc/testing/src/main/java/org/apache/hop/testing/xp/LocationMouseDoubleClickExtensionPoint.java index acff5b569a..e8ec3238ff 100644 --- a/plugins/misc/testing/src/main/java/org/apache/hop/testing/xp/LocationMouseDoubleClickExtensionPoint.java +++ b/plugins/misc/testing/src/main/java/org/apache/hop/testing/xp/LocationMouseDoubleClickExtensionPoint.java @@ -80,7 +80,7 @@ public void callExtensionPoint( } } - // Find the location that was double clicked on... + // Find the location that was double-clicked on... // MouseEvent e = pipelineGraphExtension.getEvent(); Point point = pipelineGraphExtension.getPoint(); @@ -91,8 +91,9 @@ public void callExtensionPoint( // Check if this is the flask... // if (DataSetConst.AREA_DRAWN_INPUT_DATA_SET.equals(areaOwner.getParent())) { + pipelineGraphExtension.setPreventingDefault(true); - // Open the dataset double clicked on... + // Open the dataset double-clicked on... // String transformName = (String) areaOwner.getOwner(); @@ -112,8 +113,9 @@ public void callExtensionPoint( } } } else if (DataSetConst.AREA_DRAWN_GOLDEN_DATA_SET.equals(areaOwner.getParent())) { + pipelineGraphExtension.setPreventingDefault(true); - // Open the dataset double clicked on... + // Open the dataset double-clicked on... // String transformName = (String) areaOwner.getOwner(); @@ -134,8 +136,9 @@ public void callExtensionPoint( } } } else if (DataSetConst.AREA_DRAWN_GOLDEN_DATA_RESULT.equals(areaOwner.getParent())) { + pipelineGraphExtension.setPreventingDefault(true); - // Open the dataset double clicked on... + // Open the dataset double-clicked on... // String transformName = (String) areaOwner.getOwner(); diff --git a/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/delegates/HopGuiPipelineClipboardDelegate.java b/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/delegates/HopGuiPipelineClipboardDelegate.java index 4aa20a69ec..062c8f5c8f 100644 --- a/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/delegates/HopGuiPipelineClipboardDelegate.java +++ b/ui/src/main/java/org/apache/hop/ui/hopgui/file/pipeline/delegates/HopGuiPipelineClipboardDelegate.java @@ -18,12 +18,15 @@ package org.apache.hop.ui.hopgui.file.pipeline.delegates; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; +import lombok.Getter; +import lombok.Setter; import org.apache.hop.base.BaseHopMeta; import org.apache.hop.core.Const; import org.apache.hop.core.NotePadMeta; import org.apache.hop.core.exception.HopException; +import org.apache.hop.core.exception.HopPluginLoaderException; +import org.apache.hop.core.exception.HopXmlException; import org.apache.hop.core.gui.Point; import org.apache.hop.core.logging.ILogChannel; import org.apache.hop.core.xml.XmlHandler; @@ -40,9 +43,12 @@ import org.apache.hop.ui.hopgui.HopGui; import org.apache.hop.ui.hopgui.file.pipeline.HopGuiPipelineGraph; import org.apache.hop.workflow.WorkflowMeta; +import org.jspecify.annotations.NonNull; import org.w3c.dom.Document; import org.w3c.dom.Node; +@Getter +@Setter public class HopGuiPipelineClipboardDelegate { private static final Class PKG = HopGui.class; @@ -51,18 +57,17 @@ public class HopGuiPipelineClipboardDelegate { private HopGui hopGui; private HopGuiPipelineGraph pipelineGraph; - private ILogChannel log; public HopGuiPipelineClipboardDelegate(HopGui hopGui, HopGuiPipelineGraph pipelineGraph) { this.hopGui = hopGui; this.pipelineGraph = pipelineGraph; - this.log = hopGui.getLog(); + ILogChannel log = hopGui.getLog(); } public void toClipboard(String clipText) { try { GuiResource.getInstance().toClipboard(clipText); - } catch (Throwable e) { + } catch (Exception e) { new ErrorDialog( hopGui.getActiveShell(), BaseMessages.getString(PKG, "HopGui.Dialog.ExceptionCopyToClipboard.Title"), @@ -74,7 +79,7 @@ public void toClipboard(String clipText) { public String fromClipboard() { try { return GuiResource.getInstance().fromClipboard(); - } catch (Throwable e) { + } catch (Exception e) { new ErrorDialog( hopGui.getActiveShell(), BaseMessages.getString(PKG, "HopGui.Dialog.ExceptionPasteFromClipboard.Title"), @@ -85,96 +90,45 @@ public String fromClipboard() { } public void pasteXml(PipelineMeta pipelineMeta, String clipboardContent, Point location) { - try { Document doc = XmlHandler.loadXmlString(clipboardContent); Node pipelineNode = XmlHandler.getSubNode(doc, XML_TAG_PIPELINE_TRANSFORMS); - // De-select all, re-select pasted transforms... + // Unselect all, reselect pasted transforms... pipelineMeta.unselectAll(); Node transformsNode = XmlHandler.getSubNode(pipelineNode, XML_TAG_TRANSFORMS); - int nr = XmlHandler.countNodes(transformsNode, TransformMeta.XML_TAG); - if (log.isDebug()) { - // "I found "+nr+" transforms to paste on location: " - log.logDebug(BaseMessages.getString(PKG, "HopGui.Log.FoundTransforms", "" + nr) + location); - } - TransformMeta[] transforms = new TransformMeta[nr]; - ArrayList transformOldNames = new ArrayList<>(nr); + List transformNodes = XmlHandler.getNodes(transformsNode, TransformMeta.XML_TAG); + ArrayList transformOldNames = new ArrayList<>(); Point min = new Point(99999999, 99999999); - // Load the transforms... - for (int i = 0; i < nr; i++) { - Node transformNode = XmlHandler.getSubNodeByNr(transformsNode, TransformMeta.XML_TAG, i); - transforms[i] = new TransformMeta(transformNode, hopGui.getMetadataProvider()); - - if (location != null) { - Point p = transforms[i].getLocation(); - - if (min.x > p.x) { - min.x = p.x; - } - if (min.y > p.y) { - min.y = p.y; - } - } - } - - // Load the notes... - Node notesNode = XmlHandler.getSubNode(pipelineNode, WorkflowMeta.XML_TAG_NOTEPADS); - nr = XmlHandler.countNodes(notesNode, NotePadMeta.XML_TAG); - if (log.isDebug()) { - log.logDebug(BaseMessages.getString(PKG, "HopGui.Log.FoundNotepads", "" + nr)); - } - NotePadMeta[] notes = new NotePadMeta[nr]; - for (int i = 0; i < nr; i++) { - Node noteNode = XmlHandler.getSubNodeByNr(notesNode, NotePadMeta.XML_TAG, i); - notes[i] = new NotePadMeta(noteNode); - - if (location != null) { - Point p = notes[i].getLocation(); - - if (min.x > p.x) { - min.x = p.x; - } - if (min.y > p.y) { - min.y = p.y; - } - } - } - - // Load the hops... - Node hopsNode = XmlHandler.getSubNode(pipelineNode, PipelineMeta.XML_TAG_ORDER); - nr = XmlHandler.countNodes(hopsNode, BaseHopMeta.XML_HOP_TAG); - if (log.isDebug()) { - // "I found "+nr+" hops to paste." - log.logDebug(BaseMessages.getString(PKG, "HopGui.Log.FoundHops", "" + nr)); - } - PipelineHopMeta[] hops = new PipelineHopMeta[nr]; - - for (int i = 0; i < nr; i++) { - Node hopNode = XmlHandler.getSubNodeByNr(hopsNode, BaseHopMeta.XML_HOP_TAG, i); - hops[i] = new PipelineHopMeta(hopNode, Arrays.asList(transforms)); - } + List transforms = deSerializeTransforms(location, transformNodes, min); + List notes = deSerializeNotes(location, pipelineNode, min); + List hops = deSerializePipelineHops(pipelineNode, transforms); // This is the offset: - Point offset = new Point(location.x - min.x, location.y - min.y); + Point offset; + if (location != null) { + offset = new Point(location.x - min.x, location.y - min.y); + } else { + offset = new Point(-min.x, -min.y); + } // Undo/redo object positions... - int[] position = new int[transforms.length]; + int[] position = new int[transforms.size()]; - for (int i = 0; i < transforms.length; i++) { - Point p = transforms[i].getLocation(); - String name = transforms[i].getName(); + for (int i = 0; i < transforms.size(); i++) { + Point p = transforms.get(i).getLocation(); + String name = transforms.get(i).getName(); - PropsUi.setLocation(transforms[i], p.x + offset.x, p.y + offset.y); + PropsUi.setLocation(transforms.get(i), p.x + offset.x, p.y + offset.y); // Check the name, find alternative... transformOldNames.add(name); - transforms[i].setName(pipelineMeta.getAlternativeTransformName(name)); - pipelineMeta.addTransform(transforms[i]); - position[i] = pipelineMeta.indexOfTransform(transforms[i]); - transforms[i].setSelected(true); + transforms.get(i).setName(pipelineMeta.getAlternativeTransformName(name)); + pipelineMeta.addTransform(transforms.get(i)); + position[i] = pipelineMeta.indexOfTransform(transforms.get(i)); + transforms.get(i).setSelected(true); } // Add the hops too... @@ -216,35 +170,35 @@ public void pasteXml(PipelineMeta pipelineMeta, String clipboardContent, Point l transformOldNames.indexOf(transformErrorMeta.getTargetTransform().getName()); } TransformMeta sourceTransform = - pipelineMeta.findTransform(transforms[srcTransformPos].getName()); + pipelineMeta.findTransform(transforms.get(srcTransformPos).getName()); if (sourceTransform != null) { sourceTransform.setTransformErrorMeta(transformErrorMeta); } - sourceTransform.setTransformErrorMeta(null); if (tgtTransformPos >= 0) { - sourceTransform.setTransformErrorMeta(transformErrorMeta); TransformMeta targetTransform = - pipelineMeta.findTransform(transforms[tgtTransformPos].getName()); + pipelineMeta.findTransform(transforms.get(tgtTransformPos).getName()); transformErrorMeta.setSourceTransform(sourceTransform); transformErrorMeta.setTargetTransform(targetTransform); } } // Save undo information too... - hopGui.undoDelegate.addUndoNew(pipelineMeta, transforms, position, false); + hopGui.undoDelegate.addUndoNew( + pipelineMeta, transforms.toArray(new TransformMeta[0]), position, false); - int[] hopPos = new int[hops.length]; - for (int i = 0; i < hops.length; i++) { - hopPos[i] = pipelineMeta.indexOfPipelineHop(hops[i]); + int[] hopPos = new int[hops.size()]; + for (int i = 0; i < hops.size(); i++) { + hopPos[i] = pipelineMeta.indexOfPipelineHop(hops.get(i)); } - hopGui.undoDelegate.addUndoNew(pipelineMeta, hops, hopPos, true); + hopGui.undoDelegate.addUndoNew( + pipelineMeta, hops.toArray(new PipelineHopMeta[0]), hopPos, true); - int[] notePos = new int[notes.length]; - for (int i = 0; i < notes.length; i++) { - notePos[i] = pipelineMeta.indexOfNote(notes[i]); + int[] notePos = new int[notes.size()]; + for (int i = 0; i < notes.size(); i++) { + notePos[i] = pipelineMeta.indexOfNote(notes.get(i)); } - hopGui.undoDelegate.addUndoNew(pipelineMeta, notes, notePos, true); - + hopGui.undoDelegate.addUndoNew( + pipelineMeta, notes.toArray(new NotePadMeta[0]), notePos, true); } catch (HopException e) { // See if this was different (non-XML) content // @@ -253,6 +207,61 @@ public void pasteXml(PipelineMeta pipelineMeta, String clipboardContent, Point l pipelineGraph.redraw(); } + private static @NonNull List deSerializePipelineHops( + Node pipelineNode, List transforms) throws HopXmlException { + Node hopsNode = XmlHandler.getSubNode(pipelineNode, PipelineMeta.XML_TAG_ORDER); + List hopNodes = XmlHandler.getNodes(hopsNode, BaseHopMeta.XML_HOP_TAG); + List hops = new ArrayList<>(); + + for (Node hopNode : hopNodes) { + hops.add(new PipelineHopMeta(hopNode, transforms)); + } + return hops; + } + + private static @NonNull List deSerializeNotes( + Point location, Node pipelineNode, Point min) throws HopXmlException { + Node notesNode = XmlHandler.getSubNode(pipelineNode, WorkflowMeta.XML_TAG_NOTEPADS); + List noteNodes = XmlHandler.getNodes(notesNode, NotePadMeta.XML_TAG); + + List notes = new ArrayList<>(); + for (Node noteNode : noteNodes) { + NotePadMeta note = new NotePadMeta(noteNode); + notes.add(note); + if (location != null) { + Point p = note.getLocation(); + if (min.x > p.x) { + min.x = p.x; + } + if (min.y > p.y) { + min.y = p.y; + } + } + } + return notes; + } + + private List deSerializeTransforms( + Point location, List transformNodes, Point min) + throws HopXmlException, HopPluginLoaderException { + List transforms = new ArrayList<>(); + for (Node transformNode : transformNodes) { + TransformMeta transform = new TransformMeta(transformNode, hopGui.getMetadataProvider()); + transforms.add(transform); + + if (location != null) { + Point p = transform.getLocation(); + if (min.x > p.x) { + min.x = p.x; + } + if (min.y > p.y) { + min.y = p.y; + } + } + } + return transforms; + } + private void pasteNoXmlContent( PipelineMeta pipelineMeta, String clipboardContent, Point location) { try { @@ -298,46 +307,10 @@ public void copySelected( StringBuilder xml = new StringBuilder(5000).append(XmlHandler.getXmlHeader()); try { xml.append(XmlHandler.openTag(XML_TAG_PIPELINE_TRANSFORMS)).append(Const.CR); - - xml.append(XmlHandler.openTag(XML_TAG_TRANSFORMS)).append(Const.CR); - for (TransformMeta transform : transforms) { - xml.append(transform.getXml()); - } - xml.append(XmlHandler.closeTag(XML_TAG_TRANSFORMS)).append(Const.CR); - - // Also check for the hops in between the selected transforms... - xml.append(XmlHandler.openTag(PipelineMeta.XML_TAG_ORDER)).append(Const.CR); - for (TransformMeta transform1 : transforms) { - for (TransformMeta transform2 : transforms) { - if (transform1 != transform2) { - PipelineHopMeta hop = pipelineMeta.findPipelineHop(transform1, transform2, true); - if (hop != null) { - // Ok, we found one... - xml.append(hop.getXml()).append(Const.CR); - } - } - } - } - xml.append(XmlHandler.closeTag(PipelineMeta.XML_TAG_ORDER)).append(Const.CR); - - xml.append(XmlHandler.openTag(PipelineMeta.XML_TAG_NOTEPADS)).append(Const.CR); - if (notes != null) { - for (NotePadMeta note : notes) { - xml.append(note.getXml()); - } - } - xml.append(XmlHandler.closeTag(PipelineMeta.XML_TAG_NOTEPADS)).append(Const.CR); - - xml.append(XmlHandler.openTag(PipelineMeta.XML_TAG_TRANSFORM_ERROR_HANDLING)) - .append(Const.CR); - for (TransformMeta transform : transforms) { - if (transform.getTransformErrorMeta() != null) { - xml.append(transform.getTransformErrorMeta().getXml()).append(Const.CR); - } - } - xml.append(XmlHandler.closeTag(PipelineMeta.XML_TAG_TRANSFORM_ERROR_HANDLING)) - .append(Const.CR); - + serializeTransformsToXml(transforms, xml); + serializePipelineHopsToXml(pipelineMeta, transforms, xml); + serializeNotesToXml(notes, xml); + serializeTransformErrorHandlingToXml(transforms, xml); xml.append(XmlHandler.closeTag(XML_TAG_PIPELINE_TRANSFORMS)).append(Const.CR); toClipboard(xml.toString()); @@ -346,35 +319,51 @@ public void copySelected( } } - /** - * Gets hopGui - * - * @return value of hopGui - */ - public HopGui getHopGui() { - return hopGui; + private static void serializeTransformErrorHandlingToXml( + List transforms, StringBuilder xml) throws HopException { + xml.append(XmlHandler.openTag(PipelineMeta.XML_TAG_TRANSFORM_ERROR_HANDLING)).append(Const.CR); + for (TransformMeta transform : transforms) { + if (transform.getTransformErrorMeta() != null) { + xml.append(transform.getTransformErrorMeta().getXml()).append(Const.CR); + } + } + xml.append(XmlHandler.closeTag(PipelineMeta.XML_TAG_TRANSFORM_ERROR_HANDLING)).append(Const.CR); } - /** - * @param hopGui The hopGui to set - */ - public void setHopGui(HopGui hopGui) { - this.hopGui = hopGui; + private static void serializeNotesToXml(List notes, StringBuilder xml) { + xml.append(XmlHandler.openTag(PipelineMeta.XML_TAG_NOTEPADS)).append(Const.CR); + if (notes != null) { + for (NotePadMeta note : notes) { + xml.append(note.getXml()); + } + } + xml.append(XmlHandler.closeTag(PipelineMeta.XML_TAG_NOTEPADS)).append(Const.CR); } - /** - * Gets pipelineGraph - * - * @return value of pipelineGraph - */ - public HopGuiPipelineGraph getPipelineGraph() { - return pipelineGraph; + private static void serializePipelineHopsToXml( + PipelineMeta pipelineMeta, List transforms, StringBuilder xml) + throws HopException { + xml.append(XmlHandler.openTag(PipelineMeta.XML_TAG_ORDER)).append(Const.CR); + for (TransformMeta transform1 : transforms) { + for (TransformMeta transform2 : transforms) { + if (transform1 != transform2) { + PipelineHopMeta hop = pipelineMeta.findPipelineHop(transform1, transform2, true); + if (hop != null) { + // Ok, we found one... + xml.append(hop.getXml()).append(Const.CR); + } + } + } + } + xml.append(XmlHandler.closeTag(PipelineMeta.XML_TAG_ORDER)).append(Const.CR); } - /** - * @param pipelineGraph The pipelineGraph to set - */ - public void setPipelineGraph(HopGuiPipelineGraph pipelineGraph) { - this.pipelineGraph = pipelineGraph; + private static void serializeTransformsToXml(List transforms, StringBuilder xml) + throws HopException { + xml.append(XmlHandler.openTag(XML_TAG_TRANSFORMS)).append(Const.CR); + for (TransformMeta transform : transforms) { + xml.append(transform.getXml()); + } + xml.append(XmlHandler.closeTag(XML_TAG_TRANSFORMS)).append(Const.CR); } }