How to load drool file from in-memory? - drools

I have generated the alerts using the drools , i had created the drool files from database.Every time i am loading the .drl file from resource folder in the project because of this one i am doing lot of io operation.
I want overcome from this problem , any way is there to load drool file from in-memory same as cashing?

That's Drools 5? Time to upgrade. But you just use the same steps as I've provided them using code for Drools 6; the class names have changed somewhat. You do this once:
KieBase kieBase = ...;
FileOutputStream fos1 = new FileOutputStream( OUTPATH );
ObjectOutputStream oos1 = new ObjectOutputStream( fos1 );
oos1.writeObject( kieBase );
oos1.close();
You do this for each run:
FileInputStream fis9 = new FileInputStream( OUTPATH );
ObjectInputStream ois9 = new ObjectInputStream( fis9 );
KieBase kieBase1 = (KieBase)ois9.readObject();
KieSession kieSession = kieBase1.newKieSession();

Related

Drools : How to remove dynamically created drl?

I am working on a use case where I need to dynamically add/update/remove drls.
Here I am generating drl string using Rule Templates(with the data from a database) and adding it with the below code.
KieServices ks = KieServices.Factory.get();
KieRepository kr = ks.getRepository();
KieFileSystem kfs = ks.newKieFileSystem();
kfs.write("src/main/resources/" + ruleName + ".drl", drl);
KieBuilder kb = ks.newKieBuilder(kfs);
kb.buildAll();
if (kb.getResults().hasMessages(Message.Level.ERROR)) {
System.out.println(kb.getResults().toString());
}
KieContainer kContainer = ks.newKieContainer(kr.getDefaultReleaseId());
Which API I should use for removing these drls?
The KieFileSystem has a delete method that is likely what you need. The write method, which you are already uses, "writes" a DRL file to the file system. The delete method deletes that DRL file. You'll need to specify the file path when you call the method, so it'll be necessary to keep track of those, especially if you have multiple.
Note that the method takes a vararg so you can pass multple files.
KieServices ks = KieServices.Factory.get();
KieRepository kr = ks.getRepository();
KieFileSystem kfs = ks.newKieFileSystem();
// Write the file:
kfs.write("src/main/resources/" + ruleName + ".drl", drl);
// Delete the file:
kfs.delete("src/main/resources/" + ruleName + ".drl");
Source: KieFileSystem javadoc

Read Forms from BAR file - Flowable in code -

I need an example of usign FormEngine. To be more especific....
I'm executing code below - but there’s no forms found in my BAR file :(
The BAR file was exported from Flowable Modeler and it contains one form and one process and app. Maybe there's other way to deploy and obtain forms...?
RepositoryService repositoryService = processEngine.getRepositoryService();
FormRepositoryService formRepositoryService = formEngine.getFormRepositoryService();
File file = new File(path);
ZipInputStream inputStream = new ZipInputStream(new FileInputStream(path));
String idDeployParent = repositoryService.createDeployment()
.name(file.getName())
.addZipInputStream(inputStream)
.deploy()
.getId();
DeploymentEntity deploymentEntity = (DeploymentEntity) repositoryService.createDeploymentQuery().list().get(0);
formRepositoryService.createDeployment()
.name(file.getName())
.parentDeploymentId(idDeployParent)
.deploy();
System.out.println(" FORMS FOUND: " + formRepositoryService.createFormDefinitionQuery().list().size());

Multiple Jasper reports - Single request

I have a requirement,where I can select multiple records,and choose the action to generate zipped report with document each(pdf in my case) for each of the selected entries.
For example Employee1,Employee2,Employee3 would be selected,and when I choose to generate report,3 reports should be generated one each for the employee,and the output has to be zipped and downloaded.
For now what I do is generate the jasperPrint and export the report to ZipOutputstream with a new zipentry for each of the employee.
This means running the queries thrice and adding the outputstream to zip.
Is there a better way of doing it?
Your solution is normally the correct way, the alternatives are if you need to avoid multiple queries.
Load all you data in to a List<Employee> pass a new JRBeanCollectionDataSource(List<Employee>) for each Employee. (This decrease queries but increase memory usage).
If you have control of the pages (example 1 employee per page), you can generate 1 pdf with all employees and then use itext to split it in multiple pdf.
PdfReader reader = new PdfReader("nameOfReport.pdf");
int n = reader.getNumberOfPages();
int i = 0;
while ( i < n ) {
Document document = new Document(reader.getPageSizeWithRotation(1));
PdfCopy writer = new PdfCopy(document, new FileOutputStream("Employee_" + i + ".pdf"));
document.open();
PdfImportedPage page = writer.getImportedPage(reader, ++i);
writer.addPage(page);
document.close();
writer.close();
}

How to read a directory with using InputStream in eclipse plugin developement

I'm developing an eclipse plug-in and I need to traverse a directory and whole content of the directory. I found the method which reads a file in plug-in (bundleresource) as InputStream.
InputStream stream = Activator.class.getResourceAsStream("/dir1/dir2/file.ext");
this method works for files only. I need a way to read directories, list subdirectories and files like File.io.
Thanks.
Do you want to read a resource directory of your plugin? Otherwise you have to traverse a directory and open one stream per file:
String path = "c:\\temp\\";
File directory = new File(path);
if (directory.isDirectory()) {
String[] list = directory.list();
for (String entry : list) {
String absolutePath = path + entry;
System.out.println("processing " + absolutePath);
File file = new File(absolutePath);
if (file.isFile()) {
FileInputStream stream = new FileInputStream(file);
// use stream
stream.close();
}
}
}
If you want to traverse subdirectories as well you should wrap this into a recursive method, check if file is a directory and call the recursive method in this case.

Sending an email attachment in memory using OpenXML

I've got an Excel file that's built using OpenXML 2 and I want to send it as an email attachment. e.g.
System.IO.MemoryStream stream = new System.IO.MemoryStream();
SpreadsheetDocument package = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook))
AddParts(package); //created using document reflector
Saving the spreadsheet to a temp file using
stream.WriteTo(new System.IO.FileStream(#"c:\test.xlsx", System.IO.FileMode.Create));
works fine. But trying to send the stream directly as an email attachment fails - just get an empty file attached to the email when I do
System.Net.Mail.Attachment file = new System.Net.Mail.Attachment(stream, "MobileBill.xlsx", "application/vnd.ms-excel");
Anbody know how to do this?
Ok, I got this working, though through some effort. To create the stream:
MemoryStream stream = new MemoryStream();
using (SpreadsheetDocument package = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook))
{
Excel.CreateSpreadsheet(package, Excel_Methods.CreateSpotQuoteOut(), true);
}
stream.Seek(0, SeekOrigin.Begin);
System.Net.Mail.Attachment attach = new System.Net.Mail.Attachment(stream, "spreadsheet.xlsx");
attach.ContentDisposition.CreationDate = DateTime.Now;
attach.ContentDisposition.ModificationDate = DateTime.Now;
attach.ContentDisposition.Inline = false;
attach.ContentDisposition.Size = stream.Length;
attach.ContentType.MediaType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Also, I found that mine were not being sent right after I created them, and the reason for that is "standalone=yes" was not being added to the xml declaration of all the pages, so in my AddParts function, after adding the parts, I passed them into this function:
private static void AddXMLStandalone(OpenXmlPart part)
{
System.IO.StreamWriter writer = new System.IO.StreamWriter(part.GetStream());
XmlDocument doc = new XmlDocument();
doc.Load(part.GetStream());
doc.InnerXml = doc.InnerXml.Substring(doc.InnerXml.IndexOf("?>") + 2);
doc.InnerXml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + doc.InnerXml;
part.GetStream().SetLength(doc.InnerXml.Length);
doc.Save(writer);
writer.Flush();
writer.Close();
}
Good luck!
do this:
System.Net.Mail.Attachment file = new System.Net.Mail.Attachment(new MemoryStream(stream.ToArray()), "MobileBill.xlsx", "application/vnd.ms-excel");
Apparently the memory stream doesn't get flushed or something
For your "content unreadable" problem, make sure to Save() your Workbooks and Worksheets and enclose your SpreadsheetDocument in a using statement to ensure all packages and zipped streams are flushed, closed and so on.
System.IO.MemoryStream stream = new System.IO.MemoryStream();
using (SpreadsheetDocument package = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook)))
{
AddParts(package);
//Save if AddParts hasn't done it
}
System.Net.Mail.Attachment file = ...
Thinking out load: could it be, that the Attachment class expects to read from the current possition in the provided stream? If this is the case, you would probably have to "seek" back to the beginning of the stream, before feeding it to the Attachment constructor:
AddParts(package); //created using document reflector
stream.Seek(0, SeekOrigin.Begin);
System.Net.Mail.Attachment file = new System.Net.Mail.Attachment(stream, "MobileBill.xlsx", "application/vnd.ms-excel");