Question
I need help with decoding a base 64 string and saving it to a pdf/doc in local directory using groovy
This script should work in SOAP UI
The base64 string is 52854 characters long
I have tried the following
File f = new File("c:\\document1.doc")
FileOutputStream out = null
byte[] b1 = Base64.decodeBase64(base64doccontent);
out = new FileOutputStream(f)
try {
out.write(b1)
} finally {
out.close()
}
But - it gives me below error
No signature of method: static org.apache.commons.codec.binary.Base64.decodeBase64() is applicable for argument types: (java.lang.String) values: [base64stringlong] Possible solutions: decodeBase64([B), encodeBase64([B), encodeBase64([B, boolean)
Assuming the base64 encoded text is coming from a file, a minimal example for soapUI would be:
import com.itextpdf.text.*
import com.itextpdf.text.pdf.PdfWriter;
String encodedContents = new File('/path/to/file/base64Encoded.txt')
.getText('UTF-8')
byte[] b1 = encodedContents.decodeBase64();
// Save as a text file
new File('/path/to/file/base64Decoded.txt').withOutputStream {
it.write b1
}
// Or, save as a PDF
def document = new Document()
PdfWriter.getInstance(document,
new FileOutputStream('/path/to/file/base64Decoded.pdf'))
document.open()
document.add(new Paragraph(new String(b1)))
document.close()
The File.withOutputStream method will ensure the stream is closed when the closure returns.
Or, to convert the byte array to a PDF, I used iText. I dropped itextpdf-5.5.13.jar in soapUI's bin/ext directory and restarted and then it was available for Groovy.
I have series of xml files placed in 2 separate folders as below. My objective is to read each file one at a time from both folders and apply xmlunit comaprison methods.
Folder1 : actual1.xml
actual2.xml
actual3.xml
Folder2 : compare1.xml
compare2.xml
compare3.xml
Part1: Am reading each file at a time from both folders by using below script. I welcome suggestions if there are more simpler methods to do this
log.info "**********Read files from Folder1************"
def xml_file1 = []
new File("D:\\GroovyTest\\Folder1").eachFile{ f ->
f (f.isFile()&& f.name.contains('.xml'))
{
def filename = f.name[0..-1]
xml_file1.add(filename)
log.info filename
}
}
if (xml_file1.size() <1)
{
testRunner.fail("No request files found")
}
log.info "**********Read files from Folder2************"
def xml_file2 = []
new File("D:\\GroovyTest\\Folder2").eachFile{ f ->
if (f.isFile()&& f.name.contains('.xml'))
{
def filename = f.name[0..-1]
xml_file2.add(filename)
log.info filename
}
}
if (xml_file2.size() <1)
{
testRunner.fail("No request files found")
}
Part2: Script to perform comparison for each combination of xml files contained in array xml_file1 and xml_file2.
Am actually stuck at this part as the below script works for single files if each xml file is kept in a string, but i have to pass an array as arguments since i have series of xml files to be compared. I get a run time error - groovy.lang.GroovyRuntimeException: Could not find matching constructor for: java.io.FileInputStream(java.util.ArrayList) error at line: 60
InputStream xml_stream1 = new FileInputStream(xml_file1)
String xml1 = getStringFromInputStream(xml_stream1)
InputStream xml_stream2 = new FileInputStream(xml_file2)
String xml2 = getStringFromInputStream(xml_stream2)
def factory = TransformerFactory.newInstance()
def transformer = factory.newTransformer(new StreamSource(new StringReader(xslt)))
StreamResult result_xml1 = new StreamResult(new StringWriter());
transformer.transform(new StreamSource(new StringReader(xml1)), result_xml1)
xml1 = result_xml1.getWriter().toString()
StreamResult result_xml2 = new StreamResult(newStringWriter());
transformer.transform(new StreamSource(new StringReader(xml2)), result_xml2)
xml2 = result_xml2.getWriter().toString()
XMLUnit.setIgnoreComments(true)
DifferenceListener differenceListener = newIgnoreTextAndAttributeValuesDifferenceListener();
DetailedDiff myDiff = new DetailedDiff(new Diff(xml1, xml2));
myDiff.overrideDifferenceListener(differenceListener);
myDiff.overrideElementQualifier(new RecursiveElementNameAndTextQualifier());
log.info "similar ? " + myDiff.similar()
log.info "identical ? " + myDiff.identical()
List allDifferences = myDiff.getAllDifferences();
for (Object object : allDifferences) {
Difference difference = (Difference)object;
log.info(difference);
}
Could someone also help me with methods to ignore empty tags during comparison?
Thanks
Hello I am using groovy 2.1.5 and I have to write a code which show the contens/files of a directory with a given path then it makes a backup of the file and replace a word/string from the file.
here is the code I have used to try to replace a word in the file selected
String contents = new File( '/geretd/resume.txt' ).getText( 'UTF-8' )
contents = contents.replaceAll( 'visa', 'viva' )
also here is my complete code if anyone would like to modify it in a more efficient way, I will appreciate it since I am learning.
def dir = new File('/geretd')
dir.eachFile {
if (it.isFile()) {
println it.canonicalPath
}
}
copy = { File src,File dest->
def input = src.newDataInputStream()
def output = dest.newDataOutputStream()
output << input
input.close()
output.close()
}
//File srcFile = new File(args[0])
//File destFile = new File(args[1])
File srcFile = new File('/geretd/resume.txt')
File destFile = new File('/geretd/resumebak.txt')
copy(srcFile,destFile)
x = " "
println x
def dire = new File('/geretd')
dir.eachFile {
if (it.isFile()) {
println it.canonicalPath
}
}
String contents = new File( '/geretd/resume.txt' ).getText( 'UTF-8' )
contents = contents.replaceAll( 'visa', 'viva' )
As with nearly everything Groovy, AntBuilder is the easiest route:
ant.replace(file: "myFile", token: "NEEDLE", value: "replacement")
As an alternative to loading the whole file into memory, you could do each line in turn
new File( 'destination.txt' ).withWriter { w ->
new File( 'source.txt' ).eachLine { line ->
w << line.replaceAll( 'World', 'World!!!' ) + System.getProperty("line.separator")
}
}
Of course this (and dmahapatro's answer) rely on the words you are replacing not spanning across lines
I use this code to replace port 8080 to ${port.http} directly in certain file:
def file = new File('deploy/tomcat/conf/server.xml')
def newConfig = file.text.replace('8080', '${port.http}')
file.text = newConfig
The first string reads a line of the file into variable. The second string performs a replace. The third string writes a variable into file.
Answers that use "File" objects are good and quick, but usually cause following error that of course can be avoided but at the cost of loosen security:
Scripts not permitted to use new java.io.File java.lang.String.
Administrators can decide whether to approve or reject this signature.
This solution avoids all problems presented above:
String filenew = readFile('dir/myfile.yml').replaceAll('xxx','YYY')
writeFile file:'dir/myfile2.yml', text: filenew
Refer this answer where patterns are replaced. The same principle can be used to replace strings.
Sample
def copyAndReplaceText(source, dest, Closure replaceText){
dest.write(replaceText(source.text))
}
def source = new File('source.txt') //Hello World
def dest = new File('dest.txt') //blank
copyAndReplaceText(source, dest) {
it.replaceAll('World', 'World!!!!!')
}
assert 'Hello World' == source.text
assert 'Hello World!!!!!' == dest.text
other simple solution would be following closure:
def replace = { File source, String toSearch, String replacement ->
source.write(source.text.replaceAll(toSearch, replacement))
}
My code is not working and not giving any exception:
OutputConnection con = (OutputConnection) Connector.open("file:///epsd/rescuer.txt", Connector.WRITE);
System.out.println("below con");
OutputStream out = con.openOutputStream();
PrintStream ps = new PrintStream(out);
System.out.println("below ps");
ps.println(name+"!"+no+"!"+"!"+mtype+"!#!");
System.out.println("below println");
ps.close();
con.close();
Control doesn't reach after OutputConnection line. Is this how to append data to a text file in J2ME?
Use the following to get the SDCard path and concat it with your file name
String memoryCardPath = System.getProperty("fileconn.dir.memorycard");
String filePath = memoryCardPath + "/rescuer.txt";
OutputConnection con = (OutputConnection) Connector.open(filePath, Connector.WRITE);
I have a string with length no more than 4000 chars which is a valid xml. Is there a way to pass it to Dataset without creating a temporary xml file?
At the moment I do so:
string validXml = TextBox1.Text;
string path = Directory.GetCurrentDirectory() + #"\tmp.xml";
FileInfo xmlProcess = new FileInfo(path);
using (StreamWriter sw = xmlProcess.CreateText())
{
sw.WriteLine(validXml);
}
DataSet aDataSet = new DataSet();
aDataSet.ReadXml(reader);
Is there a way to skip this creating and filling the tmp.xml?
Try this:
XmlTextReader reader = new XmlTextReader(new StringReader(validXml));
DataSet aDataSet = new DataSet();
aDataSet.ReadXml(reader);