PowerShell – Add XML keys to files inside JAR file

2015/03/18

Problem
We have a JAVA archive containing some XML files, which, from time to time, must be updated with new XML keys.
Solution
PowerShell !

We have the new keys to be added inside an XML file, as presented below
XML file with keys to be added
As you can see, we use CDATA sections to store new XML keys.
We also specify the file for which we do the adding, and the location inside the XML file, in a “XPath” way.

Then, we read the XML file like below

$fileContent = cat $xmlKeysFile
$xmlKeys = [xml]$fileContent

Then, we can use the following function
PowerShell - Add XML keys to JAR archive

For this case, I had the XML files inside the WEB-INF folder, class subfolder

We need the Jar.exe utility, which we use to list, extract and update the Java archive.

Because I’m lazy and/or I don’t have time to format the code, above is a screenshot for clarity, below is the code for whoever needs it.

function Add-XmlKeyInsideJarArchive([xml]$xmlKeys, [string]$archPath)
{
    $tempFolder = “some-temp-folder-at-your-choice”
    $JavaHome = (get-item env:JAVA_HOME).Value
    
    cd $tempFolder # We do all operations inside a temporary folder
    $list = & “$JavaHome\bin\jar.exe” tf $archPath WEB-INF/classes/ | findstr “WEB-INF/classes/[a-zA-Z]*\.xml”
    foreach ($jarFile in $list)
    {
        & “$JavaHome\bin\jar.exe” xvf $archPath $jarFile
    }
    $xmlFilesToModify = “$tempFolder\WEB-INF\classes”
    
    foreach ($file in $xmlKeys.files.file) # See XML structure for this line
    {
        $xmlFileName = $file.name
        Write-Host “XML file: $xmlFileName”
        Write-Host “————————————”
        if (-Not (Test-Path “$xmlFilesToModify\$xmlFileName”))
        {
            Write-Host “WARNING! The file $xmlFilesToModify\$xmlFileName was not found !”
            Write-Host “————————————”
            continue
        }
        $items = (cat “$xmlFilesToModify\$xmlFileName”)
        foreach ($key in $file.key)
        {
            $tabCount = ([regex]::matches(($key.location).Replace(“.”, “/”),”/”).count + 1)
            $tabs = “`t” * $tabCount # Add some pretty tabs inside the XML files for our key
            $elem = ($key.location).Substring(($key.location).LastIndexOf(“/”) + 1)
            $pattern = “(\t*)()” # We’ll add the new key under $elem node
            $items = $items -replace $pattern, (‘$1′ + “`t” + $key.’#cdata-section’ + “`n” + ‘$1’ + “”)
        }
        Set-Content “$xmlFilesToModify\$xmlFileName” $items
    }
    Write-Host “Updating archive with changes made …”
    & “$JavaHome\bin\jar.exe” uvf $archPath WEB-INF/classes/
    Remove-Item “$tempFolder\WEB-INF” -recurse -force -errorAction silentlyContinue
}

Note 1: Credits go to StackOverflow, IT blogs and alike, sites that helped me with the code when searching for solutions.
Note 2: Be aware that when copy-pasting, the quotes and possibly other characters get messed up by WordPress, you’ll have to replace them.

Advertisements

%d bloggers like this: