Skip to content

Latest commit

 

History

History
322 lines (264 loc) · 14 KB

STORAGE-DATASOURCE.md

File metadata and controls

322 lines (264 loc) · 14 KB

Reports Storage

In section 2, we have introduced how to create a project incorporating UReport2. After the project starts running, we will find a directory named “urepor tfiles” automatically generated under the WEB-INF directory of the project. This is the default directory of storage of report files provided by UReport2. In other words, the report files designed will be saved under the WEB-INF/ureportfiles directory of the project by UReport by default.

If the project runs in an Eclipse development environment, jetty (such as the run-jetty-run of eclipse plug-in) is applied. Then we will see a directory named “ureportfiles” under the WEB-INF directory of the project.

If the project runs based on tomcat, there will be no directory of “ureportfiles” under the WEB-INF directory, because tomcat needs to create a temporary working directory when tomcat is operated in Eclipse (the directory is generally located under workspace.metadata.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapp). Therefore, when the project runs based on tomcat, it is necessary to find the corresponding project under the temporary working directory and then find the corresponding “ureportfiles” directory under the WEB-INF directory of the project.

Start running the project created, open the report designer, click the save button on the toolbar and select “save”. Then we can see the pop-up window as shown in the figure below:

We only need to input the name of the report and select the storage directory of the report in this window to save the current report file. We can see that the default storage location of UReport2 is the “server file system”, i.e. the “ureportfiles” directory under WEB-INF directory of our project.

This directory is automatically generated by the system by default. We may change the location of the directory by adding an attribute if needed.

Create a file config.properties under the WEB-INF directory of the project, open the spring configuration file named context.xml under WEB-INF and add the following Bean to load the file config.properties.

<bean id="propertyConfigurer" parent="ureport.props">
    <property  name="location">
    <value>/WEB-INF/config.properties</value>
    </property>
</bean>

**Note: **The above Bean configuraton is practically a standard configuration of org.springframework.beans.factory.config.PropertyPlaceholderConfigurer class. We know that we can load external properties of Spring by configuring PropertyPlaceholderConfigurer. If the project has been configured with PropertyPlaceholderConfigurer class, the corresponding UReport2 properties can be directly added to the properties file corresponding to the class of the configuration, and it is no need to configure the config.properties file.

Open the file config.properties and add the attribute named “ureport.fileStoreDir”, while the value of the attribute is applied to define the default file system-based report storage directory provided by UReport2. For example, the attribute can be defined as follows:

ureport.fileStoreDir=D:/ureportfiles

It means to save the report files in the directory ureportfiles under the Drive D. It shall be noted that when the specific directory is assigned, we shall save the directory and assure its existence, otherwise it will not be adopted. For an instance, the directory named ureportfiles in Drive D must exist and needs to be created in advance.

The report storage mechanism known as the “server file system” provided by UReport2 by fault actually realizes the interface of com.bstek.ureport.provider.report.Report Provider provided by UReport2. The source code of the interface is as follows:

package com.bstek.ureport.provider.report; import  java.io.InputStream;
import java.util.List;
/**
*  @author  Jacky.gao
*  @since  2016年12月4日
*  @since  Dec. 4 2016
*/
public interface ReportProvider {
/**
*      根据报表名加载报表文件
* Load the report file according to the report name
*@param file 报表名称
* @param file report name
*@return  返回的InputStream
* @return  returned InputStream
*/
InputStream loadReport(String file);
/**
*       根据报表名,删除指定的报表文件
* Delete the specific report file according to the report name
*  @param  file  报表名称
*  @param  file  report name
*/
void deleteReport(String file);
/**
*     获取所有的报表文件
* Acquire all report files
*  @return  返回报表文件列表
*  @return  return the list of report file
*/
List<ReportFile>  getReportFiles();
/**
*   保存报表文件
* Save report files
*@param file 报表名称
* @param file report name
*@param content 报表的XML内容
* @param content XML content of report
*/
void saveReport(String file,String content);
/**
*  @return  返回存储器名称
*  @return  return storage name
*/
String getName();
/**
*  @return  返回是否禁用
*  @return  return if deactivation
*/
boolean  disabled();
/**
*  @return  返回报表文件名前缀
*  @return  return prefix of report name
*/
String getPrefix();
}

After realizing the ReportProvider interface, configure the implementation class to Spring and make it a standard Spring Bean. Then UReport2 will detect, find and load it. The source code of the report storage known as the “server file system” provided by UReport2 by default is listed below:

package com.bstek.ureport.provider.report.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.servlet.ServletContext;

import org.apache.commons.io.IOUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.WebApplicationContext;

import com.bstek.ureport.exception.ReportException;
import com.bstek.ureport.provider.report.ReportFile;
import com.bstek.ureport.provider.report.ReportProvider;

/**
 * @author Jacky.gao
 * @since 2017年2月11日
 */
public class FileReportProvider implements ReportProvider,ApplicationContextAware{
    private String prefix="file:";
    private String fileStoreDir;
    private boolean disabled;
    @Override
    public InputStream loadReport(String file) {
        if(file.startsWith(prefix)){
            file=file.substring(prefix.length(),file.length());
        }
        String fullPath=fileStoreDir+"/"+file;
        try {
            return new FileInputStream(fullPath);
        } catch (FileNotFoundException e) {
            throw new ReportException(e);
        }
    }

    @Override
    public void deleteReport(String file) {
        if(file.startsWith(prefix)){
            file=file.substring(prefix.length(),file.length());
        }
        String fullPath=fileStoreDir+"/"+file;
        File f=new File(fullPath);
        if(f.exists()){
            f.delete();
        }
    }

    @Override
    public List<ReportFile> getReportFiles() {
        File file=new File(fileStoreDir);
        List<ReportFile> list=new ArrayList<ReportFile>();
        for(File f:file.listFiles()){
            Calendar calendar=Calendar.getInstance();
            calendar.setTimeInMillis(f.lastModified());
            list.add(new ReportFile(f.getName(),calendar.getTime()));
        }
        Collections.sort(list, new Comparator<ReportFile>(){
            @Override
            public int compare(ReportFile f1, ReportFile f2) {
                return f2.getUpdateDate().compareTo(f1.getUpdateDate());
            }
        });
        return list;
    }

    @Override
    public String getName() {
        return "服务器文件系统";
    }

    @Override
    public void saveReport(String file,String content) {
        if(file.startsWith(prefix)){
            file=file.substring(prefix.length(),file.length());
        }
        String fullPath=fileStoreDir+"/"+file;
        FileOutputStream outStream=null;
        try{
            outStream=new FileOutputStream(new File(fullPath));
            IOUtils.write(content, outStream,"utf-8");
        }catch(Exception ex){
            throw new ReportException(ex);
        }finally{
            if(outStream!=null){
                try {
                    outStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    @Override
    public boolean disabled() {
        return disabled;
    }

    public void setDisabled(boolean disabled) {
        this.disabled = disabled;
    }

    public void setFileStoreDir(String fileStoreDir) {
        this.fileStoreDir = fileStoreDir;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        File file=new File(fileStoreDir);
        if(file.exists()){
            return;
        }
        if(applicationContext instanceof WebApplicationContext){
            WebApplicationContext context=(WebApplicationContext)applicationContext;
            ServletContext servletContext=context.getServletContext();
            String basePath=servletContext.getRealPath("/");
            fileStoreDir=basePath+fileStoreDir;
            file=new File(fileStoreDir);
            if(!file.exists()){
                file.mkdirs();
            }
        }
    }

    @Override
    public String getPrefix() {
        return prefix;
    }
}

Disable the default report storage provided by the system. If we customize the report storage and do not want to use the default report storage of “server file system” provided by the system, we only needs to add an attribute named ureport.disableFileProvider in the config.properties file mentioned above and set its value as true.

In view of the introduction above, we can easily develop other types of report storages by realizing the ReportProvider interface, such as developing a new report storage to save reports in database and FTP etc.

The data source Configuration

Open the report designer in UReport2. We can see three types of data sources of reports provided by UReport2, as shown in the figure below:

The three types of data sources are respectively directly connected with the database, Spring Bean and the built-in data soure that is provided through com.bstek.ureport.definition.datasource.BuildinDatasource interface.

It is very simple to connect with the database. Add the Jar package driven by the corresponding database in classpath of the project and configure the information on connection with the data source in the pop-up window, as shown in the figure below:The data source of Spring Bean type can choose a Bean defined in the context of Spring, click the icon and enter the name of data source and the ID of Bean to be applied in the pop-up window, as shown in the figure below:

After saving it, the specific data set can be added under the data source. Right click under the data source, choose “add the data set” in the pop-up menu and define the name of the data set, the corresponding method name and the type of the return object, as shown in the figure below:

In the configuration of the Spring bean data set, we can click the “select method” on the right to choose the method for the type corresponding to the current Bean. The requirements on the method are as follows: the method must consist of three parameters, including respctively String, String, Map. For xample, the testBean defined above consists of two legal methods, as shown below:

package com.ureport.test;

import java.util.List;
import java.util.Map;


public class TestBean {
	public List<Map<String,Object>> loadReportData(String dsName,String datasetName,Map<String,Object> parameters){
		return null;
	}
	public List<User> buildReport(String dsName,String datasetName,Map<String,Object> parameters){
		return null;
	}
}

The method of a legal Bean data set shall consist of three parameters, including String, String, Map, respectively corresponding to the name of the data source, name of the data source and the external parameter Map. The method of Bean can only be chosen upon this structure. Currently, two types of return values of the method of the data set are supported here, the List set of Map<String,Obj ect> type returned in TestBean and the List set of POJO type, like the method below:

public  List<User>  loadData(String  dsName,String  datasetName,Map<String,Object>  parameters){ 
    return null;
}

In the above example, the set of User object is returned. The User object here is an ordinary POJO object.

Built-in data source

This type of data source requires realizing the BuildinDatasource interface and configuring the implementation class of BuildinDatasource interface to Spring. The source code of BuildinDatasource interface is listed below:

package com.bstek.ureport.definition.datasource;

import java.sql.Connection;

/**
 * @author Jacky.gao
 * @since 2017年2月9日
 */
public interface BuildinDatasource {
	/**
	 * @return 返回数据源名称
	 */
	String name();
	/**
	 * @return 返回当前采用数据源的一个连接
	 */
	Connection getConnection();
}

After configuring the implementation class of BuildinDatasource interface to Spring, it can be automatically detected by UReport2. Then in the report designer, click the "Add Buildin Connection" button in the tab of data source and choose the defined built-in data source in the pop-up window, as shown in the figure below:

The three types of data sources provided by UReport2 feature different characteristics and usages. Users shall make flexible choice among them based on their characteristics.