/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ package com.sun.star.report.pentaho; import com.sun.star.beans.NamedValue; import com.sun.star.beans.PropertyVetoException; import com.sun.star.beans.UnknownPropertyException; import com.sun.star.beans.XPropertyChangeListener; import com.sun.star.beans.XPropertySet; import com.sun.star.beans.XVetoableChangeListener; import com.sun.star.container.XChild; import com.sun.star.embed.XStorage; import com.sun.star.frame.XModel; import com.sun.star.lang.IllegalArgumentException; import com.sun.star.lang.WrappedTargetException; import com.sun.star.lang.XInitialization; import com.sun.star.lang.XServiceInfo; import com.sun.star.lang.XSingleComponentFactory; import com.sun.star.lib.uno.helper.Factory; import com.sun.star.lib.uno.helper.PropertySetMixin; import com.sun.star.lib.uno.helper.WeakBase; import com.sun.star.registry.InvalidRegistryException; import com.sun.star.registry.InvalidValueException; import com.sun.star.registry.XRegistryKey; import com.sun.star.registry.XSimpleRegistry; import com.sun.star.report.DataSourceFactory; import com.sun.star.report.JobProperties; import com.sun.star.report.ReportEngineParameterNames; import com.sun.star.report.ReportExecutionException; import com.sun.star.report.ReportJob; import com.sun.star.report.ReportJobDefinition; import com.sun.star.report.ReportJobFactory; import com.sun.star.report.SDBCReportDataFactory; import com.sun.star.report.SOImageService; import com.sun.star.report.StorageRepository; import com.sun.star.report.XReportDefinition; import com.sun.star.sdb.XDocumentDataSource; import com.sun.star.sdbc.XConnection; import com.sun.star.sdbc.XRowSet; import com.sun.star.task.XJob; import com.sun.star.uno.Exception; import com.sun.star.uno.Type; import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.XComponentContext; import java.util.logging.Level; import java.util.logging.Logger; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * This class capsulates the class, that implements the minimal component, a factory for creating the service * (__getComponentFactory) and a method, that writes the information into the given registry key * (__writeRegistryServiceInfo). */ public class SOReportJobFactory { private SOReportJobFactory() { } public static class _SOReportJobFactory extends WeakBase implements XInitialization, XServiceInfo, XJob, XPropertySet, ReportJobFactory { private static final Log LOGGER = LogFactory.getLog(_SOReportJobFactory.class); /** * The service name, that must be used to get an instance of this service. */ private static final String __serviceName = "com.sun.star.report.pentaho.SOReportJobFactory"; private final PropertySetMixin m_prophlp; /** * The initial component contextr, that gives access to the service manager, supported singletons, ... It's * often later used */ private final XComponentContext m_cmpCtx; private XConnection activeConnection; private XReportDefinition report; public _SOReportJobFactory(final XComponentContext xCompContext) { m_cmpCtx = xCompContext; m_prophlp = new PropertySetMixin(m_cmpCtx, this, new Type(XJob.class), null); // no optionals } /** * This method is a member of the interface for initializing an object directly after its creation. * * @param object This array of arbitrary objects will be passed to the component after its creation. * @throws Exception Every exception will not be handled, but will be passed to the caller. */ public void initialize(final Object[] object) throws com.sun.star.uno.Exception { /* The component describes what arguments its expected and in which * order!At this point you can read the objects and can intialize * your component using these objects. */ } /** * This method returns an array of all supported service names. * * @return Array of supported service names. */ public String[] getSupportedServiceNames() { return getServiceNames(); } /** * This method is a simple helper function to used in the static component initialisation functions as well as * in getSupportedServiceNames. * @return */ public static String[] getServiceNames() { return new String[] { __serviceName }; } /** * This method returns true, if the given service will be supported by the component. * * @param sServiceName Service name. * @return True, if the given service name will be supported. */ public boolean supportsService(final String sServiceName) { return sServiceName.equals(__serviceName); } /** * Return the class name of the component. * * @return Class name of the component. */ public String getImplementationName() { return SOReportJobFactory.class.getName(); } private String getLocaleFromRegistry(final XSimpleRegistry simpleReg, final String path, final String value) { String currentLocale = null; try { simpleReg.open(path, true, false); final XRegistryKey xRegistryRootKey = simpleReg.getRootKey(); // read locale final XRegistryKey locale = xRegistryRootKey.openKey(value); if (locale != null) { final String newLocale = locale.getStringValue(); if (newLocale != null) { currentLocale = newLocale.replace('-', '_'); } } } catch (InvalidValueException ex) { Logger.getLogger(SOReportJobFactory.class.getName()).log(Level.SEVERE, null, ex); } catch (InvalidRegistryException ex) { Logger.getLogger(SOReportJobFactory.class.getName()).log(Level.SEVERE, null, ex); } return currentLocale; } public Object execute(final NamedValue[] namedValue) throws com.sun.star.lang.IllegalArgumentException, com.sun.star.uno.Exception { final ClassLoader cl = java.lang.Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); try { final XSimpleRegistry simpleReg = (XSimpleRegistry) UnoRuntime.queryInterface(XSimpleRegistry.class, m_cmpCtx.getServiceManager().createInstanceWithContext("com.sun.star.configuration.ConfigurationRegistry", m_cmpCtx)); String currentLocale = getLocaleFromRegistry(simpleReg, "org.openoffice.Setup", "L10N/ooSetupSystemLocale"); if (currentLocale == null || "".equals(currentLocale)) { currentLocale = getLocaleFromRegistry(simpleReg, "org.openoffice.Office.Linguistic", "General/DefaultLocale"); } if (currentLocale != null && !"".equals(currentLocale)) { System.setProperty("org.pentaho.reporting.libraries.formula.locale", currentLocale); } final ReportJob job = createReportJob(namedValue); job.execute(); } catch (java.lang.Exception e) { LOGGER.error("ReportProcessing failed", e); throw new com.sun.star.lang.WrappedTargetException(e.getMessage(), this, null); } catch (java.lang.IncompatibleClassChangeError e2) { LOGGER.error("Detected an IncompatibleClassChangeError"); throw new com.sun.star.lang.WrappedTargetException("caught a " + e2.getClass().getName(), this, new com.sun.star.uno.Exception(e2.getLocalizedMessage())); } Thread.currentThread().setContextClassLoader(cl); return null; } public ReportJob createReportJob(final NamedValue[] namedValue) throws IllegalArgumentException, ReportExecutionException, Exception { XStorage input = null; XStorage output = null; XRowSet rowSet = null; String mimetype = null; String author = null; String title = null; Integer maxRows = null; for (int i = 0; i < namedValue.length; ++i) { final NamedValue aProps = namedValue[i]; if ("ActiveConnection".equalsIgnoreCase(aProps.Name)) { activeConnection = (XConnection) UnoRuntime.queryInterface(XConnection.class, aProps.Value); } else if ("ReportDefinition".equalsIgnoreCase(aProps.Name)) { report = (XReportDefinition) UnoRuntime.queryInterface(XReportDefinition.class, aProps.Value); } else if ("InputStorage".equalsIgnoreCase(aProps.Name)) { input = (XStorage) UnoRuntime.queryInterface(XStorage.class, aProps.Value); } else if ("OutputStorage".equalsIgnoreCase(aProps.Name)) { output = (XStorage) UnoRuntime.queryInterface(XStorage.class, aProps.Value); } else if ("RowSet".equalsIgnoreCase(aProps.Name)) { rowSet = (XRowSet) UnoRuntime.queryInterface(XRowSet.class, aProps.Value); } else if ("mimetype".equalsIgnoreCase(aProps.Name)) { mimetype = (String) aProps.Value; } else if ("MaxRows".equalsIgnoreCase(aProps.Name)) { maxRows = (Integer) aProps.Value; } else if (ReportEngineParameterNames.AUTHOR.equalsIgnoreCase(aProps.Name)) { author = (String) aProps.Value; } else if (ReportEngineParameterNames.TITLE.equalsIgnoreCase(aProps.Name)) { title = (String) aProps.Value; } } if (input == null || output == null) { throw new com.sun.star.lang.IllegalArgumentException(); } if (rowSet == null) { if (report == null || activeConnection == null) { throw new com.sun.star.lang.IllegalArgumentException(); } mimetype = report.getMimeType(); } else { final XPropertySet set = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, rowSet); if (set == null) { throw new com.sun.star.lang.IllegalArgumentException(); } activeConnection = (XConnection) UnoRuntime.queryInterface(XConnection.class, set.getPropertyValue("ActiveConnection")); } if (mimetype == null) { mimetype = PentahoReportEngineMetaData.OPENDOCUMENT_TEXT; } final XChild child = UnoRuntime.queryInterface(XChild.class, activeConnection); final XDocumentDataSource docSource = UnoRuntime.queryInterface(XDocumentDataSource.class, child.getParent()); final XModel model = UnoRuntime.queryInterface(XModel.class, docSource.getDatabaseDocument()); final DataSourceFactory dataFactory = new SDBCReportDataFactory(m_cmpCtx, activeConnection); final StorageRepository storageRepository = new StorageRepository(input, output, model.getURL()); final String inputName = "content.xml"; final String outputName = "content.xml"; final PentahoReportEngine engine = new PentahoReportEngine(); final ReportJobDefinition definition = engine.createJobDefinition(); final JobProperties procParms = definition.getProcessingParameters(); procParms.setProperty(ReportEngineParameterNames.INPUT_REPOSITORY, storageRepository); procParms.setProperty(ReportEngineParameterNames.OUTPUT_REPOSITORY, storageRepository); procParms.setProperty(ReportEngineParameterNames.INPUT_NAME, inputName); procParms.setProperty(ReportEngineParameterNames.OUTPUT_NAME, outputName); procParms.setProperty(ReportEngineParameterNames.CONTENT_TYPE, mimetype); procParms.setProperty(ReportEngineParameterNames.INPUT_DATASOURCE_FACTORY, dataFactory); procParms.setProperty(ReportEngineParameterNames.IMAGE_SERVICE, new SOImageService(m_cmpCtx)); procParms.setProperty(ReportEngineParameterNames.INPUT_REPORTJOB_FACTORY, this); procParms.setProperty(ReportEngineParameterNames.MAXROWS, maxRows); if (author != null) { procParms.setProperty(ReportEngineParameterNames.AUTHOR, author); } if (title != null) { procParms.setProperty(ReportEngineParameterNames.TITLE, title); } return engine.createJob(definition); } // com.sun.star.beans.XPropertySet: public com.sun.star.beans.XPropertySetInfo getPropertySetInfo() { return m_prophlp.getPropertySetInfo(); } public void setPropertyValue(final String aPropertyName, final Object aValue) throws UnknownPropertyException, PropertyVetoException, com.sun.star.lang.IllegalArgumentException, WrappedTargetException { m_prophlp.setPropertyValue(aPropertyName, aValue); } public Object getPropertyValue(final String aPropertyName) throws UnknownPropertyException, WrappedTargetException { return m_prophlp.getPropertyValue(aPropertyName); } public void addPropertyChangeListener(final String aPropertyName, final XPropertyChangeListener xListener) throws UnknownPropertyException, WrappedTargetException { m_prophlp.addPropertyChangeListener(aPropertyName, xListener); } public void removePropertyChangeListener(final String aPropertyName, final XPropertyChangeListener xListener) throws UnknownPropertyException, WrappedTargetException { m_prophlp.removePropertyChangeListener(aPropertyName, xListener); } public void addVetoableChangeListener(final String aPropertyName, final XVetoableChangeListener xListener) throws UnknownPropertyException, WrappedTargetException { m_prophlp.addVetoableChangeListener(aPropertyName, xListener); } public void removeVetoableChangeListener(final String aPropertyName, final XVetoableChangeListener xListener) throws UnknownPropertyException, WrappedTargetException { m_prophlp.removeVetoableChangeListener(aPropertyName, xListener); } } /** * Gives a factory for creating the service. This method is called by the JavaLoader *

* * @param sImplName the name of the implementation for which a service is desired * @return returns a XSingleComponentFactory for creating the component * @see com.sun.star.comp.loader.JavaLoader */ public static XSingleComponentFactory __getComponentFactory(final String sImplName) { XSingleComponentFactory xFactory = null; try { if (sImplName.equals(_SOReportJobFactory.class.getName())) { xFactory = Factory.createComponentFactory(_SOReportJobFactory.class, _SOReportJobFactory.getServiceNames()); } else if (sImplName.equals(SOFunctionManager.class.getName())) { xFactory = Factory.createComponentFactory(SOFunctionManager.class, SOFunctionManager.getServiceNames()); } else if (sImplName.equals(SOFormulaParser.class.getName())) { xFactory = Factory.createComponentFactory(SOFormulaParser.class, SOFormulaParser.getServiceNames()); } } catch (java.lang.IncompatibleClassChangeError e2) { } return xFactory; } /** * Writes the service information into the given registry key. This method is called by the JavaLoader *

* * @param regKey the registryKey * @return returns true if the operation succeeded * @see com.sun.star.comp.loader.JavaLoader */ public static boolean __writeRegistryServiceInfo(final XRegistryKey regKey) { return Factory.writeRegistryServiceInfo(SOFunctionManager.class.getName(), SOFunctionManager.getServiceNames(), regKey) && Factory.writeRegistryServiceInfo(_SOReportJobFactory.class.getName(), _SOReportJobFactory.getServiceNames(), regKey) && Factory.writeRegistryServiceInfo(SOFormulaParser.class.getName(), SOFormulaParser.getServiceNames(), regKey); } }