注意: 报表的内容国际化这里不再赘述,直接看文档就OK. Pentaho 4.5不支持报表Title\Description等信息的国际化,下面来主要讲述如何通过修改源码来进行国际化Title等。
结果演示:
默认语言显示为:
language=en 即:英文显示为
看到了吧 , 该报表Title 支持国际化了。
首先我们来介绍一下Pentaho prpt报表的组织结构。
Prpt报表的文件为"*.prpt",其实是一个Jar文件包。
首先我们打开一个示例为:
可以看到:
打开meta.xml查看文件内容为:
1 <office:meta> 2 <dc:creator>Kurtis Cruzadadc:creator> 3 <dc:title>Product Salesdc:title> 4 <dc:description>Operational Reportdc:description> 5 <dc:subject>dc:subject> 6 <dc:date>2012-01-12T02:56:49 ESTdc:date> 7 <autoGenNs:visible xmlns:autoGenNs="http://reporting.pentaho.org/namespaces/engine/classic/metadata/1.0">trueautoGenNs:visible> 8 <autoGenNs:prpt-spec.version.major xmlns:autoGenNs="http://reporting.pentaho.org/namespaces/engine/classic/metadata/1.0">3autoGenNs:prpt-spec.version.major> 9 <autoGenNs:prpt-spec.version.minor xmlns:autoGenNs="http://reporting.pentaho.org/namespaces/engine/classic/metadata/1.0">8autoGenNs:prpt-spec.version.minor> 10 <autoGenNs:prpt-spec.version.patch xmlns:autoGenNs="http://reporting.pentaho.org/namespaces/engine/classic/metadata/1.0">0autoGenNs:prpt-spec.version.patch> 11 <meta:creation-date>2009-05-04T10:10:20 EDTmeta:creation-date> 12 <meta:keywords>meta:keywords> 13 <meta:initial-creator>Pentaho Reporting Classic nullmeta:initial-creator> 14 <meta:generator>Pentaho Reporting Engine Classic 3.8-SNAPSHOT.developmentmeta:generator> 15 office:meta>
可以看到这里的dc:title即为报表的显示Title。不能够动态的指定。
解决办法:
第一步:下载ReportFileMetaDataProvider.class文件,并覆盖到pentaho/WEB-INF/pentaho-reporting-engine-classic-core-platform-plugin-4.5.0-stable.jar 的org.pentaho.reporting.platform.plugin目录下
下载地址为:
http://download.csdn.net/detail/mryuqinghua/5303114
该文件是个jar包 为了方便,我就直接上传了个Jar文件。当然你们也可以直接解压出来org.pentaho.reporting.platform.plugin.ReportFileMetaDataProvider 替换到你们的pentaho-reporting-engine-classic-core-platform-plugin-4.5.0-stable.jar 中
第二步:编辑report 国际化文件,工具PentahoReportDesginer。
注:报表的文件名称和国际化文件的开头要一致:
如: VB01.prpt---->VB01.properties / VB01_en.properties/ VB01_ja.properties
File-》resource-->Edit 对应的国际化文件VB01.properties
title=Vampirewar\u751f\u547d\u5468\u671f\u7edf\u8ba1 desc=Vampirewar\u751f\u547d\u5468\u671f\u7edf\u8ba1 creator=yuqinghua
VB01_en.properties:
title=Vampirewar Life Time Value desc=Vampirewar\u751f\u547d\u5468\u671f\u7edf\u8ba1 creator=yuqinghua
第三步:发布报表
根据resource中的设置,我们发布为:
OK
登陆后,重启Pentaho BI Service 登陆进去后就可以看到国际化的Title 了。
下面讲述下如何找到源码,并进行修改的。如果你不关心这块可以不用往下看了:
供Java开发人员查看。
解决步骤:
第一步:跟踪获取菜单列表的Action.
使用Chrome浏览器,点击Tools--> Refresh --> Reposity Cache
可以跟踪到网络访问的Servlet 为:
打开Pentaho_Home/tomcat/webapp/pentaho/WEB-INF/web.xml
得到如下代码:
1 <servlet> 2 <servlet-name>SolutionRepositoryServiceservlet-name> 3 <servlet-class>org.pentaho.platform.web.servlet.SolutionRepositoryServiceservlet-class> 4 servlet>
打开源码SolutionRepositoryService.java:
1 protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, 2 IOException { 3 PentahoSystem.systemEntryPoint(); 4 OutputStream outputStream = response.getOutputStream(); 5 try { 6 boolean wrapWithSoap = "false".equals(request.getParameter("ajax")); //$NON-NLS-1$ //$NON-NLS-2$ 7 String component = request.getParameter("component"); //$NON-NLS-1$ 8 response.setContentType("text/xml"); //$NON-NLS-1$ 9 response.setCharacterEncoding(LocaleHelper.getSystemEncoding()); 10 11 IPentahoSession userSession = getPentahoSession(request); 12 // send the header of the message to prevent time-outs while we are working 13 response.setHeader("expires", "0"); //$NON-NLS-1$ //$NON-NLS-2$ 14 15 dispatch(request, response, component, outputStream, userSession, wrapWithSoap); 16 17 /** 18 * NOTE: PLEASE DO NOT CATCH Exception, since this is the super class of RuntimeException. We do NOT want to catch RuntimeException, only CHECKED 19 * exceptions! 20 */ 21 } catch (SolutionRepositoryServiceException ex) { 22 commonErrorHandler(outputStream, ex); 23 } catch (PentahoAccessControlException ex) { 24 commonErrorHandler(outputStream, ex); 25 } catch (TransformerConfigurationException ex) { 26 commonErrorHandler(outputStream, ex); 27 } catch (ParserConfigurationException ex) { 28 commonErrorHandler(outputStream, ex); 29 } catch (TransformerException ex) { 30 commonErrorHandler(outputStream, ex); 31 } catch (TransformerFactoryConfigurationError ex) { 32 commonErrorHandler(outputStream, ex.getException()); 33 } catch (IOException ex) { 34 // Use debugErrorHandler for ioException 35 debugErrorHandler(outputStream, ex); 36 } finally { 37 PentahoSystem.systemExitPoint(); 38 } 39 if (ServletBase.debug) { 40 debug(Messages.getString("HttpWebService.DEBUG_WEB_SERVICE_END")); //$NON-NLS-1$ 41 } 42 }
跟踪到dispatch 方法:
1 protected void dispatch(final HttpServletRequest request, final HttpServletResponse response, final String component, 2 final OutputStream outputStream, final IPentahoSession userSession, final boolean wrapWithSOAP) 3 throws IOException, SolutionRepositoryServiceException, PentahoAccessControlException, 4 ParserConfigurationException, TransformerConfigurationException, TransformerException, 5 TransformerFactoryConfigurationError { 6 7 ISolutionRepositoryService service = PentahoSystem.get(ISolutionRepositoryService.class, userSession); 8 IParameterProvider parameterProvider = new HttpRequestParameterProvider(request); 9 10 if ("getSolutionRepositoryDoc".equals(component)) { //$NON-NLS-1$ 11 String[] filters = getFilters(request); 12 Document doc = service.getSolutionRepositoryDoc(userSession, filters); 13 WebServiceUtil.writeDocument(outputStream, doc, wrapWithSOAP); 14 } else if ("getSolutionRepositoryFileDetails".equals(component)) { //$NON-NLS-1$ 15 String fullPath = request.getParameter("fullPath"); //$NON-NLS-1$ 16 Document doc = service.getSolutionRepositoryFileDetails(userSession, fullPath); 17 WebServiceUtil.writeDocument(outputStream, doc, wrapWithSOAP); 18 } else if ("createNewFolder".equals(component)) { //$NON-NLS-1$ 19 String solution = request.getParameter("solution"); //$NON-NLS-1$ 20 String path = request.getParameter("path"); //$NON-NLS-1$ 21 String name = request.getParameter("name"); //$NON-NLS-1$ 22 String desc = request.getParameter("desc"); //$NON-NLS-1$ 23 boolean result = service.createFolder(userSession, solution, path, name, desc); 24 WebServiceUtil.writeString(outputStream, "" + result + " ", wrapWithSOAP); //$NON-NLS-1$ //$NON-NLS-2$ 25 } else if ("delete".equals(component)) { //$NON-NLS-1$ 26 String solution = request.getParameter("solution"); //$NON-NLS-1$ 27 String path = request.getParameter("path"); //$NON-NLS-1$ 28 String name = request.getParameter("name"); //$NON-NLS-1$ 29 boolean result = service.delete(userSession, solution, path, name); 30 WebServiceUtil.writeString(outputStream, "" + result + " ", wrapWithSOAP); //$NON-NLS-1$ //$NON-NLS-2$ 31 } else if ("setAcl".equals(component)) { //$NON-NLS-1$ 32 String solution = parameterProvider.getStringParameter("solution", null); //$NON-NLS-1$ 33 String path = parameterProvider.getStringParameter("path", null); //$NON-NLS-1$ 34 String filename = parameterProvider.getStringParameter("filename", null); //$NON-NLS-1$ 35 String strAclXml = parameterProvider.getStringParameter("aclXml", null); //$NON-NLS-1$ 36 service.setAcl(solution, path, filename, strAclXml, userSession); 37 String msg = WebServiceUtil.getStatusXml(Messages.getString("AdhocWebService.ACL_UPDATE_SUCCESSFUL")); //$NON-NLS-1$ 38 WebServiceUtil.writeString(outputStream, msg, wrapWithSOAP); 39 } else if ("getAcl".equals(component)) { //$NON-NLS-1$ 40 String solution = parameterProvider.getStringParameter("solution", null); //$NON-NLS-1$ 41 String path = parameterProvider.getStringParameter("path", null); //$NON-NLS-1$ 42 String filename = parameterProvider.getStringParameter("filename", null); //$NON-NLS-1$ 43 String aclXml = service.getAclXml(solution, path, filename, userSession); 44 WebServiceUtil.writeString(outputStream, aclXml, wrapWithSOAP); 45 } else { 46 throw new RuntimeException(Messages.getErrorString("HttpWebService.UNRECOGNIZED_COMPONENT_REQUEST", component)); //$NON-NLS-1$ 47 }
打开ISolutionRepositoryService接口的Type Hirerarchy:
跟踪到:SolutionRepositoryServiceImpl.java
可以看到方法中 首先判断了 文件是否是文件夹,不是文件夹的情况下 又对.xaction、.url进行了单独处理,其他的均走了isPlugin处理(Penatho 将Report也作为其一个插件),代码如下:
1 else if (name.endsWith(".url")) { //$NON-NLS-1$ 2 3 // add special props 4 String props = new String(file.getData()); 5 StringTokenizer tokenizer = new StringTokenizer(props, "\n"); //$NON-NLS-1$ 6 while (tokenizer.hasMoreTokens()) { 7 String line = tokenizer.nextToken(); 8 int pos = line.indexOf('='); 9 if (pos > 0) { 10 String propname = line.substring(0, pos); 11 String value = line.substring(pos + 1); 12 if ((value != null) && (value.length() > 0) && (value.charAt(value.length() - 1) == '\r')) { 13 value = value.substring(0, value.length() - 1); 14 } 15 if ("URL".equalsIgnoreCase(propname)) { //$NON-NLS-1$ 16 child.setAttribute("url", value); //$NON-NLS-1$ 17 } 18 } 19 } 20 } else if (isPlugin) { 21 // must be a plugin - make it look like a URL 22 try { 23 // get the file info object for this file 24 // not all plugins are going to actually use the inputStream, so we have a special 25 // wrapper inputstream so that we can pay that price when we need to (2X speed boost) 26 pluginInputStream = new PluginFileInputStream(repository, file); 27 fileInfo = pluginManager.getFileInfo(extension, session, file, pluginInputStream); 28 String handlerId = pluginManager.getContentGeneratorIdForType(extension, session); 29 String fileUrl = pluginManager.getContentGeneratorUrlForType(extension, session); 30 String solution = file.getSolutionPath(); 31 String path = ""; //$NON-NLS-1$ 32 IPentahoRequestContext requestContext = PentahoRequestContextHolder.getRequestContext(); 33 String contextPath = requestContext.getContextPath(); 34 if (solution.startsWith(ISolutionRepository.SEPARATOR + "")) { //$NON-NLS-1$ 35 solution = solution.substring(1); 36 } 37 int pos = solution.indexOf(ISolutionRepository.SEPARATOR); 38 if (pos != -1) { 39 path = solution.substring(pos + 1); 40 solution = solution.substring(0, pos); 41 } 42 String url = null; 43 if (!"".equals(fileUrl)) { //$NON-NLS-1$ 44 url = contextPath + fileUrl + 45 "?solution=" + URLEncoder.encode(solution, URL_ENCODING) + 46 "&path=" + URLEncoder.encode(path, URL_ENCODING) + 47 "&action=" + URLEncoder.encode(name, URL_ENCODING); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 48 } else { 49 IContentInfo info = pluginManager.getContentInfoFromExtension(extension, session); 50 for (IPluginOperation operation : info.getOperations()) { 51 if (operation.getId().equalsIgnoreCase("RUN")) { //$NON-NLS-1$ 52 String command = operation.getCommand(); 53 54 command = command.replaceAll("\\{solution\\}", URLEncoder.encode(solution, URL_ENCODING)); //$NON-NLS-1$ 55 command = command.replaceAll("\\{path\\}", URLEncoder.encode(path, URL_ENCODING)); //$NON-NLS-1$ 56 command = command.replaceAll("\\{name\\}", URLEncoder.encode(name, URL_ENCODING)); //$NON-NLS-1$ 57 url = contextPath + command; 58 59 break; 60 } 61 } 62 if (url == null) { 63 url = contextPath 64 + "content/" + handlerId + 65 "?solution=" + URLEncoder.encode(solution, URL_ENCODING) + 66 "&path=" + URLEncoder.encode(path, URL_ENCODING) + 67 "&action=" + URLEncoder.encode(name, URL_ENCODING); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ 68 } 69 } 70 child.setAttribute("url", url); //$NON-NLS-1$ 71 72 // do not come up with fantasy values for a non-existing service. 73 // if there is no param-service then do not claim that there is one. 74 String paramUrl = null; 75 final IContentInfo info = pluginManager.getContentInfoFromExtension(extension, session); 76 for (final IPluginOperation operation : info.getOperations()) { 77 if (operation.getId().equals("PARAMETER")) { //$NON-NLS-1$ 78 String command = operation.getCommand(); 79 command = command.replaceAll("\\{solution\\}", URLEncoder.encode(solution, URL_ENCODING)); //$NON-NLS-1$ 80 command = command.replaceAll("\\{path\\}", URLEncoder.encode(path, URL_ENCODING)); //$NON-NLS-1$ 81 command = command.replaceAll("\\{name\\}", URLEncoder.encode(name, URL_ENCODING)); //$NON-NLS-1$ 82 paramUrl = contextPath + command; 83 84 85 break; 86 } 87 } 88 89 if (StringUtil.isEmpty(paramUrl) == false) { 90 child.setAttribute("param-service-url", paramUrl); //$NON-NLS-1$ 91 } 92 } catch (Throwable t) { 93 t.printStackTrace(); 94 } 95
在上述红色字体下方加入一行代码 打印该对象的类:
1 System.out.println(pluginManager.getClass().getName());
可以看到是ReportFileMetaDataProvider类。
其代码为:
1 public IFileInfo getFileInfo(final ISolutionFile solutionFile, 2 final InputStream in) { 3 try { 4 DocumentBundle bundle = loadBundle(solutionFile.getSolutionPath() 5 + "/" + solutionFile.getFileName()); 6 7 DocumentMetaData metaData = bundle.getMetaData(); //$NON-NLS-1$ 8 9 final String title = (String) metaData.getBundleAttribute( 10 ODFMetaAttributeNames.DublinCore.NAMESPACE, 11 ODFMetaAttributeNames.DublinCore.TITLE); 12 final String author = (String) metaData.getBundleAttribute( 13 ODFMetaAttributeNames.DublinCore.NAMESPACE, 14 ODFMetaAttributeNames.DublinCore.CREATOR); 15 final String description = (String) metaData.getBundleAttribute( 16 ODFMetaAttributeNames.DublinCore.NAMESPACE, 17 ODFMetaAttributeNames.DublinCore.DESCRIPTION); 18 final IFileInfo fileInfo = new FileInfo(); 19 if (StringUtils.isEmpty(title)) { 20 fileInfo.setTitle(solutionFile.getFileName()); 21 } else { 22 fileInfo.setTitle(title); 23 } 24 fileInfo.setAuthor(author); //$NON-NLS-1$ 25 fileInfo.setDescription(description); 26 27 // displaytype is a magical constant defined in a internal class of 28 // the platform. 29 if ("false".equals(metaData.getBundleAttribute( 30 ClassicEngineBoot.METADATA_NAMESPACE, "visible"))) { 31 fileInfo.setDisplayType("none"); // NON-NLS 32 } else { 33 fileInfo.setDisplayType("report"); // NON-NLS 34 } 35 return fileInfo; 36 } catch (Exception e) { 37 logger.warn( 38 Messages.getInstance().getString( 39 "ReportPlugin.errorMetadataNotReadable"), e); 40 return null; 41 } 42 }
根据作者尝试并修改该类的为:
1 package org.pentaho.reporting.platform.plugin; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.util.HashMap; 6 import java.util.Locale; 7 import java.util.Properties; 8 9 import org.apache.commons.logging.Log; 10 import org.apache.commons.logging.LogFactory; 11 import org.pentaho.platform.api.engine.IFileInfo; 12 import org.pentaho.platform.api.engine.ILogger; 13 import org.pentaho.platform.api.engine.ISolutionFile; 14 import org.pentaho.platform.api.engine.SolutionFileMetaAdapter; 15 import org.pentaho.platform.engine.core.solution.FileInfo; 16 import org.pentaho.platform.util.messages.LocaleHelper; 17 import org.pentaho.reporting.engine.classic.core.ClassicEngineBoot; 18 import org.pentaho.reporting.libraries.base.util.StringUtils; 19 import org.pentaho.reporting.libraries.docbundle.DocumentBundle; 20 import org.pentaho.reporting.libraries.docbundle.DocumentMetaData; 21 import org.pentaho.reporting.libraries.docbundle.ODFMetaAttributeNames; 22 import org.pentaho.reporting.libraries.resourceloader.Resource; 23 import org.pentaho.reporting.libraries.resourceloader.ResourceException; 24 import org.pentaho.reporting.libraries.resourceloader.ResourceKey; 25 import org.pentaho.reporting.libraries.resourceloader.ResourceManager; 26 import org.pentaho.reporting.platform.plugin.messages.Messages; 27 28 public class ReportFileMetaDataProvider extends SolutionFileMetaAdapter { 29 private static final Log logger = LogFactory 30 .getLog(ReportFileMetaDataProvider.class); 31 32 private static final String PROPERTIES_SUFFIX = ".properties"; //$NON-NLS-1$ 33 34 public ReportFileMetaDataProvider() { 35 } 36 37 public void setLogger(final ILogger logger) { 38 } 39 40 private DocumentBundle loadBundle(final String reportDefinitionPath) 41 throws ResourceException { 42 final ResourceManager resourceManager = new ResourceManager(); 43 resourceManager.registerDefaults(); 44 final HashMap helperObjects = new HashMap(); 45 // add the runtime context so that PentahoResourceData class can get 46 // access 47 // to the solution repo 48 final ResourceKey key = resourceManager.createKey( 49 RepositoryResourceLoader.SOLUTION_SCHEMA_NAME 50 + RepositoryResourceLoader.SCHEMA_SEPARATOR 51 + reportDefinitionPath, helperObjects); 52 final Resource resource = resourceManager.create(key, null, 53 DocumentBundle.class); 54 final DocumentBundle bundle = (DocumentBundle) resource.getResource(); 55 return bundle; 56 } 57 58 public IFileInfo getFileInfo(final ISolutionFile solutionFile, 59 final InputStream in) { 60 try { 61 DocumentBundle bundle = loadBundle(solutionFile.getSolutionPath() 62 + "/" + solutionFile.getFileName()); 63 64 DocumentMetaData metaData = bundle.getMetaData(); //$NON-NLS-1$ 65 66 String title = (String) metaData.getBundleAttribute( 67 ODFMetaAttributeNames.DublinCore.NAMESPACE, 68 ODFMetaAttributeNames.DublinCore.TITLE); 69 String author = (String) metaData.getBundleAttribute( 70 ODFMetaAttributeNames.DublinCore.NAMESPACE, 71 ODFMetaAttributeNames.DublinCore.CREATOR); 72 String description = (String) metaData.getBundleAttribute( 73 ODFMetaAttributeNames.DublinCore.NAMESPACE, 74 ODFMetaAttributeNames.DublinCore.DESCRIPTION); 75 76 if (title != null && title.startsWith("%")) { 77 78 title = getValue(solutionFile, bundle, title); 79 } 80 81 if (author != null && author.startsWith("%")) { 82 author = getValue(solutionFile, bundle, author); 83 } 84 85 if (description != null && description.startsWith("%")) { 86 description = getValue(solutionFile, bundle, description); 87 } 88 89 final IFileInfo fileInfo = new FileInfo(); 90 if (StringUtils.isEmpty(title)) { 91 fileInfo.setTitle(solutionFile.getFileName()); 92 } else { 93 fileInfo.setTitle(title); 94 } 95 fileInfo.setAuthor(author); //$NON-NLS-1$ 96 fileInfo.setDescription(description); 97 98 // displaytype is a magical constant defined in a internal class of 99 // the platform. 100 if ("false".equals(metaData.getBundleAttribute( 101 ClassicEngineBoot.METADATA_NAMESPACE, "visible"))) { 102 fileInfo.setDisplayType("none"); // NON-NLS 103 } else { 104 fileInfo.setDisplayType("report"); // NON-NLS 105 } 106 return fileInfo; 107 } catch (Exception e) { 108 logger.warn( 109 Messages.getInstance().getString( 110 "ReportPlugin.errorMetadataNotReadable"), e); 111 return null; 112 } 113 } 114 115 private String getValue(ISolutionFile solutionFile, DocumentBundle bundle, String key) { 116 if (key == null) { 117 return null; 118 } 119 key = key.substring(1); 120 try { 121 String baseName = solutionFile.getFileName().substring(0, 122 solutionFile.getFileName().lastIndexOf('.')); 123 // System.out.println("--------------" + baseName); 124 125 String plcv = null; 126 String plc = null; 127 String pl = null; 128 String p = null; 129 130 plcv = baseName + '_' + getLocale().getLanguage() + '_' 131 + getLocale().getCountry() + '_' + getLocale().getVariant() 132 + PROPERTIES_SUFFIX; 133 plc = baseName + '_' + getLocale().getLanguage() + '_' 134 + getLocale().getCountry() + PROPERTIES_SUFFIX; 135 pl = baseName + '_' + getLocale().getLanguage() + PROPERTIES_SUFFIX; 136 p = baseName + PROPERTIES_SUFFIX; 137 String localeText = getLocaleText(bundle, key, plcv); 138 // System.out.println("localeText 01: " +localeText); 139 if (localeText == null) { 140 localeText = getLocaleText(bundle, key, plc); 141 // System.out.println("localeText 02: " +localeText); 142 if (localeText == null) { 143 localeText = getLocaleText(bundle, key, pl); 144 // System.out.println("localeText 03: " +localeText); 145 if (localeText == null) { 146 localeText = getLocaleText(bundle, key, p); 147 // System.out.println("localeText 04: " +localeText); 148 } 149 } 150 // System.out.println("localeText 05: " +localeText); 151 } 152 if (localeText != null) { 153 return localeText; 154 } 155 return baseName; 156 }catch (Exception e) { 157 // TODO Auto-generated catch block 158 e.printStackTrace(); 159 } 160 return null; 161 162 } 163 164 private String getLocaleText(DocumentBundle bundle, String key, String fileName) { 165 InputStream in = null; 166 String localText = null; 167 try { 168 if(!bundle.isEntryExists(fileName)){ 169 return null; 170 } 171 in = bundle.getEntryAsStream(fileName); 172 Properties prop = new Properties(); 173 prop.load(in); 174 localText = prop.getProperty(key); 175 if (localText != null) { 176 return localText; 177 } 178 } catch (IOException e) { 179 // TODO Auto-generated catch block 180 e.printStackTrace(); 181 } finally { 182 //we cont close this input , for this input is managed by Bundle 183 // if (in != null) { 184 // try { 185 // in.close(); 186 // } catch (IOException e) { 187 // // TODO Auto-generated catch block 188 // e.printStackTrace(); 189 // } 190 // } 191 } 192 193 return null; 194 } 195 196 protected Locale getLocale() { 197 return LocaleHelper.getLocale(); 198 } 199 200 } } }
作者做了如下处理:
1、读取title\description\author
2、判断如果是以%开头,则获取国际化字符串
3、获取国际化字符串,从prpt 的Entry中根据Location 获取国际化文件,读出国际化字符串的值。
另外:这个Entry的InputStream 不能close掉,因为它是由Pentaho加载数据的时候给初始化的,每次进行刷新Repository都是拿这个InputStream.
OK,修改完成后,将该class文件替换到原有的Jar包中,即可。
经过研究之后发现:PRPT报表的参数也是可以国际化的 代码献上来:
1 package org.pentaho.reporting.platform.plugin; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.io.OutputStream; 6 import java.lang.reflect.Array; 7 import java.math.BigDecimal; 8 import java.text.DateFormat; 9 import java.text.SimpleDateFormat; 10 import java.util.Collections; 11 import java.util.Date; 12 import java.util.HashMap; 13 import java.util.LinkedHashMap; 14 import java.util.LinkedHashSet; 15 import java.util.List; 16 import java.util.Locale; 17 import java.util.Map; 18 import java.util.Properties; 19 import java.util.TimeZone; 20 21 import javax.xml.parsers.DocumentBuilderFactory; 22 import javax.xml.transform.Transformer; 23 import javax.xml.transform.TransformerFactory; 24 import javax.xml.transform.dom.DOMSource; 25 import javax.xml.transform.stream.StreamResult; 26 27 import org.apache.commons.logging.Log; 28 import org.apache.commons.logging.LogFactory; 29 import org.pentaho.di.core.util.StringUtil; 30 import org.pentaho.platform.api.engine.IParameterProvider; 31 import org.pentaho.platform.api.engine.IPentahoSession; 32 import org.pentaho.platform.api.repository.ISchedule; 33 import org.pentaho.platform.api.repository.ISubscribeContent; 34 import org.pentaho.platform.api.repository.ISubscription; 35 import org.pentaho.platform.api.repository.ISubscriptionRepository; 36 import org.pentaho.platform.engine.core.system.PentahoSystem; 37 import org.pentaho.platform.util.UUIDUtil; 38 import org.pentaho.platform.util.messages.LocaleHelper; 39 import org.pentaho.reporting.engine.classic.core.AttributeNames; 40 import org.pentaho.reporting.engine.classic.core.MasterReport; 41 import org.pentaho.reporting.engine.classic.core.ReportDataFactoryException; 42 import org.pentaho.reporting.engine.classic.core.ReportElement; 43 import org.pentaho.reporting.engine.classic.core.Section; 44 import org.pentaho.reporting.engine.classic.core.function.Expression; 45 import org.pentaho.reporting.engine.classic.core.function.FormulaExpression; 46 import org.pentaho.reporting.engine.classic.core.modules.output.pageable.pdf.PdfPageableModule; 47 import org.pentaho.reporting.engine.classic.core.modules.output.pageable.plaintext.PlainTextPageableModule; 48 import org.pentaho.reporting.engine.classic.core.modules.output.table.csv.CSVTableModule; 49 import org.pentaho.reporting.engine.classic.core.modules.output.table.html.HtmlTableModule; 50 import org.pentaho.reporting.engine.classic.core.modules.output.table.rtf.RTFTableModule; 51 import org.pentaho.reporting.engine.classic.core.modules.output.table.xls.ExcelTableModule; 52 import org.pentaho.reporting.engine.classic.core.parameters.AbstractParameter; 53 import org.pentaho.reporting.engine.classic.core.parameters.DefaultParameterContext; 54 import org.pentaho.reporting.engine.classic.core.parameters.ListParameter; 55 import org.pentaho.reporting.engine.classic.core.parameters.ParameterAttributeNames; 56 import org.pentaho.reporting.engine.classic.core.parameters.ParameterContext; 57 import org.pentaho.reporting.engine.classic.core.parameters.ParameterContextWrapper; 58 import org.pentaho.reporting.engine.classic.core.parameters.ParameterDefinitionEntry; 59 import org.pentaho.reporting.engine.classic.core.parameters.ParameterValues; 60 import org.pentaho.reporting.engine.classic.core.parameters.PlainParameter; 61 import org.pentaho.reporting.engine.classic.core.parameters.ReportParameterDefinition; 62 import org.pentaho.reporting.engine.classic.core.parameters.StaticListParameter; 63 import org.pentaho.reporting.engine.classic.core.parameters.ValidationMessage; 64 import org.pentaho.reporting.engine.classic.core.parameters.ValidationResult; 65 import org.pentaho.reporting.engine.classic.core.style.ElementStyleKeys; 66 import org.pentaho.reporting.engine.classic.core.util.NullOutputStream; 67 import org.pentaho.reporting.engine.classic.core.util.ReportParameterValues; 68 import org.pentaho.reporting.engine.classic.core.util.beans.BeanException; 69 import org.pentaho.reporting.engine.classic.core.util.beans.ConverterRegistry; 70 import org.pentaho.reporting.engine.classic.core.util.beans.ValueConverter; 71 import org.pentaho.reporting.engine.classic.extensions.drilldown.DrillDownProfile; 72 import org.pentaho.reporting.engine.classic.extensions.drilldown.DrillDownProfileMetaData; 73 import org.pentaho.reporting.libraries.base.util.StringUtils; 74 import org.pentaho.reporting.libraries.docbundle.DocumentBundle; 75 import org.pentaho.reporting.libraries.formula.DefaultFormulaContext; 76 import org.pentaho.reporting.libraries.formula.lvalues.DataTable; 77 import org.pentaho.reporting.libraries.formula.lvalues.FormulaFunction; 78 import org.pentaho.reporting.libraries.formula.lvalues.LValue; 79 import org.pentaho.reporting.libraries.formula.lvalues.StaticValue; 80 import org.pentaho.reporting.libraries.formula.parser.FormulaParser; 81 import org.pentaho.reporting.libraries.resourceloader.Resource; 82 import org.pentaho.reporting.libraries.resourceloader.ResourceException; 83 import org.pentaho.reporting.libraries.resourceloader.ResourceKey; 84 import org.pentaho.reporting.libraries.resourceloader.ResourceManager; 85 import org.pentaho.reporting.platform.plugin.messages.Messages; 86 import org.w3c.dom.Document; 87 import org.w3c.dom.Element; 88 89 /** 90 * Todo: Document me! 91 * 92 * Date: 22.07.2010 Time: 16:24:30 93 * 94 * @author Thomas Morgner. 95 */ 96 public class ParameterXmlContentHandler { 97 private static class OutputParameterCollector { 98 private OutputParameterCollector() { 99 } 100 101 public String[] collectParameter(final MasterReport reportDefinition) { 102 final LinkedHashSetparameter = new LinkedHashSet (); 103 104 inspectElement(reportDefinition, parameter); 105 traverseSection(reportDefinition, parameter); 106 107 return parameter.toArray(new String[parameter.size()]); 108 } 109 110 private void traverseSection(final Section section, 111 final LinkedHashSet parameter) { 112 final int count = section.getElementCount(); 113 for (int i = 0; i < count; i++) { 114 final ReportElement element = section.getElement(i); 115 inspectElement(element, parameter); 116 if (element instanceof Section) { 117 traverseSection((Section) element, parameter); 118 } 119 } 120 } 121 122 private void inspectElement(final ReportElement element, 123 final LinkedHashSet parameter) { 124 try { 125 final Expression expression = element 126 .getStyleExpression(ElementStyleKeys.HREF_TARGET); 127 if (expression instanceof FormulaExpression == false) { 128 // DrillDown only works with the formula function of the 129 // same name 130 return; 131 } 132 133 final FormulaExpression fe = (FormulaExpression) expression; 134 final String formulaText = fe.getFormulaExpression(); 135 if (StringUtils.isEmpty(formulaText)) { 136 // DrillDown only works with the formula function of the 137 // same name 138 return; 139 } 140 141 if (formulaText.startsWith("DRILLDOWN") == false) // NON-NLS 142 { 143 // DrillDown only works if the function is the only element. 144 // Everything else is beyond our control. 145 return; 146 } 147 final FormulaParser formulaParser = new FormulaParser(); 148 final LValue value = formulaParser.parse(formulaText); 149 if (value instanceof FormulaFunction == false) { 150 // Not a valid formula or a complex term - we do not handle 151 // that 152 return; 153 } 154 final DefaultFormulaContext context = new DefaultFormulaContext(); 155 value.initialize(context); 156 157 final FormulaFunction fn = (FormulaFunction) value; 158 final LValue[] params = fn.getChildValues(); 159 if (params.length != 3) { 160 // Malformed formula: Need 3 parameter 161 return; 162 } 163 final String config = extractText(params[0]); 164 if (config == null) { 165 // Malformed formula: No statically defined config profile 166 return; 167 } 168 169 final DrillDownProfile profile = DrillDownProfileMetaData 170 .getInstance().getDrillDownProfile(config); 171 if (profile == null) { 172 // Malformed formula: Unknown drilldown profile 173 return; 174 } 175 176 if ("pentaho".equals(profile.getAttribute("group")) == false) // NON-NLS 177 { 178 // Only 'pentaho' drill-down profiles can be used. Filters 179 // out all other third party drilldowns 180 return; 181 } 182 183 if (params[2] instanceof DataTable == false) { 184 // Malformed formula: Not a parameter table 185 return; 186 } 187 final DataTable dataTable = (DataTable) params[2]; 188 final int rowCount = dataTable.getRowCount(); 189 final int colCount = dataTable.getColumnCount(); 190 if (colCount != 2) { 191 // Malformed formula: Parameter table is invalid. Must be 192 // two cols, many rows .. 193 return; 194 } 195 196 for (int i = 0; i < rowCount; i++) { 197 final LValue valueAt = dataTable.getValueAt(i, 0); 198 final String name = extractText(valueAt); 199 if (name == null) { 200 continue; 201 } 202 parameter.add(name); 203 } 204 } catch (Exception e) { 205 // ignore .. 206 } 207 } 208 209 private String extractText(final LValue value) { 210 if (value == null) { 211 return null; 212 } 213 if (value.isConstant()) { 214 if (value instanceof StaticValue) { 215 final StaticValue staticValue = (StaticValue) value; 216 final Object o = staticValue.getValue(); 217 if (o == null) { 218 return null; // NON-NLS 219 } 220 return String.valueOf(o); 221 } 222 } 223 return null; // NON-NLS 224 225 } 226 227 } 228 229 private static final Log logger = LogFactory 230 .getLog(ParameterXmlContentHandler.class); 231 public static final String SYS_PARAM_ACCEPTED_PAGE = "accepted-page"; 232 233 private Map systemParameter; 234 235 private ReportContentGenerator contentGenerator; 236 private boolean paginate; 237 private Document document; 238 private IParameterProvider requestParameters; 239 private IPentahoSession userSession; 240 private Map inputs; 241 private String reportDefinitionPath; 242 243 public static final String SYS_PARAM_RENDER_MODE = "renderMode"; 244 private static final String SYS_PARAM_OUTPUT_TARGET = SimpleReportingComponent.OUTPUT_TARGET; 245 private static final String SYS_PARAM_SUBSCRIPTION_NAME = "subscription-name"; 246 private static final String SYS_PARAM_DESTINATION = "destination"; 247 private static final String SYS_PARAM_SCHEDULE_ID = "schedule-id"; 248 public static final String SYS_PARAM_CONTENT_LINK = "::cl"; 249 public static final String SYS_PARAM_SESSION_ID = "::session"; 250 private static final String GROUP_SUBSCRIPTION = "subscription"; 251 private static final String GROUP_SYSTEM = "system"; 252 private static final String GROUP_PARAMETERS = "parameters"; 253 private static final String SYS_PARAM_TAB_NAME = "::TabName"; 254 private static final String SYS_PARAM_TAB_ACTIVE = "::TabActive"; 255 256 private static final String SYS_PARAM_HTML_PROPORTIONAL_WIDTH = "htmlProportionalWidth"; 257 private static final String CONFIG_PARAM_HTML_PROPORTIONAL_WIDTH = "org.pentaho.reporting.engine.classic.core.modules.output.table.html.ProportionalColumnWidths"; 258 259 private static Map parameterLabels = new HashMap (); 260 261 public ParameterXmlContentHandler( 262 final ReportContentGenerator contentGenerator, 263 final boolean paginate) { 264 this.contentGenerator = contentGenerator; 265 this.paginate = paginate; 266 this.inputs = contentGenerator.createInputs(); 267 this.requestParameters = contentGenerator.getRequestParameters(); 268 this.userSession = contentGenerator.getUserSession(); 269 } 270 271 private IParameterProvider getRequestParameters() { 272 return requestParameters; 273 } 274 275 private Map getSystemParameter() { 276 if (systemParameter == null) { 277 final Map parameter = new LinkedHashMap (); 278 parameter.put(SYS_PARAM_SUBSCRIPTION_NAME, 279 createSubscriptionNameParameter()); 280 parameter.put(SYS_PARAM_DESTINATION, createDestinationParameter()); 281 parameter.put(SYS_PARAM_SCHEDULE_ID, createScheduleIdParameter()); 282 parameter.put(SYS_PARAM_OUTPUT_TARGET, createOutputParameter()); 283 parameter.put( 284 "subscribe", 285 createGenericBooleanSystemParameter("subscribe", false, 286 false)); // NON-NLS 287 parameter.put(SYS_PARAM_CONTENT_LINK, 288 createContentLinkingParameter()); // NON-NLS 289 parameter.put( 290 SYS_PARAM_TAB_NAME, 291 createGenericSystemParameter(SYS_PARAM_TAB_NAME, false, 292 true)); // NON-NLS 293 parameter.put( 294 SYS_PARAM_TAB_ACTIVE, 295 createGenericBooleanSystemParameter(SYS_PARAM_TAB_ACTIVE, 296 false, true)); // NON-NLS 297 // parameter.put("solution", 298 // createGenericSystemParameter("solution", false, false)); // 299 // NON-NLS 300 parameter 301 .put("yield-rate", 302 createGenericIntSystemParameter("yield-rate", 303 false, false)); // NON-NLS 304 parameter.put( 305 SYS_PARAM_ACCEPTED_PAGE, 306 createGenericIntSystemParameter(SYS_PARAM_ACCEPTED_PAGE, 307 false, false)); // NON-NLS 308 parameter.put( 309 SYS_PARAM_SESSION_ID, 310 createGenericSystemParameter(SYS_PARAM_SESSION_ID, false, 311 false)); // NON-NLS 312 // parameter.put("path", createGenericSystemParameter("path", false, 313 // false)); // NON-NLS 314 // parameter.put("name", createGenericSystemParameter("name", false, 315 // false)); // NON-NLS 316 // parameter.put("action", createGenericSystemParameter("action", 317 // true, false)); // NON-NLS 318 parameter.put("output-type", 319 createGenericSystemParameter("output-type", true, false)); // NON-NLS 320 parameter.put("layout", 321 createGenericSystemParameter("layout", true, false)); // NON-NLS 322 parameter.put( 323 "content-handler-pattern", 324 createGenericSystemParameter("content-handler-pattern", 325 true, false)); // NON-NLS 326 parameter.put( 327 "autoSubmit", 328 createGenericBooleanSystemParameter("autoSubmit", true, 329 true)); // NON-NLS 330 parameter.put( 331 "autoSubmitUI", 332 createGenericBooleanSystemParameter("autoSubmitUI", true, 333 true)); // NON-NLS 334 parameter.put( 335 "dashboard-mode", 336 createGenericBooleanSystemParameter("dashboard-mode", 337 false, true)); // NON-NLS 338 parameter.put( 339 "showParameters", 340 createGenericBooleanSystemParameter("showParameters", true, 341 true)); // NON-NLS 342 parameter 343 .put("paginate", 344 createGenericBooleanSystemParameter("paginate", 345 true, false)); // NON-NLS 346 parameter.put( 347 "ignoreDefaultDates", 348 createGenericBooleanSystemParameter("ignoreDefaultDates", 349 true, false)); // NON-NLS 350 parameter.put("print", 351 createGenericBooleanSystemParameter("print", false, false)); // NON-NLS 352 parameter.put("printer-name", 353 createGenericSystemParameter("printer-name", false, false)); // NON-NLS 354 parameter.put(SYS_PARAM_RENDER_MODE, 355 createRenderModeSystemParameter()); // NON-NLS 356 parameter.put( 357 SYS_PARAM_HTML_PROPORTIONAL_WIDTH, 358 createGenericBooleanSystemParameter( 359 SYS_PARAM_HTML_PROPORTIONAL_WIDTH, false, true)); 360 361 systemParameter = Collections.unmodifiableMap(parameter); 362 } 363 364 return systemParameter; 365 } 366 367 /** 368 * Defines whether parameter with display-type "datepicker" that have no 369 * default value set shall default to "today". This setting generates a 370 * default value for the parameter UI, but has no effect otherwise. It is 371 * flawed from the very beginning and should not be used. 372 * 373 * @return whether we generate default dates. 374 */ 375 private boolean isGenerateDefaultDates() { 376 final Object value = inputs.get("ignoreDefaultDates"); // NON-NLS 377 if (value == null) { 378 // we do not generate default dates until it is explicitly 379 // requested. 380 // if the users want default values for parameters then let them 381 // define those in the parameter 382 return false; 383 } 384 385 return "true".equals(value); 386 } 387 388 public void createParameterContent(final OutputStream outputStream, 389 final String reportDefinitionPath) throws Exception { 390 createParameterContent(outputStream, reportDefinitionPath, null); 391 } 392 393 public void createParameterContent(final OutputStream outputStream, 394 final String reportDefinitionPath, MasterReport report) 395 throws Exception { 396 final Object rawSessionId = inputs 397 .get(ParameterXmlContentHandler.SYS_PARAM_SESSION_ID); 398 if ((rawSessionId instanceof String) == false 399 || "".equals(rawSessionId)) { 400 inputs.put(ParameterXmlContentHandler.SYS_PARAM_SESSION_ID, 401 UUIDUtil.getUUIDAsString()); 402 } 403 404 this.reportDefinitionPath = reportDefinitionPath; 405 this.document = DocumentBuilderFactory.newInstance() 406 .newDocumentBuilder().newDocument(); 407 408 final IParameterProvider requestParams = getRequestParameters(); 409 410 final boolean subscribe = "true".equals(requestParams.getStringParameter("subscribe", "false")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 411 // handle parameter feedback (XML) services 412 413 final SimpleReportingComponent reportComponent = new SimpleReportingComponent(); 414 reportComponent.setReportDefinitionPath(reportDefinitionPath); 415 if (report != null) { 416 reportComponent.setReport(report); 417 } 418 reportComponent.setPaginateOutput(true); 419 reportComponent 420 .setDefaultOutputTarget(HtmlTableModule.TABLE_HTML_PAGE_EXPORT_TYPE); 421 reportComponent.setInputs(inputs); 422 423 report = reportComponent.getReport(); 424 final DefaultParameterContext parameterContext = new DefaultParameterContext( 425 report); 426 final ValidationResult vr; 427 final Element parameters; 428 try { 429 // open parameter context 430 parameterContext.open(); 431 // apply inputs to parameters 432 final ValidationResult validationResult = reportComponent 433 .applyInputsToReportParameters(parameterContext, 434 new ValidationResult()); 435 436 final ReportParameterDefinition reportParameterDefinition = report 437 .getParameterDefinition(); 438 // System.out.println(reportDefinitionPath); 439 vr = reportParameterDefinition.getValidator().validate( 440 validationResult, reportParameterDefinition, 441 parameterContext); 442 443 parameters = document.createElement(GROUP_PARAMETERS); //$NON-NLS-1$ 444 parameters.setAttribute( 445 "is-prompt-needed", String.valueOf(vr.isEmpty() == false)); //$NON-NLS-1$ //$NON-NLS-2$ 446 parameters.setAttribute("subscribe", String.valueOf(subscribe)); //$NON-NLS-1$ //$NON-NLS-2$ 447 parameters.setAttribute("ignore-biserver-5538", "true"); 448 449 // check if pagination is allowed and turned on 450 451 final Boolean autoSubmitFlag = requestFlag("autoSubmit", report, 452 AttributeNames.Core.NAMESPACE, 453 AttributeNames.Core.AUTO_SUBMIT_PARAMETER, 454 "org.pentaho.reporting.engine.classic.core.ParameterAutoSubmit"); 455 if (Boolean.TRUE.equals(autoSubmitFlag)) { 456 parameters.setAttribute("autoSubmit", "true"); 457 } else if (Boolean.FALSE.equals(autoSubmitFlag)) { 458 parameters.setAttribute("autoSubmit", "false"); 459 } 460 461 final Boolean autoSubmitUiFlag = requestFlag( 462 "autoSubmitUI", 463 report, // NON-NLS 464 AttributeNames.Core.NAMESPACE, 465 AttributeNames.Core.AUTO_SUBMIT_DEFAULT, 466 "org.pentaho.reporting.engine.classic.core.ParameterAutoSubmitUI"); 467 if (Boolean.FALSE.equals(autoSubmitUiFlag)) { 468 parameters.setAttribute("autoSubmitUI", "false"); // NON-NLS 469 } else { 470 parameters.setAttribute("autoSubmitUI", "true"); // NON-NLS 471 } 472 473 parameters 474 .setAttribute( 475 "layout", 476 requestConfiguration( 477 "layout", 478 report, // NON-NLS 479 AttributeNames.Core.NAMESPACE, 480 AttributeNames.Core.PARAMETER_UI_LAYOUT, 481 "org.pentaho.reporting.engine.classic.core.ParameterUiLayout")); 482 483 final ParameterDefinitionEntry[] parameterDefinitions = reportParameterDefinition 484 .getParameterDefinitions(); 485 // Collect all parameter, but allow user-parameter to override 486 // system parameter. 487 // It is the user's problem if the types do not match and weird 488 // errors occur, but 489 // there are sensible usecases where this should be allowed. 490 // System parameter must come last in the list, as this is how it 491 // was done in the original 492 // version and this is how people expect it to be now. 493 DocumentBundle bundle = loadBundle(reportDefinitionPath); 494 final LinkedHashMap reportParameters = new LinkedHashMap (); 495 { 496 //System.out.println("------------------------" + reportDefinitionPath); 497 // DocumentBundle bundle = loadBundle(reportDefinitionPath); 498 final String baseName = reportDefinitionPath.substring(reportDefinitionPath.lastIndexOf("/") + 1, reportDefinitionPath.lastIndexOf(".")); 499 String labelText = ""; 500 String labelTextKey = ""; 501 // System.out.println("==================================================="); 502 for (ParameterDefinitionEntry parameter : parameterDefinitions){ 503 //parameter. 504 AbstractParameter ap = (AbstractParameter)parameter; 505 labelTextKey = ap.getParameterAttribute(ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.LABEL); 506 if(labelTextKey.startsWith("%") || parameterLabels.containsKey(reportDefinitionPath + labelTextKey)){ 507 if(labelTextKey.startsWith("%")){ 508 // parameterLabels.put(reportDefinitionPath + labelText.substring(1)); 509 labelTextKey = labelTextKey.substring(1); 510 }else{ 511 labelTextKey = parameterLabels.get(reportDefinitionPath + labelTextKey); 512 } 513 // System.out.println("labelkey : " + labelTextKey); 514 labelText = getValue(baseName, bundle, labelTextKey); 515 if(!StringUtil.isEmpty(labelText)){ 516 // System.out.println("labelText : " + labelText); 517 ap.setParameterAttribute(ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.LABEL, labelText); 518 if(!parameterLabels.containsKey(reportDefinitionPath + labelText)){ 519 parameterLabels.put(reportDefinitionPath + labelText, labelTextKey); 520 } 521 } 522 // System.out.println("labelText2 : " + parameter.getParameterAttribute(ParameterAttributeNames.Core.NAMESPACE, ParameterAttributeNames.Core.LABEL, parameterContext)); 523 } 524 525 reportParameters.put(parameter.getName(), parameter); 526 } 527 528 } 529 for (final Map.Entry entry : getSystemParameter() 530 .entrySet()) { 531 if (reportParameters.containsKey(entry.getKey()) == false) { 532 reportParameters.put(entry.getKey(), entry.getValue()); 533 } 534 } 535 536 hideOutputParameterIfLocked(report, reportParameters); 537 hideSubscriptionParameter(subscribe, reportParameters); 538 final Map inputs = computeRealInput( 539 parameterContext, reportParameters, 540 reportComponent.getComputedOutputTarget(), vr); 541 542 final Boolean showParameterUI = requestFlag( 543 "showParameters", 544 report, // NON-NLS 545 AttributeNames.Core.NAMESPACE, 546 AttributeNames.Core.SHOW_PARAMETER_UI, null); 547 if (Boolean.FALSE.equals(showParameterUI)) { 548 inputs.put("showParameters", Boolean.FALSE); // NON-NLS 549 } else { 550 inputs.put("showParameters", Boolean.TRUE); // NON-NLS 551 } 552 553 // Adding proportional width config parameter 554 String proportionalWidth = report.getReportConfiguration() 555 .getConfigProperty(CONFIG_PARAM_HTML_PROPORTIONAL_WIDTH); 556 inputs.put(SYS_PARAM_HTML_PROPORTIONAL_WIDTH, 557 Boolean.valueOf(proportionalWidth)); 558 559 for (final ParameterDefinitionEntry parameter : reportParameters 560 .values()) { 561 final Object selections = inputs.get(parameter.getName()); 562 final ParameterContextWrapper wrapper = new ParameterContextWrapper( 563 parameterContext, vr.getParameterValues()); 564 parameters.appendChild(createParameterElement(parameter, 565 wrapper, selections)); 566 } 567 568 if (vr.isEmpty() == false) { 569 parameters.appendChild(createErrorElements(vr)); 570 } 571 572 final String[] outputParameter = new OutputParameterCollector() 573 .collectParameter(report); 574 for (int i = 0; i < outputParameter.length; i++) { 575 final String outputParameterName = outputParameter[i]; 576 // 577 // id="[Markets].[Territory]"/> 578 final Element element = document 579 .createElement("output-parameter");// NON-NLS 580 element.setAttribute("displayName", outputParameterName);// NON-NLS 581 element.setAttribute("id", outputParameterName);// NON-NLS 582 parameters.appendChild(element); 583 } 584 585 if (vr.isEmpty() && paginate) //$NON-NLS-1$ //$NON-NLS-2$ 586 { 587 appendPageCount(reportComponent, parameters); 588 } 589 document.appendChild(parameters); 590 591 final DOMSource source = new DOMSource(document); 592 final StreamResult result = new StreamResult(outputStream); 593 final Transformer transformer = TransformerFactory.newInstance() 594 .newTransformer(); 595 596 transformer.transform(source, result); 597 // close parameter context 598 } finally { 599 parameterContext.close(); 600 } 601 } 602 603 private Map computeRealInput( 604 final ParameterContext parameterContext, 605 final LinkedHashMap reportParameters, 606 final String computedOutputTarget, final ValidationResult result) { 607 final Map realInputs = new HashMap (); 608 realInputs.put(SYS_PARAM_DESTINATION, lookupDestination()); 609 realInputs.put(SYS_PARAM_SCHEDULE_ID, lookupSchedules()); 610 realInputs.put(SYS_PARAM_SUBSCRIPTION_NAME, lookupSubscriptionName()); 611 612 final ReportParameterValues parameterValues = result 613 .getParameterValues(); 614 615 for (final ParameterDefinitionEntry parameter : reportParameters 616 .values()) { 617 final String parameterName = parameter.getName(); 618 final Object parameterFromReport = parameterValues 619 .get(parameterName); 620 if (parameterFromReport != null) { 621 // always prefer the report parameter. The user's input has been 622 // filtered already and values 623 // may have been replaced by a post-processing formula. 624 // 625 realInputs.put(parameterName, parameterFromReport); 626 continue; 627 } 628 629 // the parameter values collection only contains declared parameter. 630 // So everything else will 631 // be handled now. This is also the time to handle rejected 632 // parameter. For these parameter, 633 // the calculated value for the report is . 634 final Object value = inputs.get(parameterName); 635 if (value == null) { 636 // have no value, so we use the default value .. 637 realInputs.put(parameterName, null); 638 continue; 639 } 640 641 try { 642 final Object translatedValue = ReportContentUtil 643 .computeParameterValue(parameterContext, parameter, 644 value); 645 if (translatedValue != null) { 646 realInputs.put(parameterName, translatedValue); 647 } else { 648 realInputs.put(parameterName, null); 649 } 650 } catch (Exception be) { 651 if (logger.isDebugEnabled()) { 652 logger.debug( 653 Messages.getInstance() 654 .getString( 655 "ReportPlugin.debugParameterCannotBeConverted", 656 parameter.getName(), 657 String.valueOf(value)), be); 658 } 659 } 660 } 661 662 // thou cannot override the output target with invalid values .. 663 realInputs.put(SYS_PARAM_OUTPUT_TARGET, computedOutputTarget); 664 return realInputs; 665 } 666 667 private void hideOutputParameterIfLocked(final MasterReport report, 668 final MapreportParameters) { 669 final boolean lockOutputType = Boolean.TRUE.equals(report.getAttribute( 670 AttributeNames.Core.NAMESPACE, 671 AttributeNames.Core.LOCK_PREFERRED_OUTPUT_TYPE)); 672 final ParameterDefinitionEntry definitionEntry = reportParameters 673 .get(SimpleReportingComponent.OUTPUT_TARGET); 674 if (definitionEntry instanceof AbstractParameter) { 675 final AbstractParameter parameter = (AbstractParameter) definitionEntry; 676 parameter.setHidden(lockOutputType); 677 parameter.setMandatory(!lockOutputType); 678 } 679 } 680 681 private Element createParameterElement( 682 final ParameterDefinitionEntry parameter, 683 final ParameterContext parameterContext, final Object selections) 684 throws BeanException, ReportDataFactoryException { 685 try { 686 final Element parameterElement = document 687 .createElement("parameter"); //$NON-NLS-1$ 688 parameterElement.setAttribute("name", parameter.getName()); //$NON-NLS-1$ 689 final Class valueType = parameter.getValueType(); 690 parameterElement.setAttribute("type", valueType.getName()); //$NON-NLS-1$ 691 parameterElement.setAttribute( 692 "is-mandatory", String.valueOf(parameter.isMandatory())); //$NON-NLS-1$ //$NON-NLS-2$ 693 // System.out.println("- name:" + parameter.getName()); 694 final String[] namespaces = parameter 695 .getParameterAttributeNamespaces(); 696 for (int i = 0; i < namespaces.length; i++) { 697 final String namespace = namespaces[i]; 698 // System.out.println(" - namespace:" + namespace); 699 final String[] attributeNames = parameter 700 .getParameterAttributeNames(namespace); 701 for (final String attributeName : attributeNames) { 702 final String attributeValue = parameter 703 .getParameterAttribute(namespace, attributeName, 704 parameterContext); 705 // expecting: label, parameter-render-type, parameter-layout 706 // but others possible as well, so we set them all 707 final Element attributeElement = document 708 .createElement("attribute"); // NON-NLS 709 attributeElement.setAttribute("namespace", namespace); // NON-NLS 710 attributeElement.setAttribute("name", attributeName); // NON-NLS 711 attributeElement.setAttribute("value", attributeValue); // NON-NLS 712 parameterElement.appendChild(attributeElement); 713 } 714 } 715 716 final Class elementValueType; 717 if (valueType.isArray()) { 718 elementValueType = valueType.getComponentType(); 719 } else { 720 elementValueType = valueType; 721 } 722 723 if (Date.class.isAssignableFrom(elementValueType)) { 724 parameterElement 725 .setAttribute( 726 "timzone-hint", computeTimeZoneHint(parameter, parameterContext));//$NON-NLS-1$ 727 } 728 729 final LinkedHashSet
明亮显示部分为作者添加的代码:
主要功能是将Parameter的label每次读取的时候读取国际化文件,读出国际化字符。
用法: add Parameter 后将label设置为“%" +国家化字符 如:%begin_date 然后在国际化文件中添加begin_date 的国际化字符。
大家如果要下载的话 可以上我的CSDN下载。
http://download.csdn.net/detail/mryuqinghua/5336309
转自:http://www.cnblogs.com/lucas-yu/archive/2013/04/26/Pentaho%E4%B8%AD%E6%96%87%E5%9B%BD%E9%99%85%E5%8C%96%E4%B9%8BPRPT.html