-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
fa37227
commit d195546
Showing
39 changed files
with
1,027 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
75 changes: 75 additions & 0 deletions
75
cli/src/main/java/com/devonfw/tools/ide/merge/xmlmerger/matcher/ElementMatcher.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package com.devonfw.tools.ide.merge.xmlmerger.matcher; | ||
|
||
import com.devonfw.tools.ide.merge.xmlmerger.model.MergeElement; | ||
import org.w3c.dom.Document; | ||
import org.w3c.dom.Element; | ||
|
||
import javax.xml.namespace.QName; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
/** | ||
* The ElementMatcher class is responsible for matching XML elements in a target document based on the provided update elements. | ||
*/ | ||
public class ElementMatcher { | ||
|
||
private final Map<QName, IdComputer> qNameIdMap; | ||
|
||
public ElementMatcher() { | ||
|
||
qNameIdMap = new HashMap<>(); | ||
} | ||
|
||
/** | ||
* Updates the ID strategy for a given QName (qualified name) of an XML element. | ||
* | ||
* @param qname the QName of the XML element | ||
* @param id the ID value to be used for matching the element | ||
*/ | ||
public void updateId(QName qname, String id) { | ||
|
||
qNameIdMap.put(qname, new IdComputer(id)); | ||
} | ||
|
||
/** | ||
* Matches an update element in the target document. | ||
* | ||
* @param updateElement the update element to be matched | ||
* @param targetDocument the target document in which to match the element | ||
* @return the matched MergeElement if found, or {@code null} if not found | ||
*/ | ||
public MergeElement matchElement(MergeElement updateElement, Document targetDocument) { | ||
|
||
if (updateElement.isRootElement()) { | ||
Element sourceRoot = updateElement.getElement(); | ||
Element targetRoot = targetDocument.getDocumentElement(); | ||
if (sourceRoot.getNamespaceURI() != null || targetRoot.getNamespaceURI() != null) { | ||
if (!sourceRoot.getNamespaceURI().equals(targetRoot.getNamespaceURI())) { | ||
throw new IllegalStateException("URI of elements don't match. Found " + sourceRoot.getNamespaceURI() + "and " + targetRoot.getNamespaceURI()); | ||
} | ||
} | ||
return new MergeElement(targetRoot); | ||
} | ||
|
||
String id = updateElement.getId(); | ||
if (id.isEmpty()) { | ||
IdComputer idComputer = qNameIdMap.get(updateElement.getQName()); | ||
if (idComputer == null) { | ||
throw new IllegalStateException("no Id value was defined for " + updateElement.getXPath()); | ||
} | ||
Element matchedNode = idComputer.evaluateExpression(updateElement, targetDocument); | ||
if (matchedNode != null) { | ||
return new MergeElement(matchedNode); | ||
} | ||
} else { | ||
updateId(updateElement.getQName(), id); | ||
IdComputer idComputer = qNameIdMap.get(updateElement.getQName()); | ||
Element matchedNode = idComputer.evaluateExpression(updateElement, targetDocument); | ||
if (matchedNode != null) { | ||
return new MergeElement(matchedNode); | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
} |
74 changes: 74 additions & 0 deletions
74
cli/src/main/java/com/devonfw/tools/ide/merge/xmlmerger/matcher/IdComputer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package com.devonfw.tools.ide.merge.xmlmerger.matcher; | ||
|
||
import com.devonfw.tools.ide.merge.xmlmerger.model.MergeElement; | ||
import org.w3c.dom.Document; | ||
import org.w3c.dom.Element; | ||
|
||
import javax.xml.xpath.XPath; | ||
import javax.xml.xpath.XPathConstants; | ||
import javax.xml.xpath.XPathExpression; | ||
import javax.xml.xpath.XPathExpressionException; | ||
import javax.xml.xpath.XPathFactory; | ||
|
||
/** | ||
* The IdComputer class is responsible for building XPath expressions and evaluating those expressions to match elements in a target document. | ||
*/ | ||
public class IdComputer { | ||
|
||
private final String id; | ||
|
||
private static XPathFactory xPathFactory = XPathFactory.newInstance(); | ||
|
||
public IdComputer(String id) { | ||
|
||
this.id = id; | ||
} | ||
|
||
/** | ||
* Evaluates the XPath expression for the given merge element in the target document. | ||
* | ||
* @param mergeElement the merge element for which to build the XPath expression | ||
* @param targetDocument the target document in which to evaluate the XPath expression | ||
* @return the matched Element if found, or null if not found | ||
*/ | ||
|
||
public Element evaluateExpression(MergeElement mergeElement, Document targetDocument) { | ||
|
||
try { | ||
XPath xpath = xPathFactory.newXPath(); | ||
String xpathExpr = buildXPathExpression(mergeElement); | ||
XPathExpression xpathExpression = xpath.compile(xpathExpr); | ||
return (Element) xpathExpression.evaluate(targetDocument, XPathConstants.NODE); | ||
} catch (XPathExpressionException e) { | ||
throw new IllegalStateException("Failed to match " + mergeElement.getXPath(), e); | ||
} | ||
} | ||
|
||
/** | ||
* Builds the XPath expression for the given merge element based on the ID value. | ||
* | ||
* @param mergeElement the merge element for which to build the XPath expression | ||
* @return the XPath expression as a String | ||
*/ | ||
private String buildXPathExpression(MergeElement mergeElement) { | ||
|
||
String xPath = mergeElement.getXPath(); | ||
if (id.startsWith(".")) { | ||
return xPath + "/" + id; | ||
} else if (id.startsWith("/")) { | ||
return id; | ||
} else if (id.startsWith("@")) { | ||
String attributeName = id.substring(1); | ||
String attributeValue = mergeElement.getElement().getAttribute(attributeName); | ||
return xPath + String.format("[@%s='%s']", attributeName, attributeValue); | ||
} else if (id.equals("name()")) { | ||
String tagName = mergeElement.getElement().getTagName(); | ||
return xPath + String.format("[name()='%s']", tagName); | ||
} else if (id.equals("text()")) { | ||
String textContent = mergeElement.getElement().getTextContent(); | ||
return xPath + String.format("[text()='%s']", textContent); | ||
} | ||
return null; | ||
} | ||
|
||
} |
Oops, something went wrong.