Skip to content

Commit

Permalink
SAK-50943 Web Content cc+ export not keeping the "open in new window"…
Browse files Browse the repository at this point in the history
… option (#13280)
  • Loading branch information
csev authored Feb 6, 2025
1 parent 4558c7c commit 0b9375e
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,12 @@ public String merge(String fileName, String siteId, String creatorId, String m_s
Map<Long, Map<String, Object>> ltiContentItems = new HashMap();

// The archive.xml is really a debug log, not actual archive data - it does not participate in any merge
// the web.xml is now merged in the site merger
for (int i = 0; i < files.length; i++)
{
if ((files[i] != null) && (files[i].getPath().indexOf("archive.xml") != -1))
if (files[i] != null && (files[i].getPath().contains("archive.xml") || files[i].getPath().contains("web.xml")))
{
files[i] = null;
break;
}
}

Expand Down
62 changes: 62 additions & 0 deletions kernel/api/src/main/java/org/sakaiproject/util/Xml.java
Original file line number Diff line number Diff line change
Expand Up @@ -508,4 +508,66 @@ public static void xmlToProperties(Properties properties, Element el)
}
}
}

/**
* Convert a Node and its children to a readable string representation
* @param node The node to convert
* @return A formatted string showing the node structure
*/
public static String nodeToString(Node node) {
StringBuilder sb = new StringBuilder();
appendNodeDetails(node, "", sb);
return sb.toString();
}

private static void appendNodeDetails(Node node, String indent, StringBuilder sb) {
sb.append(indent)
.append("Node Type: ")
.append(getNodeTypeName(node.getNodeType()))
.append(", Name: ")
.append(node.getNodeName());

// Handle attributes if it's an element
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element elem = (Element) node;
var attributes = elem.getAttributes();
if (attributes.getLength() > 0) {
sb.append("\n").append(indent).append("Attributes: ");
for (int i = 0; i < attributes.getLength(); i++) {
Node attr = attributes.item(i);
sb.append("\n").append(indent).append(" ")
.append(attr.getNodeName())
.append("=\"")
.append(attr.getNodeValue())
.append("\"");
}
}
}

// Handle node value if it exists and isn't just whitespace
if (node.getNodeValue() != null && !node.getNodeValue().trim().isEmpty()) {
sb.append("\n").append(indent).append("Value: \"")
.append(node.getNodeValue().trim())
.append("\"");
}

sb.append("\n");

// Recursively process child nodes
NodeList children = node.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
appendNodeDetails(children.item(i), indent + " ", sb);
}
}

private static String getNodeTypeName(short nodeType) {
switch (nodeType) {
case Node.ELEMENT_NODE: return "Element";
case Node.ATTRIBUTE_NODE: return "Attribute";
case Node.TEXT_NODE: return "Text";
case Node.CDATA_SECTION_NODE: return "CDATA";
case Node.COMMENT_NODE: return "Comment";
default: return "Other(" + nodeType + ")";
}
}
}
130 changes: 130 additions & 0 deletions kernel/api/src/test/java/org/sakaiproject/util/XmlTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package org.sakaiproject.util;

import static org.junit.Assert.*;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
import java.util.Stack;

import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class XmlTest {

private static final String TEST_XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<root>\n" +
" <child attribute=\"value\">content</child>\n" +
"</root>";

private File tempFile;

@Before
public void setUp() throws IOException {
// Create a temporary file for testing
tempFile = File.createTempFile("xml-test", ".xml");
try (FileWriter writer = new FileWriter(tempFile)) {
writer.write(TEST_XML);
}
}

@Test
public void testCreateDocument() {
Document doc = Xml.createDocument();
assertNotNull("Document should be created", doc);
}

@Test
public void testReadDocument() {
Document doc = Xml.readDocument(tempFile.getPath());
assertNotNull("Document should be read from file", doc);
assertEquals("root", doc.getDocumentElement().getTagName());
}

@Test
public void testReadDocumentFromString() {
Document doc = Xml.readDocumentFromString(TEST_XML);
assertNotNull("Document should be read from string", doc);
assertEquals("root", doc.getDocumentElement().getTagName());
}

@Test
public void testProcessString() throws SAXException, IOException {
final StringBuilder result = new StringBuilder();
DefaultHandler handler = new DefaultHandler() {
@Override
public void characters(char[] ch, int start, int length) {
result.append(ch, start, length);
}
};

Xml.processString(TEST_XML, handler);
assertTrue("Content should be processed", result.toString().contains("content"));
}

@Test
public void testReadDocumentFromStream() {
ByteArrayInputStream stream = new ByteArrayInputStream(
TEST_XML.getBytes(StandardCharsets.UTF_8));
Document doc = Xml.readDocumentFromStream(stream);
assertNotNull("Document should be read from stream", doc);
assertEquals("root", doc.getDocumentElement().getTagName());
}

@Test
public void testWriteDocumentToString() {
Document doc = Xml.readDocumentFromString(TEST_XML);
String result = Xml.writeDocumentToString(doc);
assertNotNull("Document should be written to string", result);
assertTrue("Output should contain XML content", result.contains("<root>"));
}

@Test
public void testEncodeDecodeAttribute() {
Document doc = Xml.createDocument();
Element element = doc.createElement("test");
String originalValue = "Test Value with special chars: &<>";

Xml.encodeAttribute(element, "testAttr", originalValue);
String decodedValue = Xml.decodeAttribute(element, "testAttr");

assertEquals("Value should be preserved after encode/decode",
originalValue, decodedValue);
}

@Test
public void testPropertiesXmlConversion() {
Properties original = new Properties();
original.setProperty("key1", "value1");
original.setProperty("key2", "value2");

Document doc = Xml.createDocument();
Element root = doc.createElement("root");
doc.appendChild(root);

Properties result = new Properties();
Element propsElement = Xml.propertiesToXml(original, doc, new Stack<Element>() {{ push(root); }});
Xml.xmlToProperties(result, propsElement);

assertEquals("Properties should match after conversion",
original.getProperty("key1"), result.getProperty("key1"));
assertEquals("Properties should match after conversion",
original.getProperty("key2"), result.getProperty("key2"));
}

@Test
public void testNodeToString() {
Document doc = Xml.readDocumentFromString(TEST_XML);
String result = Xml.nodeToString(doc.getDocumentElement());
assertNotNull("Node string representation should not be null", result);
assertTrue("Should contain node type", result.contains("Node Type: Element"));
assertTrue("Should contain node name", result.contains("Name: root"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,10 @@ public String getLabel()
return "web";
}

// As of SAK-50943, this is not used as the import from site.xml captures the page, tool, and tool properties
// In a sense, looking at the code - this is reading the Site data structures and doing a bad job of it
// We will still put web.xml into exports in case thye are valuable in some use case - but import
// will skip web.xml (see org.sakaiproject.archive.impl.SiteMerger.java)
@Override
public String merge(String siteId, Element root, String archivePath, String fromSiteId, Map attachmentNames, Map userIdTrans, Set userListAllowImport)
{
Expand Down

0 comments on commit 0b9375e

Please sign in to comment.