I want to use an xml datasource to create a dynamic jasper report. But I get MalformedURLException exception when running the program.
The xml file works with ireport without any problem. But does not work with dynamic jasper. I tried the solutions given in the internet. But none of them solved my problem.
Here is the xml code:
<employees>
<employee>
<id>1001</id>
<name>John</name>
<email>john#somecorp.com</email>
<salary>2000</salary>
</employee>
<employee>
<id>1002</id>
<name>David</name>
<email>davida#somecorp.com</email>
<salary>1000</salary>
</employee>
<employee>
<id>1003</id>
<name>Susan</name>
<email>susana#somecorp.com</email>
<salary>4000</salary>
</employee>
<employee>
<id>1004</id>
<name>Susan</name>
<email>susanb#somecorp.com</email>
<salary>2000</salary>
</employee>
<employee>
<id>1005</id>
<name>David</name>
<email>davidb#somecorp.com</email>
<salary>3000</salary>
</employee>
Here's the exception:
Exception in thread "main" net.sf.jasperreports.engine.JRException: java.net.MalformedURLException
this is the code I am using to generate report:
public class ReportPrint {
public static void main(String[] args) throws JRException, IOException {
JasperReport jasperReport = JasperCompileManager.compileReport(ReportPrint.class.getResourceAsStream("data.xml"));
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,new HashMap(), new JREmptyDataSource());
JasperExportManager.exportReportToPdfFile(jasperPrint, "sample.pdf");
}
public ReportPrint(){
try {
DynamicReportBuilder dynamicReportBuilder = new DynamicReportBuilder();
// configure report-level settings
dynamicReportBuilder.setReportName("Some");
dynamicReportBuilder.setPageSizeAndOrientation(Page.Page_Letter_Landscape());
// add id column to report
ColumnBuilder columnBuilderID = ColumnBuilder.getNew();
columnBuilderID.setTitle("ID");
columnBuilderID.setWidth(180);
columnBuilderID.setFixedWidth(true);
columnBuilderID.setColumnProperty("ID", Integer.class.getName(), "#id");
dynamicReportBuilder.addColumn(columnBuilderID.build());
// add name column to report
ColumnBuilder columnBuilderName = ColumnBuilder.getNew();
columnBuilderName.setTitle("Name");
columnBuilderName.setWidth(180);
columnBuilderName.setFixedWidth(true);
columnBuilderName.setColumnProperty("Name", String.class.getName(), "#name");
dynamicReportBuilder.addColumn(columnBuilderName.build());
// add email column to report
ColumnBuilder columnBuilderEmail = ColumnBuilder.getNew();
columnBuilderEmail.setTitle("Email");
columnBuilderEmail.setWidth(180);
columnBuilderEmail.setFixedWidth(true);
columnBuilderEmail.setColumnProperty("Email", String.class.getName(), "#email");
dynamicReportBuilder.addColumn(columnBuilderEmail.build());
// add salary column to report
ColumnBuilder columnBuilderSalary = ColumnBuilder.getNew();
columnBuilderSalary.setTitle("Salary");
columnBuilderSalary.setWidth(180);
columnBuilderSalary.setFixedWidth(true);
columnBuilderSalary.setColumnProperty("Salary", Integer.class.getName(), "#salary");
dynamicReportBuilder.addColumn(columnBuilderSalary.build());
DynamicReport dynamicReport = dynamicReportBuilder.build();
// build a datasource representing the XML file
JRDataSource dataSource = new JRXmlDataSource(new File("data.xml"), "//employee");
// build JasperPrint instance, filling the report with data from datasource created above
JasperPrint jasperPrint = DynamicJasperHelper.generateJasperPrint(
dynamicReport, new ClassicLayoutManager(), dataSource, new HashMap<String, Object>());
// export to pdf
String pdfFile = Math.round(Math.random() * 100000) + ".pdf";
JRExporter exporter = new JRPdfExporter();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, pdfFile);
exporter.exportReport();
} catch(JRException e) {
e.printStackTrace();
}
}
}
Related
My restful service accepts a file argument, the contents of which is an Apache SS (XSSF) Workbook. The method iterates through the cells of the Workbook and takes various actions, based on the values of the cells.
I've conceived a Junit test where I instantiate and populate an Apache SS Workbook, add it to a 'file'object and then pass the 'file' object to the method under test. The primary problem that I'm having is how to instantiate the 'file' object using the Workbook object.
Following is a sample of the method under test (omitting details unrelated to the Workbook), followed by a pseudo-code example of what I'm trying to do:
/* Method under test */
public Object workbookProcessing(HttpServletRequest request) {
List<Part> workbookParts = request.getParts().collect(Collectors.toList());
for (Part workbookPart : workbookParts) {
InputStream workbookContent = workbookPart.getInputStream();
Workbook workbook = WorkbookFactory.create(workbookContent);
// ...
}
/* Junit test pseudo-code */
public void testWorkbookProcessing() {
RestfulService rs = new RestfulService();
Workbook wb = WorkbookFactory.create(true) // Create XSSF workbook
CreationHelper createHelper = wb.getCreationHelper();
Sheet sheet = wb.createSheet("Sheet 1");
Row row = sheet.createRow(0);
row.createCell(0).setCellValue(createHelper.createRichTextString("Row 1 Cell 1"));
row.createCell(1).setCellValue(12345678);
// ...
HttpServletRequest request = new HttpServletRequest(); // Create HttpServletRequest
// Create InputStream, using above Workbook <- Help!
// Create Part object from InputStream <- Help!
request.addPart(inputStream); // Add Part object to request
ResponseEntity re = rs.workbookProcessing(request);
assertEquals(200, re.getStatusCodeValue());
}
Alternatively, if there is a way to Mock the workbook and it's cell values, I'm happy to do that as well.
After quite a bit of research, trial and error and combining techniques, here is how I was able to write a working Junit test to submit a multi-part HTTP request which contained an Apache SS workbook object.
// Working Junit test code:
#Test
public void testWorkbookProcessing() {
RestfulService rs = new RestfulService();
Workbook wb = WorkbookFactory.create(true) // Create XSSF workbook
CreationHelper createHelper = wb.getCreationHelper();
Sheet sheet = wb.createSheet("Sheet 1");
Row row = sheet.createRow(0); // First row of sheet
row.createCell(0).setCellValue(createHelper.createRichTextString("Row 1 Cell 1"));
row.createCell(1).setCellValue(12345678);
// ...
// This is the code to create the multi-part content
ByteArrayOutputStream baos = New ByteArrayOutputStream();
wb.write(baos); // Write workbook to output stream
byte[] bytes = baos.toByteArray(); // Convert output stream to byte array
MockPart part = new MockPart("file", "test_filename.xlsx", bytes); // Add byte array to mocked Part object
MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest();
request.setMethod(RequestMethod.POST.name());
request.addHeader("Content-Type", "multipart/form-data");
request.addParameter("id", "12345678"); // optional
request.addPart(part); // Add Part to request
ResponseEntity re = rs.workbookProcessing(request);
assertEquals(202, re.getStatusCodeValue());
}
Refinements/comments/suggestions appreciated.
I always get the system not found exception. How can I find a xml file in a bundle of my xamarin.android application?
public Dictionary<string, string> TilePropertiesForTileID(short tileGid)
{
Dictionary<string, string> propertiesDict = null;
try
{
// Loading from a file, you can also load from a stream
var xml = XDocument.Load(Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), "Assets/Content/tileMap/wood_tileset.tsx"));
// Query the data and write out a subset of contacts
var propertiesQuery = from c in xml.Root.Descendants("tile")
where (int)c.Attribute("id") == tileGid
select c.Element("property").Value;
foreach (string property in propertiesQuery)
{
Console.WriteLine("Property: {0}", property);
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw e;
}
return propertiesDict;
}
This line:
var xml = XDocument.Load(Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData), "Assets/Content/tileMap/wood_tileset.tsx"));
always throws the exception. I don't know How to get access to this file.
updated: Thanks to apineda I am now able to find the file : here is the xml file
<?xml version="1.0" encoding="UTF-8"?>
<tileset version="1.2" tiledversion="1.2.1" name="wood_tileset"
tilewidth="32" tileheight="32" tilecount="256" columns="16">
<image source="wood_tileset.png" width="512" height="512"/>
<tile id="68">
<properties>
<property name="IsTreasure" value="true"/>
</properties>
</tile>
</tileset>
For this you don't necessarily need the Full Path of the File. Since you placed the file in the Assets directory and I hope also marked it as AndroidAsset in the Build Action all you need is to make use of the AssetManager.
If you are within an Activity you can open a file in the Assets like this:
Assets.Open("fileName.ext")
If you added subdirectories in the Assets directory you will need to include the full path (without including the word "Assets").
Using your code as sample, it should look like this:
using (var sReader = new StreamReader(Assets.Open("Content/titleMap/wood_tileset.tsx")))
{
var xmlDoc = XDocument.Load(sReader);
// Query the data and write out a subset of contacts
var propertiesQuery = xmlDoc.Root.Descendants("tile")
.Where(item => (int)item.Attribute("id") == tileGid)
.SelectMany(a => a.Descendants("property"))
.Select(property => new
{
Name = property.Attribute("name").Value,
Value = property.Attribute("value").Value
})
.ToList();
foreach (var property in propertiesQuery)
{
Console.WriteLine($"Property Name: {property.Name}, Value: {property.Value}");
}
}
As you can see the return of the Assets.Open method is passed into a StreamReader. The using is not necessary but this will prevent leaving resources opened.
The StreamReader is then passed in to the Load() method of the XDocument and the rest is exactly as you had it.
Note: This assume you have a file structure like the following:
Assets
Content
titleMap
wood_titleset.tsx
Hope this helps.-
Like title, when i execute the mybatis-generator, i want to overwriting the already generated *Mapper.xml all, not merge!
but i try many config way, it doesn't implement correct.
and everytime is generator the more once the xml content.
like this:
<resultMap id="BaseResultMap" type="com.test.entity.GoodsEntity"> ...
<resultMap id="BaseResultMap" type="com.test.entity.GoodsEntity"> ...
<resultMap id="BaseResultMap" type="com.test.entity.GoodsEntity"> ...
in the properties, i had add this line:
<mybatis.generator.overwrite>true</mybatis.generator.overwrite>
and in the build > plugin, i add below lines:
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
<configuration>
<verbose>true</verbose>
<overwrite>true</overwrite>
<configurationFile>${mybatis.generator.configurationFile}</configurationFile>
</configuration>
<executions>
<execution>
<id>Generate MyBatis Artifacts</id>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>com.test</groupId>
<artifactId>ob-maven-plugin-mybatis-generator</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</plugin>
in the mybatis-generator.xml, i try overwrite config yet.
all config it doesn't work goo.
How could I modify the configuration?
MyBatis generator will always merge XML files if it finds a match. There is currently no option to turn that off.
You can use plugin <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" /> in Mybatis Generator 1.3.7 to overwrite xml.
See http://www.mybatis.org/generator/reference/plugins.html
This plugin will disable the XML merge function for generated mapper XML files. This will cause the generator to respect the overwrite flag for XML files in the same way it does for Java files - if overwrite is true, then an existing file will be overwritten, else a new file will be written with a unique name.
This plugin can be helpful if you disable all comments.
Setting <property name="suppressAllComments" value="true" /> in Mybatis Generator configuration file can cause this problem. Mybatis Generator uses comments flag to decide whether to merge XML.
If you disable all comments, you might find the UnmergeableXmlMappersPlugin useful. It will cause the generator to respect the overwrite flag for XML files.
See http://www.mybatis.org/generator/configreference/commentGenerator.html
I was able to get around this by creating a plugin and adding it to the mybatis-generator-config.xml file. Note, of course, that this solution will cause the Mapper.xml files to always be overwritten regardless of whether or not the -overwrite flag is specified.
mybatis-generator-config.xml:
<generatorConfiguration>
...
<context id="myContextId">
<plugin type="com.mydomain.DeleteExistingSqlMapsPlugin"></plugin>
...
</context>
</generatorConfiguration>
DeleteExistingSqlMapsPlugin.java:
...
public class DeleteExistingSqlMapsPlugin extends PluginAdapter {
#Override
public boolean validate(List<String> warnings) {
return true;
}
#Override
public boolean sqlMapGenerated(GeneratedXmlFile sqlMap,
IntrospectedTable introspectedTable)
{
String sqlMapPath = sqlMap.getTargetProject() + File.separator
+ sqlMap.getTargetPackage().replaceAll("\\.", File.separator)
+ File.separator + sqlMap.getFileName();
File sqlMapFile = new File(sqlMapPath);
sqlMapFile.delete();
return true;
}
}
This works because sqlMapGenerated() is called after a Mapper.xml file is created in memory but before it is written to disk.
I encountered the same problem today.To solve this problem, just need to change the version of mybatis-generator-maven-plugin。
<mybatis-generator-maven-plugin.version>1.3.4-SNAPSHOT</mybatis-generator-maven-plugin.version>
I write a plugin to merge xml mapper file.
And modifiy mybatis-generator-core to combine java and xml.
This can keep your xml and java file 's modification not override.
https://github.com/zwxbest/mybatis-generator-plugin
Usage:
<generatorConfiguration>
...
<context id="myContextId">
<plugin type="com.mydomain.CombineXmlPlugin"></plugin>
...
</context>
</generatorConfiguration>
Plugin Code:
package com.haitian.plugins;
import org.mybatis.generator.api.GeneratedXmlFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.ShellCallback;
import org.mybatis.generator.api.dom.xml.Element;
import org.mybatis.generator.internal.DefaultShellCallback;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.io.FileInputStream;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* User:zhangweixiao
* Description:
* old nodes is your existing xml file's first level nodes,like <insert><resultMap>
* new nodes is mybatis-generator generate for you to combine
* This compare the first level node's name and "id" attribute of new nodes and old nodes
* if the two equal,then new node will not generate
* so this can make you modification in old nodes not override.
* if you want to regenrate old node,delete it,it will generate new.
*/
public class CombineXmlPlugin extends PluginAdapter {
//shellCallback use TargetProject and TargetPackage to get targetFile
ShellCallback shellCallback = new DefaultShellCallback(false);
//save new nodes
org.mybatis.generator.api.dom.xml.Document document;
#Override
public boolean validate(List<String> warnings) {
return true;
}
/**
* assing document variable to get new nodes
* #param document
* #param introspectedTable
* #return
*/
#Override
public boolean sqlMapDocumentGenerated(org.mybatis.generator.api.dom.xml.Document document,
IntrospectedTable introspectedTable) {
this.document = document;
return true;
}
//new nodes is generated,but not write on disk,we just need to filter.
#Override
public boolean sqlMapGenerated(GeneratedXmlFile sqlMap,
IntrospectedTable introspectedTable) {
try {
//get old nodes
File directory = shellCallback.getDirectory(sqlMap.getTargetProject(), sqlMap.getTargetPackage());
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
DocumentBuilder db = dbf.newDocumentBuilder();
File xmlFile = new File(directory, sqlMap.getFileName());
if (directory.exists() == false || xmlFile.exists() == false)
return true;
Document doc = db.parse(new FileInputStream(xmlFile));
org.w3c.dom.Element rootElement = doc.getDocumentElement();
NodeList list = rootElement.getChildNodes();
//get new nodes
List<Element> elements = document.getRootElement().getElements();
//get nodeName and the value of id attribute use regex
Pattern p = Pattern.compile("<(\\w+)\\s+id=\"(\\w+)\"");
boolean findSameNode = false;
// traverse new nodes to compare old nodes to filter
for (Iterator<Element> elementIt = elements.iterator(); elementIt.hasNext(); ) {
findSameNode = false;
String newNodeName = "";
String NewIdValue = "";
Element element = elementIt.next();
Matcher m = p.matcher(element.getFormattedContent(0));
if (m.find()) {
//get nodeName and the value of id attribute
newNodeName = m.group(1);
NewIdValue = m.group(2);
}
//if the nodeName of newNode and oldNode are equal
//and the id attribute of newNode and oldNode are equal
//then filter newNode
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
if (newNodeName.equals(node.getNodeName())) {
NamedNodeMap attr = node.getAttributes();
for (int j = 0; j < attr.getLength(); j++) {
Node attrNode = attr.item(j);
if (attrNode.getNodeName().equals("id") && attrNode.getNodeValue().equals(NewIdValue)) {
//filter new node,just delete it ,and it will not generate
elementIt.remove();
findSameNode = true;
break;
}
}
if (findSameNode == true)
break;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
}
you add "batchInsert",and delte insertSelective,and modify other node.
then regenerate xml mapper file,only insertSelective will be generated,others will not be override.
The official tutorial of dbunit already give a good example for exporting dataset from a single database schema.
Is there any way to export different tables from different schemas into one single dataset (say Table_A from schema_A, Table_B from schema_B)?
The exported dataset, when written into an xml file, would be like this:
<?xml version='1.0' encoding='UTF-8'?>
<dataset schema:schemaA schema:schemaB>
<schemaA:tableA ..... />
<schemaA:tableA ..... />
<schemaB:tableB ..... />
</dataset>
I've just got the same problem and to fix it you need to set the FEATURE_QUALIFIED_TABLE_NAMES properties:
See below the same example code with the change (I removed some part of the code because I don't need full database export):
public static void main(String[] args) throws Exception
{
// database connection
Class driverClass = Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection jdbcConnection = DriverManager.getConnection(
"jdbc:sqlserver://<server>:1433;DatabaseName=<dbName>", "<usr>", "<passwd>");
IDatabaseConnection connection = new DatabaseConnection(jdbcConnection);
Properties props = new Properties();
props.put(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, "true");
connection.getConfig().setPropertiesByString(props);
// dependent tables database export: export table X and all tables that
// have a PK which is a FK on X, in the right order for insertion
String[] depTableNames = TablesDependencyHelper.getAllDependentTables( connection, "vehicle.Vehicle_Series_Model_SMA" );
IDataSet depDataset = connection.createDataSet( depTableNames );
FlatXmlDataSet.write(depDataset, new FileOutputStream("vehicle.Vehicle_Series_Model_SMA.xml"));
}
Using spring3.2 and netbeans 7.2
Warning code :
#Override
protected List<Entry> buildFeedEntries(Map<String, Object> model,
HttpServletRequest request, HttpServletResponse response) throws Exception {
#SuppressWarnings("unchecked")
List<Feed_vo> contentList = (List<Feed_vo>) model.get("feedContent");
List<Entry> entries = new ArrayList<Entry>(contentList.size());
for (Feed_vo content : contentList) {
Entry entry = new Entry();
String date = String.format("%1$tY-%1$tm-%1$td", content.getCreatedDate());
entry.setId(String.format("tag:featuriz.com,%s:%d", date, content.getId()));
entry.setTitle(String.format("%s | on %s by %s",content.getTitle(), date, content.getAuthor()));
entry = setLink(content, entry);
entry.setUpdated(content.getCreatedDate());
Content summary = new Content();
summary.setValue(content.getSummary());
entry.setSummary(summary);
entries.add(entry);
}
return entries;
}
private Entry setLink(Feed_vo vo, Entry entry) {
ArrayList l = new ArrayList();
Link link = new Link();
link.setType("text/html");
link.setHref(vo.getUrl());
l.add(link);
entry.setAlternateLinks(l);
return entry;
}
This code works but Netbeans warning :
/home/sudhakar/**/CustomAtomViewer.java:72: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.ArrayList
l.add(link);
1 warning
How to solve this warning.
Also inform me the correct format for atom and rss feed.
(How the output should look like. ie. output source).
Warnings solved by this code:
List<Link> v = new ArrayList<Link>();
Link link = new Link();
link.setType("text/html");
link.setHref(vo.getUrl());
v.add(link);
entry.setAlternateLinks(v);