/* ************************************************************************ * * 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.wizards.reportbuilder; import com.sun.star.util.XModeSelector; import com.sun.star.awt.XWindowPeer; import com.sun.star.beans.PropertyValue; import com.sun.star.beans.XPropertySet; import com.sun.star.container.XHierarchicalNameContainer; import com.sun.star.container.XNameContainer; import com.sun.star.frame.XController; import com.sun.star.frame.XDispatch; import com.sun.star.frame.XDispatchProvider; import com.sun.star.frame.XFrame; import com.sun.star.lang.XComponent; import com.sun.star.lang.XMultiServiceFactory; import com.sun.star.report.XReportDefinition; import com.sun.star.sdb.XSubDocument; import com.sun.star.sdb.application.DatabaseObject; import com.sun.star.sdb.application.XDatabaseDocumentUI; import com.sun.star.sdbc.XConnection; import com.sun.star.ucb.XCommandProcessor; import com.sun.star.uno.UnoRuntime; import com.sun.star.util.XModifiable; import com.sun.star.util.XURLTransformer; import com.sun.star.wizards.common.NoValidPathException; import com.sun.star.wizards.common.Resource; import com.sun.star.wizards.db.FieldColumn; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Set; import java.util.Vector; import com.sun.star.wizards.common.FileAccess; import com.sun.star.wizards.common.NamedValueCollection; import com.sun.star.wizards.report.IReportBuilderLayouter; import com.sun.star.wizards.report.IReportDefinitionReadAccess; import com.sun.star.wizards.report.IReportDocument; import com.sun.star.wizards.report.ReportImplementationHelper; import com.sun.star.wizards.report.ReportLayouter; import com.sun.star.wizards.report.ReportWizard; import java.util.logging.Level; import java.util.logging.Logger; /** * This class use the IReportDocument Interface to communicate between the UI * and the ReportBuilderLayouter which communicates to the new Sun Report Builder. * * @author ll93751 */ public class ReportBuilderImplementation extends ReportImplementationHelper implements IReportDocument, IReportDefinitionReadAccess { private Resource m_resource; private XDatabaseDocumentUI m_documentUI; private static final int MAXIMUM_GROUPCOUNT = 4; private ReportBuilderImplementation( XMultiServiceFactory _serviceFactory ) { // creates an access to the ReportBuilder Extension super(_serviceFactory, ReportLayouter.SOOPTLANDSCAPE); } public static IReportDocument create( XMultiServiceFactory i_serviceFactory ) { return new ReportBuilderImplementation( i_serviceFactory ); } public void initialize( final XDatabaseDocumentUI i_documentUI, final Resource i_resource ) { m_documentUI = i_documentUI; m_resource = i_resource; } public void clearDocument() { } public XWindowPeer getWizardParent() { final XWindowPeer aWindowPeer = UnoRuntime.queryInterface( XWindowPeer.class, getFrame().getComponentWindow() ); return aWindowPeer; } private XFrame m_xFrame = null; // private ReportBuilderLayouter m_aReportBuilderLayouter = null; private String m_sReportBuilderLayoutName = ""; /** * Get access to the current ReportLayouter, which depends on the name. * To change the ReportBuilderLayouter use setReportBuilderLayouterName(String Name). * @return */ private IReportBuilderLayouter getReportBuilderLayouter() { final IReportBuilderLayouter aReportBuilderLayouter = (IReportBuilderLayouter) getLayoutMap().get(m_sReportBuilderLayoutName); return aReportBuilderLayouter; } private Object m_aReportDocument; private XPropertySet m_documentDefinition; private XReportDefinition m_reportDocument; /** * initialize the Report Builder and open it representation * @param _aDoc * @param _xConnection */ private void initialize(Object _aDoc) { m_aReportDocument = _aDoc; try { NamedValueCollection creationArgs = new NamedValueCollection(); creationArgs.put( "DocumentServiceName", "com.sun.star.report.ReportDefinition" ); creationArgs.put( "Mode", "remote" ); XComponent[] docDefinition = new XComponent[] { null }; XComponent reportDefinitionComp = m_documentUI.createComponentWithArguments( DatabaseObject.REPORT, creationArgs.getPropertyValues(), docDefinition ); m_documentDefinition = UnoRuntime.queryInterface( XPropertySet.class, docDefinition[0] ); m_reportDocument = UnoRuntime.queryInterface( XReportDefinition.class, reportDefinitionComp ); } catch (com.sun.star.uno.Exception e) { ReportWizard.getLogger().log(com.sun.star.logging.LogLevel.SEVERE, "Problems with initialize the ReportDefinition" + e.getMessage()); } switchOffPropertyBrowser(); switchOffAddFieldWindow(); setPageOrientation(m_nDefaultPageOrientation, false /* NO_LAYOUT*/); } private XModeSelector getModeSelector() { final XController xController = getReportDefinition().getCurrentController(); final XModeSelector xModeSelector = UnoRuntime.queryInterface( XModeSelector.class, xController ); return xModeSelector; } private void switchOffAddFieldWindow() { try { getModeSelector().setMode("remote"); } catch (com.sun.star.uno.Exception e) { int dummy = 0; } } private void switchOnAddFieldWindow() { try { getModeSelector().setMode("normal"); } catch (com.sun.star.uno.Exception e) { int dummy = 0; } } private void sleep(int _nSeconds) { try { Thread.sleep(_nSeconds * 1000); } catch (java.lang.InterruptedException e) { } } private void switchOffPropertyBrowser() { try { final XController xController = getReportDefinition().getCurrentController(); final XDispatchProvider xDP = UnoRuntime.queryInterface( XDispatchProvider.class, xController ); // Create special service for parsing of given URL. final Object aURLTransformer = getMSF().createInstance("com.sun.star.util.URLTransformer"); final XURLTransformer xURLTransformer = UnoRuntime.queryInterface( com.sun.star.util.XURLTransformer.class, aURLTransformer ); com.sun.star.util.URL[] aURL = new com.sun.star.util.URL[1]; aURL[0] = new com.sun.star.util.URL(); aURL[0].Complete = ".uno:ControlProperties"; xURLTransformer.parseStrict(aURL); final XDispatch xDispatch = xDP.queryDispatch(aURL[0], "_self", 0); PropertyValue[] xEmpty = new PropertyValue[0]; xDispatch.dispatch(aURL[0], xEmpty); } catch (com.sun.star.uno.Exception e) { int dummy = 0; } } private void switchOnPropertyBrowser() { // This is implemented with a toggle algorithm. switchOffPropertyBrowser(); } /** * Returns the Frame of the underlieing Document * @return Returns the Frame of the parent (underlieing) Document */ public XFrame getFrame() { if (m_xFrame == null) { initialize(getRecordParser().getReportDocuments()); m_xFrame = getReportDefinition().getCurrentController().getFrame(); setPageOrientation(m_nDefaultPageOrientation, true /* NO_LAYOUT*/); } return m_xFrame; } public boolean reconnectToDatabase(XMultiServiceFactory xMSF, PropertyValue[] Properties) { return false; } public void insertDatabaseDatatoReportDocument(XMultiServiceFactory xMSF) { } public void StopProcess() { } public void store(String Name, int OpenMode) throws com.sun.star.uno.Exception { // store into the ZIP Storage if (OpenMode == 1 /* static Report */) { // we will store later return; } final XCommandProcessor xProcessor = UnoRuntime.queryInterface( XCommandProcessor.class, m_documentDefinition ); final com.sun.star.ucb.Command aCommand = new com.sun.star.ucb.Command(); aCommand.Name = "store"; xProcessor.execute(aCommand, xProcessor.createCommandIdentifier(), null); final XHierarchicalNameContainer aNameContainer = UnoRuntime.queryInterface(XHierarchicalNameContainer.class, m_aReportDocument); aNameContainer.insertByHierarchicalName( Name, m_documentDefinition ); } public boolean liveupdate_addGroupNametoDocument(String[] GroupNames, String CurGroupTitle, Vector GroupFieldVector, ArrayList ReportPath, int iSelCount) { final int GroupCount = GroupFieldVector.size(); if (GroupCount < MAXIMUM_GROUPCOUNT) { final FieldColumn CurFieldColumn = getRecordParser().getFieldColumnByTitle(CurGroupTitle); GroupFieldVector.addElement(CurFieldColumn.getFieldName()); } return true; } public void refreshGroupFields(String[] _sNewNames) { } public void liveupdate_removeGroupName(String[] NewSelGroupNames, String CurGroupTitle, Vector GroupFieldVector) { final FieldColumn CurFieldColumn = getRecordParser().getFieldColumnByTitle(CurGroupTitle); GroupFieldVector.removeElement(CurFieldColumn.getFieldName()); } private void setPageOrientation(int nOrientation, boolean bDoLayout) { getReportBuilderLayouter().setPageOrientation(nOrientation); if (bDoLayout) { getReportBuilderLayouter().layout(); } } public void setPageOrientation(int nOrientation) { setPageOrientation(nOrientation, true); } public void liveupdate_changeLayoutTemplate(String LayoutTemplatePath/*, String BitmapPath*/) { /* Right Listbox */ final IReportBuilderLayouter aLayouter = getReportBuilderLayouter(); aLayouter.loadAndSetBackgroundTemplate(LayoutTemplatePath); aLayouter.layout(); } /** * Change the current Layouter by a new one with the given Name _sName. * If there exist no other layouter with the given name, nothing happens, the layouter will not change to * an illegal one. * @param _sName Name of the other layouter. */ public void setReportBuilderLayouterName(String _sName) { final IReportBuilderLayouter aCurrentLayouter = getReportBuilderLayouter(); final IReportBuilderLayouter aNewLayouter = (IReportBuilderLayouter) m_aLayoutMap.get(_sName); if (aNewLayouter != null) { m_sReportBuilderLayoutName = _sName; aNewLayouter.initializeData(aCurrentLayouter); aNewLayouter.layout(); } } public void liveupdate_changeContentTemplate(String ContentTemplatePath) { /* Left Listbox */ setReportBuilderLayouterName(ContentTemplatePath); } public void layout_setupRecordSection(String TemplateName) { } public void removeTextTableAndTextSection() { } public void layout_selectFirstPage() { } private void closeReportDefinition() { try { if ( m_documentDefinition != null ) { // set the document to "not modified", to ensure that it won't ask the user before closing XModifiable documentModify = UnoRuntime.queryInterface( XModifiable.class, m_reportDocument ); documentModify.setModified( false ); // actually close XSubDocument subComponent = UnoRuntime.queryInterface( XSubDocument.class, m_documentDefinition ); subComponent.close(); } } catch ( Exception ex ) { Logger.getLogger( ReportBuilderImplementation.class.getName() ).log( Level.SEVERE, null, ex ); } m_documentDefinition = null; m_reportDocument = null; } public void dispose() { getReportBuilderLayouter().dispose(); closeReportDefinition(); } public XComponent getComponent() { return null; } public void liveupdate_changeUserFieldContent(String fieldName, String titlename) { } public void liveupdate_updateReportTitle(String _sTitleName) { } public void addReportToDBView() { } private XComponent loadReport( final String i_reportName ) { try { return m_documentUI.loadComponent( DatabaseObject.REPORT, i_reportName, false ); } catch ( Exception ex ) { Logger.getLogger( ReportBuilderImplementation.class.getName() ).log( Level.SEVERE, null, ex ); } return null; } private XComponent loadReportFromDocumentDefinition() { final XCommandProcessor commandProcessor = UnoRuntime.queryInterface(XCommandProcessor.class, m_documentDefinition); com.sun.star.ucb.Command aCommand = new com.sun.star.ucb.Command(); aCommand.Name = "open"; try { final Object result = commandProcessor.execute( aCommand, commandProcessor.createCommandIdentifier(), null ); return UnoRuntime.queryInterface( XComponent.class, result ); } catch ( Exception ex ) { Logger.getLogger( ReportBuilderImplementation.class.getName() ).log( Level.SEVERE, null, ex ); } return null; } public void createAndOpenReportDocument( String i_name, boolean i_asTemplate, boolean i_openForEditing ) { if ( i_openForEditing ) { // we won't destroy the report builder window, also don't create a document // Do we need to reopen the report builder with the known name? switchOnAddFieldWindow(); switchOnPropertyBrowser(); return; } if ( i_asTemplate ) { // don't need the report definition anymore - the document it represents has already been stored closeReportDefinition(); // open the report, again, this time not in design, but containing data loadReport( i_name ); } else { // execute the report from the (yet unsaved) report definition XComponent document = loadReportFromDocumentDefinition(); // don't need the report definition anymore closeReportDefinition(); // store the generated report if ( getRecordParser().storeDatabaseDocumentToTempPath( document, i_name ) ) getRecordParser().addReportDocument( document, false ); } dispose(); } private XConnection getConnection() { return getRecordParser().DBConnection; } public void initializeFieldColumns(final int _nType, final String TableName, final String[] FieldNames) { getRecordParser().initializeFieldColumns(FieldNames, TableName); final com.sun.star.wizards.db.RecordParser a = getRecordParser(); int[] FieldTypes = new int[FieldNames.length]; int[] FieldWidths = new int[FieldNames.length]; for (int i = 0; i < FieldNames.length; i++) { FieldTypes[i] = a.FieldColumns[i].getFieldType(); FieldWidths[i] = a.FieldColumns[i].getFieldWidth(); } getReportBuilderLayouter().setTableName(_nType, TableName); getReportBuilderLayouter().insertFieldNames(FieldNames); getReportBuilderLayouter().insertFieldTypes(FieldTypes); getReportBuilderLayouter().insertFieldWidths(FieldWidths); getReportBuilderLayouter().layout(); } public void setFieldTitles(String[] _aFieldTitles) { getRecordParser().setFieldTitles(_aFieldTitles); getReportBuilderLayouter().insertFieldTitles(_aFieldTitles); getReportBuilderLayouter().layout(); } public void setSorting(String[][] _aSortFieldNames) { getRecordParser().setSortFieldNames(_aSortFieldNames); } public void setGrouping(String[] _aGroupFieldNames) { getRecordParser().prependSortFieldNames(_aGroupFieldNames); getReportBuilderLayouter().insertGroupNames(_aGroupFieldNames); getReportBuilderLayouter().layout(); } public String getLayoutPath() { return "default"; } private ArrayList m_aReportPath; public ArrayList getReportPath() { if (m_aReportPath == null) { try { // Check general availability of office paths m_aReportPath = FileAccess.getOfficePaths( getMSF(), "Template", "share", "/wizard" ); FileAccess.combinePaths( getMSF(), m_aReportPath, "/wizard/report" ); } catch ( NoValidPathException ex ) { Logger.getLogger( ReportBuilderImplementation.class.getName() ).log( Level.SEVERE, null, ex ); } } return m_aReportPath; } public String getContentPath() { return ""; } public int getDefaultPageOrientation() { return m_nDefaultPageOrientation; } /** * Helper function to get a com.sun.star.wizards.report.layout.ReportBuilderLayouter by it's name * * @param _sClassName * @return the object or null */ private IReportBuilderLayouter getLayoutInstanceFrom(String _sClassName) { try { // TODO: Use Package.getPackages(...) final Class a = Class.forName(_sClassName); final Constructor cTor = a.getConstructor(new Class[] { IReportDefinitionReadAccess.class, Resource.class }); Object[] aParams = new Object[2]; aParams[0] = this; aParams[1] = m_resource; final IReportBuilderLayouter aReportBuilderLayouter = (IReportBuilderLayouter) cTor.newInstance(aParams); return aReportBuilderLayouter; } catch (Exception e) { e.printStackTrace(); } return null; } private LinkedHashMap m_aLayoutMap = null; private void insertIntoLayoutMap(IReportBuilderLayouter _aLayout) { insertIntoLayoutMap(_aLayout, false); } private void insertIntoLayoutMap(IReportBuilderLayouter _aLayout, boolean _bDefault) { if (_aLayout != null) { final String sName = _aLayout.getName(); if (_bDefault) { m_sReportBuilderLayoutName = sName; // here we set the default layout name! } m_aLayoutMap.put(sName, _aLayout); } } /** * Initialize all well known com.sun.star.wizards.report.layout.ReportBuilderLayouter Objects and create exact one instance. */ private LinkedHashMap getLayoutMap() { if (m_aLayoutMap == null) { // The LayoutMap is empty, so we create a new LinkedHashMap m_aLayoutMap = new LinkedHashMap(); // TODO: We must know the name of a layouts, There should be a way to say where to find, not the names. IReportBuilderLayouter aLayout = getLayoutInstanceFrom("com.sun.star.wizards.reportbuilder.layout.Tabular"); insertIntoLayoutMap(aLayout, true); aLayout = getLayoutInstanceFrom("com.sun.star.wizards.reportbuilder.layout.ColumnarSingleColumn"); insertIntoLayoutMap(aLayout); aLayout = getLayoutInstanceFrom("com.sun.star.wizards.reportbuilder.layout.ColumnarTwoColumns"); insertIntoLayoutMap(aLayout); aLayout = getLayoutInstanceFrom("com.sun.star.wizards.reportbuilder.layout.ColumnarThreeColumns"); insertIntoLayoutMap(aLayout); aLayout = getLayoutInstanceFrom("com.sun.star.wizards.reportbuilder.layout.InBlocksLabelsAbove"); insertIntoLayoutMap(aLayout); aLayout = getLayoutInstanceFrom("com.sun.star.wizards.reportbuilder.layout.InBlocksLabelsLeft"); insertIntoLayoutMap(aLayout); } return m_aLayoutMap; } /** * Return a string array array with all found layouts * At the moment these layout are hard coded * @return */ public String[][] getDataLayout() { String[][] ContentFiles; ContentFiles = new String[2][]; String[] a = new String[getLayoutMap().size()]; String[] b = new String[getLayoutMap().size()]; // run through the whole layoutmap and final Set aKeys = getLayoutMap().keySet(); final Iterator aKeyIterator = aKeys.iterator(); int i = 0; while (aKeyIterator.hasNext()) { final String sKey = (String) aKeyIterator.next(); a[i] = sKey; final IReportBuilderLayouter aLayouter = (IReportBuilderLayouter) m_aLayoutMap.get(sKey); b[i++] = aLayouter.getLocalizedName(); } ContentFiles[1] = a; ContentFiles[0] = b; return ContentFiles; } private String m_sDefaultHeaderLayoutPath; public String[][] getHeaderLayout() { String[][] LayoutFiles; try { // TODO: check different languages in header layouts ArrayList aReportPath = FileAccess.getOfficePaths(getMSF(), "Template", "share", "/wizard"); FileAccess.combinePaths(getMSF(), aReportPath, "/wizard/report"); LayoutFiles = FileAccess.getFolderTitles(getMSF(), null, aReportPath, ".otr"); } catch (com.sun.star.wizards.common.NoValidPathException e) { // if there are problems, don't show anything is a little bit hard. LayoutFiles = new String[2][]; String[] a = new String[1]; String[] b = new String[1]; a[0] = "DefaultLayoutOfHeaders"; b[0] = "default"; LayoutFiles[1] = a; LayoutFiles[0] = b; } for (int i = 0; i < LayoutFiles[0].length; i++) { if (LayoutFiles[0][i].equals("default")) { m_sDefaultHeaderLayoutPath = LayoutFiles[1][i]; break; } } return LayoutFiles; } public XReportDefinition getReportDefinition() { if (m_reportDocument == null) { throw new NullPointerException("Report Definition is not already initialized, check if you too early access the report definition."); } return m_reportDocument; } public XMultiServiceFactory getGlobalMSF() { return getMSF(); } public void importReportData(ReportWizard aWizard) { } public String getDefaultHeaderLayout() { return m_sDefaultHeaderLayoutPath; } public void setCommand(String _sCommand) { getRecordParser().Command = _sCommand; getReportDefinition().setCommand(_sCommand); } public void setCommandType(int _nCommand) { getReportDefinition().setCommandType(_nCommand); } public void checkInvariants() throws java.lang.Exception { final String sDefaultHeaderLayoutPath = getDefaultHeaderLayout(); if (sDefaultHeaderLayoutPath == null) { throw new java.io.IOException("default.otr"); } FileAccess aAccess = new FileAccess(getGlobalMSF()); if (! aAccess.exists(sDefaultHeaderLayoutPath, true)) { throw new java.io.IOException("default.otr"); } } }