diff options
Diffstat (limited to 'xmlhelp')
66 files changed, 14604 insertions, 0 deletions
diff --git a/xmlhelp/inc/makefile.mk b/xmlhelp/inc/makefile.mk new file mode 100644 index 000000000000..b12c06c14fa8 --- /dev/null +++ b/xmlhelp/inc/makefile.mk @@ -0,0 +1,51 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.3 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ=.. + +PRJNAME=xmlhelp +TARGET=inc + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- +# --- Targets ------------------------------------------------------- + +.INCLUDE : target.mk + +.IF "$(ENABLE_PCH)"!="" +ALLTAR : \ + $(SLO)$/precompiled.pch \ + $(SLO)$/precompiled_ex.pch + +.ENDIF # "$(ENABLE_PCH)"!="" + diff --git a/xmlhelp/inc/pch/precompiled_xmlhelp.cxx b/xmlhelp/inc/pch/precompiled_xmlhelp.cxx new file mode 100644 index 000000000000..00fcb098a915 --- /dev/null +++ b/xmlhelp/inc/pch/precompiled_xmlhelp.cxx @@ -0,0 +1,32 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: precompiled_xmlhelp.cxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_xmlhelp.hxx" + diff --git a/xmlhelp/inc/pch/precompiled_xmlhelp.hxx b/xmlhelp/inc/pch/precompiled_xmlhelp.hxx new file mode 100644 index 000000000000..b6ab234ab6e9 --- /dev/null +++ b/xmlhelp/inc/pch/precompiled_xmlhelp.hxx @@ -0,0 +1,35 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: precompiled_xmlhelp.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): Generated on 2006-09-01 17:50:19.701395 + +#ifdef PRECOMPILED_HEADERS +#endif + diff --git a/xmlhelp/prj/build.lst b/xmlhelp/prj/build.lst new file mode 100644 index 000000000000..7430bf6d7ba9 --- /dev/null +++ b/xmlhelp/prj/build.lst @@ -0,0 +1,9 @@ +xh xmlhelp : comphelper ucbhelper LIBXSLT:libxslt unoil BERKELEYDB:berkeleydb LUCENE:lucene javaunohelper l10ntools NULL +xh xmlhelp usr1 - all xh_mkout NULL +xh xmlhelp\inc nmake - all xh_inc NULL +xh xmlhelp\source\treeview nmake - all xh_treeview xh_inc NULL +xh xmlhelp\source\com\sun\star\help nmake - all xh_help xh_inc NULL +xh xmlhelp\source\cxxhelp\util nmake - all xh_cutil xh_inc NULL +xh xmlhelp\source\cxxhelp\qe nmake - all xh_qe xh_inc NULL +xh xmlhelp\source\cxxhelp\provider nmake - all xh_provider xh_inc NULL +xh xmlhelp\util nmake - all xh_util xh_cutil xh_qe xh_provider NULL diff --git a/xmlhelp/prj/d.lst b/xmlhelp/prj/d.lst new file mode 100644 index 000000000000..5f208e51c20f --- /dev/null +++ b/xmlhelp/prj/d.lst @@ -0,0 +1,9 @@ +..\%__SRC%\bin\*.dll %_DEST%\bin%_EXT%\*.* +..\%__SRC%\bin\HelpLinker* %_DEST%\bin%_EXT% +..\%__SRC%\lib\lib*.so %_DEST%\lib%_EXT% +..\%__SRC%\lib\*.dylib %_DEST%\lib%_EXT%\*.* +..\%__SRC%\class\*.jar %_DEST%\bin%_EXT%\*.* +..\util\ucpchelp.xml %_DEST%\xml%_EXT%\ucpchelp.xml +..\inc\xmlhelp\compilehelp.hxx %_DEST%\inc%_EXT%\xmlhelp\compilehelp.hxx +..\inc\xmlhelp\helplinkerdllapi.h %_DEST%\inc%_EXT%\xmlhelp\helplinkerdllapi.h +..\%__SRC%\lib\ihelplinker.lib %_DEST%\lib%_EXT%\ihelplinker.lib
\ No newline at end of file diff --git a/xmlhelp/source/com/sun/star/help/HelpComponent.java b/xmlhelp/source/com/sun/star/help/HelpComponent.java new file mode 100755 index 000000000000..481605cb2984 --- /dev/null +++ b/xmlhelp/source/com/sun/star/help/HelpComponent.java @@ -0,0 +1,138 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: HelpSearch.java,v $ + * $Revision: 1.2 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.help; + +import com.sun.star.lib.uno.helper.Factory; +import com.sun.star.lang.XSingleComponentFactory; +import com.sun.star.registry.XRegistryKey; + +/* +import com.sun.star.lib.uno.helper.Factory; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.lang.XSingleComponentFactory; +import com.sun.star.lib.uno.helper.WeakBase; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; +import com.sun.star.registry.XRegistryKey; +import com.sun.star.lang.XInitialization; +import com.sun.star.lang.XTypeProvider; +import com.sun.star.lang.XServiceInfo; +import com.sun.star.uno.Type; +import com.sun.star.uno.Any; +import com.sun.star.uno.AnyConverter; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.index.FilterIndexReader; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.Term; +import org.apache.lucene.queryParser.QueryParser; +import org.apache.lucene.search.Hits; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.Searcher; +import org.apache.lucene.search.TermQuery; +import org.apache.lucene.search.WildcardQuery; + +import com.sun.star.script.XInvocation; +import com.sun.star.beans.XIntrospectionAccess; + +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.io.File; +*/ + +/** This class capsulates the class, that implements the minimal component, a + * factory for creating the service (<CODE>__getComponentFactory</CODE>) and a + * method, that writes the information into the given registry key + * (<CODE>__writeRegistryServiceInfo</CODE>). + */ +public class HelpComponent +{ + /** + * Gives a factory for creating the service. + * This method is called by the <code>JavaLoader</code> + * <p> + * @return returns a <code>XSingleComponentFactory</code> for creating + * the component + * @param sImplName the name of the implementation for which a + * service is desired + * @see com.sun.star.comp.loader.JavaLoader + */ + public static XSingleComponentFactory __getComponentFactory(String sImplName) + { + XSingleComponentFactory xFactory = null; + + if ( sImplName.equals( HelpSearch._HelpSearch.class.getName() ) ) + xFactory = Factory.createComponentFactory(HelpSearch._HelpSearch.class, + HelpSearch._HelpSearch.getServiceNames()); + else if ( sImplName.equals( HelpIndexer.class.getName() ) ) + xFactory = Factory.createComponentFactory(HelpIndexer.class, + HelpIndexer.getServiceNames()); + return xFactory; + } + + /** + * Writes the service information into the given registry key. + * This method is called by the <code>JavaLoader</code> + * <p> + * @return returns true if the operation succeeded + * @param regKey the registryKey + * @see com.sun.star.comp.loader.JavaLoader + */ + public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) + { + boolean bSuccessHelpSearch = Factory.writeRegistryServiceInfo + (HelpSearch._HelpSearch.class.getName(), + HelpSearch._HelpSearch.getServiceNames(), regKey); + boolean bSuccessHelpIndexer = Factory.writeRegistryServiceInfo + (HelpIndexer.class.getName(), + HelpIndexer.getServiceNames(), regKey); + + return bSuccessHelpSearch && bSuccessHelpIndexer; + } + /** 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( 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. + */ + } +} diff --git a/xmlhelp/source/com/sun/star/help/HelpIndexer.java b/xmlhelp/source/com/sun/star/help/HelpIndexer.java new file mode 100644 index 000000000000..abb803289e7e --- /dev/null +++ b/xmlhelp/source/com/sun/star/help/HelpIndexer.java @@ -0,0 +1,189 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: HelpIndexer.java,v $ + * $Revision: 1.21 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.help; + +import com.sun.star.lib.uno.helper.WeakBase; +import com.sun.star.lang.XServiceInfo; +import com.sun.star.script.XInvocation; +import com.sun.star.beans.XIntrospectionAccess; +import com.sun.star.uno.AnyConverter; +import com.sun.star.uno.XComponentContext; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Date; +import java.util.zip.ZipOutputStream; + +public class HelpIndexer extends WeakBase + implements XServiceInfo, XInvocation +{ + static private final String __serviceName = + "com.sun.star.help.HelpIndexer"; + static private final String aCreateIndexMethodName = "createIndex"; + + static private com.sun.star.help.HelpIndexerTool helpindexer = new com.sun.star.help.HelpIndexerTool(); + + public HelpIndexer() + { + } + + public HelpIndexer(XComponentContext xCompContext) + { + } + + public static void mainImpl( String[] args, boolean bExtensionMode ) + { + helpindexer.mainImpl( args , bExtensionMode ); + } + + public static void createZipFile( File aDirToZip, String aTargetZipFileStr ) + throws FileNotFoundException, IOException + { + helpindexer.createZipFile( aDirToZip , aTargetZipFileStr ); + } + + public static void addToZipRecursively( ZipOutputStream zos, File aFile, String aBasePath ) + throws FileNotFoundException, IOException + { + helpindexer.addToZipRecursively( zos , aFile , aBasePath ); + } + + static public boolean deleteRecursively( File aFile ) + { + return helpindexer.deleteRecursively( aFile ); + } + + //=================================================== + // XInvocation + public XIntrospectionAccess getIntrospection() + { + return null; + } + + public Object invoke( String aFunctionName, java.lang.Object[] aParams, + short[][] aOutParamIndex, java.lang.Object[][] aOutParam ) + throws com.sun.star.lang.IllegalArgumentException, + com.sun.star.script.CannotConvertException, + com.sun.star.reflection.InvocationTargetException + { + if( + !aFunctionName.equals( aCreateIndexMethodName ) ) + throw new com.sun.star.lang.IllegalArgumentException(); + + aOutParamIndex[0] = new short[0]; + aOutParam[0] = new Object[0]; + + int nParamCount = aParams.length; + String aStrs[] = new String[nParamCount]; + for( int i = 0 ; i < nParamCount ; i++ ) + { + try + { + aStrs[i] = AnyConverter.toString( aParams[i] ); + } + catch( IllegalArgumentException e ) + { + aStrs[i] = ""; + } + } + + boolean bExtensionMode = true; + mainImpl( aStrs, bExtensionMode ); + + return null; + } + + public void setValue( String aPropertyName, java.lang.Object aValue ) + throws com.sun.star.beans.UnknownPropertyException, + com.sun.star.script.CannotConvertException, + com.sun.star.reflection.InvocationTargetException + { + throw new com.sun.star.beans.UnknownPropertyException(); + } + + public Object getValue( String aPropertyName ) + throws com.sun.star.beans.UnknownPropertyException + { + throw new com.sun.star.beans.UnknownPropertyException(); + } + + public boolean hasMethod( String aMethodName ) + { + boolean bRet = (aMethodName.equals( aCreateIndexMethodName ) ); + return bRet; + } + public boolean hasProperty( String aName ) { + return false; + } + + + + /** 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. + */ + public static String[] getServiceNames() + { + String[] sSupportedServiceNames = { __serviceName }; + return sSupportedServiceNames; + } + + + /** 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( String sServiceName ) + { + return sServiceName.equals( __serviceName ); + } + + + /** Return the class name of the component. + * @return Class name of the component. + */ + public String getImplementationName() + { + return HelpIndexer.class.getName(); + } + +} + diff --git a/xmlhelp/source/com/sun/star/help/HelpSearch.java b/xmlhelp/source/com/sun/star/help/HelpSearch.java new file mode 100644 index 000000000000..117ab181f844 --- /dev/null +++ b/xmlhelp/source/com/sun/star/help/HelpSearch.java @@ -0,0 +1,347 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: HelpSearch.java,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +package com.sun.star.help; + +import com.sun.star.lib.uno.helper.Factory; +import com.sun.star.lang.XMultiComponentFactory; +import com.sun.star.lang.XSingleComponentFactory; +import com.sun.star.lib.uno.helper.WeakBase; +import com.sun.star.uno.XComponentContext; +import com.sun.star.registry.XRegistryKey; +import com.sun.star.lang.XServiceInfo; +import com.sun.star.uno.Type; +import com.sun.star.uno.Any; +import com.sun.star.uno.AnyConverter; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.analysis.cjk.CJKAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.Hits; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.Searcher; +import org.apache.lucene.search.TermQuery; +import org.apache.lucene.search.WildcardQuery; + +import com.sun.star.script.XInvocation; +import com.sun.star.beans.XIntrospectionAccess; + +/** This class capsulates the class, that implements the minimal component, a + * factory for creating the service (<CODE>__getComponentFactory</CODE>) and a + * method, that writes the information into the given registry key + * (<CODE>__writeRegistryServiceInfo</CODE>). + */ +public class HelpSearch +{ + /** This class implements the component. At least the interfaces XServiceInfo, + * XTypeProvider, and XInitialization should be provided by the service. + */ + public static class _HelpSearch extends WeakBase + implements XServiceInfo, XInvocation + { + /** The service name, that must be used to get an instance of this service. + */ + static private final String __serviceName = + "com.sun.star.help.HelpSearch"; + static private final String aSearchMethodName = "search"; + + /** The initial component contextr, that gives access to + * the service manager, supported singletons, ... + * It's often later used + */ + private XComponentContext m_cmpCtx; + + /** The service manager, that gives access to all registered services. + * It's often later used + */ + private XMultiComponentFactory m_xMCF; + + /** The constructor of the inner class has a XMultiServiceFactory parameter. + * @param xmultiservicefactoryInitialization A special service factory + * could be introduced while initializing. + */ + public _HelpSearch(XComponentContext xCompContext) + { + try { + m_cmpCtx = xCompContext; + m_xMCF = m_cmpCtx.getServiceManager(); + } + catch( Exception e ) { + e.printStackTrace(); + } + } + + /** 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. + */ + public static String[] getServiceNames() + { + String[] sSupportedServiceNames = { __serviceName }; + return sSupportedServiceNames; + } + + /** 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( String sServiceName ) + { + return sServiceName.equals( __serviceName ); + } + + /** Return the class name of the component. + * @return Class name of the component. + */ + public String getImplementationName() + { + return _HelpSearch.class.getName(); + } + + //=================================================== + // XInvocation + public XIntrospectionAccess getIntrospection() + { + return null; + } + + public Object invoke( String aFunctionName, java.lang.Object[] aParams, + short[][] aOutParamIndex, java.lang.Object[][] aOutParam ) + throws com.sun.star.lang.IllegalArgumentException, + com.sun.star.script.CannotConvertException, + com.sun.star.reflection.InvocationTargetException + { + String[] aRet = null; + if( !aFunctionName.equals( aSearchMethodName ) ) + throw new com.sun.star.lang.IllegalArgumentException(); + + Object[] aScoreOutArray = new Object[1]; + aScoreOutArray[0] = null; + try + { + aRet = doQuery( aParams, aScoreOutArray ); + } + catch( Exception e ) + { + aRet = null; + } + + Object aScoreArray = aScoreOutArray[0]; + if( aScoreArray == null ) + { + aOutParamIndex[0] = new short[0]; + aOutParam[0] = new Object[0]; + } + else + { + short nInParamCount = (short)aParams.length; + aOutParamIndex[0] = new short[1]; + aOutParamIndex[0][0] = nInParamCount; + aOutParam[0] = new Object[1]; + aOutParam[0][0] = aScoreArray; + } + + Any aRetAny = new Any( new Type( String[].class ), aRet ); + return aRetAny; + } + + public void setValue( String aPropertyName, java.lang.Object aValue ) + throws com.sun.star.beans.UnknownPropertyException, + com.sun.star.script.CannotConvertException, + com.sun.star.reflection.InvocationTargetException { + throw new com.sun.star.beans.UnknownPropertyException(); + } + + public Object getValue( String aPropertyName ) + throws com.sun.star.beans.UnknownPropertyException { + throw new com.sun.star.beans.UnknownPropertyException(); + } + + public boolean hasMethod( String aMethodName ) { + boolean bRet = (aMethodName.equals( aSearchMethodName ) ); + return bRet; + } + public boolean hasProperty( String aName ) { + return false; + } + + // Command line interface for testing + private static String[] doQuery( Object[] args, Object[] aScoreOutArray ) throws Exception + { + String aLanguageStr = ""; + String aIndexStr = ""; + String aQueryStr = ""; + boolean bCaptionOnly = false; + + int nParamCount = args.length; + String aStrs[] = new String[nParamCount]; + for( int i = 0 ; i < nParamCount ; i++ ) + { + try + { + aStrs[i] = AnyConverter.toString( args[i] ); + } + catch( IllegalArgumentException e ) + { + aStrs[i] = ""; + } + } + + // TODO: Error handling + for( int i = 0 ; i < nParamCount ; i++ ) + { + if ("-lang".equals(aStrs[i]) ) + { + aLanguageStr = aStrs[i + 1]; + i++; + } + else if( "-index".equals(aStrs[i]) ) + { + aIndexStr = aStrs[i+1]; + i++; + } + else if( "-query".equals(aStrs[i]) ) + { + aQueryStr = aStrs[i+1]; + i++; + } + else if( "-caption".equals(aStrs[i]) ) + { + bCaptionOnly = true; + } + } + String[] aDocs = queryImpl( aLanguageStr, aIndexStr, aQueryStr, bCaptionOnly, aScoreOutArray ); + + return aDocs; + } + + private static String[] queryImpl( String aLanguageStr, String aIndexStr, String aQueryStr, + boolean bCaptionOnly, Object[] aScoreOutArray ) throws Exception + { + IndexReader reader = IndexReader.open( aIndexStr ); + Searcher searcher = new IndexSearcher( reader ); + Analyzer analyzer = aLanguageStr.equals("ja") ? (Analyzer)new CJKAnalyzer() : (Analyzer)new StandardAnalyzer(); + + String aField; + if( bCaptionOnly ) + aField = "caption"; + else + aField = "content"; + + Query aQuery; + if( aQueryStr.endsWith( "*" ) ) + aQuery = new WildcardQuery( new Term( aField, aQueryStr ) ); + else + aQuery = new TermQuery( new Term( aField, aQueryStr ) ); + + // Perform search + Hits aHits = searcher.search( aQuery ); + int nHitCount = aHits.length(); + + String aDocs[] = new String[nHitCount]; + float aScores[] = null; + aScores = new float[nHitCount]; + for( int iHit = 0 ; iHit < nHitCount ; iHit++ ) + { + Document aDoc = aHits.doc( iHit ); + String aPath = aDoc.get( "path" ); + aDocs[iHit] = ( aPath != null ) ? aPath : ""; + aScores[iHit] = aHits.score( iHit ); + } + aScoreOutArray[0] = aScores; + + reader.close(); + + return aDocs; + } + } + + /** + * Gives a factory for creating the service. + * This method is called by the <code>JavaLoader</code> + * <p> + * @return returns a <code>XSingleComponentFactory</code> for creating + * the component + * @param sImplName the name of the implementation for which a + * service is desired + * @see com.sun.star.comp.loader.JavaLoader + */ + public static XSingleComponentFactory __getComponentFactory(String sImplName) + { + XSingleComponentFactory xFactory = null; + + if ( sImplName.equals( _HelpSearch.class.getName() ) ) + xFactory = Factory.createComponentFactory(_HelpSearch.class, + _HelpSearch.getServiceNames()); + + return xFactory; + } + + /** + * Writes the service information into the given registry key. + * This method is called by the <code>JavaLoader</code> + * <p> + * @return returns true if the operation succeeded + * @param regKey the registryKey + * @see com.sun.star.comp.loader.JavaLoader + */ + public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) { + return Factory.writeRegistryServiceInfo(_HelpSearch.class.getName(), + _HelpSearch.getServiceNames(), + regKey); + } + /** 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( 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. + */ + } +} diff --git a/xmlhelp/source/com/sun/star/help/MANIFEST.MF b/xmlhelp/source/com/sun/star/help/MANIFEST.MF new file mode 100644 index 000000000000..a4c5d50fde5c --- /dev/null +++ b/xmlhelp/source/com/sun/star/help/MANIFEST.MF @@ -0,0 +1 @@ +RegistrationClassName: com.sun.star.help.HelpComponent diff --git a/xmlhelp/source/com/sun/star/help/helplinker.pmk b/xmlhelp/source/com/sun/star/help/helplinker.pmk new file mode 100644 index 000000000000..569c5f4dbdee --- /dev/null +++ b/xmlhelp/source/com/sun/star/help/helplinker.pmk @@ -0,0 +1,35 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: helplinker.pmk,v $ +# +# $Revision: 1.4 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +# define HELPLINKER_DLLIMPLEMENTATION (see @ inc/xmlhelp/helplinkerdllapi.h) +CDEFS += -DHELPLINKER_DLLIMPLEMENTATION + +VISIBILITY_HIDDEN=TRUE diff --git a/xmlhelp/source/com/sun/star/help/makefile.mk b/xmlhelp/source/com/sun/star/help/makefile.mk new file mode 100644 index 000000000000..eab2a6a08a4d --- /dev/null +++ b/xmlhelp/source/com/sun/star/help/makefile.mk @@ -0,0 +1,112 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.38 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ = ..$/..$/..$/..$/.. +PRJNAME = xmlhelp +TARGET = HelpLinker +LIBBASENAME = helplinker +PACKAGE = com$/sun$/star$/help +TARGETTYPE=CUI + +.IF "$(SOLAR_JAVA)"!="" +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : helplinker.pmk + +.IF "$(SYSTEM_LIBXSLT)" == "YES" +CFLAGS+= $(LIBXSLT_CFLAGS) +.ELSE +LIBXSLTINCDIR=external$/libxslt +CFLAGS+= -I$(SOLARINCDIR)$/$(LIBXSLTINCDIR) +.ENDIF + +.IF "$(SYSTEM_DB)" == "YES" +CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES) +.ENDIF + +.IF "$(SYSTEM_EXPAT)" == "YES" +CFLAGS+=-DSYSTEM_EXPAT +.ENDIF + + +JAVACLASSFILES = \ + $(CLASSDIR)$/$(PACKAGE)$/HelpSearch.class \ + $(CLASSDIR)$/$(PACKAGE)$/HelpComponent.class \ + $(CLASSDIR)$/$(PACKAGE)$/HelpIndexer.class + +JAVAFILES = \ + HelpSearch.java \ + HelpComponent.java \ + HelpIndexer.java + +TRANSEX3FILES = \ + $(SOLARBINDIR)$/help$/$(PACKAGE)$/HelpIndexerTool.class \ + $(SOLARBINDIR)$/help$/$(PACKAGE)$/HelpFileDocument.class + +ADDFILES = $(subst,$(SOLARBINDIR)$/help,$(CLASSDIR) $(TRANSEX3FILES)) + +JARFILES = ridl.jar jurt.jar unoil.jar juh.jar +.IF "$(SYSTEM_LUCENE)" == "YES" +XCLASSPATH!:=$(XCLASSPATH)$(PATH_SEPERATOR)$(LUCENE_CORE_JAR)$(PATH_SEPERATOR)$(LUCENE_ANALYZERS_JAR) +JARCLASSPATH = file://$(LUCENE_CORE_JAR) file://$(LUCENE_ANALYZERS_JAR) +.ELSE +JARFILES += lucene-core-2.3.jar lucene-analyzers-2.3.jar +JARCLASSPATH = lucene-core-2.3.jar lucene-analyzers-2.3.jar +.ENDIF + +JARTARGET = LuceneHelpWrapper.jar +JARCOMPRESS = TRUE +CUSTOMMANIFESTFILE = MANIFEST.MF + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +ALLTAR : $(ADDFILES) + +.IF "$(JARTARGETN)"!="" +$(JAVATARGET) : $(ADDFILES) +$(JARTARGETN) : $(ADDFILES) +.ENDIF + +$(CLASSDIR)$/$(PACKAGE)$/%.class : $(SOLARBINDIR)$/help$/$(PACKAGE)$/%.class + $(MKDIRHIER) $(@:d) + $(COPY) $< $@ + +fix_system_lucene: + @echo "Fix Java Class-Path entry for Lucene libraries from system." + @$(SED) -r -e "s#^(Class-Path:).*#\1 file://$(LUCENE_CORE_JAR) file://$(LUCENE_ANALYZERS_JAR)#" \ + -i ../../../../../$(INPATH)/class/HelpLinker/META-INF/MANIFEST.MF +.ELSE +all: + @echo java disabled +.ENDIF diff --git a/xmlhelp/source/cxxhelp/inc/db/EntryProcessor.hxx b/xmlhelp/source/cxxhelp/inc/db/EntryProcessor.hxx new file mode 100644 index 000000000000..66c812ca7000 --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/db/EntryProcessor.hxx @@ -0,0 +1,55 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: EntryProcessor.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLSEARCH_DB_ENTRYPROCESSOR_HXX_ +#define _XMLSEARCH_DB_ENTRYPROCESSOR_HXX_ + +#ifndef _RTL_USTRING_HXX_ +#include <rtl/ustring> +#endif + +namespace xmlsearch { + + namespace db { + + + class EntryProcessor + { + public: + + virtual ~EntryProcessor() = 0; + virtual void processEntry( rtl::OUString string,sal_Int32 id ) = 0; + }; + + + } +} + + +#endif diff --git a/xmlhelp/source/cxxhelp/inc/excep/XmlSearchExceptions.hxx b/xmlhelp/source/cxxhelp/inc/excep/XmlSearchExceptions.hxx new file mode 100644 index 000000000000..839de7699eef --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/excep/XmlSearchExceptions.hxx @@ -0,0 +1,110 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: XmlSearchExceptions.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLSEARCH_EXCEP_XMLSEARCHEXCEPTIONS_HXX_ +#define _XMLSEARCH_EXCEP_XMLSEARCHEXCEPTIONS_HXX_ + +#include <rtl/ustring.hxx> + + +namespace xmlsearch { + + namespace excep { + + + class XmlSearchException + { + public: + + XmlSearchException( const rtl::OUString& message ) + : _message( message ) + { + } + + rtl::OUString getMessage() const + { + return _message; + } + + + private: + + rtl::OUString _message; + }; + + + class IOException + : public virtual XmlSearchException + { + public: + + IOException( const rtl::OUString& message ) + : XmlSearchException( message ) + { + } + }; + + + class NoFactoryException + : public virtual XmlSearchException + { + public: + NoFactoryException( const rtl::OUString& message ) + : XmlSearchException( message ) + { + } + }; + + + class NoSuchBlock + : public virtual XmlSearchException + { + public: + NoSuchBlock( const rtl::OUString& message ) + : XmlSearchException( message ) + { + } + }; + + + class IllegalIndexException + : public virtual XmlSearchException + { + public: + IllegalIndexException( const rtl::OUString& message ) + : XmlSearchException( message ) + { + } + }; + + } +} + + +#endif diff --git a/xmlhelp/source/cxxhelp/inc/qe/ConceptData.hxx b/xmlhelp/source/cxxhelp/inc/qe/ConceptData.hxx new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/qe/ConceptData.hxx diff --git a/xmlhelp/source/cxxhelp/inc/qe/ContextTables.hxx b/xmlhelp/source/cxxhelp/inc/qe/ContextTables.hxx new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/qe/ContextTables.hxx diff --git a/xmlhelp/source/cxxhelp/inc/qe/DocGenerator.hxx b/xmlhelp/source/cxxhelp/inc/qe/DocGenerator.hxx new file mode 100644 index 000000000000..bdad2d01d43c --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/qe/DocGenerator.hxx @@ -0,0 +1,107 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocGenerator.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLSEARCH_QE_DOCGENERATOR_HXX_ +#define _XMLSEARCH_QE_DOCGENERATOR_HXX_ + +#include <rtl/ref.hxx> +#ifndef _RTL_USTRING_HXX__ +#include <rtl/ustring.hxx> +#endif +#include <excep/XmlSearchExceptions.hxx> +#include <util/CompressorIterator.hxx> +#include <util/Decompressor.hxx> + + +namespace xmlsearch { + + namespace qe { + + + class Query; + + + class NonnegativeIntegerGenerator + { + public: + + static const sal_Int32 END; + + virtual ~NonnegativeIntegerGenerator() { }; + virtual sal_Int32 first() throw( xmlsearch::excep::XmlSearchException ) = 0; + virtual sal_Int32 next() throw( xmlsearch::excep::XmlSearchException ) = 0; + }; + + + class RoleFiller + { + public: + + static RoleFiller* STOP() { return &roleFiller_; } + + RoleFiller(); + + ~RoleFiller(); + + void acquire() { ++m_nRefcount; } + void release() { if( ! --m_nRefcount ) delete this; } + + private: + + static RoleFiller roleFiller_; + + sal_uInt32 m_nRefcount; + sal_uInt8 fixedRole_; + sal_Int16 filled_; + sal_Int32 begin_,end_,parentContext_,limit_; + + RoleFiller* next_; + std::vector< RoleFiller* > fillers_; + }; + + + class GeneratorHeap + { + public: + + GeneratorHeap() + : heapSize_( 0 ), + free_( 0 ) + { } + private: + + sal_Int32 heapSize_,free_; + }; + + + + } +} + +#endif diff --git a/xmlhelp/source/cxxhelp/inc/qe/Query.hxx b/xmlhelp/source/cxxhelp/inc/qe/Query.hxx new file mode 100644 index 000000000000..33b0d3153ba4 --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/qe/Query.hxx @@ -0,0 +1,178 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Query.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLSEARCH_QE_QUERY_HXX_ +#define _XMLSEARCH_QE_QUERY_HXX_ + +#include <sal/types.h> +#include <rtl/memory.h> +#include <rtl/ustring.hxx> +#include <vector> + + +namespace xmlsearch { + + namespace qe { + + class Search; + class RoleFiller; + + class QueryHit + { + public: + + QueryHit( sal_Int32 nColumns,double penalty,sal_Int32 doc,sal_Int32 begin,sal_Int32 end ) + : doc_( doc ), + begin_( begin ), + end_( end ), + matchesL_( 2*nColumns ), + matches_( new sal_Int32[ 2*nColumns ] ), + penalty_( penalty ) + { + rtl_zeroMemory( matches_,sizeof( sal_Int32 ) * matchesL_ ); + } + + ~QueryHit() { delete[] matches_; } + + sal_Int32 getDocument() const { return doc_; } + + sal_Int32 countOfMatches() const { return matchesL_; } + + sal_Int32 getBegin() const { return begin_; } + + sal_Int32 getEnd() const { return end_; } + + double getPenalty() const { return penalty_; } + + bool betterThan( const QueryHit* o ) + { + if( penalty_ != o->penalty_ ) + return penalty_ < o->penalty_; + else if( begin_ != o->begin_ ) + return begin_ < o->begin_; + else if( end_ != o->end_ ) + return end_ < o->end_; + else + return false; + } + + bool worseThan( const QueryHit* o ) + { + if( penalty_ != o->penalty_ ) + return penalty_ > o->penalty_; + else if( begin_ != o->begin_ ) + return begin_ > o->begin_; + else if( end_ != o->end_ ) + return end_ > o->end_; + else + return false; + } + + bool worseThan( double penalty,sal_Int32 begin,sal_Int32 end ) + { + if( penalty_ != penalty ) + return penalty_ > penalty; + else if( begin_ != begin ) + return begin_ > begin; + else if( end_ != end ) + return end_ > end; + else + return false; + } + + bool compareTo( const QueryHit* o ) const + { + if( penalty_ != o->penalty_ ) + return penalty_ < o->penalty_; + else if( begin_ != o->begin_ ) + return begin_ < o->begin_; + else if( end_ != o->end_ ) + return end_ < o->end_; + else + return false; + } + + + private: + + sal_Int32 doc_,begin_,end_; + + sal_Int32 matchesL_; + sal_Int32 *matches_; // ...concept, word number, ... + + double penalty_; + + }; // end class QueryHit + + + + class QueryHitData + { + public: + + QueryHitData( double penalty,const rtl::OUString& document,sal_Int32 termsL, rtl::OUString* terms ) + : penalty_( penalty ), + document_( document ), + termsL_( termsL ), + terms_( terms ) { } + + ~QueryHitData() { delete[] terms_; } + + rtl::OUString getDocument() const { return document_; } + + double getPenalty() const { return penalty_; } + + + private: + + double penalty_; + + const rtl::OUString document_; + + sal_Int32 termsL_; + rtl::OUString* terms_; + + }; // end class QueryHitData + + + class PrefixTranslator + { + public: + + static PrefixTranslator* makePrefixTranslator( const rtl::OUString*,sal_Int32 ) + { + return 0; + } + }; + } + +} + + +#endif diff --git a/xmlhelp/source/cxxhelp/inc/qe/QueryProcessor.hxx b/xmlhelp/source/cxxhelp/inc/qe/QueryProcessor.hxx new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/qe/QueryProcessor.hxx diff --git a/xmlhelp/source/cxxhelp/inc/qe/Search.hxx b/xmlhelp/source/cxxhelp/inc/qe/Search.hxx new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/qe/Search.hxx diff --git a/xmlhelp/source/cxxhelp/inc/qe/XmlIndex.hxx b/xmlhelp/source/cxxhelp/inc/qe/XmlIndex.hxx new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/qe/XmlIndex.hxx diff --git a/xmlhelp/source/cxxhelp/inc/util/CompressorIterator.hxx b/xmlhelp/source/cxxhelp/inc/util/CompressorIterator.hxx new file mode 100644 index 000000000000..c4a88bf92427 --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/util/CompressorIterator.hxx @@ -0,0 +1,52 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: CompressorIterator.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLSEARCH_UTIL_COMPRESSORITERATOR_HXX_ +#define _XMLSEARCH_UTIL_COMPRESSORITERATOR_HXX_ + + +namespace xmlsearch { + + namespace util { + + class CompressorIterator + { + public: + + virtual void value( sal_Int32 ) = 0; + + }; + + + } + +} + + +#endif diff --git a/xmlhelp/source/cxxhelp/inc/util/ConceptList.hxx b/xmlhelp/source/cxxhelp/inc/util/ConceptList.hxx new file mode 100644 index 000000000000..246d647603ee --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/util/ConceptList.hxx @@ -0,0 +1,73 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ConceptList.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLSEARCH_UTIL_CONCEPTLIST_HXX_ +#define _XMLSEARCH_UTIL_CONCEPTLIST_HXX_ + +#include <excep/XmlSearchExceptions.hxx> +#include <qe/DocGenerator.hxx> +#include <util/Decompressor.hxx> +#include <util/CompressorIterator.hxx> + + +namespace xmlsearch { + + namespace util { + + + class CompressorIterator; + + + + class ConceptList + : public CompressorIterator, + public xmlsearch::qe::NonnegativeIntegerGenerator + { + public: + + ConceptList( sal_Int8* array,sal_Int32 arrl,sal_Int32 index ) + : k_( array[index] ), + value_( 0 ), + list_( arrl,array,index + 1 ) { } + + void value( sal_Int32 val ) { value_ += val; } + + private: + + sal_Int32 k_,value_; + ByteArrayDecompressor list_; + + }; + + } + +} + + +#endif diff --git a/xmlhelp/source/cxxhelp/inc/util/Decompressor.hxx b/xmlhelp/source/cxxhelp/inc/util/Decompressor.hxx new file mode 100644 index 000000000000..2f68133d7f6f --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/util/Decompressor.hxx @@ -0,0 +1,154 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Decompressor.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLSEARCH_UTIL_DECOMPRESSOR_HXX_ +#define _XMLSEARCH_UTIL_DECOMPRESSOR_HXX_ + +#ifndef INCLUDED_STL_VECTOR +#include <vector> +#define INCLUDED_STL_VECTOR +#endif +#include <excep/XmlSearchExceptions.hxx> +#include <util/RandomAccessStream.hxx> + + +namespace xmlsearch { + + namespace util { + + + class CompressorIterator; + + + class Decompressor + { + public: + + Decompressor() + : toRead_( 0 ), + path_( 0 ) + { + } + + virtual ~Decompressor() { } + + virtual sal_Int32 getNextByte() = 0; + + virtual void initReading() + { + toRead_ = 0; + } + + private: + + static const sal_Int32 BitsInByte; + static const sal_Int32 NBits; + + sal_Int32 readByte_, toRead_, path_; + }; + + + + + class StreamDecompressor + : public Decompressor + { + public: + + StreamDecompressor( RandomAccessStream* in ) + : in_( in ) + { + } + + ~StreamDecompressor() { } + + + virtual sal_Int32 getNextByte(); + + private: + + RandomAccessStream* in_; + + }; + + + + class ByteArrayDecompressor + : public Decompressor + { + public: + + ByteArrayDecompressor( sal_Int32 arrayL,sal_Int8* array,sal_Int32 index ) + { + initReading(array,arrayL,index); + } + + + ~ByteArrayDecompressor() { } + + sal_Int32 bytesRead() + { + return index_ - index0_; + } + + + sal_Int32 getNextByte() throw( xmlsearch::excep::XmlSearchException ) + { + if( arrayL_ <= index_ ) + throw xmlsearch::excep::XmlSearchException( + rtl::OUString::createFromAscii( "ByteArrayDecompressor->getNextByte()" ) ); + return array_[index_++] & 0xFF; + } + + + private: + + sal_Int32 arrayL_; + sal_Int8 *array_; + + sal_Int32 index_,index0_; + + using xmlsearch::util::Decompressor::initReading; + void initReading( sal_Int8* array,sal_Int32 arrayL,sal_Int32 index ) + { + arrayL_ = arrayL; + array_ = array; + index_ = index0_ = index; + Decompressor::initReading(); + } + + }; + + + } + +} + + +#endif diff --git a/xmlhelp/source/cxxhelp/inc/util/RandomAccessStream.hxx b/xmlhelp/source/cxxhelp/inc/util/RandomAccessStream.hxx new file mode 100644 index 000000000000..49adc24cf164 --- /dev/null +++ b/xmlhelp/source/cxxhelp/inc/util/RandomAccessStream.hxx @@ -0,0 +1,66 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: RandomAccessStream.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _XMLEARCH_UTIL_RANDOMACCESSSTREAM_HXX_ +#define _XMLEARCH_UTIL_RANDOMACCESSSTREAM_HXX_ + +#include <osl/file.hxx> + +namespace xmlsearch { + + namespace util { + + + class RandomAccessStream + { + public: + + virtual ~RandomAccessStream() { }; + + // The calle is responsible for allocating the buffer + virtual void seek( sal_Int32 ) = 0; + virtual sal_Int32 readBytes( sal_Int8*,sal_Int32 ) = 0; + virtual void writeBytes( sal_Int8*, sal_Int32 ) = 0; + virtual sal_Int32 length() = 0; + virtual void close() = 0; + + + protected: + + enum OPENFLAG { Read = OpenFlag_Read, + Write = OpenFlag_Write, + Create = OpenFlag_Create }; + + }; + + + } +} + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/bufferedinputstream.cxx b/xmlhelp/source/cxxhelp/provider/bufferedinputstream.cxx new file mode 100644 index 000000000000..b507c6965115 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/bufferedinputstream.cxx @@ -0,0 +1,236 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: bufferedinputstream.cxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <rtl/memory.h> +#include "bufferedinputstream.hxx" + + +using namespace cppu; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::io; +using namespace chelp; + + +Reference<XInputStream> chelp::turnToSeekable(const Reference<XInputStream>& xInputStream) +{ + if( ! xInputStream.is() ) + return xInputStream; + + Reference<XSeekable> xSeekable(xInputStream,UNO_QUERY); + + if( xSeekable.is() ) + return xInputStream; + + return new BufferedInputStream(xInputStream); +} + + + +BufferedInputStream::BufferedInputStream(const Reference<XInputStream>& xInputStream) + : m_nBufferLocation(0), + m_nBufferSize(0), + m_pBuffer(new sal_Int8[1]) // Initialize with one to avoid gcc compiler warnings +{ + try + { + sal_Int32 num; + sal_Int8 *tmp; + Sequence< sal_Int8 > aData(4096); + do{ + num = xInputStream->readBytes(aData,4096); + if( num > 0 ) + { + tmp = m_pBuffer; + m_pBuffer = new sal_Int8[m_nBufferSize+num]; + rtl_copyMemory((void *)(m_pBuffer), + (void *)(tmp), + sal_uInt32(m_nBufferSize)); + rtl_copyMemory((void *)(m_pBuffer+m_nBufferSize), + (void *)(aData.getArray()), + sal_uInt32(num)); + m_nBufferSize += num; + delete[] tmp; + } + } while( num == 4096 ); + } + catch( const NotConnectedException&) + { + } + catch( const BufferSizeExceededException&) + { + } + catch( const IOException&) + { + } + catch( const RuntimeException&) + { + } + xInputStream->closeInput(); +} + + +BufferedInputStream::~BufferedInputStream() +{ + delete[] m_pBuffer; +} + + +Any SAL_CALL BufferedInputStream::queryInterface( const Type& rType ) throw( RuntimeException ) +{ + Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( XInputStream*,this ), + SAL_STATIC_CAST( XSeekable*,this ) ); + + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +void SAL_CALL BufferedInputStream::acquire( void ) throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL BufferedInputStream::release( void ) throw() +{ + OWeakObject::release(); +} + + + +sal_Int32 SAL_CALL BufferedInputStream::readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if( 0 > nBytesToRead ) + throw BufferSizeExceededException(); + + if( m_nBufferLocation + nBytesToRead > m_nBufferSize ) + nBytesToRead = m_nBufferSize - m_nBufferLocation; + + if( aData.getLength() < nBytesToRead ) + aData.realloc(nBytesToRead); + + rtl_copyMemory((void*)(aData.getArray()), + (void*)(m_pBuffer+m_nBufferLocation), + nBytesToRead); + + return nBytesToRead; +} + + +sal_Int32 SAL_CALL BufferedInputStream::readSomeBytes( + Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException) +{ + return readBytes(aData,nMaxBytesToRead); +} + + + +void SAL_CALL BufferedInputStream::skipBytes( sal_Int32 nBytesToSkip ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException ) +{ + try + { + seek(m_nBufferLocation+nBytesToSkip); + } + catch( const IllegalArgumentException& ) + { + throw BufferSizeExceededException(); + } +} + + + +sal_Int32 SAL_CALL BufferedInputStream::available( void ) + throw( NotConnectedException, + IOException, + RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + return m_nBufferSize-m_nBufferLocation; +} + + + +void SAL_CALL BufferedInputStream::closeInput( void ) + throw( NotConnectedException, + IOException, + RuntimeException ) +{ +} + + +void SAL_CALL BufferedInputStream::seek( sal_Int64 location ) + throw( IllegalArgumentException, + IOException, + RuntimeException ) +{ + if( 0 <= location && location < m_nBufferSize ) + { + osl::MutexGuard aGuard( m_aMutex ); + m_nBufferLocation = sal::static_int_cast<sal_Int32>( location ); + } + else + throw IllegalArgumentException(); +} + + + +sal_Int64 SAL_CALL BufferedInputStream::getPosition( void ) + throw( IOException, + RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + return m_nBufferLocation; +} + + + +sal_Int64 SAL_CALL BufferedInputStream::getLength( void ) throw( IOException,RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + return m_nBufferSize; +} diff --git a/xmlhelp/source/cxxhelp/provider/bufferedinputstream.hxx b/xmlhelp/source/cxxhelp/provider/bufferedinputstream.hxx new file mode 100644 index 000000000000..e85820caa363 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/bufferedinputstream.hxx @@ -0,0 +1,116 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: bufferedinputstream.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <cppuhelper/weak.hxx> +#include <osl/mutex.hxx> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> + + +namespace chelp { + + class BufferedInputStream + : public cppu::OWeakObject, + public com::sun::star::io::XInputStream, + public com::sun::star::io::XSeekable + { + private: + + sal_Int32 m_nBufferLocation; + sal_Int32 m_nBufferSize; + sal_Int8 *m_pBuffer; + osl::Mutex m_aMutex; + + public: + + BufferedInputStream( + const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& xInputStream); + + ~BufferedInputStream(); + + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( const com::sun::star::uno::Type& rType ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL acquire( void ) throw(); + + virtual void SAL_CALL release( void ) throw(); + + + virtual sal_Int32 SAL_CALL readBytes( com::sun::star::uno::Sequence< sal_Int8 >& aData, + sal_Int32 nBytesToRead ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int32 SAL_CALL readSomeBytes( com::sun::star::uno::Sequence< sal_Int8 >& aData, + sal_Int32 nMaxBytesToRead ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int32 SAL_CALL available( void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL closeInput( void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL seek( sal_Int64 location ) + throw( com::sun::star::lang::IllegalArgumentException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int64 SAL_CALL getPosition( void ) + throw( com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int64 SAL_CALL getLength( void ) + throw( com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + }; + + + extern com::sun::star::uno::Reference<com::sun::star::io::XInputStream> + turnToSeekable( + const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& xInputStream); + +} diff --git a/xmlhelp/source/cxxhelp/provider/content.cxx b/xmlhelp/source/cxxhelp/provider/content.cxx new file mode 100644 index 000000000000..11dca28ed7da --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/content.cxx @@ -0,0 +1,581 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: content.cxx,v $ + * $Revision: 1.21 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" + +/************************************************************************** + TODO + ************************************************************************** + + *************************************************************************/ +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/XPropertyAccess.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/ucb/OpenCommandArgument2.hpp> +#include <com/sun/star/ucb/OpenMode.hpp> +#include <com/sun/star/ucb/XCommandInfo.hpp> +#include <com/sun/star/io/XActiveDataSink.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/lang/IllegalAccessException.hpp> +#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp> +#include <com/sun/star/io/XActiveDataStreamer.hpp> +#include <com/sun/star/ucb/XPersistentPropertySet.hpp> +#ifndef _VOS_DIAGNOSE_HXX_ +#include <vos/diagnose.hxx> +#endif +#include <ucbhelper/contentidentifier.hxx> +#include <ucbhelper/propertyvalueset.hxx> +#ifndef _UCBHELPER_CANCELCOMMANDEXECUTION_HXX +#include <ucbhelper/cancelcommandexecution.hxx> +#endif +#include "content.hxx" +#include "provider.hxx" +#include "resultset.hxx" +#include "databases.hxx" +#include "resultsetfactory.hxx" +#include "resultsetbase.hxx" +#include "resultsetforroot.hxx" +#include "resultsetforquery.hxx" + +using namespace com::sun::star; +using namespace chelp; + +//========================================================================= +//========================================================================= +// +// Content Implementation. +// +//========================================================================= +//========================================================================= + +Content::Content( const uno::Reference< lang::XMultiServiceFactory >& rxSMgr, + ::ucbhelper::ContentProviderImplHelper* pProvider, + const uno::Reference< ucb::XContentIdentifier >& + Identifier, + Databases* pDatabases ) + : ContentImplHelper( rxSMgr, pProvider, Identifier ), + m_aURLParameter( Identifier->getContentIdentifier(),pDatabases ), + m_pDatabases( pDatabases ) // not owner +{ +} + +//========================================================================= +// virtual +Content::~Content() +{ +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +// virtual +void SAL_CALL Content::acquire() + throw( ) +{ + ContentImplHelper::acquire(); +} + +//========================================================================= +// virtual +void SAL_CALL Content::release() + throw( ) +{ + ContentImplHelper::release(); +} + +//========================================================================= +// virtual +uno::Any SAL_CALL Content::queryInterface( const uno::Type & rType ) + throw ( uno::RuntimeException ) +{ + uno::Any aRet; + return aRet.hasValue() ? aRet : ContentImplHelper::queryInterface( rType ); +} + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_COMMON_IMPL( Content ); + +//========================================================================= +// virtual +uno::Sequence< uno::Type > SAL_CALL Content::getTypes() + throw( uno::RuntimeException ) +{ + static cppu::OTypeCollection* pCollection = NULL; + + if ( !pCollection ) + { + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ); + if ( !pCollection ) + { + static cppu::OTypeCollection aCollection( + CPPU_TYPE_REF( lang::XTypeProvider ), + CPPU_TYPE_REF( lang::XServiceInfo ), + CPPU_TYPE_REF( lang::XComponent ), + CPPU_TYPE_REF( ucb::XContent ), + CPPU_TYPE_REF( ucb::XCommandProcessor ), + CPPU_TYPE_REF( beans::XPropertiesChangeNotifier ), + CPPU_TYPE_REF( ucb::XCommandInfoChangeNotifier ), + CPPU_TYPE_REF( beans::XPropertyContainer ), + CPPU_TYPE_REF( beans::XPropertySetInfoChangeNotifier ), + CPPU_TYPE_REF( container::XChild ) ); + pCollection = &aCollection; + } + } + + return (*pCollection).getTypes(); +} + +//========================================================================= +// +// XServiceInfo methods. +// +//========================================================================= + +// virtual +rtl::OUString SAL_CALL Content::getImplementationName() + throw( uno::RuntimeException ) +{ + return rtl::OUString::createFromAscii( "CHelpContent" ); +} + +//========================================================================= +// virtual +uno::Sequence< rtl::OUString > SAL_CALL Content::getSupportedServiceNames() + throw( uno::RuntimeException ) +{ + uno::Sequence< rtl::OUString > aSNS( 1 ); + aSNS.getArray()[ 0 ] + = rtl::OUString::createFromAscii( MYUCP_CONTENT_SERVICE_NAME ); + return aSNS; +} + +//========================================================================= +// +// XContent methods. +// +//========================================================================= + +// virtual +rtl::OUString SAL_CALL Content::getContentType() + throw( uno::RuntimeException ) +{ + return rtl::OUString::createFromAscii( MYUCP_CONTENT_TYPE ); +} + +//========================================================================= +// +// XCommandProcessor methods. +// +//========================================================================= + +//virtual +void SAL_CALL Content::abort( sal_Int32 /*CommandId*/ ) + throw( uno::RuntimeException ) +{ +} + + + +class ResultSetForRootFactory + : public ResultSetFactory +{ +private: + + uno::Reference< lang::XMultiServiceFactory > m_xSMgr; + uno::Reference< ucb::XContentProvider > m_xProvider; + sal_Int32 m_nOpenMode; + uno::Sequence< beans::Property > m_seq; + uno::Sequence< ucb::NumberedSortingInfo > m_seqSort; + URLParameter m_aURLParameter; + Databases* m_pDatabases; + + +public: + + ResultSetForRootFactory( + const uno::Reference< lang::XMultiServiceFactory >& xSMgr, + const uno::Reference< ucb::XContentProvider >& xProvider, + sal_Int32 nOpenMode, + const uno::Sequence< beans::Property >& seq, + const uno::Sequence< ucb::NumberedSortingInfo >& seqSort, + URLParameter aURLParameter, + Databases* pDatabases ) + : m_xSMgr( xSMgr ), + m_xProvider( xProvider ), + m_nOpenMode( nOpenMode ), + m_seq( seq ), + m_seqSort( seqSort ), + m_aURLParameter( aURLParameter ), + m_pDatabases( pDatabases ) + { + } + + ResultSetBase* createResultSet() + { + return new ResultSetForRoot( m_xSMgr, + m_xProvider, + m_nOpenMode, + m_seq, + m_seqSort, + m_aURLParameter, + m_pDatabases ); + } +}; + + + +class ResultSetForQueryFactory + : public ResultSetFactory +{ +private: + + uno::Reference< lang::XMultiServiceFactory > m_xSMgr; + uno::Reference< ucb::XContentProvider > m_xProvider; + sal_Int32 m_nOpenMode; + uno::Sequence< beans::Property > m_seq; + uno::Sequence< ucb::NumberedSortingInfo > m_seqSort; + URLParameter m_aURLParameter; + Databases* m_pDatabases; + + +public: + + ResultSetForQueryFactory( + const uno::Reference< lang::XMultiServiceFactory >& xSMgr, + const uno::Reference< ucb::XContentProvider >& xProvider, + sal_Int32 nOpenMode, + const uno::Sequence< beans::Property >& seq, + const uno::Sequence< ucb::NumberedSortingInfo >& seqSort, + URLParameter aURLParameter, + Databases* pDatabases ) + : m_xSMgr( xSMgr ), + m_xProvider( xProvider ), + m_nOpenMode( nOpenMode ), + m_seq( seq ), + m_seqSort( seqSort ), + m_aURLParameter( aURLParameter ), + m_pDatabases( pDatabases ) + { + } + + ResultSetBase* createResultSet() + { + return new ResultSetForQuery( m_xSMgr, + m_xProvider, + m_nOpenMode, + m_seq, + m_seqSort, + m_aURLParameter, + m_pDatabases ); + } +}; + + + +// virtual +uno::Any SAL_CALL Content::execute( + const ucb::Command& aCommand, + sal_Int32 CommandId, + const uno::Reference< ucb::XCommandEnvironment >& Environment ) + throw( uno::Exception, + ucb::CommandAbortedException, + uno::RuntimeException ) +{ + uno::Any aRet; + + if ( aCommand.Name.compareToAscii( "getPropertyValues" ) == 0 ) + { + uno::Sequence< beans::Property > Properties; + if ( !( aCommand.Argument >>= Properties ) ) + { + aRet <<= lang::IllegalArgumentException(); + ucbhelper::cancelCommandExecution(aRet,Environment); + } + + aRet <<= getPropertyValues( Properties ); + } + else if ( aCommand.Name.compareToAscii( "setPropertyValues" ) == 0 ) + { + uno::Sequence<beans::PropertyValue> propertyValues; + + if( ! ( aCommand.Argument >>= propertyValues ) ) { + aRet <<= lang::IllegalArgumentException(); + ucbhelper::cancelCommandExecution(aRet,Environment); + } + + uno::Sequence< uno::Any > ret(propertyValues.getLength()); + uno::Sequence< beans::Property > props(getProperties(Environment)); + // No properties can be set + for(sal_Int32 i = 0; i < ret.getLength(); ++i) { + ret[i] <<= beans::UnknownPropertyException(); + for(sal_Int32 j = 0; j < props.getLength(); ++j) + if(props[j].Name == propertyValues[i].Name) { + ret[i] <<= lang::IllegalAccessException(); + break; + } + } + + aRet <<= ret; + } + else if ( aCommand.Name.compareToAscii( "getPropertySetInfo" ) == 0 ) + { + // Note: Implemented by base class. + aRet <<= getPropertySetInfo( Environment ); + } + else if ( aCommand.Name.compareToAscii( "getCommandInfo" ) == 0 ) + { + // Note: Implemented by base class. + aRet <<= getCommandInfo( Environment ); + } + else if ( aCommand.Name.compareToAscii( "open" ) == 0 ) + { + ucb::OpenCommandArgument2 aOpenCommand; + if ( !( aCommand.Argument >>= aOpenCommand ) ) + { + aRet <<= lang::IllegalArgumentException(); + ucbhelper::cancelCommandExecution(aRet,Environment); + } + + uno::Reference< io::XActiveDataSink > xActiveDataSink( + aOpenCommand.Sink, uno::UNO_QUERY); + + if(xActiveDataSink.is()) + m_aURLParameter.open(m_xSMgr, + aCommand, + CommandId, + Environment, + xActiveDataSink); + + uno::Reference< io::XActiveDataStreamer > xActiveDataStreamer( + aOpenCommand.Sink, uno::UNO_QUERY); + + if(xActiveDataStreamer.is()) { + aRet <<= ucb::UnsupportedDataSinkException(); + ucbhelper::cancelCommandExecution(aRet,Environment); + } + + uno::Reference< io::XOutputStream > xOutputStream( + aOpenCommand.Sink, uno::UNO_QUERY); + + if(xOutputStream.is() ) + m_aURLParameter.open(m_xSMgr, + aCommand, + CommandId, + Environment, + xOutputStream); + + if( m_aURLParameter.isRoot() ) + { + uno::Reference< ucb::XDynamicResultSet > xSet + = new DynamicResultSet( + m_xSMgr, + this, + aOpenCommand, + Environment, + new ResultSetForRootFactory( + m_xSMgr, + m_xProvider.get(), + aOpenCommand.Mode, + aOpenCommand.Properties, + aOpenCommand.SortingInfo, + m_aURLParameter, + m_pDatabases)); + aRet <<= xSet; + } + else if( m_aURLParameter.isQuery() ) + { + uno::Reference< ucb::XDynamicResultSet > xSet + = new DynamicResultSet( + m_xSMgr, + this, + aOpenCommand, + Environment, + new ResultSetForQueryFactory( + m_xSMgr, + m_xProvider.get(), + aOpenCommand.Mode, + aOpenCommand.Properties, + aOpenCommand.SortingInfo, + m_aURLParameter, + m_pDatabases ) ); + aRet <<= xSet; + } + } + else + { + ////////////////////////////////////////////////////////////////// + // Unsupported command + ////////////////////////////////////////////////////////////////// + aRet <<= ucb::UnsupportedCommandException(); + ucbhelper::cancelCommandExecution(aRet,Environment); + } + + return aRet; +} + + + + +//========================================================================= +uno::Reference< sdbc::XRow > Content::getPropertyValues( + const uno::Sequence< beans::Property >& rProperties ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + rtl::Reference< ::ucbhelper::PropertyValueSet > xRow = + new ::ucbhelper::PropertyValueSet( m_xSMgr ); + + for ( sal_Int32 n = 0; n < rProperties.getLength(); ++n ) + { + const beans::Property& rProp = rProperties[n]; + + if ( rProp.Name.compareToAscii( "ContentType" ) == 0 ) + xRow->appendString( + rProp, + rtl::OUString::createFromAscii( + "application/vnd.sun.star.help" ) ); + else if( rProp.Name.compareToAscii( "Title" ) == 0 ) + xRow->appendString ( rProp,m_aURLParameter.get_title() ); + else if( rProp.Name.compareToAscii( "IsReadOnly" ) == 0 ) + xRow->appendBoolean( rProp,true ); + else if( rProp.Name.compareToAscii( "IsDocument" ) == 0 ) + xRow->appendBoolean( + rProp, + m_aURLParameter.isFile() || m_aURLParameter.isRoot() ); + else if( rProp.Name.compareToAscii( "IsFolder" ) == 0 ) + xRow->appendBoolean( + rProp, + ! m_aURLParameter.isFile() || m_aURLParameter.isRoot() ); + else if( rProp.Name.compareToAscii( "IsErrorDocument" ) == 0 ) + xRow->appendBoolean( rProp, m_aURLParameter.isErrorDocument() ); + else if( rProp.Name.compareToAscii( "MediaType" ) == 0 ) + if( m_aURLParameter.isPicture() ) + xRow->appendString( + rProp, + rtl::OUString::createFromAscii( "image/gif" ) ); + else if( m_aURLParameter.isActive() ) + xRow->appendString( + rProp, + rtl::OUString::createFromAscii( "text/plain" ) ); + else if( m_aURLParameter.isFile() ) + xRow->appendString( + rProp,rtl::OUString::createFromAscii( "text/html" ) ); + else if( m_aURLParameter.isRoot() ) + xRow->appendString( + rProp, + rtl::OUString::createFromAscii( "text/css" ) ); + else + xRow->appendVoid( rProp ); + else if( m_aURLParameter.isModule() ) + if( rProp.Name.compareToAscii( "KeywordList" ) == 0 ) + { + KeywordInfo *inf = + m_pDatabases->getKeyword( m_aURLParameter.get_module(), + m_aURLParameter.get_language() ); + + uno::Any aAny; + if( inf ) + aAny <<= inf->getKeywordList(); + xRow->appendObject( rProp,aAny ); + } + else if( rProp.Name.compareToAscii( "KeywordRef" ) == 0 ) + { + KeywordInfo *inf = + m_pDatabases->getKeyword( m_aURLParameter.get_module(), + m_aURLParameter.get_language() ); + + uno::Any aAny; + if( inf ) + aAny <<= inf->getIdList(); + xRow->appendObject( rProp,aAny ); + } + else if( rProp.Name.compareToAscii( "KeywordAnchorForRef" ) == 0 ) + { + KeywordInfo *inf = + m_pDatabases->getKeyword( m_aURLParameter.get_module(), + m_aURLParameter.get_language() ); + + uno::Any aAny; + if( inf ) + aAny <<= inf->getAnchorList(); + xRow->appendObject( rProp,aAny ); + } + else if( rProp.Name.compareToAscii( "KeywordTitleForRef" ) == 0 ) + { + KeywordInfo *inf = + m_pDatabases->getKeyword( m_aURLParameter.get_module(), + m_aURLParameter.get_language() ); + + uno::Any aAny; + if( inf ) + aAny <<= inf->getTitleList(); + xRow->appendObject( rProp,aAny ); + } + else if( rProp.Name.compareToAscii( "SearchScopes" ) == 0 ) + { + uno::Sequence< rtl::OUString > seq( 2 ); + seq[0] = rtl::OUString::createFromAscii( "Heading" ); + seq[1] = rtl::OUString::createFromAscii( "FullText" ); + uno::Any aAny; + aAny <<= seq; + xRow->appendObject( rProp,aAny ); + } + else if( rProp.Name.compareToAscii( "Order" ) == 0 ) + { + StaticModuleInformation *inf = + m_pDatabases->getStaticInformationForModule( + m_aURLParameter.get_module(), + m_aURLParameter.get_language() ); + + uno::Any aAny; + if( inf ) + aAny <<= sal_Int32( inf->get_order() ); + xRow->appendObject( rProp,aAny ); + } + else + xRow->appendVoid( rProp ); + else if( rProp.Name.compareToAscii( "AnchorName" ) == 0 && + m_aURLParameter.isFile() ) + xRow->appendString( rProp,m_aURLParameter.get_tag() ); + else + xRow->appendVoid( rProp ); + } + + return uno::Reference< sdbc::XRow >( xRow.get() ); +} diff --git a/xmlhelp/source/cxxhelp/provider/content.hxx b/xmlhelp/source/cxxhelp/provider/content.hxx new file mode 100644 index 000000000000..b2ce79104b06 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/content.hxx @@ -0,0 +1,155 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: content.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _CONTENT_HXX +#define _CONTENT_HXX + +#include <vos/ref.hxx> +#include <ucbhelper/contenthelper.hxx> +#include <com/sun/star/io/XInputStream.hpp> + +#include "urlparameter.hxx" + +namespace com { namespace sun { namespace star { namespace beans { + struct Property; + struct PropertyValue; +} } } } + +namespace com { namespace sun { namespace star { namespace sdbc { + class XRow; +} } } } + +namespace chelp +{ + +//========================================================================= + +// UNO service name for the content. +#define MYUCP_CONTENT_SERVICE_NAME \ + "com.sun.star.ucb.CHelpContent" + +//========================================================================= + + class Databases; + + struct ContentProperties + { + ::rtl::OUString aTitle; // Title + ::rtl::OUString aContentType; // ContentType + sal_Bool bIsDocument; // IsDocument + sal_Bool bIsFolder; // IsFolder + + ContentProperties() + : bIsDocument( sal_True ), bIsFolder( sal_False ) {} + }; + +//========================================================================= + + class Content : public ::ucbhelper::ContentImplHelper + { + public: + + Content( const ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + ::ucbhelper::ContentProviderImplHelper* pProvider, + const ::com::sun::star::uno::Reference< + ::com::sun::star::ucb::XContentIdentifier >& Identifier, + Databases* pDatabases ); + + virtual ~Content(); + + // XInterface + XINTERFACE_DECL() + + // XTypeProvider + XTYPEPROVIDER_DECL() + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL + getImplementationName() + throw( ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames() + throw( ::com::sun::star::uno::RuntimeException ); + + // XContent + virtual rtl::OUString SAL_CALL + getContentType() + throw( com::sun::star::uno::RuntimeException ); + + // XCommandProcessor + virtual com::sun::star::uno::Any SAL_CALL + execute( const com::sun::star::ucb::Command& aCommand, + sal_Int32 CommandId, + const com::sun::star::uno::Reference< + com::sun::star::ucb::XCommandEnvironment >& Environment ) + throw( com::sun::star::uno::Exception, + com::sun::star::ucb::CommandAbortedException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + abort( sal_Int32 CommandId ) + throw( com::sun::star::uno::RuntimeException ); + + + private: + + // private members; + + ContentProperties m_aProps; + URLParameter m_aURLParameter; + Databases* m_pDatabases; + + + // private methods + + virtual com::sun::star::uno::Sequence< com::sun::star::beans::Property > + getProperties( const com::sun::star::uno::Reference< + com::sun::star::ucb::XCommandEnvironment > & xEnv ); + virtual com::sun::star::uno::Sequence< com::sun::star::ucb::CommandInfo > + getCommands( const com::sun::star::uno::Reference< + com::sun::star::ucb::XCommandEnvironment > & xEnv ); + + virtual ::rtl::OUString getParentURL() { return ::rtl::OUString(); } + + ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRow > + getPropertyValues( const ::com::sun::star::uno::Sequence< + ::com::sun::star::beans::Property >& rProperties ); + void setPropertyValues( + const ::com::sun::star::uno::Sequence< + ::com::sun::star::beans::PropertyValue >& rValues ); + + + }; + +} + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/contentcaps.cxx b/xmlhelp/source/cxxhelp/provider/contentcaps.cxx new file mode 100644 index 000000000000..032e2e6f7b55 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/contentcaps.cxx @@ -0,0 +1,250 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: contentcaps.cxx,v $ + * $Revision: 1.12 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <com/sun/star/beans/Property.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/ucb/CommandInfo.hpp> +#include <com/sun/star/ucb/OpenCommandArgument2.hpp> +#include <com/sun/star/uno/Sequence.hxx> + +#include "content.hxx" + +using namespace com::sun; +using namespace com::sun::star; + +using namespace chelp; + +// virtual +uno::Sequence< beans::Property > Content::getProperties( + const uno::Reference< star::ucb::XCommandEnvironment > & /*xEnv*/ ) +{ + bool withMediaType = m_aURLParameter.isFile() || m_aURLParameter.isRoot(); + bool isModule = m_aURLParameter.isModule(); + bool isFile = m_aURLParameter.isFile(); + + sal_Int32 num = withMediaType ? 7 : 6; + if( isModule ) num+=6; + if( isFile ) num++; + + uno::Sequence< beans::Property > props(num); + + sal_Int32 idx = 0; + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContentType" ) ), + -1, + getCppuType( static_cast< const rtl::OUString * >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ), + -1, + getCppuBooleanType(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsErrorDocument" ) ), + -1, + getCppuBooleanType(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsDocument" ) ), + -1, + getCppuBooleanType(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) ), + -1, + getCppuBooleanType(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ), + -1, + getCppuType( static_cast< const rtl::OUString * >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + if( withMediaType ) + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MediaType" ) ), + -1, + getCppuType( static_cast< const rtl::OUString * >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + if( isModule ) + { + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Order" ) ), + -1, + getCppuType( static_cast< sal_Int32* >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeywordList" ) ), + -1, + getCppuType( + static_cast< const uno::Sequence< rtl::OUString >* >( + 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "KeywordRef" ) ), + -1, + getCppuType( + static_cast< const uno::Sequence< uno::Sequence< rtl::OUString > >* >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "KeywordTitleForRef" ) ), + -1, + getCppuType( + static_cast< const uno::Sequence< uno::Sequence< rtl::OUString > >* >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "KeywordAnchorForRef" ) ), + -1, + getCppuType( + static_cast< const uno::Sequence< uno::Sequence< rtl::OUString > >* >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SearchScopes" ) ), + -1, + getCppuType( + static_cast< const uno::Sequence< rtl::OUString >* >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + } + + if( isFile ) + { + props[idx++] = + beans::Property( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AnchorName" ) ), + -1, + getCppuType( static_cast< const rtl::OUString * >( 0 ) ), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::READONLY ); + } + + return props; +} + + + +//========================================================================= +// virtual +uno::Sequence< star::ucb::CommandInfo > Content::getCommands( + const uno::Reference< star::ucb::XCommandEnvironment > & /*xEnv*/ ) +{ +// osl::MutexGuard aGuard( m_aMutex ); + + //================================================================= + // + // Supported commands + // + //================================================================= + +#define COMMAND_COUNT 5 + + static const star::ucb::CommandInfo aCommandInfoTable[] = + { + /////////////////////////////////////////////////////////////// + // Required commands + /////////////////////////////////////////////////////////////// + star::ucb::CommandInfo( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "getCommandInfo" ) ), + -1, + getCppuVoidType() + ), + star::ucb::CommandInfo( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "getPropertySetInfo" ) ), + -1, + getCppuVoidType() + ), + star::ucb::CommandInfo( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "getPropertyValues" ) ), + -1, + getCppuType( + static_cast< uno::Sequence< beans::Property > * >( 0 ) ) + ), + star::ucb::CommandInfo( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM( "setPropertyValues" ) ), + -1, + getCppuType( + static_cast< uno::Sequence< beans::PropertyValue > * >( 0 ) ) + ), + star::ucb::CommandInfo( + rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "open" ) ), + -1, + getCppuType( + static_cast< star::ucb::OpenCommandArgument2 * >( 0 ) ) + ) + }; + + return uno::Sequence< star::ucb::CommandInfo >( + aCommandInfoTable, COMMAND_COUNT ); +} + diff --git a/xmlhelp/source/cxxhelp/provider/databases.cxx b/xmlhelp/source/cxxhelp/provider/databases.cxx new file mode 100644 index 000000000000..f5ff5b12c531 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/databases.cxx @@ -0,0 +1,2146 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: databases.cxx,v $ + * $Revision: 1.54 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include "db.hxx" +#ifndef _VOS_DIAGNOSE_HXX_ +#include <vos/diagnose.hxx> +#endif +#include <osl/thread.h> +#include <rtl/uri.hxx> +#include <osl/file.hxx> +#include <rtl/memory.h> +#include <com/sun/star/lang/Locale.hpp> +#include <rtl/ustrbuf.hxx> +#include "inputstream.hxx" +#include <algorithm> +#include <string.h> + +// Extensible help +#include "com/sun/star/deployment/thePackageManagerFactory.hpp" +#include <comphelper/processfactory.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/beans/Optional.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/frame/XConfigManager.hpp> +#include <com/sun/star/util/XMacroExpander.hpp> +#include <com/sun/star/uri/XUriReferenceFactory.hpp> +#include <com/sun/star/uri/XVndSunStarExpandUrl.hpp> +#include <com/sun/star/script/XInvocation.hpp> +#include <comphelper/locale.hxx> + +#include <l10ntools/compilehelp.hxx> +#include <comphelper/storagehelper.hxx> + +#include "databases.hxx" +#include "urlparameter.hxx" + +using namespace chelp; +using namespace berkeleydbproxy; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::io; +using namespace com::sun::star::container; +using namespace com::sun::star::i18n; +using namespace com::sun::star::lang; +using namespace com::sun::star::deployment; +using namespace com::sun::star::beans; + + +static rtl::OUString aSlash( rtl::OUString::createFromAscii( "/" ) ); +static rtl::OUString aHelpFilesBaseName( rtl::OUString::createFromAscii( "help" ) ); +static rtl::OUString aHelpMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.help" ) ); + +rtl::OUString Databases::expandURL( const rtl::OUString& aURL ) +{ + osl::MutexGuard aGuard( m_aMutex ); + rtl::OUString aRetURL = expandURL( aURL, m_xContext ); + return aRetURL; +} + +rtl::OUString Databases::expandURL( const rtl::OUString& aURL, Reference< uno::XComponentContext > xContext ) +{ + static Reference< util::XMacroExpander > xMacroExpander; + static Reference< uri::XUriReferenceFactory > xFac; + + if( !xContext.is() ) + return rtl::OUString(); + + if( !xMacroExpander.is() || !xFac.is() ) + { + Reference< XMultiComponentFactory > xSMgr( xContext->getServiceManager(), UNO_QUERY ); + + xFac = Reference< uri::XUriReferenceFactory >( + xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( + "com.sun.star.uri.UriReferenceFactory"), xContext ) , UNO_QUERY ); + if( !xFac.is() ) + { + throw RuntimeException( + ::rtl::OUString::createFromAscii( "Databases::expand(), could not instatiate UriReferenceFactory." ), + Reference< XInterface >() ); + } + + xMacroExpander = Reference< util::XMacroExpander >( + xContext->getValueByName( + ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ), + UNO_QUERY_THROW ); + } + + rtl::OUString aRetURL = aURL; + if( xMacroExpander.is() ) + { + Reference< uri::XUriReference > uriRef; + for (;;) + { + uriRef = Reference< uri::XUriReference >( xFac->parse( aRetURL ), UNO_QUERY ); + if ( uriRef.is() ) + { + Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY ); + if( !sxUri.is() ) + break; + + aRetURL = sxUri->expand( xMacroExpander ); + } + } + } + return aRetURL; +} + + +// Hold Packages to improve performance (#i106100) +// The PackageManager implementation seems to completely throw away all cached data +// as soon as the last reference to a XPackage dies. Maybe this should be changed. +struct ImplPackageSequenceHolder +{ + Sequence< Reference< deployment::XPackage > > m_aUserPackagesSeq; + Sequence< Reference< deployment::XPackage > > m_aSharedPackagesSeq; +}; + +static ImplPackageSequenceHolder* GpPackageSequenceHolder = NULL; + +Databases::Databases( sal_Bool showBasic, + const rtl::OUString& instPath, + const com::sun::star::uno::Sequence< rtl::OUString >& imagesZipPaths, + const rtl::OUString& productName, + const rtl::OUString& productVersion, + const rtl::OUString& vendorName, + const rtl::OUString& vendorVersion, + const rtl::OUString& vendorShort, + const rtl::OUString& styleSheet, + Reference< uno::XComponentContext > xContext ) + : m_xContext( xContext ), + m_bShowBasic(showBasic), + m_nErrorDocLength( 0 ), + m_pErrorDoc( 0 ), + m_nCustomCSSDocLength( 0 ), + m_pCustomCSSDoc( 0 ), + m_aCSS(styleSheet.toAsciiLowerCase()), + newProdName(rtl::OUString::createFromAscii( "$[officename]" ) ), + newProdVersion(rtl::OUString::createFromAscii( "$[officeversion]" ) ), + prodName( rtl::OUString::createFromAscii( "%PRODUCTNAME" ) ), + prodVersion( rtl::OUString::createFromAscii( "%PRODUCTVERSION" ) ), + vendName( rtl::OUString::createFromAscii( "%VENDORNAME" ) ), + vendVersion( rtl::OUString::createFromAscii( "%VENDORVERSION" ) ), + vendShort( rtl::OUString::createFromAscii( "%VENDORSHORT" ) ), + m_aImagesZipPaths( imagesZipPaths ), + m_nSymbolsStyle( 0 ) +{ + m_xSMgr = Reference< XMultiComponentFactory >( m_xContext->getServiceManager(), UNO_QUERY ); + + m_vAdd[0] = 12; + m_vAdd[1] = 15; + m_vAdd[2] = 11; + m_vAdd[3] = 14; + m_vAdd[4] = 12; + m_vAdd[5] = 13; + m_vAdd[6] = 16; + + m_vReplacement[0] = productName; + m_vReplacement[1] = productVersion; + m_vReplacement[2] = vendorName; + m_vReplacement[3] = vendorVersion; + m_vReplacement[4] = vendorShort; + m_vReplacement[5] = productName; + m_vReplacement[6] = productVersion; + + setInstallPath( instPath ); + + m_xSFA = Reference< ucb::XSimpleFileAccess >( + m_xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), + m_xContext ), UNO_QUERY_THROW ); + GpPackageSequenceHolder = new ImplPackageSequenceHolder(); +} + +Databases::~Databases() +{ + // release stylesheet + + delete[] m_pCustomCSSDoc; + + // release errorDocument + + delete[] m_pErrorDoc; + + // unload the databases + + { + // DatabasesTable + DatabasesTable::iterator it = m_aDatabases.begin(); + while( it != m_aDatabases.end() ) + { + if( it->second ) + it->second->close( 0 ); + delete it->second; + ++it; + } + } + + { + // ModInfoTable + + ModInfoTable::iterator it = m_aModInfo.begin(); + while( it != m_aModInfo.end() ) + { + delete it->second; + ++it; + } + } + + { + // KeywordInfoTable + + KeywordInfoTable::iterator it = m_aKeywordInfo.begin(); + while( it != m_aKeywordInfo.end() ) + { + delete it->second; + ++it; + } + } + + delete GpPackageSequenceHolder; +} + +static bool impl_getZipFile( + Sequence< rtl::OUString > & rImagesZipPaths, + const rtl::OUString & rZipName, + rtl::OUString & rFileName ) +{ + const rtl::OUString *pPathArray = rImagesZipPaths.getArray(); + for ( int i = 0; i < rImagesZipPaths.getLength(); ++i ) + { + rFileName = pPathArray[ i ]; + if ( rFileName.getLength() ) + { + if ( 1 + rFileName.lastIndexOf( '/' ) != rFileName.getLength() ) + { + rFileName += rtl::OUString::createFromAscii( "/" ); + } + rFileName += rZipName; + + // test existence + osl::DirectoryItem aDirItem; + if ( osl::DirectoryItem::get( rFileName, aDirItem ) == osl::FileBase::E_None ) + return true; + } + } + return false; +} + +rtl::OString Databases::getImagesZipFileURL() +{ + //sal_Int16 nSymbolsStyle = SvtMiscOptions().GetCurrentSymbolsStyle(); + sal_Int16 nSymbolsStyle = 0; + try + { + uno::Reference< lang::XMultiServiceFactory > xConfigProvider( + m_xSMgr ->createInstanceWithContext(::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider"), m_xContext), uno::UNO_QUERY_THROW); + + // set root path + uno::Sequence < uno::Any > lParams(1); + beans::PropertyValue aParam ; + aParam.Name = ::rtl::OUString::createFromAscii("nodepath"); + aParam.Value <<= ::rtl::OUString::createFromAscii("org.openoffice.Office.Common"); + lParams[0] = uno::makeAny(aParam); + + // open it + uno::Reference< uno::XInterface > xCFG( xConfigProvider->createInstanceWithArguments( + ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"), + lParams) ); + + bool bChanged = false; + uno::Reference< container::XHierarchicalNameAccess > xAccess(xCFG, uno::UNO_QUERY_THROW); + uno::Any aResult = xAccess->getByHierarchicalName(::rtl::OUString::createFromAscii("Misc/SymbolSet")); + if ( (aResult >>= nSymbolsStyle) && m_nSymbolsStyle != nSymbolsStyle ) + { + m_nSymbolsStyle = nSymbolsStyle; + bChanged = true; + } + + if ( !m_aImagesZipFileURL.getLength() || bChanged ) + { + rtl::OUString aImageZip, aSymbolsStyleName; + aResult = xAccess->getByHierarchicalName(::rtl::OUString::createFromAscii("Misc/SymbolStyle")); + aResult >>= aSymbolsStyleName; + + bool bFound = false; + if ( aSymbolsStyleName.getLength() != 0 ) + { + rtl::OUString aZipName = rtl::OUString::createFromAscii( "images_" ); + aZipName += aSymbolsStyleName; + aZipName += rtl::OUString::createFromAscii( ".zip" ); + + bFound = impl_getZipFile( m_aImagesZipPaths, aZipName, aImageZip ); + } + + if ( ! bFound ) + bFound = impl_getZipFile( m_aImagesZipPaths, rtl::OUString::createFromAscii( "images.zip" ), aImageZip ); + + if ( ! bFound ) + aImageZip = rtl::OUString(); + + m_aImagesZipFileURL = rtl::OUStringToOString( + rtl::Uri::encode( + aImageZip, + rtl_UriCharClassPchar, + rtl_UriEncodeIgnoreEscapes, + RTL_TEXTENCODING_UTF8 ), RTL_TEXTENCODING_UTF8 ); + } + } + catch ( NoSuchElementException const & ) + { + } + + return m_aImagesZipFileURL; +} + +void Databases::replaceName( rtl::OUString& oustring ) const +{ + sal_Int32 idx = -1,idx1 = -1,idx2 = -1,k = 0,off; + bool cap = false; + rtl::OUStringBuffer aStrBuf( 0 ); + + while( true ) + { + ++idx; + idx1 = oustring.indexOf( sal_Unicode('%'),idx); + idx2 = oustring.indexOf( sal_Unicode('$'),idx); + + if(idx1 == -1 && idx2 == -1) + break; + + if(idx1 == -1) + idx = idx2; + else if(idx2 == -1) + idx = idx1; + else { + // no index is zero + if(idx1 < idx2) + idx = idx1; + else if(idx2 < idx1 ) + idx = idx2; + } + + if( oustring.indexOf( prodName,idx ) == idx ) + off = PRODUCTNAME; + else if( oustring.indexOf( prodVersion,idx ) == idx ) + off = PRODUCTVERSION; + else if( oustring.indexOf( vendName,idx ) == idx ) + off = VENDORNAME; + else if( oustring.indexOf( vendVersion,idx ) == idx ) + off = VENDORVERSION; + else if( oustring.indexOf( vendShort,idx ) == idx ) + off = VENDORSHORT; + else if( oustring.indexOf( newProdName,idx ) == idx ) + off = NEWPRODUCTNAME; + else if( oustring.indexOf( newProdVersion,idx ) == idx ) + off = NEWPRODUCTVERSION; + else + off = -1; + + if( off != -1 ) + { + if( ! cap ) + { + cap = true; + aStrBuf.ensureCapacity( 256 ); + } + + aStrBuf.append( &oustring.getStr()[k],idx - k ); + aStrBuf.append( m_vReplacement[off] ); + k = idx + m_vAdd[off]; + } + } + + if( cap ) + { + if( k < oustring.getLength() ) + aStrBuf.append( &oustring.getStr()[k],oustring.getLength()-k ); + oustring = aStrBuf.makeStringAndClear(); + } +} + + + + +rtl::OUString Databases::getInstallPathAsSystemPath() +{ + osl::MutexGuard aGuard( m_aMutex ); + + if( ! m_aInstallDirectoryAsSystemPath.getLength() ) + { +#ifdef DBG_UTIL + bool bla = + osl::FileBase::E_None == + osl::FileBase::getSystemPathFromFileURL( m_aInstallDirectory,m_aInstallDirectoryAsSystemPath ); + VOS_ENSURE( bla,"HelpProvider, no installpath" ); +#else + osl::FileBase::getSystemPathFromFileURL( m_aInstallDirectory,m_aInstallDirectoryAsSystemPath ); +#endif + } + + return m_aInstallDirectoryAsSystemPath; +} + + + + +rtl::OUString Databases::getInstallPathAsURL() +{ + osl::MutexGuard aGuard( m_aMutex ); + + return m_aInstallDirectory; +} + + +const std::vector< rtl::OUString >& Databases::getModuleList( const rtl::OUString& Language ) +{ + if( m_avModules.size() == 0 ) + { + rtl::OUString fileName,dirName = getInstallPathAsURL() + processLang( Language ); + osl::Directory dirFile( dirName ); + + osl::DirectoryItem aDirItem; + osl::FileStatus aStatus( FileStatusMask_FileName ); + + sal_Int32 idx; + + if( osl::FileBase::E_None != dirFile.open() ) + return m_avModules; + + while( dirFile.getNextItem( aDirItem ) == osl::FileBase::E_None && + aDirItem.getFileStatus( aStatus ) == osl::FileBase::E_None ) + { + if( ! aStatus.isValid( FileStatusMask_FileName ) ) + continue; + + fileName = aStatus.getFileName(); + + // Check, whether fileName is of the form *.cfg + idx = fileName.lastIndexOf( sal_Unicode( '.' ) ); + + if( idx == -1 ) + continue; + + const sal_Unicode* str = fileName.getStr(); + + if( fileName.getLength() == idx + 4 && + ( str[idx + 1] == 'c' || str[idx + 1] == 'C' ) && + ( str[idx + 2] == 'f' || str[idx + 2] == 'F' ) && + ( str[idx + 3] == 'g' || str[idx + 3] == 'G' ) && + ( fileName = fileName.copy(0,idx).toAsciiLowerCase() ).compareToAscii( "picture" ) != 0 ) { + if(! m_bShowBasic && fileName.compareToAscii("sbasic") == 0 ) + continue; + m_avModules.push_back( fileName ); + } + } + } + return m_avModules; +} + + + +StaticModuleInformation* Databases::getStaticInformationForModule( const rtl::OUString& Module, + const rtl::OUString& Language ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + rtl::OUString key = processLang(Language) + rtl::OUString::createFromAscii( "/" ) + Module; + + std::pair< ModInfoTable::iterator,bool > aPair = + m_aModInfo.insert( ModInfoTable::value_type( key,0 ) ); + + ModInfoTable::iterator it = aPair.first; + + if( aPair.second && ! it->second ) + { + osl::File cfgFile( getInstallPathAsURL() + + key + + rtl::OUString::createFromAscii( ".cfg" ) ); + + if( osl::FileBase::E_None != cfgFile.open( OpenFlag_Read ) ) + it->second = 0; + else + { + sal_uInt32 pos = 0; + sal_uInt64 nRead; + sal_Char buffer[2048]; + sal_Unicode lineBuffer[1028]; + rtl::OUString fileContent; + + while( osl::FileBase::E_None == cfgFile.read( &buffer,2048,nRead ) && nRead ) + fileContent += rtl::OUString( buffer,sal_Int32( nRead ),RTL_TEXTENCODING_UTF8 ); + + cfgFile.close(); + + const sal_Unicode* str = fileContent.getStr(); + rtl::OUString current,lang_,program,startid,title,heading,fulltext; + rtl::OUString order = rtl::OUString::createFromAscii( "1" ); + + for( sal_Int32 i = 0;i < fileContent.getLength();i++ ) + { + sal_Unicode ch = str[ i ]; + if( ch == sal_Unicode( '\n' ) || ch == sal_Unicode( '\r' ) ) + { + if( pos ) + { + current = rtl::OUString( lineBuffer,pos ); + + if( current.compareToAscii( "Title",5 ) == 0 ) + { + title = current.copy( current.indexOf(sal_Unicode( '=' ) ) + 1 ); + } + else if( current.compareToAscii( "Start",5 ) == 0 ) + { + startid = current.copy( current.indexOf('=') + 1 ); + } + else if( current.compareToAscii( "Language",8 ) == 0 ) + { + lang_ = current.copy( current.indexOf('=') + 1 ); + } + else if( current.compareToAscii( "Program",7 ) == 0 ) + { + program = current.copy( current.indexOf('=') + 1 ); + } + else if( current.compareToAscii( "Heading",7 ) == 0 ) + { + heading = current.copy( current.indexOf('=') + 1 ); + } + else if( current.compareToAscii( "FullText",8 ) == 0 ) + { + fulltext = current.copy( current.indexOf('=') + 1 ); + } + else if( current.compareToAscii( "Order",5 ) == 0 ) + { + order = current.copy( current.indexOf('=') + 1 ); + } + } + pos = 0; + } + else + lineBuffer[ pos++ ] = ch; + } + replaceName( title ); + it->second = new StaticModuleInformation( title, + startid, + program, + heading, + fulltext, + order ); + } + } + + return it->second; +} + + + + +rtl::OUString Databases::processLang( const rtl::OUString& Language ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + rtl::OUString ret; + LangSetTable::iterator it = m_aLangSet.find( Language ); + + if( it == m_aLangSet.end() ) + { + sal_Int32 idx; + osl::DirectoryItem aDirItem; + + if( osl::FileBase::E_None == osl::DirectoryItem::get( getInstallPathAsURL() + Language,aDirItem ) ) + { + ret = Language; + m_aLangSet[ Language ] = ret; + } + else if( ( ( idx = Language.indexOf( '-' ) ) != -1 || + ( idx = Language.indexOf( '_' ) ) != -1 ) && + osl::FileBase::E_None == osl::DirectoryItem::get( getInstallPathAsURL() + Language.copy( 0,idx ), + aDirItem ) ) + { + ret = Language.copy( 0,idx ); + m_aLangSet[ Language ] = ret; + } + } + else + ret = it->second; + + return ret; +} + + +rtl::OUString Databases::country( const rtl::OUString& Language ) +{ + sal_Int32 idx; + if( ( idx = Language.indexOf( '-' ) ) != -1 || + ( idx = Language.indexOf( '_' ) ) != -1 ) + return Language.copy( 1+idx ); + + return rtl::OUString(); +} + + + +Db* Databases::getBerkeley( const rtl::OUString& Database, + const rtl::OUString& Language, bool helpText, + const rtl::OUString* pExtensionPath ) +{ + if( ! Database.getLength() || ! Language.getLength() ) + return 0; + + osl::MutexGuard aGuard( m_aMutex ); + + + rtl::OUString aFileExt( rtl::OUString::createFromAscii( helpText ? ".ht" : ".db" ) ); + rtl::OUString dbFileName = aSlash + Database + aFileExt; + rtl::OUString key; + if( pExtensionPath == NULL ) + key = processLang( Language ) + dbFileName; + else + key = *pExtensionPath + Language + dbFileName; // make unique, don't change language + + std::pair< DatabasesTable::iterator,bool > aPair = + m_aDatabases.insert( DatabasesTable::value_type( key,0 ) ); + + DatabasesTable::iterator it = aPair.first; + + if( aPair.second && ! it->second ) + { + Db* table = new Db(); + + rtl::OUString fileNameOU; + if( pExtensionPath ) + { + rtl::OUString aExpandedURL = expandURL( *pExtensionPath ); + aExpandedURL += Language + dbFileName; + osl::FileBase::getSystemPathFromFileURL( aExpandedURL, fileNameOU ); + } + else + fileNameOU = getInstallPathAsSystemPath() + key; + + + rtl::OString fileName( fileNameOU.getStr(),fileNameOU.getLength(),osl_getThreadTextEncoding() ); + + rtl::OUString fileNameDBHelp( fileNameOU ); + if( pExtensionPath != NULL ) + fileNameDBHelp += rtl::OUString::createFromAscii( "_" ); + if( m_xSFA->exists( fileNameDBHelp ) ) + { + DBHelp* pDBHelp = new DBHelp( fileNameDBHelp, m_xSFA ); + table->setDBHelp( pDBHelp ); + +#ifdef TEST_DBHELP + bool bSuccess; + bool bOldDbAccess = false; + bSuccess = pDBHelp->testAgainstDb( fileName, bOldDbAccess ); + + bOldDbAccess = true; + bSuccess = pDBHelp->testAgainstDb( fileName, bOldDbAccess ); +#endif + } + else if( table->open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) ) + { + table->close( 0 ); + delete table; + table = 0; + } + + it->second = table; + } + + return it->second; +} + +Reference< XCollator > +Databases::getCollator( const rtl::OUString& Language, + const rtl::OUString& System ) +{ + (void)System; + + rtl::OUString key = Language; + + osl::MutexGuard aGuard( m_aMutex ); + + CollatorTable::iterator it = + m_aCollatorTable.insert( CollatorTable::value_type( key,0 ) ).first; + + if( ! it->second.is() ) + { + it->second = + Reference< XCollator > ( + m_xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.i18n.Collator" ), + m_xContext ), UNO_QUERY ); + rtl::OUString langStr = processLang(Language); + rtl::OUString countryStr = country(Language); + if( !countryStr.getLength() ) + { + if( langStr.compareToAscii("de") == 0 ) + countryStr = rtl::OUString::createFromAscii("DE"); + else if( langStr.compareToAscii("en") == 0 ) + countryStr = rtl::OUString::createFromAscii("US"); + else if( langStr.compareToAscii("es") == 0 ) + countryStr = rtl::OUString::createFromAscii("ES"); + else if( langStr.compareToAscii("it") == 0 ) + countryStr = rtl::OUString::createFromAscii("IT"); + else if( langStr.compareToAscii("fr") == 0 ) + countryStr = rtl::OUString::createFromAscii("FR"); + else if( langStr.compareToAscii("sv") == 0 ) + countryStr = rtl::OUString::createFromAscii("SE"); + else if( langStr.compareToAscii("ja") == 0 ) + countryStr = rtl::OUString::createFromAscii("JP"); + else if( langStr.compareToAscii("ko") == 0 ) + countryStr = rtl::OUString::createFromAscii("KR"); + } + it->second->loadDefaultCollator( Locale( langStr, + countryStr, + rtl::OUString() ), + 0 ); + } + + return it->second; +} + + + +namespace chelp { + + struct KeywordElementComparator + { + KeywordElementComparator( const Reference< XCollator >& xCollator ) + : m_xCollator( xCollator ) + { } + + bool operator()( const KeywordInfo::KeywordElement& la, + const KeywordInfo::KeywordElement& ra ) const + { + const rtl::OUString& l = la.key; + const rtl::OUString& r = ra.key; + + bool ret; + + if( m_xCollator.is() ) + { + sal_Int32 l1 = l.indexOf( sal_Unicode( ';' ) ); + sal_Int32 l3 = ( l1 == -1 ? l.getLength() : l1 ); + + sal_Int32 r1 = r.indexOf( sal_Unicode( ';' ) ); + sal_Int32 r3 = ( r1 == -1 ? r.getLength() : r1 ); + + sal_Int32 c1 = m_xCollator->compareSubstring( l,0,l3,r,0,r3 ); + + if( c1 == +1 ) + ret = false; + else if( c1 == 0 ) + { + sal_Int32 l2 = l.getLength() - l1 - 1; + sal_Int32 r2 = r.getLength() - r1 - 1; + ret = ( m_xCollator->compareSubstring( l,1+l1,l2,r,1+r1,r2 ) < 0 ); + } + else + ret = true; + } + else + ret = bool( l < r ); + + return ret; + } + + Reference< XCollator > m_xCollator; + }; // end struct KeywordElementComparator + +} + + + +KeywordInfo::KeywordElement::KeywordElement( Databases *pDatabases, + Db* pDb, + rtl::OUString& ky, + rtl::OUString& data ) + : key( ky ) +{ + pDatabases->replaceName( key ); + init( pDatabases,pDb,data ); +} + + + +void KeywordInfo::KeywordElement::init( Databases *pDatabases,Db* pDb,const rtl::OUString& ids ) +{ + const sal_Unicode* idstr = ids.getStr(); + std::vector< rtl::OUString > id,anchor; + int idx = -1,k; + while( ( idx = ids.indexOf( ';',k = ++idx ) ) != -1 ) + { + int h = ids.indexOf( sal_Unicode( '#' ),k ); + if( h < idx ) + { + // found an anchor + id.push_back( rtl::OUString( &idstr[k],h-k ) ); + anchor.push_back( rtl::OUString( &idstr[h+1],idx-h-1 ) ); + } + else + { + id.push_back( rtl::OUString( &idstr[k],idx-k ) ); + anchor.push_back( rtl::OUString() ); + } + } + + listId.realloc( id.size() ); + listAnchor.realloc( id.size() ); + listTitle.realloc( id.size() ); + + int nSize = 0; + const sal_Char* pData = NULL; + const sal_Char pEmpty[] = ""; + + for( sal_uInt32 i = 0; i < id.size(); ++i ) + { + listId[i] = id[i]; + listAnchor[i] = anchor[i]; + + nSize = 0; + pData = pEmpty; + if( pDb ) + { + rtl::OString idi( id[i].getStr(),id[i].getLength(),RTL_TEXTENCODING_UTF8 ); + DBHelp* pDBHelp = pDb->getDBHelp(); + if( pDBHelp != NULL ) + { + DBData aDBData; + bool bSuccess = pDBHelp->getValueForKey( idi, aDBData ); + if( bSuccess ) + { + nSize = aDBData.getSize(); + pData = aDBData.getData(); + } + } + else + { + Dbt key_( static_cast< void* >( const_cast< sal_Char* >( idi.getStr() ) ), + idi.getLength() ); + Dbt data; + pDb->get( 0,&key_,&data,0 ); + nSize = data.get_size(); + pData = static_cast<sal_Char*>( data.get_data() ); + } + } + + DbtToStringConverter converter( pData, nSize ); + + rtl::OUString title = converter.getTitle(); + pDatabases->replaceName( title ); + listTitle[i] = title; + } +} + + + +KeywordInfo::KeywordInfo( const std::vector< KeywordElement >& aVec ) + : listKey( aVec.size() ), + listId( aVec.size() ), + listAnchor( aVec.size() ), + listTitle( aVec.size() ) +{ + for( unsigned int i = 0; i < aVec.size(); ++i ) + { + listKey[i] = aVec[i].key; + listId[i] = aVec[i].listId; + listAnchor[i] = aVec[i].listAnchor; + listTitle[i] = aVec[i].listTitle; + } +} + +bool Databases::checkModuleMatchForExtension + ( const rtl::OUString& Database, const rtl::OUString& doclist ) +{ + bool bBelongsToDatabase = true; + + // Analyse doclist string to find module assignments + bool bFoundAtLeastOneModule = false; + bool bModuleMatch = false; + sal_Int32 nLen = doclist.getLength(); + sal_Int32 nLastFound = doclist.lastIndexOf( sal_Unicode(';') ); + if( nLastFound == -1 ) + nLastFound = nLen; + const sal_Unicode* pStr = doclist.getStr(); + sal_Int32 nFound = doclist.lastIndexOf( sal_Unicode('_') ); + while( nFound != -1 ) + { + // Simple optimization, stop if '_' is followed by "id" + if( nLen - nFound > 2 ) + { + if( pStr[ nFound + 1 ] == sal_Unicode('i') && + pStr[ nFound + 2 ] == sal_Unicode('d') ) + break; + } + + rtl::OUString aModule = doclist.copy( nFound + 1, nLastFound - nFound - 1 ); + std::vector< rtl::OUString >::iterator result = std::find( m_avModules.begin(), m_avModules.end(), aModule ); + if( result != m_avModules.end() ) + { + bFoundAtLeastOneModule = true; + if( Database == aModule ) + { + bModuleMatch = true; + break; + } + } + + nLastFound = nFound; + if( nLastFound == 0 ) + break; + nFound = doclist.lastIndexOf( sal_Unicode('_'), nLastFound - 1 ); + } + + if( bFoundAtLeastOneModule && !bModuleMatch ) + bBelongsToDatabase = false; + + return bBelongsToDatabase; +} + + +KeywordInfo* Databases::getKeyword( const rtl::OUString& Database, + const rtl::OUString& Language ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + rtl::OUString key = processLang(Language) + rtl::OUString::createFromAscii( "/" ) + Database; + + std::pair< KeywordInfoTable::iterator,bool > aPair = + m_aKeywordInfo.insert( KeywordInfoTable::value_type( key,0 ) ); + + KeywordInfoTable::iterator it = aPair.first; + + if( aPair.second && ! it->second ) + { + std::vector<KeywordInfo::KeywordElement> aVector; + + KeyDataBaseFileIterator aDbFileIt( m_xContext, *this, Database, Language ); + rtl::OUString fileNameOU; + bool bExtension = false; + while( (fileNameOU = aDbFileIt.nextDbFile( bExtension )).getLength() > 0 ) + { + rtl::OString fileName( fileNameOU.getStr(), + fileNameOU.getLength(), + osl_getThreadTextEncoding() ); + + Db table; + + rtl::OUString fileNameDBHelp( fileNameOU ); + if( bExtension ) + fileNameDBHelp += rtl::OUString::createFromAscii( "_" ); + if( m_xSFA->exists( fileNameDBHelp ) ) + { + DBHelp aDBHelp( fileNameDBHelp, m_xSFA ); + + DBData aKey; + DBData aValue; + if( aDBHelp.startIteration() ) + { + Db* idmap = getBerkeley( Database,Language ); + + DBHelp* pDBHelp = idmap->getDBHelp(); + if( pDBHelp != NULL ) + { + bool bOptimizeForPerformance = true; + pDBHelp->releaseHashMap(); + pDBHelp->createHashMap( bOptimizeForPerformance ); + } + + while( aDBHelp.getNextKeyAndValue( aKey, aValue ) ) + { + rtl::OUString keyword( aKey.getData(), aKey.getSize(), + RTL_TEXTENCODING_UTF8 ); + rtl::OUString doclist( aValue.getData(), aValue.getSize(), + RTL_TEXTENCODING_UTF8 ); + + bool bBelongsToDatabase = true; + if( bExtension ) + bBelongsToDatabase = checkModuleMatchForExtension( Database, doclist ); + + if( !bBelongsToDatabase ) + continue; + + aVector.push_back( KeywordInfo::KeywordElement( this, + idmap, + keyword, + doclist ) ); + } + aDBHelp.stopIteration(); + + if( pDBHelp != NULL ) + pDBHelp->releaseHashMap(); + } + +#ifdef TEST_DBHELP + bool bSuccess; + bool bOldDbAccess = false; + bSuccess = aDBHelp.testAgainstDb( fileName, bOldDbAccess ); + + bOldDbAccess = true; + bSuccess = aDBHelp.testAgainstDb( fileName, bOldDbAccess ); + + int nDummy = 0; +#endif + } + + else if( 0 == table.open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) ) + { + Db* idmap = getBerkeley( Database,Language ); + + bool first = true; + + Dbc* cursor = 0; + table.cursor( 0,&cursor,0 ); + Dbt key_,data; + key_.set_flags( DB_DBT_MALLOC ); // Initially the cursor must allocate the necessary memory + data.set_flags( DB_DBT_MALLOC ); + while( cursor && DB_NOTFOUND != cursor->get( &key_,&data,DB_NEXT ) ) + { + rtl::OUString keyword( static_cast<sal_Char*>(key_.get_data()), + key_.get_size(), + RTL_TEXTENCODING_UTF8 ); + rtl::OUString doclist( static_cast<sal_Char*>(data.get_data()), + data.get_size(), + RTL_TEXTENCODING_UTF8 ); + + bool bBelongsToDatabase = true; + if( bExtension ) + bBelongsToDatabase = checkModuleMatchForExtension( Database, doclist ); + + if( !bBelongsToDatabase ) + continue; + + aVector.push_back( KeywordInfo::KeywordElement( this, + idmap, + keyword, + doclist ) ); + if( first ) + { + key_.set_flags( DB_DBT_REALLOC ); + data.set_flags( DB_DBT_REALLOC ); + first = false; + } + } + + if( cursor ) cursor->close(); + } + table.close( 0 ); + } + + // sorting + Reference< XCollator > xCollator = getCollator( Language,rtl::OUString()); + KeywordElementComparator aComparator( xCollator ); + std::sort(aVector.begin(),aVector.end(),aComparator); + + KeywordInfo* pInfo = it->second = new KeywordInfo( aVector ); + (void)pInfo; + } + + return it->second; +} + +Reference< XHierarchicalNameAccess > Databases::jarFile( const rtl::OUString& jar, + const rtl::OUString& Language ) +{ + if( ! jar.getLength() || + ! Language.getLength() ) + { + return Reference< XHierarchicalNameAccess >( 0 ); + } + rtl::OUString key = processLang(Language) + aSlash + jar; + + osl::MutexGuard aGuard( m_aMutex ); + + ZipFileTable::iterator it = + m_aZipFileTable.insert( ZipFileTable::value_type( key,Reference< XHierarchicalNameAccess >(0) ) ).first; + + if( ! it->second.is() ) + { + rtl::OUString zipFile; + try + { + // Extension jar file? Search for ? + sal_Int32 nQuestionMark1 = jar.indexOf( sal_Unicode('?') ); + sal_Int32 nQuestionMark2 = jar.lastIndexOf( sal_Unicode('?') ); + if( nQuestionMark1 != -1 && nQuestionMark2 != -1 && nQuestionMark1 != nQuestionMark2 ) + { + ::rtl::OUString aExtensionPath = jar.copy( nQuestionMark1 + 1, nQuestionMark2 - nQuestionMark1 - 1 ); + ::rtl::OUString aPureJar = jar.copy( nQuestionMark2 + 1 ); + + rtl::OUStringBuffer aStrBuf; + aStrBuf.append( aExtensionPath ); + aStrBuf.append( aSlash ); + aStrBuf.append( aPureJar ); + + zipFile = expandURL( aStrBuf.makeStringAndClear() ); + } + else + { + zipFile = getInstallPathAsURL() + key; + } + + Sequence< Any > aArguments( 2 ); + + XInputStream_impl* p = new XInputStream_impl( zipFile ); + if( p->CtorSuccess() ) + { + Reference< XInputStream > xInputStream( p ); + aArguments[ 0 ] <<= xInputStream; + } + else + { + delete p; + aArguments[ 0 ] <<= zipFile; + } + + // let ZipPackage be used ( no manifest.xml is required ) + beans::NamedValue aArg; + aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) ); + aArg.Value <<= ZIP_STORAGE_FORMAT_STRING; + aArguments[ 1 ] <<= aArg; + + Reference< XInterface > xIfc + = m_xSMgr->createInstanceWithArgumentsAndContext( + rtl::OUString::createFromAscii( + "com.sun.star.packages.comp.ZipPackage" ), + aArguments, m_xContext ); + + if ( xIfc.is() ) + { + it->second = Reference< XHierarchicalNameAccess >( xIfc, UNO_QUERY ); + + VOS_ENSURE( it->second.is(), + "ContentProvider::createPackage - " + "Got no hierarchical name access!" ); + + } + } + catch ( RuntimeException & ) + { + } + catch ( Exception & ) + { + } + } + + return it->second; +} + +Reference< XHierarchicalNameAccess > Databases::findJarFileForPath + ( const rtl::OUString& jar, const rtl::OUString& Language, + const rtl::OUString& path, rtl::OUString* o_pExtensionPath ) +{ + Reference< XHierarchicalNameAccess > xNA; + if( ! jar.getLength() || + ! Language.getLength() ) + { + return xNA; + } + + JarFileIterator aJarFileIt( m_xContext, *this, jar, Language ); + Reference< XHierarchicalNameAccess > xTestNA; + Reference< deployment::XPackage > xParentPackageBundle; + while( (xTestNA = aJarFileIt.nextJarFile( xParentPackageBundle, o_pExtensionPath )).is() ) + { + if( xTestNA.is() && xTestNA->hasByHierarchicalName( path ) ) + { + bool bSuccess = true; + if( xParentPackageBundle.is() ) + { + rtl::OUString aIdentifierInPath; + sal_Int32 nFindSlash = path.indexOf( '/' ); + if( nFindSlash != -1 ) + aIdentifierInPath = path.copy( 0, nFindSlash ); + + beans::Optional<rtl::OUString> aIdentifierOptional = xParentPackageBundle->getIdentifier(); + if( aIdentifierInPath.getLength() && aIdentifierOptional.IsPresent ) + { + rtl::OUString aUnencodedIdentifier = aIdentifierOptional.Value; + rtl::OUString aIdentifier = rtl::Uri::encode( aUnencodedIdentifier, + rtl_UriCharClassPchar, rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8 ); + + if( !aIdentifierInPath.equals( aIdentifier ) ) + { + // path does not start with extension identifier -> ignore + bSuccess = false; + } + } + else + { + // No identifier -> ignore + bSuccess = false; + } + } + + if( bSuccess ) + { + xNA = xTestNA; + break; + } + } + } + + return xNA; +} + +void Databases::popupDocument( URLParameter* urlPar,char **buffer,int *byteCount ) +{ + const char* pop1 = + " <html> " + " <head> " + " <help:css-file-link xmlns:help=\"http://openoffice.org/2000/help\"/> " + " </head> " + " <body> " + " <help:popup-cut Id=\""; + const sal_Int32 l1 = strlen( pop1 ); + + const char* pop3 = "\" Eid=\""; + const sal_Int32 l3 = strlen( pop3 ); + + const char* pop5 = + "\" xmlns:help=\"http://openoffice.org/2000/help\"></help:popup-cut> " + " </body> " + " </html>"; + const sal_Int32 l5 = strlen( pop5 ); + sal_Int32 l2,l4; + + rtl::OUString val = urlPar->get_id(); + rtl::OString pop2O( val.getStr(),l2 = val.getLength(),RTL_TEXTENCODING_UTF8 ); + const char* pop2 = pop2O.getStr(); + + val = urlPar->get_eid(); + rtl::OString pop4O( val.getStr(),l4 = val.getLength(),RTL_TEXTENCODING_UTF8 ); + const char* pop4 = pop4O.getStr(); + + (*byteCount) = l1 + l2 + l3 + l4 + l5; + + *buffer = new char[ 1+*byteCount ]; + + rtl_copyMemory( *buffer,pop1,l1 ); + rtl_copyMemory( *buffer+l1,pop2,l2 ); + rtl_copyMemory( *buffer+(l1+l2),pop3,l3 ); + rtl_copyMemory( *buffer+(l1+l2+l3),pop4,l4 ); + rtl_copyMemory( *buffer+(l1+l2+l3+l4),pop5,l5 ); + (*buffer)[*byteCount] = 0; +} + + +void Databases::changeCSS(const rtl::OUString& newStyleSheet) +{ + m_aCSS = newStyleSheet.toAsciiLowerCase(); + delete[] m_pCustomCSSDoc, m_pCustomCSSDoc = 0,m_nCustomCSSDocLength = 0; +} + + + +void Databases::cascadingStylesheet( const rtl::OUString& Language, + char** buffer, + int* byteCount ) +{ + if( ! m_pCustomCSSDoc ) + { + int retry = 2; + bool error = true; + rtl::OUString fileURL; + + while( error && retry ) + { + if( retry == 2 ) + fileURL = + getInstallPathAsURL() + + processLang( Language ) + + rtl::OUString::createFromAscii( "/" ) + + m_aCSS + + rtl::OUString::createFromAscii( ".css" ); + else if( retry == 1 ) + fileURL = + getInstallPathAsURL() + + m_aCSS + + rtl::OUString::createFromAscii( ".css" ); + + osl::DirectoryItem aDirItem; + osl::File aFile( fileURL ); + osl::FileStatus aStatus( FileStatusMask_FileSize ); + + if( osl::FileBase::E_None == osl::DirectoryItem::get( fileURL,aDirItem ) && + osl::FileBase::E_None == aFile.open( OpenFlag_Read ) && + osl::FileBase::E_None == aDirItem.getFileStatus( aStatus ) ) + { + m_nCustomCSSDocLength = int( aStatus.getFileSize() ); + m_pCustomCSSDoc = new char[ 1 + m_nCustomCSSDocLength ]; + m_pCustomCSSDoc[ m_nCustomCSSDocLength ] = 0; + sal_uInt64 a = m_nCustomCSSDocLength,b = m_nCustomCSSDocLength; + aFile.read( m_pCustomCSSDoc,a,b ); + aFile.close(); + error = false; + } + + --retry; + } + + if( error ) + { + m_nCustomCSSDocLength = 0; + m_pCustomCSSDoc = new char[ 1 ]; // Initialize with 1 to avoid gcc compiler warning + } + } + + *byteCount = m_nCustomCSSDocLength; + *buffer = new char[ 1 + *byteCount ]; + (*buffer)[*byteCount] = 0; + rtl_copyMemory( *buffer,m_pCustomCSSDoc,m_nCustomCSSDocLength ); + +} + + +void Databases::setActiveText( const rtl::OUString& Module, + const rtl::OUString& Language, + const rtl::OUString& Id, + char** buffer, + int* byteCount ) +{ + DataBaseIterator aDbIt( m_xContext, *this, Module, Language, true ); + + // #i84550 Cache information about failed ids + rtl::OString id( Id.getStr(),Id.getLength(),RTL_TEXTENCODING_UTF8 ); + EmptyActiveTextSet::iterator it = m_aEmptyActiveTextSet.find( id ); + bool bFoundAsEmpty = ( it != m_aEmptyActiveTextSet.end() ); + Dbt data; + DBData aDBData; + + int nSize = 0; + const sal_Char* pData = NULL; + + bool bSuccess = false; + if( !bFoundAsEmpty ) + { + Db* db; + Dbt key( static_cast< void* >( const_cast< sal_Char* >( id.getStr() ) ),id.getLength() ); + while( !bSuccess && (db = aDbIt.nextDb()) != NULL ) + { + DBHelp* pDBHelp = db->getDBHelp(); + if( pDBHelp != NULL ) + { + bSuccess = pDBHelp->getValueForKey( id, aDBData ); + nSize = aDBData.getSize(); + pData = aDBData.getData(); + } + else + { + int err = db->get( 0, &key, &data, 0 ); + if( err == 0 ) + { + bSuccess = true; + nSize = data.get_size(); + pData = static_cast<sal_Char*>( data.get_data() ); + } + } + } + } + + if( bSuccess ) + { + // ensure existence of tmp after for + rtl::OString tmp; + for( int i = 0; i < nSize; ++i ) + if( pData[i] == '%' || pData[i] == '$' ) + { + // need of replacement + rtl::OUString temp = rtl::OUString( pData, nSize, RTL_TEXTENCODING_UTF8 ); + replaceName( temp ); + tmp = rtl::OString( temp.getStr(), + temp.getLength(), + RTL_TEXTENCODING_UTF8 ); + nSize = tmp.getLength(); + pData = tmp.getStr(); + break; + } + + *byteCount = nSize; + *buffer = new char[ 1 + nSize ]; + (*buffer)[nSize] = 0; + rtl_copyMemory( *buffer, pData, nSize ); + } + else + { + *byteCount = 0; + *buffer = new char[1]; // Initialize with 1 to avoid compiler warnings + if( !bFoundAsEmpty ) + m_aEmptyActiveTextSet.insert( id ); + } +} + + +void Databases::setInstallPath( const rtl::OUString& aInstDir ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + osl::FileBase::getFileURLFromSystemPath( aInstDir,m_aInstallDirectory ); + //TODO: check returned error code + + if( m_aInstallDirectory.lastIndexOf( sal_Unicode( '/' ) ) != m_aInstallDirectory.getLength() - 1 ) + m_aInstallDirectory += rtl::OUString::createFromAscii( "/" ); + + m_aInstallDirectoryWithoutEncoding = rtl::Uri::decode( m_aInstallDirectory, + rtl_UriDecodeWithCharset, + RTL_TEXTENCODING_UTF8 ); +} + + +//=================================================================== +// class ExtensionIteratorBase + +ExtensionHelpExistanceMap ExtensionIteratorBase::aHelpExistanceMap; + +ExtensionIteratorBase::ExtensionIteratorBase( Reference< XComponentContext > xContext, + Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage ) + : m_xContext( xContext ) + , m_rDatabases( rDatabases ) + , m_eState( INITIAL_MODULE ) + , m_aInitialModule( aInitialModule ) + , m_aLanguage( aLanguage ) +{ + init(); +} + +ExtensionIteratorBase::ExtensionIteratorBase( Databases& rDatabases, + const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage ) + : m_rDatabases( rDatabases ) + , m_eState( INITIAL_MODULE ) + , m_aInitialModule( aInitialModule ) + , m_aLanguage( aLanguage ) +{ + init(); +} + +void ExtensionIteratorBase::init() +{ + if( !m_xContext.is() ) + { + Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory(); + Reference< XPropertySet > xProps( xFactory, UNO_QUERY ); + OSL_ASSERT( xProps.is() ); + if (xProps.is()) + { + xProps->getPropertyValue( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= m_xContext; + OSL_ASSERT( m_xContext.is() ); + } + } + if( !m_xContext.is() ) + { + throw RuntimeException( + ::rtl::OUString::createFromAscii( "ExtensionIteratorBase::init(), no XComponentContext" ), + Reference< XInterface >() ); + } + + Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); + m_xSFA = Reference< ucb::XSimpleFileAccess >( + xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), + m_xContext ), UNO_QUERY_THROW ); + + m_bUserPackagesLoaded = false; + m_bSharedPackagesLoaded = false; + m_iUserPackage = 0; + m_iSharedPackage = 0; +} + +Reference< deployment::XPackage > ExtensionIteratorBase::implGetHelpPackageFromPackage + ( Reference< deployment::XPackage > xPackage, Reference< deployment::XPackage >& o_xParentPackageBundle ) +{ + o_xParentPackageBundle.clear(); + + Reference< deployment::XPackage > xHelpPackage; + if( !xPackage.is() ) + return xHelpPackage; + + // #i84550 Cache information about help content in extension + rtl::OUString aExtensionPath = xPackage->getURL(); + ExtensionHelpExistanceMap::iterator it = aHelpExistanceMap.find( aExtensionPath ); + bool bFound = ( it != aHelpExistanceMap.end() ); + bool bHasHelp = bFound ? it->second : false; + if( bFound && !bHasHelp ) + return xHelpPackage; + + // Check if parent package is registered + beans::Optional< beans::Ambiguous<sal_Bool> > option( xPackage->isRegistered + ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) ); + bool bRegistered = false; + if( option.IsPresent ) + { + beans::Ambiguous<sal_Bool> const & reg = option.Value; + if( !reg.IsAmbiguous && reg.Value ) + bRegistered = true; + } + if( bRegistered ) + { + if( xPackage->isBundle() ) + { + Sequence< Reference< deployment::XPackage > > aPkgSeq = xPackage->getBundle + ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ); + sal_Int32 nPkgCount = aPkgSeq.getLength(); + const Reference< deployment::XPackage >* pSeq = aPkgSeq.getConstArray(); + for( sal_Int32 iPkg = 0 ; iPkg < nPkgCount ; ++iPkg ) + { + const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ]; + const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xSubPkg->getPackageType(); + rtl::OUString aMediaType = xPackageTypeInfo->getMediaType(); + if( aMediaType.equals( aHelpMediaType ) ) + { + xHelpPackage = xSubPkg; + o_xParentPackageBundle = xPackage; + break; + } + } + } + else + { + const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType(); + rtl::OUString aMediaType = xPackageTypeInfo->getMediaType(); + if( aMediaType.equals( aHelpMediaType ) ) + xHelpPackage = xPackage; + } + } + + if( !bFound ) + aHelpExistanceMap[ aExtensionPath ] = xHelpPackage.is(); + + return xHelpPackage; +} + +Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextUserHelpPackage + ( Reference< deployment::XPackage >& o_xParentPackageBundle ) +{ + Reference< deployment::XPackage > xHelpPackage; + + if( !m_bUserPackagesLoaded ) + { + Reference< XPackageManager > xUserManager = + thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("user") ); + m_aUserPackagesSeq = xUserManager->getDeployedPackages + ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); + if( GpPackageSequenceHolder != NULL ) + GpPackageSequenceHolder->m_aUserPackagesSeq = m_aUserPackagesSeq; + + m_bUserPackagesLoaded = true; + } + + if( m_iUserPackage == m_aUserPackagesSeq.getLength() ) + { + m_eState = SHARED_EXTENSIONS; // Later: SHARED_MODULE + } + else + { + const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray(); + Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage++ ]; + VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextUserHelpPackage(): Invalid package" ); + xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle ); + } + + return xHelpPackage; +} + +Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextSharedHelpPackage + ( Reference< deployment::XPackage >& o_xParentPackageBundle ) +{ + Reference< deployment::XPackage > xHelpPackage; + + if( !m_bSharedPackagesLoaded ) + { + Reference< XPackageManager > xSharedManager = + thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("shared") ); + m_aSharedPackagesSeq = xSharedManager->getDeployedPackages + ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); + if( GpPackageSequenceHolder != NULL ) + GpPackageSequenceHolder->m_aSharedPackagesSeq = m_aSharedPackagesSeq; + + m_bSharedPackagesLoaded = true; + } + + if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() ) + { + m_eState = END_REACHED; + } + else + { + const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray(); + Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage++ ]; + VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextSharedHelpPackage(): Invalid package" ); + xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle ); + } + + return xHelpPackage; +} + +rtl::OUString ExtensionIteratorBase::implGetFileFromPackage( + const rtl::OUString& rFileExtension, Reference< deployment::XPackage > xPackage ) +{ + // No extension -> search for pure language folder + bool bLangFolderOnly = (rFileExtension.getLength() == 0); + + rtl::OUString aFile; + rtl::OUString aLanguage = m_aLanguage; + for( sal_Int32 iPass = 0 ; iPass < 2 ; ++iPass ) + { + rtl::OUStringBuffer aStrBuf; + aStrBuf.append( xPackage->getURL() ); + aStrBuf.append( aSlash ); + aStrBuf.append( aLanguage ); + if( !bLangFolderOnly ) + { + aStrBuf.append( aSlash ); + aStrBuf.append( aHelpFilesBaseName ); + aStrBuf.append( rFileExtension ); + } + + aFile = m_rDatabases.expandURL( aStrBuf.makeStringAndClear() ); + if( iPass == 0 ) + { + if( m_xSFA->exists( aFile ) ) + break; + + ::std::vector< ::rtl::OUString > av; + implGetLanguageVectorFromPackage( av, xPackage ); + ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end(); + try + { + pFound = ::comphelper::Locale::getFallback( av, m_aLanguage ); + } + catch( ::comphelper::Locale::MalFormedLocaleException& ) + {} + if( pFound != av.end() ) + aLanguage = *pFound; + } + } + return aFile; +} + +inline bool isLetter( sal_Unicode c ) +{ + bool bLetter = ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); + return bLetter; +} + +void ExtensionIteratorBase::implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv, + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage ) +{ + rv.clear(); + rtl::OUString aExtensionPath = xPackage->getURL(); + Sequence< rtl::OUString > aEntrySeq = m_xSFA->getFolderContents( aExtensionPath, true ); + + const rtl::OUString* pSeq = aEntrySeq.getConstArray(); + sal_Int32 nCount = aEntrySeq.getLength(); + for( sal_Int32 i = 0 ; i < nCount ; ++i ) + { + rtl::OUString aEntry = pSeq[i]; + if( m_xSFA->isFolder( aEntry ) ) + { + sal_Int32 nLastSlash = aEntry.lastIndexOf( '/' ); + if( nLastSlash != -1 ) + { + rtl::OUString aPureEntry = aEntry.copy( nLastSlash + 1 ); + + // Check language sceme + int nLen = aPureEntry.getLength(); + const sal_Unicode* pc = aPureEntry.getStr(); + bool bStartCanBeLanguage = ( nLen >= 2 && isLetter( pc[0] ) && isLetter( pc[1] ) ); + bool bIsLanguage = bStartCanBeLanguage && + ( nLen == 2 || (nLen == 5 && pc[2] == '-' && isLetter( pc[3] ) && isLetter( pc[4] )) ); + if( bIsLanguage ) + rv.push_back( aPureEntry ); + } + } + } +} + + +//=================================================================== +// class DataBaseIterator + +Db* DataBaseIterator::nextDb( rtl::OUString* o_pExtensionPath ) +{ + Db* pRetDb = NULL; + + while( !pRetDb && m_eState != END_REACHED ) + { + switch( m_eState ) + { + case INITIAL_MODULE: + pRetDb = m_rDatabases.getBerkeley( m_aInitialModule, m_aLanguage, m_bHelpText ); + m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE + break; + + // Later: + //case SHARED_MODULE + //... + + case USER_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + pRetDb = implGetDbFromPackage( xHelpPackage, o_pExtensionPath ); + break; + } + + case SHARED_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + pRetDb = implGetDbFromPackage( xHelpPackage, o_pExtensionPath ); + break; + } + case END_REACHED: + VOS_ENSURE( false, "DataBaseIterator::nextDb(): Invalid case END_REACHED" ); + break; + } + } + + return pRetDb; +} + +Db* DataBaseIterator::implGetDbFromPackage( Reference< deployment::XPackage > xPackage, + rtl::OUString* o_pExtensionPath ) +{ + rtl::OUString aExtensionPath = xPackage->getURL(); + //if( o_pExtensionPath ) + //*o_pExtensionPath = aExtensionPath; + aExtensionPath += aSlash; + + rtl::OUString aUsedLanguage = m_aLanguage; + Db* pRetDb = m_rDatabases.getBerkeley( aHelpFilesBaseName, aUsedLanguage, + m_bHelpText, &aExtensionPath ); + + // Language fallback + if( !pRetDb ) + { + ::std::vector< ::rtl::OUString > av; + implGetLanguageVectorFromPackage( av, xPackage ); + ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end(); + try + { + pFound = ::comphelper::Locale::getFallback( av, m_aLanguage ); + } + catch( ::comphelper::Locale::MalFormedLocaleException& ) + {} + if( pFound != av.end() ) + { + aUsedLanguage = *pFound; + pRetDb = m_rDatabases.getBerkeley( aHelpFilesBaseName, aUsedLanguage, m_bHelpText, &aExtensionPath ); + } + } + + if( o_pExtensionPath ) + *o_pExtensionPath = aExtensionPath + aUsedLanguage; + + return pRetDb; +} + + +//=================================================================== +// class KeyDataBaseFileIterator + +rtl::OUString KeyDataBaseFileIterator::nextDbFile( bool& o_rbExtension ) +{ + rtl::OUString aRetFile; + + while( !aRetFile.getLength() && m_eState != END_REACHED ) + { + switch( m_eState ) + { + case INITIAL_MODULE: + aRetFile = + m_rDatabases.getInstallPathAsSystemPath() + + m_rDatabases.processLang( m_aLanguage ) + aSlash + m_aInitialModule + + rtl::OUString::createFromAscii( ".key" ); + + o_rbExtension = false; + + m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE + break; + + // Later: + //case SHARED_MODULE + //... + + case USER_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + aRetFile = implGetDbFileFromPackage( xHelpPackage ); + o_rbExtension = true; + break; + } + + case SHARED_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + aRetFile = implGetDbFileFromPackage( xHelpPackage ); + o_rbExtension = true; + break; + } + case END_REACHED: + VOS_ENSURE( false, "DataBaseIterator::nextDbFile(): Invalid case END_REACHED" ); + break; + } + } + + return aRetFile; +} + +rtl::OUString KeyDataBaseFileIterator::implGetDbFileFromPackage + ( Reference< deployment::XPackage > xPackage ) +{ + rtl::OUString aExpandedURL = + implGetFileFromPackage( rtl::OUString::createFromAscii( ".key" ), xPackage ); + + rtl::OUString aRetFile; + osl::FileBase::getSystemPathFromFileURL( aExpandedURL, aRetFile ); + + return aRetFile; +} + + +//=================================================================== +// class JarFileIterator + +Reference< XHierarchicalNameAccess > JarFileIterator::nextJarFile + ( Reference< deployment::XPackage >& o_xParentPackageBundle, rtl::OUString* o_pExtensionPath ) +{ + Reference< XHierarchicalNameAccess > xNA; + + while( !xNA.is() && m_eState != END_REACHED ) + { + switch( m_eState ) + { + case INITIAL_MODULE: + xNA = m_rDatabases.jarFile( m_aInitialModule, m_aLanguage ); + m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE + break; + + // Later: + //case SHARED_MODULE + //... + + case USER_EXTENSIONS: + { + Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( o_xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + xNA = implGetJarFromPackage( xHelpPackage, o_pExtensionPath ); + break; + } + + case SHARED_EXTENSIONS: + { + Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( o_xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + xNA = implGetJarFromPackage( xHelpPackage, o_pExtensionPath ); + break; + } + case END_REACHED: + VOS_ENSURE( false, "JarFileIterator::nextJarFile(): Invalid case END_REACHED" ); + break; + } + } + + return xNA; +} + +Reference< XHierarchicalNameAccess > JarFileIterator::implGetJarFromPackage + ( Reference< deployment::XPackage > xPackage, rtl::OUString* o_pExtensionPath ) +{ + Reference< XHierarchicalNameAccess > xNA; + + rtl::OUString zipFile = + implGetFileFromPackage( rtl::OUString::createFromAscii( ".jar" ), xPackage ); + + try + { + Sequence< Any > aArguments( 2 ); + aArguments[ 0 ] <<= zipFile; + + // let ZipPackage be used ( no manifest.xml is required ) + beans::NamedValue aArg; + aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) ); + aArg.Value <<= ZIP_STORAGE_FORMAT_STRING; + aArguments[ 1 ] <<= aArg; + + Reference< XMultiComponentFactory >xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); + Reference< XInterface > xIfc + = xSMgr->createInstanceWithArgumentsAndContext( + rtl::OUString::createFromAscii( + "com.sun.star.packages.comp.ZipPackage" ), + aArguments, m_xContext ); + + if ( xIfc.is() ) + { + xNA = Reference< XHierarchicalNameAccess >( xIfc, UNO_QUERY ); + + VOS_ENSURE( xNA.is(), + "JarFileIterator::implGetJarFromPackage() - " + "Got no hierarchical name access!" ); + } + } + catch ( RuntimeException & ) + {} + catch ( Exception & ) + {} + + if( xNA.is() && o_pExtensionPath != NULL ) + { + // Extract path including language from file name + sal_Int32 nLastSlash = zipFile.lastIndexOf( '/' ); + if( nLastSlash != -1 ) + *o_pExtensionPath = zipFile.copy( 0, nLastSlash ); + } + + return xNA; +} + + +//=================================================================== +// class IndexFolderIterator + +rtl::OUString IndexFolderIterator::nextIndexFolder( bool& o_rbExtension, bool& o_rbTemporary ) +{ + rtl::OUString aIndexFolder; + + while( !aIndexFolder.getLength() && m_eState != END_REACHED ) + { + switch( m_eState ) + { + case INITIAL_MODULE: + aIndexFolder = + m_rDatabases.getInstallPathAsURL() + + m_rDatabases.processLang( m_aLanguage ) + aSlash + m_aInitialModule + + rtl::OUString::createFromAscii( ".idxl" ); + + o_rbTemporary = false; + o_rbExtension = false; + + m_eState = USER_EXTENSIONS; // Later: SHARED_MODULE + break; + + // Later: + //case SHARED_MODULE + //... + + case USER_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + aIndexFolder = implGetIndexFolderFromPackage( o_rbTemporary, xHelpPackage ); + o_rbExtension = true; + break; + } + + case SHARED_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + aIndexFolder = implGetIndexFolderFromPackage( o_rbTemporary, xHelpPackage ); + o_rbExtension = true; + break; + } + case END_REACHED: + VOS_ENSURE( false, "IndexFolderIterator::nextIndexFolder(): Invalid case END_REACHED" ); + break; + } + } + + return aIndexFolder; +} + +rtl::OUString IndexFolderIterator::implGetIndexFolderFromPackage( bool& o_rbTemporary, Reference< deployment::XPackage > xPackage ) +{ + rtl::OUString aIndexFolder = + implGetFileFromPackage( rtl::OUString::createFromAscii( ".idxl" ), xPackage ); + + o_rbTemporary = false; + if( !m_xSFA->isFolder( aIndexFolder ) ) + { + // i98680: Missing index? Try to generate now + rtl::OUString aLangURL = implGetFileFromPackage( rtl::OUString(), xPackage ); + if( m_xSFA->isFolder( aLangURL ) ) + { + // Test write access (shared extension may be read only) + bool bIsWriteAccess = false; + try + { + rtl::OUString aCreateTestFolder = aLangURL + rtl::OUString::createFromAscii( "CreateTestFolder" ); + m_xSFA->createFolder( aCreateTestFolder ); + if( m_xSFA->isFolder( aCreateTestFolder ) ) + bIsWriteAccess = true; + + m_xSFA->kill( aCreateTestFolder ); + } + catch (Exception &) + {} + + // TEST + //bIsWriteAccess = false; + + Reference< script::XInvocation > xInvocation; + Reference< XMultiComponentFactory >xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); + try + { + xInvocation = Reference< script::XInvocation >( + m_xContext->getServiceManager()->createInstanceWithContext( rtl::OUString::createFromAscii( + "com.sun.star.help.HelpIndexer" ), m_xContext ) , UNO_QUERY ); + + if( xInvocation.is() ) + { + Sequence<uno::Any> aParamsSeq( bIsWriteAccess ? 6 : 8 ); + + aParamsSeq[0] = uno::makeAny( rtl::OUString::createFromAscii( "-lang" ) ); + + rtl::OUString aLang; + sal_Int32 nLastSlash = aLangURL.lastIndexOf( '/' ); + if( nLastSlash != -1 ) + aLang = aLangURL.copy( nLastSlash + 1 ); + else + aLang = rtl::OUString::createFromAscii( "en" ); + aParamsSeq[1] = uno::makeAny( aLang ); + + aParamsSeq[2] = uno::makeAny( rtl::OUString::createFromAscii( "-mod" ) ); + aParamsSeq[3] = uno::makeAny( rtl::OUString::createFromAscii( "help" ) ); + + rtl::OUString aZipDir = aLangURL; + if( !bIsWriteAccess ) + { + rtl::OUString aTempFileURL; + ::osl::FileBase::RC eErr = ::osl::File::createTempFile( 0, 0, &aTempFileURL ); + if( eErr == ::osl::FileBase::E_None ) + { + rtl::OUString aTempDirURL = aTempFileURL; + try + { + m_xSFA->kill( aTempDirURL ); + } + catch (Exception &) + {} + m_xSFA->createFolder( aTempDirURL ); + + aZipDir = aTempDirURL; + o_rbTemporary = true; + } + } + + aParamsSeq[4] = uno::makeAny( rtl::OUString::createFromAscii( "-zipdir" ) ); + rtl::OUString aSystemPath; + osl::FileBase::getSystemPathFromFileURL( aZipDir, aSystemPath ); + aParamsSeq[5] = uno::makeAny( aSystemPath ); + + if( !bIsWriteAccess ) + { + aParamsSeq[6] = uno::makeAny( rtl::OUString::createFromAscii( "-srcdir" ) ); + rtl::OUString aSrcDirVal; + osl::FileBase::getSystemPathFromFileURL( aLangURL, aSrcDirVal ); + aParamsSeq[7] = uno::makeAny( aSrcDirVal ); + } + + Sequence< sal_Int16 > aOutParamIndex; + Sequence< uno::Any > aOutParam; + uno::Any aRet = xInvocation->invoke( rtl::OUString::createFromAscii( "createIndex" ), + aParamsSeq, aOutParamIndex, aOutParam ); + + if( bIsWriteAccess ) + aIndexFolder = implGetFileFromPackage( rtl::OUString::createFromAscii( ".idxl" ), xPackage ); + else + aIndexFolder = aZipDir + rtl::OUString::createFromAscii( "/help.idxl" ); + } + } + catch (Exception &) + {} + } + } + + return aIndexFolder; +} + +void IndexFolderIterator::deleteTempIndexFolder( const rtl::OUString& aIndexFolder ) +{ + sal_Int32 nLastSlash = aIndexFolder.lastIndexOf( '/' ); + if( nLastSlash != -1 ) + { + rtl::OUString aTmpFolder = aIndexFolder.copy( 0, nLastSlash ); + try + { + m_xSFA->kill( aTmpFolder ); + } + catch (Exception &) + {} + } +} diff --git a/xmlhelp/source/cxxhelp/provider/databases.hxx b/xmlhelp/source/cxxhelp/provider/databases.hxx new file mode 100644 index 000000000000..87491c1b1e45 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/databases.hxx @@ -0,0 +1,560 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: databases.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _DATABASES_HXX_ +#define _DATABASES_HXX_ + +#ifndef INCLUDED_STL_SET +#include <set> +#define INCLUDED_STL_SET +#endif +#ifndef INCLUDED_STL_VECTOR +#include <vector> +#define INCLUDED_STL_VECTOR +#endif +#include <hash_map> +#include <hash_set> +#include <osl/mutex.hxx> +#include <rtl/ustring.hxx> +#include <rtl/string.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/ucb/XContent.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/i18n/XCollator.hpp> +#include <com/sun/star/deployment/XPackage.hpp> +#include "com/sun/star/ucb/XSimpleFileAccess.hpp" + +// Forward declaration + + +namespace berkeleydbproxy { + + class Db; + +} + + +namespace chelp { + + + class Databases; + class URLParameter; + + class StaticModuleInformation + { + private: + + rtl::OUString m_aStartId; + rtl::OUString m_aProgramSwitch; + rtl::OUString m_aTitle; + rtl::OUString m_aHeading; + rtl::OUString m_aFulltext; + int m_nOrder; + + + public: + + StaticModuleInformation( rtl::OUString aTitle, + rtl::OUString aStartId, + rtl::OUString aProgramSwitch, + rtl::OUString aHeading, + rtl::OUString aFulltext, + rtl::OUString aOrder ) + : m_aStartId( aStartId ), + m_aProgramSwitch( aProgramSwitch ), + m_aTitle( aTitle ), + m_aHeading( aHeading ), + m_aFulltext( aFulltext ), + m_nOrder( aOrder.toInt32() ) + { + } + + ~StaticModuleInformation() { } + + rtl::OUString get_title() { return m_aTitle; } + rtl::OUString get_id() { return m_aStartId; } + rtl::OUString get_program() { return m_aProgramSwitch; } + rtl::OUString get_heading() { return m_aHeading; } + rtl::OUString get_fulltext() { return m_aFulltext; } + int get_order() { return m_nOrder; } + }; // end class StaticModuleInformation + + + + class KeywordInfo + { + public: + + class KeywordElement + { + friend struct KeywordElementComparator; + friend class KeywordInfo; + + public: + + KeywordElement( Databases* pDatabases, + berkeleydbproxy::Db* pDb, + rtl::OUString& key, + rtl::OUString& ids ); + + private: + + rtl::OUString key; + com::sun::star::uno::Sequence< rtl::OUString > listId; + com::sun::star::uno::Sequence< rtl::OUString > listAnchor; + com::sun::star::uno::Sequence< rtl::OUString > listTitle; + + void init( Databases *pDatabases,berkeleydbproxy::Db* pDb,const rtl::OUString& ids ); + }; + + + KeywordInfo( const std::vector< KeywordElement >& aVector ); + + ~KeywordInfo() { }; + + com::sun::star::uno::Sequence< rtl::OUString >& + getKeywordList() { return listKey; } + + com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< rtl::OUString > >& + getIdList() { return listId; } + + com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< rtl::OUString > >& + getAnchorList() { return listAnchor; } + + com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< rtl::OUString > >& + getTitleList() { return listTitle; } + + private: + + com::sun::star::uno::Sequence< rtl::OUString > listKey; + com::sun::star::uno::Sequence< com::sun::star::uno::Sequence< rtl::OUString > > listId,listAnchor,listTitle; + }; // end class KeywordInfo + + + + class Databases + { + public: + + struct eq + { + bool operator()( const rtl::OUString& rKey1, const rtl::OUString& rKey2 ) const + { + return rKey1.compareTo( rKey2 ) == 0; + } + }; + + struct ha + { + size_t operator()( const rtl::OUString& rName ) const + { + return rName.hashCode(); + } + }; + + + /** + * Input is the installdirectory in system dependent notation + */ + + Databases( sal_Bool showBasic, + const rtl::OUString& instPath, + const com::sun::star::uno::Sequence< rtl::OUString >& imagesZipPaths, + const rtl::OUString& productName, + const rtl::OUString& productVersion, + const rtl::OUString& vendorName, + const rtl::OUString& vendorVersion, + const rtl::OUString& vendorShort, + const rtl::OUString& styleSheet, + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext ); + + ~Databases(); + + rtl::OString getImagesZipFileURL(); + + rtl::OUString getInstallPathAsSystemPath(); + + rtl::OUString getInstallPathAsURL(); + + const std::vector< rtl::OUString >& getModuleList( const rtl::OUString& Language ); + + StaticModuleInformation* getStaticInformationForModule( const rtl::OUString& Module, + const rtl::OUString& Language ); + + bool checkModuleMatchForExtension( const rtl::OUString& Database, const rtl::OUString& doclist ); + KeywordInfo* getKeyword( const rtl::OUString& Module, + const rtl::OUString& Language ); + + berkeleydbproxy::Db* getBerkeley( const rtl::OUString& Module, + const rtl::OUString& Language, bool helpText = false, + const rtl::OUString* pExtensionPath = NULL ); + + + /** + * The following method returns the Collator for the given language-country combination + */ + + com::sun::star::uno::Reference< com::sun::star::i18n::XCollator > + getCollator( const rtl::OUString& Language, + const rtl::OUString& System ); // System not used by current implementation + // // of XCollator + + /** + * Returns a copy of the popupfile + */ + + void popupDocument( URLParameter* urlPar,char **buffer,int *byteCount ); + + + /** + * Returns the cascading stlye sheet used to format the HTML-output. + * First try is language directory, second try is main installation directory. + */ + + void cascadingStylesheet( const rtl::OUString& Language, + char** buffer, + int* byteCount ); + + + /** + * Changes the the stylesheet for further reads. + */ + + void changeCSS(const rtl::OUString& newStyleSheet); + + + /** + * Returns the active help text for the given module, language and id. + */ + + void setActiveText( const rtl::OUString& Module, + const rtl::OUString& Language, + const rtl::OUString& Id, + char** buffer, + int* byteCount ); + + /** + * Has the purpose of forcing the the jarfile to stay open + */ + + com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > + jarFile( const rtl::OUString& jar, + const rtl::OUString& Language ); + + com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > + findJarFileForPath( const rtl::OUString& jar, const rtl::OUString& Language, + const rtl::OUString& path, rtl::OUString* o_pExtensionPath = NULL ); + + /** + * Maps a given language-locale combination to language. + */ + + rtl::OUString processLang( const rtl::OUString& Language ); + + + /** + * Maps a given language-locale combination to locale. + * The returned string maybe empty + */ + + rtl::OUString country( const rtl::OUString& Language ); + + + void replaceName( rtl::OUString& oustring ) const; + + rtl::OUString getProductName() const { return m_vReplacement[0]; } + rtl::OUString getProductVersion() const { return m_vReplacement[1]; } + rtl::OUString getVendorName() const { return m_vReplacement[2]; } + rtl::OUString getVendorVersion() const { return m_vReplacement[3]; } + rtl::OUString getVendorShort() const { return m_vReplacement[4]; } + + rtl::OUString expandURL( const rtl::OUString& aURL ); + + static rtl::OUString expandURL( const rtl::OUString& aURL, + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext ); + + private: + + osl::Mutex m_aMutex; + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > m_xContext; + com::sun::star::uno::Reference< com::sun::star::lang::XMultiComponentFactory > m_xSMgr; + com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess > m_xSFA; + + sal_Bool m_bShowBasic; + int m_nErrorDocLength; + char* m_pErrorDoc; + + int m_nCustomCSSDocLength; + char* m_pCustomCSSDoc; + rtl::OUString m_aCSS; + +#define PRODUCTNAME 0 +#define PRODUCTVERSION 1 +#define VENDORNAME 2 +#define VENDORVERSION 3 +#define VENDORSHORT 4 +#define NEWPRODUCTNAME 5 +#define NEWPRODUCTVERSION 6 + + int m_vAdd[7]; + rtl::OUString m_vReplacement[7]; + rtl::OUString newProdName,newProdVersion, + prodName,prodVersion,vendName,vendVersion,vendShort; + + rtl::OUString m_aInstallDirectory; // Installation directory + com::sun::star::uno::Sequence< rtl::OUString > m_aImagesZipPaths; + rtl::OString m_aImagesZipFileURL; + sal_Int16 m_nSymbolsStyle; + rtl::OUString m_aInstallDirectoryWithoutEncoding; // a work around for a Sablot bug. + rtl::OUString m_aInstallDirectoryAsSystemPath; // Installation directory + + std::vector< rtl::OUString > m_avModules; + + typedef std::hash_map< rtl::OUString,berkeleydbproxy::Db*,ha,eq > DatabasesTable; + DatabasesTable m_aDatabases; // Language and module dependent databases + + typedef std::hash_map< rtl::OUString,rtl::OUString,ha,eq > LangSetTable; + LangSetTable m_aLangSet; // Mapping to of lang-country to lang + + typedef std::hash_map< rtl::OUString,StaticModuleInformation*,ha,eq > ModInfoTable; + ModInfoTable m_aModInfo; // Module information + + typedef std::hash_map< rtl::OUString,KeywordInfo*,ha,eq > KeywordInfoTable; + KeywordInfoTable m_aKeywordInfo; // Module information + + typedef + std::hash_map< + rtl::OUString, + ::com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess >, + ha, + eq > ZipFileTable; + ZipFileTable m_aZipFileTable; // No closing of an once opened jarfile + + typedef + std::hash_map< + rtl::OUString, + ::com::sun::star::uno::Reference< com::sun::star::i18n::XCollator >, + ha, + eq > CollatorTable; + CollatorTable m_aCollatorTable; + + + struct ostring_eq + { + bool operator()( const rtl::OString& rKey1, const rtl::OString& rKey2 ) const + { + return rKey1.compareTo( rKey2 ) == 0; + } + }; + + struct ostring_ha + { + size_t operator()( const rtl::OString& rName ) const + { + return rName.hashCode(); + } + }; + + typedef + std::hash_set< + rtl::OString, + ostring_ha, + ostring_eq > EmptyActiveTextSet; + EmptyActiveTextSet m_aEmptyActiveTextSet; + + + // methods + + void setInstallPath( const rtl::OUString& aInstallDirectory ); + + }; // end class Databases + + + //=================================================================== + enum IteratorState + { + INITIAL_MODULE, + //SHARED_MODULE, // Later, avoids redundancies in help compiling + USER_EXTENSIONS, + SHARED_EXTENSIONS, + END_REACHED + }; + + // Hashtable to cache extension help status + typedef std::hash_map + < + ::rtl::OUString, + bool, + Databases::ha, + Databases::eq + > + ExtensionHelpExistanceMap; + + + class ExtensionIteratorBase + { + static ExtensionHelpExistanceMap aHelpExistanceMap; + + public: + ExtensionIteratorBase( com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext, + Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage ); + ExtensionIteratorBase( Databases& rDatabases, const rtl::OUString& aInitialModule, + const rtl::OUString& aLanguage ); + void init( void ); + + private: + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetHelpPackageFromPackage + ( const com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage, + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle ); + + protected: + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetNextUserHelpPackage + ( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle ); + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetNextSharedHelpPackage + ( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle ); + rtl::OUString implGetFileFromPackage( const rtl::OUString& rFileExtension, + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage ); + void implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv, + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage ); + + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > m_xContext; + com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess > m_xSFA; + Databases& m_rDatabases; + + IteratorState m_eState; + rtl::OUString m_aExtensionPath; + + rtl::OUString m_aInitialModule; + rtl::OUString m_aLanguage; + + com::sun::star::uno::Sequence< com::sun::star::uno::Reference + < com::sun::star::deployment::XPackage > > m_aUserPackagesSeq; + bool m_bUserPackagesLoaded; + + com::sun::star::uno::Sequence< com::sun::star::uno::Reference + < com::sun::star::deployment::XPackage > > m_aSharedPackagesSeq; + bool m_bSharedPackagesLoaded; + + int m_iUserPackage; + int m_iSharedPackage; + + }; // end class ExtensionIteratorBase + + + //=================================================================== + class DataBaseIterator : public ExtensionIteratorBase + { + public: + DataBaseIterator( com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext, + Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage, bool bHelpText ) + : ExtensionIteratorBase( xContext, rDatabases, aInitialModule, aLanguage ) + , m_bHelpText( bHelpText ) + {} + DataBaseIterator( Databases& rDatabases, const rtl::OUString& aInitialModule, + const rtl::OUString& aLanguage, bool bHelpText ) + : ExtensionIteratorBase( rDatabases, aInitialModule, aLanguage ) + , m_bHelpText( bHelpText ) + {} + + berkeleydbproxy::Db* nextDb( rtl::OUString* o_pExtensionPath = NULL ); + + + private: + berkeleydbproxy::Db* implGetDbFromPackage( + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage, + rtl::OUString* o_pExtensionPath ); + + bool m_bHelpText; + + }; // end class DataBaseIterator + + //=================================================================== + class KeyDataBaseFileIterator : public ExtensionIteratorBase + { + public: + KeyDataBaseFileIterator( com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext, + Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage ) + : ExtensionIteratorBase( xContext, rDatabases, aInitialModule, aLanguage ) + {} + + rtl::OUString nextDbFile( bool& o_rbExtension ); + + private: + rtl::OUString implGetDbFileFromPackage( + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage ); + + }; // end class KeyDataBaseFileIterator + + //=================================================================== + class JarFileIterator : public ExtensionIteratorBase + { + public: + JarFileIterator( com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > xContext, + Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage ) + : ExtensionIteratorBase( xContext, rDatabases, aInitialModule, aLanguage ) + {} + + com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > + nextJarFile( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle, + rtl::OUString* o_pExtensionPath = NULL ); + + private: + com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess > + implGetJarFromPackage(com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage, + rtl::OUString* o_pExtensionPath = NULL ); + + }; // end class JarFileIterator + + //=================================================================== + class IndexFolderIterator : public ExtensionIteratorBase + { + public: + IndexFolderIterator( Databases& rDatabases, const rtl::OUString& aInitialModule, const rtl::OUString& aLanguage ) + : ExtensionIteratorBase( rDatabases, aInitialModule, aLanguage ) + {} + + rtl::OUString nextIndexFolder( bool& o_rbExtension, bool& o_rbTemporary ); + void deleteTempIndexFolder( const rtl::OUString& aIndexFolder ); + + private: + rtl::OUString implGetIndexFolderFromPackage( bool& o_rbTemporary, + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage ); + + }; // end class KeyDataBaseFileIterator + + //=================================================================== + +} // end namespace chelp + + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/db.cxx b/xmlhelp/source/cxxhelp/provider/db.cxx new file mode 100644 index 000000000000..e3129f8e94b5 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/db.cxx @@ -0,0 +1,667 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: db.cxx,v $ + * $Revision: 1.8 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" + +#include "db.hxx" + +#include <rtl/alloc.h> +#include <cstring> + +#include "com/sun/star/io/XSeekable.hpp" + +#ifdef TEST_DBHELP +#include <osl/time.h> +#endif + +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::io; + +namespace berkeleydbproxy { + +//---------------------------------------------------------------------------- +namespace db_internal +{ + // static void raise_error(int dberr, const char * where); + + static inline int check_error(int dberr, const char * where) + { + (void)where; + + // if (dberr) raise_error(dberr,where); + return dberr; + } +} + +void DBData::copyToBuffer( const char* pSrcData, int nSize ) +{ + m_nSize = nSize; + delete [] m_pBuffer; + m_pBuffer = new char[m_nSize+1]; + memcpy( m_pBuffer, pSrcData, m_nSize ); + m_pBuffer[m_nSize] = 0; +} + + +// DBHelp + +bool DBHelp::implReadLenAndData( const char* pData, int& riPos, DBData& rValue ) +{ + bool bSuccess = false; + + // Read key len + const char* pStartPtr = pData + riPos; + char* pEndPtr; + sal_Int32 nKeyLen = strtol( pStartPtr, &pEndPtr, 16 ); + if( pEndPtr == pStartPtr ) + return bSuccess; + riPos += (pEndPtr - pStartPtr) + 1; + + const char* pKeySrc = pData + riPos; + rValue.copyToBuffer( pKeySrc, nKeyLen ); + riPos += nKeyLen + 1; + + bSuccess = true; + return bSuccess; +} + +#ifdef TEST_DBHELP + +typedef std::pair< rtl::OString, rtl::OString > KeyValPair; +typedef std::vector< KeyValPair > KeyValPairVector; + +void testWriteKeyValue( FILE* pFile, const KeyValPair& rKeyValPair ) +{ + if( pFile == NULL ) + return; + char cLF = 10; + + const rtl::OString& aKeyStr = rKeyValPair.first; + const rtl::OString& aValueStr = rKeyValPair.second; + int nKeyLen = aKeyStr.getLength(); + int nValueLen = aValueStr.getLength(); + fprintf( pFile, "%x ", nKeyLen ); + if( nKeyLen > 0 ) + fwrite( aKeyStr.getStr(), 1, nKeyLen, pFile ); + fprintf( pFile, " %x ", nValueLen ); + if( nValueLen > 0 ) + fwrite( aValueStr.getStr(), 1, nValueLen, pFile ); + fprintf( pFile, "%c", cLF ); +} + +bool DBHelp::testAgainstDb( const rtl::OString& fileName, bool bOldDbAccess ) +{ + bool bSuccess = true; + + KeyValPairVector avKeyValPair; + + rtl::OString aOutFileName = fileName; + aOutFileName += "_TestOut"; + if( bOldDbAccess ) + aOutFileName += "_Old"; + FILE* pFile = fopen( aOutFileName.getStr(), "wb" ); + + // Get all values + Db table; + if( 0 == table.open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) ) + { + bool first = true; + + Dbc* cursor = 0; + table.cursor( 0,&cursor,0 ); + Dbt key_,data; + key_.set_flags( DB_DBT_MALLOC ); // Initially the cursor must allocate the necessary memory + data.set_flags( DB_DBT_MALLOC ); + + while( cursor && DB_NOTFOUND != cursor->get( &key_,&data,DB_NEXT ) ) + { + rtl::OString keyword( static_cast<sal_Char*>(key_.get_data()), + key_.get_size() ); + rtl::OString value( static_cast<sal_Char*>(data.get_data()), + data.get_size() ); + + KeyValPair aPair( keyword, value ); + avKeyValPair.push_back( aPair ); + if( pFile != NULL ) + testWriteKeyValue( pFile, aPair ); + + if( first ) + { + key_.set_flags( DB_DBT_REALLOC ); + data.set_flags( DB_DBT_REALLOC ); + first = false; + } + } + + if( cursor ) cursor->close(); + } + table.close( 0 ); + + // TEST + DBData aDBData; + Db tableTest; + Dbt data; + + int nOkCount = 0; + int nErrCount = 0; + + bool bTestSuccess; + const char* pTestReadData = NULL; + int nTestReadDataSize = 0; + + sal_uInt32 starttime = osl_getGlobalTimer(); + sal_uInt32 afterfirsttime = starttime; + + if( pFile != NULL ) + { + if( bOldDbAccess ) + fprintf( pFile, "\nTesting old access:\n" ); + else + fprintf( pFile, "\nTesting new access:\n" ); + } + + KeyValPairVector::const_iterator it; + bool bFirst = true; + for( it = avKeyValPair.begin() ; it != avKeyValPair.end() ; ++it ) + { + const KeyValPair& rKeyValPair = *it; + + const rtl::OString& aKeyStr = rKeyValPair.first; + const rtl::OString& aValueStr = rKeyValPair.second; + int nKeyLen = aKeyStr.getLength(); + int nValueLen = aValueStr.getLength(); + + const sal_Char* ptr = aValueStr.getStr(); + + bTestSuccess = false; + pTestReadData = NULL; + nTestReadDataSize = 0; + if( bOldDbAccess ) + { + if( bFirst ) + { + if( tableTest.open( 0,fileName.getStr(),0,DB_BTREE,DB_RDONLY,0644 ) ) + { + if( pFile != NULL ) + fprintf( pFile, "Cannot open database\n" ); + + break; + } + } + + Dbt key( static_cast< void* >( const_cast< sal_Char* >( aKeyStr.getStr() ) ), aKeyStr.getLength() ); + int err = tableTest.get( 0, &key, &data, 0 ); + if( err == 0 ) + { + bTestSuccess = true; + pTestReadData = static_cast< sal_Char* >( data.get_data() ); + nTestReadDataSize = data.get_size(); + } + } + else + { + bTestSuccess = getValueForKey( aKeyStr, aDBData ); + if( bTestSuccess ) + { + pTestReadData = aDBData.getData(); + nTestReadDataSize = aDBData.getSize(); + } + } + if( bFirst ) + { + afterfirsttime = osl_getGlobalTimer(); + bFirst = false; + } + int nError = 0; + if( bTestSuccess && pTestReadData != NULL ) + { + int nCmp = memcmp( ptr, pTestReadData, nValueLen ); + if( nCmp == 0 ) + ++nOkCount; + else + nError = 1; + + if( nValueLen != nTestReadDataSize ) + nError = 2; + } + else + nError = 3; + + if( nError != 0 ) + { + bSuccess = false; + ++nErrCount; + + if( pFile != NULL ) + { + fprintf( pFile, "ERROR, not found:\n" ); + testWriteKeyValue( pFile, rKeyValPair ); + fprintf( pFile, "\nError Code: %d\n", nError ); + } + } + } + tableTest.close( 0 ); + + sal_uInt32 endtime = osl_getGlobalTimer(); + double dDiffTime = (endtime-starttime) / 1000.0; + double dDiffFirstTime = (afterfirsttime-starttime) / 1000.0; + if( pFile != NULL ) + { + int nCount = avKeyValPair.size(); + fprintf( pFile, "%d key/values in total, read %d correctly, %d errors\n", + nCount, nOkCount, nErrCount ); + fprintf( pFile, "Time taken: %g s (First access %g s)\n", dDiffTime, dDiffFirstTime ); + fprintf( pFile, "Average time per access: %g s\n", dDiffTime / nCount ); + } + + if( pFile != NULL ) + fclose( pFile ); + + return bSuccess; +} + +#endif + + +void DBHelp::createHashMap( bool bOptimizeForPerformance ) +{ + releaseHashMap(); + if( bOptimizeForPerformance ) + { + if( m_pStringToDataMap != NULL ) + return; + m_pStringToDataMap = new StringToDataMap(); + } + else + { + if( m_pStringToValPosMap != NULL ) + return; + m_pStringToValPosMap = new StringToValPosMap(); + } + + Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileName ); + if( xIn.is() ) + { + Sequence< sal_Int8 > aData; + sal_Int32 nSize = m_xSFA->getSize( m_aFileName ); + sal_Int32 nRead = xIn->readBytes( aData, nSize ); + + const char* pData = (const char*)aData.getConstArray(); + int iPos = 0; + while( iPos < nRead ) + { + DBData aDBKey; + if( !implReadLenAndData( pData, iPos, aDBKey ) ) + break; + + rtl::OString aOKeyStr = aDBKey.getData(); + + // Read val len + const char* pStartPtr = pData + iPos; + char* pEndPtr; + sal_Int32 nValLen = strtol( pStartPtr, &pEndPtr, 16 ); + if( pEndPtr == pStartPtr ) + break; + + iPos += (pEndPtr - pStartPtr) + 1; + + if( bOptimizeForPerformance ) + { + const char* pValSrc = pData + iPos; + rtl::OString aValStr( pValSrc, nValLen ); + (*m_pStringToDataMap)[aOKeyStr] = aValStr; + } + else + { + // store value start position + (*m_pStringToValPosMap)[aOKeyStr] = std::pair<int,int>( iPos, nValLen ); + } + iPos += nValLen + 1; + } + + xIn->closeInput(); + } +} + +void DBHelp::releaseHashMap( void ) +{ + if( m_pStringToDataMap != NULL ) + { + delete m_pStringToDataMap; + m_pStringToDataMap = NULL; + } + if( m_pStringToValPosMap != NULL ) + { + delete m_pStringToValPosMap; + m_pStringToValPosMap = NULL; + } +} + + +bool DBHelp::getValueForKey( const rtl::OString& rKey, DBData& rValue ) +{ + bool bSuccess = false; + if( !m_xSFA.is() ) + return bSuccess; + + try + { + + if( m_pStringToDataMap == NULL && m_pStringToValPosMap == NULL ) + { + bool bOptimizeForPerformance = false; + createHashMap( bOptimizeForPerformance ); + } + + if( m_pStringToValPosMap != NULL ) + { + StringToValPosMap::const_iterator it = m_pStringToValPosMap->find( rKey ); + if( it != m_pStringToValPosMap->end() ) + { + const std::pair<int,int>& rValPair = it->second; + int iValuePos = rValPair.first; + int nValueLen = rValPair.second; + + Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileName ); + if( xIn.is() ) + { + Reference< XSeekable > xXSeekable( xIn, UNO_QUERY ); + if( xXSeekable.is() ) + { + xXSeekable->seek( iValuePos ); + + Sequence< sal_Int8 > aData; + sal_Int32 nRead = xIn->readBytes( aData, nValueLen ); + if( nRead == nValueLen ) + { + const char* pData = (const sal_Char*)aData.getConstArray(); + rValue.copyToBuffer( pData, nValueLen ); + bSuccess = true; + } + } + xIn->closeInput(); + } + } + } + + else if( m_pStringToDataMap != NULL ) + { + StringToDataMap::const_iterator it = m_pStringToDataMap->find( rKey ); + if( it != m_pStringToDataMap->end() ) + { + const rtl::OString& rValueStr = it->second; + int nValueLen = rValueStr.getLength(); + const char* pData = rValueStr.getStr(); + rValue.copyToBuffer( pData, nValueLen ); + bSuccess = true; + } + } + + } + catch( Exception & ) + { + bSuccess = false; + } + + return bSuccess; +} + +bool DBHelp::startIteration( void ) +{ + bool bSuccess = false; + + sal_Int32 nSize = m_xSFA->getSize( m_aFileName ); + + Reference< XInputStream > xIn = m_xSFA->openFileRead( m_aFileName ); + if( xIn.is() ) + { + m_nItRead = xIn->readBytes( m_aItData, nSize ); + if( m_nItRead == nSize ) + { + bSuccess = true; + m_pItData = (const char*)m_aItData.getConstArray(); + m_iItPos = 0; + } + else + { + stopIteration(); + } + } + + return bSuccess; +} + +bool DBHelp::getNextKeyAndValue( DBData& rKey, DBData& rValue ) +{ + bool bSuccess = false; + + if( m_iItPos < m_nItRead ) + { + if( implReadLenAndData( m_pItData, m_iItPos, rKey ) ) + { + if( implReadLenAndData( m_pItData, m_iItPos, rValue ) ) + bSuccess = true; + } + } + + return bSuccess; +} + +void DBHelp::stopIteration( void ) +{ + m_aItData = Sequence<sal_Int8>(); + m_pItData = NULL; + m_nItRead = -1; + m_iItPos = -1; +} + + +Db::Db() +{ + db_internal::check_error( db_create(&m_pDBP,0,0),"Db::Db" ); + m_pDBHelp = NULL; +} + + +Db::~Db() +{ + if (m_pDBP) + { + // should not happen + // TODO: add assert + } + + delete m_pDBHelp; +} + + +int Db::close(u_int32_t flags) +{ + int error = m_pDBP->close(m_pDBP,flags); + m_pDBP = 0; + return db_internal::check_error(error,"Db::close"); +} + +int Db::open(DB_TXN *txnid, + const char *file, + const char *database, + DBTYPE type, + u_int32_t flags, + int mode) +{ + int err = m_pDBP->open(m_pDBP,txnid,file,database,type,flags,mode); + return db_internal::check_error( err,"Db::open" ); +} + + +int Db::get(DB_TXN *txnid, Dbt *key, Dbt *data, u_int32_t flags) +{ + int err = m_pDBP->get(m_pDBP,txnid,key,data,flags); + + // these are non-exceptional outcomes + if (err != DB_NOTFOUND && err != DB_KEYEMPTY) + db_internal::check_error( err,"Db::get" ); + + return err; +} + +int Db::cursor(DB_TXN *txnid, Dbc **cursorp, u_int32_t flags) +{ + DBC * dbc = 0; + int error = m_pDBP->cursor(m_pDBP,txnid,&dbc,flags); + + if (!db_internal::check_error(error,"Db::cursor")) + *cursorp = new Dbc(dbc); + + return error; +} + +//---------------------------------------------------------------------------- + +Dbc::Dbc(DBC * dbc) +: m_pDBC(dbc) +{ +} + +Dbc::~Dbc() +{ +} + +int Dbc::close() +{ + int err = m_pDBC->c_close(m_pDBC); + delete this; + return db_internal::check_error( err,"Dbcursor::close" ); +} + +int Dbc::get(Dbt *key, Dbt *data, u_int32_t flags) +{ + int err = m_pDBC->c_get(m_pDBC,key,data,flags); + + // these are non-exceptional outcomes + if (err != DB_NOTFOUND && err != DB_KEYEMPTY) + db_internal::check_error( err, "Dbcursor::get" ); + + return err; +} + +//---------------------------------------------------------------------------- + + +Dbt::Dbt() +{ + using namespace std; + DBT * thispod = this; + memset(thispod, 0, sizeof *thispod); +} + + +Dbt::Dbt(void *data_arg, u_int32_t size_arg) +{ + using namespace std; + DBT * thispod = this; + memset(thispod, 0, sizeof *thispod); + this->set_data(data_arg); + this->set_size(size_arg); +} + +/* +Dbt::Dbt(const Dbt & other) +{ + using namespace std; + const DBT *otherpod = &other; + DBT *thispod = this; + memcpy(thispod, otherpod, sizeof *thispod); +} + +Dbt& Dbt::operator = (const Dbt & other) +{ + if (this != &other) + { + using namespace std; + const DBT *otherpod = &other; + DBT *thispod = this; + memcpy(thispod, otherpod, sizeof *thispod); + } + return *this; +} +*/ + +Dbt::~Dbt() +{ +} + +void * Dbt::get_data() const +{ + return this->data; +} + +void Dbt::set_data(void *value) +{ + this->data = value; +} + +u_int32_t Dbt::get_size() const +{ + return this->size; +} + +void Dbt::set_size(u_int32_t value) +{ + this->size = value; +} + +void Dbt::set_flags(u_int32_t value) +{ + this->flags = value; +} + +//---------------------------------------------------------------------------- +/* +void db_internal::raise_error(int dberr, const char * where) +{ + if (!where) where = "<unknown>"; + + const char * dberrmsg = db_strerror(dberr); + if (!dberrmsg || !*dberrmsg) dberrmsg = "<unknown DB error>"; + + rtl::OString msg = where; + msg += ": "; + msg += dberrmsg; + + throw DbException(msg); +} +*/ + +//---------------------------------------------------------------------------- +} // namespace ecomp + diff --git a/xmlhelp/source/cxxhelp/provider/db.hxx b/xmlhelp/source/cxxhelp/provider/db.hxx new file mode 100644 index 000000000000..e98cd9040cf7 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/db.hxx @@ -0,0 +1,253 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: db.hxx,v $ + * $Revision: 1.9 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef BERKELEYDBPROXY_DB_HXX_ +#define BERKELEYDBPROXY_DB_HXX_ + +#ifdef SYSTEM_DB +#include <db.h> +#else +#include <berkeleydb/db.h> +#endif + +#include "com/sun/star/ucb/XSimpleFileAccess.hpp" + +#include <hash_map> +#include <rtl/string.hxx> + +extern "C" { + typedef void *(*db_malloc_fcn_type)(size_t); + typedef void *(*db_realloc_fcn_type)(void *, size_t); + typedef void (*db_free_fcn_type)(void *); +} + + +namespace berkeleydbproxy { + + class Dbc; + class Dbt; + + namespace db_internal + { + class Noncopyable + { + // not implemented + Noncopyable(const Noncopyable&); + void operator=(const Noncopyable&); + protected: + Noncopyable() {} + ~Noncopyable() {} + }; + } + + class DbException + { + rtl::OString what_; + public: + explicit DbException(rtl::OString const & whatparam) + : what_(whatparam) + {} + + const char *what() const + { return what_.getStr(); } + }; + + struct eq + { + bool operator()( const rtl::OString& rKey1, const rtl::OString& rKey2 ) const + { return rKey1.compareTo( rKey2 ) == 0; } + }; + + struct ha + { + size_t operator()( const rtl::OString& rName ) const + { return rName.hashCode(); } + }; + + +//#define TEST_DBHELP + + class DBData + { + friend class DBHelp; + + int m_nSize; + char* m_pBuffer; + + void copyToBuffer( const char* pSrcData, int nSize ); + + public: + DBData( void ) + : m_nSize( 0 ) + , m_pBuffer( NULL ) + {} + ~DBData() + { delete [] m_pBuffer; } + + int getSize() const + { return m_nSize; } + const char* getData() const + { return m_pBuffer; } + }; + + typedef std::hash_map< rtl::OString,std::pair<int,int>,ha,eq > StringToValPosMap; + typedef std::hash_map< rtl::OString,rtl::OString,ha,eq > StringToDataMap; + + class DBHelp + { + rtl::OUString m_aFileName; + StringToDataMap* m_pStringToDataMap; + StringToValPosMap* m_pStringToValPosMap; + com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess > + m_xSFA; + + com::sun::star::uno::Sequence< sal_Int8 > + m_aItData; + const char* m_pItData; + int m_nItRead; + int m_iItPos; + + bool implReadLenAndData( const char* pData, int& riPos, DBData& rValue ); + + public: + DBHelp( const rtl::OUString& rFileName, + com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess > xSFA ) + : m_aFileName( rFileName ) + , m_pStringToDataMap( NULL ) + , m_pStringToValPosMap( NULL ) + , m_xSFA( xSFA ) + , m_pItData( NULL ) + , m_nItRead( -1 ) + , m_iItPos( -1 ) + {} + ~DBHelp() + { releaseHashMap(); } + + void createHashMap( bool bOptimizeForPerformance = false ); + void releaseHashMap( void ); + +#ifdef TEST_DBHELP + bool testAgainstDb( const rtl::OString& fileName, bool bOldDbAccess ); +#endif + + bool getValueForKey( const rtl::OString& rKey, DBData& rValue ); + + bool startIteration( void ); + bool getNextKeyAndValue( DBData& rKey, DBData& rValue ); + void stopIteration( void ); + }; + + class Db : db_internal::Noncopyable + { + private: + DB* m_pDBP; + DBHelp* m_pDBHelp; + + public: + Db(); + ~Db(); + + void setDBHelp( DBHelp* pDBHelp ) + { m_pDBHelp = pDBHelp; } + DBHelp* getDBHelp( void ) + { return m_pDBHelp; } + + int close(u_int32_t flags); + + int open(DB_TXN *txnid, + const char *file, + const char *database, + DBTYPE type, + u_int32_t flags, + int mode); + + + int get(DB_TXN* txnid, Dbt *key, Dbt *data, u_int32_t flags); + + int cursor(DB_TXN *txnid, Dbc **cursorp, u_int32_t flags); + }; + + class Dbc : db_internal::Noncopyable + { + friend class Db; + friend class Dbt; + + private: + DBC* m_pDBC; + + explicit Dbc(DBC* pDBC); + ~Dbc(); + + public: + int close(); + + int get(Dbt *key, Dbt *data, u_int32_t flags); + }; + + class Dbt: private DBT + { + friend class Db; + friend class Dbc; + + public: + Dbt(void *data_arg, u_int32_t size_arg); + + Dbt(); + //Dbt(const Dbt & other); + //Dbt & operator=(const Dbt & other); + + ~Dbt(); + + void *get_data() const; + void set_data(void *value); + + u_int32_t get_size() const; + void set_size(u_int32_t value); + + void set_flags(u_int32_t); + }; +} + +#endif + + + + + + + + + + + + + + + + diff --git a/xmlhelp/source/cxxhelp/provider/inputstream.cxx b/xmlhelp/source/cxxhelp/provider/inputstream.cxx new file mode 100644 index 000000000000..d9eba67ce15a --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/inputstream.cxx @@ -0,0 +1,226 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: inputstream.cxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include "inputstream.hxx" + + +using namespace chelp; +using namespace com::sun::star; +using namespace com::sun::star::ucb; + + + +XInputStream_impl::XInputStream_impl( const rtl::OUString& aUncPath ) + : m_bIsOpen( false ), + m_aFile( aUncPath ) +{ + m_bIsOpen = ( osl::FileBase::E_None == m_aFile.open( OpenFlag_Read ) ); +} + + +XInputStream_impl::~XInputStream_impl() +{ + closeInput(); +} + + +bool SAL_CALL XInputStream_impl::CtorSuccess() +{ + return m_bIsOpen; +}; + + +uno::Any SAL_CALL +XInputStream_impl::queryInterface( + const uno::Type& rType ) + throw( uno::RuntimeException) +{ + uno::Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( io::XInputStream*,this ), + SAL_STATIC_CAST( io::XSeekable*,this ) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +void SAL_CALL +XInputStream_impl::acquire( + void ) + throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL +XInputStream_impl::release( + void ) + throw() +{ + OWeakObject::release(); +} + + + +sal_Int32 SAL_CALL +XInputStream_impl::readBytes( + uno::Sequence< sal_Int8 >& aData, + sal_Int32 nBytesToRead ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException) +{ + if( ! m_bIsOpen ) + throw io::IOException(); + + aData.realloc(nBytesToRead); + //TODO! translate memory exhaustion (if it were detectable...) into + // io::BufferSizeExceededException + + sal_uInt64 nrc; + m_aFile.read( aData.getArray(),sal_uInt64(nBytesToRead),nrc ); + + // Shrink aData in case we read less than nBytesToRead (XInputStream + // documentation does not tell whether this is required, and I do not know + // if any code relies on this, so be conservative---SB): + if (nrc != sal::static_int_cast<sal_uInt64>( nBytesToRead) ) + aData.realloc(sal_Int32(nrc)); + return ( sal_Int32 ) nrc; +} + +sal_Int32 SAL_CALL +XInputStream_impl::readSomeBytes( + uno::Sequence< sal_Int8 >& aData, + sal_Int32 nMaxBytesToRead ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException) +{ + return readBytes( aData,nMaxBytesToRead ); +} + + +void SAL_CALL +XInputStream_impl::skipBytes( + sal_Int32 nBytesToSkip ) + throw( io::NotConnectedException, + io::BufferSizeExceededException, + io::IOException, + uno::RuntimeException) +{ + m_aFile.setPos( osl_Pos_Current, sal_uInt64( nBytesToSkip ) ); +} + + +sal_Int32 SAL_CALL +XInputStream_impl::available( + void ) + throw( io::NotConnectedException, + io::IOException, + uno::RuntimeException) +{ + return 0; +} + + +void SAL_CALL +XInputStream_impl::closeInput( + void ) + throw( io::NotConnectedException, + io::IOException, + uno::RuntimeException ) +{ + if( m_bIsOpen ) + { + osl::FileBase::RC err = m_aFile.close(); + if( err != osl::FileBase::E_None ) + throw io::IOException(); + m_bIsOpen = false; + } +} + + +void SAL_CALL +XInputStream_impl::seek( + sal_Int64 location ) + throw( lang::IllegalArgumentException, + io::IOException, + uno::RuntimeException ) +{ + if( location < 0 ) + throw lang::IllegalArgumentException(); + if( osl::FileBase::E_None != m_aFile.setPos( Pos_Absolut, sal_uInt64( location ) ) ) + throw io::IOException(); +} + + +sal_Int64 SAL_CALL +XInputStream_impl::getPosition( + void ) + throw( io::IOException, + uno::RuntimeException ) +{ + sal_uInt64 uPos; + if( osl::FileBase::E_None != m_aFile.getPos( uPos ) ) + throw io::IOException(); + return sal_Int64( uPos ); +} + +sal_Int64 SAL_CALL +XInputStream_impl::getLength( + void ) + throw( io::IOException, + uno::RuntimeException ) +{ + osl::FileBase::RC err; + sal_uInt64 uCurrentPos, uEndPos; + + err = m_aFile.getPos( uCurrentPos ); + if( err != osl::FileBase::E_None ) + throw io::IOException(); + + err = m_aFile.setPos( Pos_End, 0 ); + if( err != osl::FileBase::E_None ) + throw io::IOException(); + + err = m_aFile.getPos( uEndPos ); + if( err != osl::FileBase::E_None ) + throw io::IOException(); + + err = m_aFile.setPos( Pos_Absolut, uCurrentPos ); + if( err != osl::FileBase::E_None ) + throw io::IOException(); + else + return sal_Int64( uEndPos ); +} diff --git a/xmlhelp/source/cxxhelp/provider/inputstream.hxx b/xmlhelp/source/cxxhelp/provider/inputstream.hxx new file mode 100644 index 000000000000..3205f5ae493e --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/inputstream.hxx @@ -0,0 +1,147 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: inputstream.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _INPUSTREAM_HXX_ +#define _INPUSTREAM_HXX_ + +#include <rtl/ustring.hxx> +#include <osl/file.hxx> +#include <cppuhelper/weak.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> + + +namespace chelp { + + // forward declaration + + class XInputStream_impl + : public cppu::OWeakObject, + public com::sun::star::io::XInputStream, + public com::sun::star::io::XSeekable + { + public: + + XInputStream_impl( const rtl::OUString& aUncPath ); + + virtual ~XInputStream_impl(); + + /** + * Returns an error code as given by filerror.hxx + */ + + bool SAL_CALL CtorSuccess(); + + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& rType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + virtual sal_Int32 SAL_CALL + readBytes( + com::sun::star::uno::Sequence< sal_Int8 >& aData, + sal_Int32 nBytesToRead ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL + readSomeBytes( + com::sun::star::uno::Sequence< sal_Int8 >& aData, + sal_Int32 nMaxBytesToRead ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + skipBytes( + sal_Int32 nBytesToSkip ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::BufferSizeExceededException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int32 SAL_CALL + available( + void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + closeInput( + void ) + throw( com::sun::star::io::NotConnectedException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + seek( + sal_Int64 location ) + throw( com::sun::star::lang::IllegalArgumentException, + com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int64 SAL_CALL + getPosition( + void ) + throw( com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Int64 SAL_CALL + getLength( + void ) + throw( com::sun::star::io::IOException, + com::sun::star::uno::RuntimeException ); + + private: + + bool m_bIsOpen; + osl::File m_aFile; + }; + + +} // end namespace XInputStream_impl + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/makefile.mk b/xmlhelp/source/cxxhelp/provider/makefile.mk new file mode 100644 index 000000000000..dee7d40d9540 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/makefile.mk @@ -0,0 +1,101 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.21 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJNAME=xmlhelp +TARGET=chelp + +ENABLE_EXCEPTIONS=TRUE +USE_DEFFILE=TRUE +NO_BSYMBOLIC=TRUE + + +# --- Settings --------------------------------------------------------- + +.INCLUDE: settings.mk + +# GCC versions 4.2.x introduced a warning "allocating zero-element array" +# Allocating zero-element arrays is an allowed if not somewhat dubious +# technique though, so this warning is plain wrong and has been fixed +# in gcc 4.3. Unfortunately there is no way at all to suppress this warning. +# Some files in this directory use zero allocated arrays, we need to +# diable the WaE mechanism for the GCC 4.2.x series. +.IF "$(COM)"=="GCC" +.IF "$(CCNUMVER)">="000400020000" && "$(CCNUMVER)"<="000400020003" +CFLAGSWERRCXX:= +.ENDIF # "$(CCNUMVER)">="000400020000" && "$(CCNUMVER)"<="000400020003" +.ENDIF # "$(COM)"=="GCC" + +CFLAGS += -DHAVE_EXPAT_H + +.IF "$(SYSTEM_DB)" == "YES" +CFLAGS+=-DSYSTEM_DB -I$(DB_INCLUDES) +.ENDIF + +.IF "$(SYSTEM_LIBXML)" == "YES" +CFLAGS+= $(LIBXML_CFLAGS) +.ELSE +LIBXMLINCDIR=external$/libxml +CFLAGS+= -I$(SOLARINCDIR)$/$(LIBXMLINCDIR) +.ENDIF + +.IF "$(SYSTEM_LIBXSLT)" == "YES" +CFLAGS+= $(LIBXSLT_CFLAGS) +.ELSE +LIBXSLTINCDIR=external$/libxslt +CFLAGS+= -I$(SOLARINCDIR)$/$(LIBXSLTINCDIR) +.ENDIF + +.IF "$(GUI)"=="WNT" +CFLAGS+=-GR +.ENDIF + +# --- General ----------------------------------------------------- + +SLOFILES=\ + $(SLO)$/services.obj \ + $(SLO)$/provider.obj \ + $(SLO)$/content.obj \ + $(SLO)$/resultset.obj \ + $(SLO)$/resultsetbase.obj \ + $(SLO)$/resultsetforroot.obj \ + $(SLO)$/resultsetforquery.obj \ + $(SLO)$/contentcaps.obj \ + $(SLO)$/urlparameter.obj \ + $(SLO)$/inputstream.obj \ + $(SLO)$/databases.obj \ + $(SLO)$/db.obj \ + $(SLO)$/bufferedinputstream.obj + +# --- Targets ---------------------------------------------------------- + +.INCLUDE: target.mk + diff --git a/xmlhelp/source/cxxhelp/provider/provider.cxx b/xmlhelp/source/cxxhelp/provider/provider.cxx new file mode 100644 index 000000000000..9718d17c3844 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/provider.cxx @@ -0,0 +1,546 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: provider.cxx,v $ + * $Revision: 1.28 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" + +/************************************************************************** + TODO + ************************************************************************** + + *************************************************************************/ + +#include <stdio.h> +#include <osl/file.hxx> +#ifndef _VOS_DIAGNOSE_HXX_ +#include <vos/diagnose.hxx> +#endif +#include <ucbhelper/contentidentifier.hxx> +#include <com/sun/star/frame/XConfigManager.hpp> +#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_ +#include <com/sun/star/beans/PropertyAttribute.hpp> +#endif +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/PropertyState.hpp> +#include <com/sun/star/container/XContainer.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XNameReplace.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <rtl/bootstrap.hxx> + +#include "databases.hxx" +#include "provider.hxx" +#include "content.hxx" +#include "databases.hxx" + +using namespace com::sun::star; +using namespace chelp; + +//========================================================================= +//========================================================================= +// +// ContentProvider Implementation. +// +//========================================================================= +//========================================================================= + +ContentProvider::ContentProvider( + const uno::Reference< lang::XMultiServiceFactory >& rSMgr ) + : ::ucbhelper::ContentProviderImplHelper( rSMgr ), + isInitialized( false ), + m_aScheme( rtl::OUString::createFromAscii( MYUCP_URL_SCHEME ) ), + m_pDatabases( 0 ) +{ +} + +//========================================================================= +// virtual +ContentProvider::~ContentProvider() +{ + delete m_pDatabases; +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +XINTERFACE_IMPL_6( ContentProvider, + lang::XTypeProvider, + lang::XServiceInfo, + ucb::XContentProvider, + lang::XComponent, + lang::XEventListener, /* base of XContainerListener */ + container::XContainerListener); + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_IMPL_5( ContentProvider, + lang::XTypeProvider, + lang::XServiceInfo, + ucb::XContentProvider, + lang::XComponent, + container::XContainerListener); + +//========================================================================= +// +// XServiceInfo methods. +// +//========================================================================= + +rtl::OUString SAL_CALL ContentProvider::getImplementationName() + throw( uno::RuntimeException ) +{ + return getImplementationName_Static(); +} + +rtl::OUString ContentProvider::getImplementationName_Static() +{ + return rtl::OUString::createFromAscii("CHelpContentProvider" ); +} + +sal_Bool SAL_CALL +ContentProvider::supportsService(const rtl::OUString& ServiceName ) + throw( uno::RuntimeException ) +{ + uno::Sequence< rtl::OUString > aSNL = getSupportedServiceNames(); + const rtl::OUString* pArray = aSNL.getArray(); + for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) + { + if( pArray[ i ] == ServiceName ) + return sal_True; + } + + return sal_False; +} + +uno::Sequence< rtl::OUString > SAL_CALL +ContentProvider::getSupportedServiceNames() + throw( uno::RuntimeException ) +{ + return getSupportedServiceNames_Static(); +} + +static uno::Reference< uno::XInterface > SAL_CALL +ContentProvider_CreateInstance( + const uno::Reference< lang::XMultiServiceFactory> & rSMgr ) + throw( uno::Exception ) +{ + lang::XServiceInfo * pX = static_cast< lang::XServiceInfo * >( + new ContentProvider( rSMgr ) ); + return uno::Reference< uno::XInterface >::query( pX ); +} + +uno::Sequence< rtl::OUString > +ContentProvider::getSupportedServiceNames_Static() +{ + uno::Sequence< rtl::OUString > aSNS( 2 ); + aSNS.getArray()[ 0 ] = + rtl::OUString::createFromAscii( + MYUCP_CONTENT_PROVIDER_SERVICE_NAME1 ); + aSNS.getArray()[ 1 ] = + rtl::OUString::createFromAscii( + MYUCP_CONTENT_PROVIDER_SERVICE_NAME2 ); + + return aSNS; +} + +//========================================================================= +// +// Service factory implementation. +// +//========================================================================= + +ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider ); + +//========================================================================= +// +// XContentProvider methods. +// +//========================================================================= + +// virtual +uno::Reference< ucb::XContent > SAL_CALL +ContentProvider::queryContent( + const uno::Reference< ucb::XContentIdentifier >& xCanonicId ) + throw( ucb::IllegalIdentifierException, uno::RuntimeException ) +{ + if ( !xCanonicId->getContentProviderScheme() + .equalsIgnoreAsciiCase( m_aScheme ) ) + { // Wrong URL-scheme + throw ucb::IllegalIdentifierException(); + } + + { + osl::MutexGuard aGuard( m_aMutex ); + if( !isInitialized ) + init(); + } + + if( !m_pDatabases ) + throw uno::RuntimeException(); + + rtl::OUString aOUString( m_pDatabases->getInstallPathAsURL() ); + rtl::OString aOString( aOUString.getStr(), + aOUString.getLength(), + RTL_TEXTENCODING_UTF8 ); + + // Check, if a content with given id already exists... + uno::Reference< ucb::XContent > xContent + = queryExistingContent( xCanonicId ).get(); + if ( xContent.is() ) + return xContent; + + xContent = new Content( m_xSMgr, this, xCanonicId, m_pDatabases ); + + // register new content + registerNewContent( xContent ); + + // Further checks + + if ( !xContent->getIdentifier().is() ) + throw ucb::IllegalIdentifierException(); + + return xContent; +} + +void SAL_CALL +ContentProvider::dispose() + throw ( uno::RuntimeException) +{ + if(m_xContainer.is()) + { + m_xContainer->removeContainerListener(this); + m_xContainer.clear(); + } +} + +void SAL_CALL +ContentProvider::elementReplaced(const container::ContainerEvent& Event) + throw (uno::RuntimeException) +{ + if(!m_pDatabases) + return; + + rtl::OUString accessor; + Event.Accessor >>= accessor; + if(accessor.compareToAscii("HelpStyleSheet")) + return; + + rtl::OUString replacedElement,element; + Event.ReplacedElement >>= replacedElement; + Event.Element >>= element; + + if(replacedElement == element) + return; + + m_pDatabases->changeCSS(element); +} + +void ContentProvider::init() +{ + osl::MutexGuard aGuard( m_aMutex ); + + isInitialized = true; + uno::Reference< lang::XMultiServiceFactory > sProvider( + getConfiguration() ); + uno::Reference< container::XHierarchicalNameAccess > xHierAccess( + getHierAccess( sProvider, + "org.openoffice.Office.Common" ) ); + + rtl::OUString instPath( getKey( xHierAccess,"Path/Current/Help" ) ); + if( ! instPath.getLength() ) + // try to determine path from default + instPath = rtl::OUString::createFromAscii( "$(instpath)/help" ); + // replace anything like $(instpath); + subst( instPath ); + + rtl::OUString stylesheet( getKey( xHierAccess,"Help/HelpStyleSheet" ) ); + try + { + // now adding as configuration change listener for the stylesheet + uno::Reference< container::XNameAccess> xAccess( + xHierAccess, uno::UNO_QUERY ); + if( xAccess.is() ) + { + uno::Any aAny = + xAccess->getByName( rtl::OUString::createFromAscii( "Help" ) ); + aAny >>= m_xContainer; + if( m_xContainer.is() ) + m_xContainer->addContainerListener( this ); + } + } + catch( uno::Exception const & ) + { + } + + /** + * now determing + * productname, + * productversion, + * vendorname, + * vendorversion, + * vendorshort + */ + + xHierAccess = getHierAccess( sProvider, "org.openoffice.Setup" ); + rtl::OUString productname( + getKey( xHierAccess,"Product/ooName" ) ); + + rtl::OUString setupversion( + getKey( xHierAccess,"Product/ooSetupVersion" ) ); + rtl::OUString setupextension; + + try + { + uno::Reference< lang::XMultiServiceFactory > xConfigProvider( + m_xSMgr ->createInstance(::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), uno::UNO_QUERY_THROW); + + uno::Sequence < uno::Any > lParams(1); + beans::PropertyValue aParam ; + aParam.Name = ::rtl::OUString::createFromAscii("nodepath"); + aParam.Value <<= ::rtl::OUString::createFromAscii("/org.openoffice.Setup/Product"); + lParams[0] = uno::makeAny(aParam); + + // open it + uno::Reference< uno::XInterface > xCFG( xConfigProvider->createInstanceWithArguments( + ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"), + lParams) ); + + uno::Reference< container::XNameAccess > xDirectAccess(xCFG, uno::UNO_QUERY); + uno::Any aRet = xDirectAccess->getByName(::rtl::OUString::createFromAscii("ooSetupExtension")); + + aRet >>= setupextension; + } + catch ( uno::Exception& ) + { + } + + rtl::OUString productversion( + setupversion + + rtl::OUString::createFromAscii( " " ) + + setupextension ); + + xHierAccess = getHierAccess( sProvider, "org.openoffice.Webtop.Common" ); + rtl::OUString vendorname( + getKey( xHierAccess,"Product/ooName" ) ); + + setupversion = rtl::OUString( + getKey( xHierAccess,"Product/ooSetupVersion" ) ); + setupextension = rtl::OUString( + getKey( xHierAccess,"Product/ooSetupExtension") ); + rtl::OUString vendorversion( + setupversion + + rtl::OUString::createFromAscii( " " ) + + setupextension ); + rtl::OUString vendorshort = vendorname; + + uno::Sequence< rtl::OUString > aImagesZipPaths( 2 ); + xHierAccess = getHierAccess( sProvider, "org.openoffice.Office.Common" ); + + rtl::OUString aPath( getKey( xHierAccess, "Path/Current/UserConfig" ) ); + subst( aPath ); + aImagesZipPaths[ 0 ] = aPath; + + aPath = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/share/config")); + rtl::Bootstrap::expandMacros(aPath); + aImagesZipPaths[ 1 ] = aPath; + + uno::Reference< uno::XComponentContext > xContext; + uno::Reference< beans::XPropertySet > xProps( m_xSMgr, uno::UNO_QUERY ); + OSL_ASSERT( xProps.is() ); + if (xProps.is()) + { + xProps->getPropertyValue( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext; + OSL_ASSERT( xContext.is() ); + } + + sal_Bool showBasic = getBooleanKey(xHierAccess,"Help/ShowBasic"); + m_pDatabases = new Databases( showBasic, + instPath, + aImagesZipPaths, + productname, + productversion, + vendorname, + vendorversion, + vendorshort, + stylesheet, + xContext ); +} + +uno::Reference< lang::XMultiServiceFactory > +ContentProvider::getConfiguration() const +{ + uno::Reference< lang::XMultiServiceFactory > sProvider; + if( m_xSMgr.is() ) + { + uno::Any aAny; + aAny <<= rtl::OUString::createFromAscii( "plugin" ); + beans::PropertyValue aProp( + rtl::OUString::createFromAscii( "servertype" ), + -1, + aAny, + beans::PropertyState_DIRECT_VALUE ); + + uno::Sequence< uno::Any > seq(1); + seq[0] <<= aProp; + + try + { + rtl::OUString sProviderService = + rtl::OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationProvider" ); + sProvider = + uno::Reference< lang::XMultiServiceFactory >( + m_xSMgr->createInstanceWithArguments( + sProviderService,seq ), + uno::UNO_QUERY ); + } + catch( const uno::Exception& ) + { + OSL_ENSURE( sProvider.is(), "cant instantiate configuration" ); + } + } + + return sProvider; +} + +uno::Reference< container::XHierarchicalNameAccess > +ContentProvider::getHierAccess( + const uno::Reference< lang::XMultiServiceFactory >& sProvider, + const char* file ) const +{ + uno::Reference< container::XHierarchicalNameAccess > xHierAccess; + + if( sProvider.is() ) + { + uno::Sequence< uno::Any > seq( 1 ); + rtl::OUString sReaderService( + rtl::OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationAccess" ) ); + + seq[ 0 ] <<= rtl::OUString::createFromAscii( file ); + + try + { + xHierAccess = + uno::Reference< container::XHierarchicalNameAccess >( + sProvider->createInstanceWithArguments( + sReaderService, seq ), + uno::UNO_QUERY ); + } + catch( const uno::Exception& ) + { + } + } + return xHierAccess; +} + + + +rtl::OUString +ContentProvider::getKey( + const uno::Reference< container::XHierarchicalNameAccess >& xHierAccess, + const char* key ) const +{ + rtl::OUString instPath; + if( xHierAccess.is() ) + { + uno::Any aAny; + try + { + aAny = + xHierAccess->getByHierarchicalName( + rtl::OUString::createFromAscii( key ) ); + } + catch( const container::NoSuchElementException& ) + { + } + aAny >>= instPath; + } + return instPath; +} + +sal_Bool +ContentProvider::getBooleanKey( + const uno::Reference< container::XHierarchicalNameAccess >& xHierAccess, + const char* key ) const +{ + sal_Bool ret = sal_False; + if( xHierAccess.is() ) + { + uno::Any aAny; + try + { + aAny = + xHierAccess->getByHierarchicalName( + rtl::OUString::createFromAscii( key ) ); + } + catch( const container::NoSuchElementException& ) + { + } + aAny >>= ret; + } + return ret; +} + +void ContentProvider::subst( rtl::OUString& instpath ) const +{ + uno::Reference< frame::XConfigManager > xCfgMgr; + if( m_xSMgr.is() ) + { + try + { + xCfgMgr = + uno::Reference< frame::XConfigManager >( + m_xSMgr->createInstance( + rtl::OUString::createFromAscii( + "com.sun.star.config.SpecialConfigManager" ) ), + uno::UNO_QUERY ); + } + catch( const uno::Exception&) + { + OSL_ENSURE( xCfgMgr.is(), + "cant instantiate the special config manager " ); + } + } + + OSL_ENSURE( xCfgMgr.is(), "specialconfigmanager not found\n" ); + + if( xCfgMgr.is() ) + instpath = xCfgMgr->substituteVariables( instpath ); +} diff --git a/xmlhelp/source/cxxhelp/provider/provider.hxx b/xmlhelp/source/cxxhelp/provider/provider.hxx new file mode 100644 index 000000000000..faaac63d2e56 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/provider.hxx @@ -0,0 +1,190 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: provider.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _PROVIDER_HXX +#define _PROVIDER_HXX + +#include <rtl/ustring.hxx> +#include <osl/mutex.hxx> +#include <ucbhelper/providerhelper.hxx> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/container/XContainerListener.hpp> +#include <com/sun/star/container/XContainer.hpp> +#include <com/sun/star/lang/XComponent.hpp> + + +namespace chelp { + +//========================================================================= + +// UNO service name for the provider. This name will be used by the UCB to +// create instances of the provider. + +//#define MYUCP_CONTENT_PROVIDER_SERVICE_NAME "com.sun.star.ucb.CHelpContentProvider" +#define MYUCP_CONTENT_PROVIDER_SERVICE_NAME1 "com.sun.star.help.XMLHelp" +#define MYUCP_CONTENT_PROVIDER_SERVICE_NAME_LENGTH1 25 + +#define MYUCP_CONTENT_PROVIDER_SERVICE_NAME2 "com.sun.star.ucb.HelpContentProvider" +#define MYUCP_CONTENT_PROVIDER_SERVICE_NAME_LENGTH2 36 + +// URL scheme. This is the scheme the provider will be able to create +// contents for. The UCB will select the provider ( i.e. in order to create +// contents ) according to this scheme. + +#define MYUCP_URL_SCHEME "vnd.sun.star.help" +#define MYUCP_URL_SCHEME_LENGTH 18 +#define MYUCP_CONTENT_TYPE "application/vnd.sun.star.xmlhelp" // UCB Content Type. + +//========================================================================= + + + class Databases; + + + class ContentProvider : + public ::ucbhelper::ContentProviderImplHelper, + public ::com::sun::star::container::XContainerListener, + public ::com::sun::star::lang::XComponent + { + public: + ContentProvider( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rSMgr ); + + virtual ~ContentProvider(); + + // XInterface + XINTERFACE_DECL() + + // XTypeProvider + XTYPEPROVIDER_DECL() + + // XServiceInfo + XSERVICEINFO_DECL() + + // XContentProvider + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::ucb::XContent > SAL_CALL + queryContent( const ::com::sun::star::uno::Reference< + ::com::sun::star::ucb::XContentIdentifier >& Identifier ) + throw( ::com::sun::star::ucb::IllegalIdentifierException, + ::com::sun::star::uno::RuntimeException ); + + ////////////////////////////////////////////////////////////////////// + // Additional interfaces + ////////////////////////////////////////////////////////////////////// + + // XComponent + + virtual void SAL_CALL + dispose( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) + throw (::com::sun::star::uno::RuntimeException) + { + (void)xListener; + } + + virtual void SAL_CALL + removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) + throw (::com::sun::star::uno::RuntimeException) + { + (void)aListener; + } + + // XConainerListener ( deriver from XEventListener ) + + virtual void SAL_CALL + disposing( const ::com::sun::star::lang::EventObject& Source ) + throw (::com::sun::star::uno::RuntimeException) + { + (void)Source; + m_xContainer = com::sun::star::uno::Reference<com::sun::star::container::XContainer>(0); + } + + virtual void SAL_CALL + elementInserted( const ::com::sun::star::container::ContainerEvent& Event ) + throw (::com::sun::star::uno::RuntimeException) + { + (void)Event; + } + + virtual void SAL_CALL + elementRemoved( const ::com::sun::star::container::ContainerEvent& Event ) + throw (::com::sun::star::uno::RuntimeException) + { + (void)Event; + } + + virtual void SAL_CALL + elementReplaced( const ::com::sun::star::container::ContainerEvent& Event ) + throw (::com::sun::star::uno::RuntimeException); + + + ////////////////////////////////////////////////////////////////////// + // Non-interface methods. + ////////////////////////////////////////////////////////////////////// + + private: + + osl::Mutex m_aMutex; + bool isInitialized; + rtl::OUString m_aScheme; + Databases* m_pDatabases; + com::sun::star::uno::Reference<com::sun::star::container::XContainer> m_xContainer; + + // private methods + + void init(); + + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > + getConfiguration() const; + + ::com::sun::star::uno::Reference< ::com::sun::star::container::XHierarchicalNameAccess > + getHierAccess( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& sProvider, + const char* file ) const; + + ::rtl::OUString + getKey( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XHierarchicalNameAccess >& xHierAccess, + const char* key ) const; + + sal_Bool + getBooleanKey( + const ::com::sun::star::uno::Reference< + ::com::sun::star::container::XHierarchicalNameAccess >& xHierAccess, + const char* key) const; + + void subst( rtl::OUString& instpath ) const; + }; + +} + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/resultset.cxx b/xmlhelp/source/cxxhelp/provider/resultset.cxx new file mode 100644 index 000000000000..d7a000134200 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultset.cxx @@ -0,0 +1,93 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: resultset.cxx,v $ + * $Revision: 1.6 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <com/sun/star/sdbc/XResultSet.hpp> + +#include "resultset.hxx" +#include "resultsetfactory.hxx" + +using namespace com::sun::star::lang; +using namespace com::sun::star::sdbc; +using namespace com::sun::star::ucb; +using namespace com::sun::star::uno; + + +using namespace chelp; + +//========================================================================= +//========================================================================= +// +// DynamicResultSet Implementation. +// +//========================================================================= +//========================================================================= + +DynamicResultSet::DynamicResultSet( + const Reference< XMultiServiceFactory >& rxSMgr, + const vos::ORef< Content >& rxContent, + const OpenCommandArgument2& rCommand, + const Reference< XCommandEnvironment >& rxEnv, + ResultSetFactory* pFactory ) + : ResultSetImplHelper( rxSMgr, rCommand ), + m_xContent( rxContent ), + m_xEnv( rxEnv ), + m_pFactory( pFactory ) +{ +} + +DynamicResultSet::~DynamicResultSet() +{ + delete m_pFactory; +} + +//========================================================================= +// +// Non-interface methods. +// +//========================================================================= + +void DynamicResultSet::initStatic() +{ + m_xResultSet1 = Reference< XResultSet >( m_pFactory->createResultSet() ); +} + +//========================================================================= +void DynamicResultSet::initDynamic() +{ + m_xResultSet1 = Reference< XResultSet >( m_pFactory->createResultSet() ); + + m_xResultSet2 = m_xResultSet1; +} + + + + diff --git a/xmlhelp/source/cxxhelp/provider/resultset.hxx b/xmlhelp/source/cxxhelp/provider/resultset.hxx new file mode 100644 index 000000000000..37e15bd0c907 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultset.hxx @@ -0,0 +1,70 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: resultset.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _RESULTSET_HXX +#define _RESULTSET_HXX + +#include <ucbhelper/resultsethelper.hxx> +#include <vos/ref.hxx> + +#include "content.hxx" + +namespace chelp { + + class ResultSetFactory; + + class DynamicResultSet : public ::ucbhelper::ResultSetImplHelper + { + vos::ORef< Content > m_xContent; + com::sun::star::uno::Reference< + com::sun::star::ucb::XCommandEnvironment > m_xEnv; + ResultSetFactory* m_pFactory; + + private: + virtual void initStatic(); + virtual void initDynamic(); + + public: + DynamicResultSet( + const com::sun::star::uno::Reference< + com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + const vos::ORef< Content >& rxContent, + const com::sun::star::ucb::OpenCommandArgument2& rCommand, + const com::sun::star::uno::Reference< + com::sun::star::ucb::XCommandEnvironment >& rxEnv, + ResultSetFactory* pFactory ); + + ~DynamicResultSet(); + }; + +} + +#endif + diff --git a/xmlhelp/source/cxxhelp/provider/resultsetbase.cxx b/xmlhelp/source/cxxhelp/provider/resultsetbase.cxx new file mode 100644 index 000000000000..7a35afe25067 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultsetbase.cxx @@ -0,0 +1,659 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: resultsetbase.cxx,v $ + * $Revision: 1.10 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <ucbhelper/contentidentifier.hxx> +#include <com/sun/star/ucb/OpenMode.hpp> +#include <com/sun/star/uno/Reference.h> +#ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBBUTE_HPP_ +#include <com/sun/star/beans/PropertyAttribute.hpp> +#endif +#include <com/sun/star/ucb/ListActionType.hpp> +#include <com/sun/star/ucb/XSourceInitialization.hpp> +#include <ucbhelper/resultsetmetadata.hxx> + +#include "resultsetbase.hxx" + +using namespace chelp; +using namespace com::sun::star; + +ResultSetBase::ResultSetBase( const uno::Reference< lang::XMultiServiceFactory >& xMSF, + const uno::Reference< ucb::XContentProvider >& xProvider, + sal_Int32 nOpenMode, + const uno::Sequence< beans::Property >& seq, + const uno::Sequence< ucb::NumberedSortingInfo >& seqSort ) + : m_xMSF( xMSF ), + m_xProvider( xProvider ), + m_nRow( -1 ), + m_nWasNull( true ), + m_nOpenMode( nOpenMode ), + m_bRowCountFinal( true ), + m_sProperty( seq ), + m_sSortingInfo( seqSort ), + m_pDisposeEventListeners( 0 ), + m_pRowCountListeners( 0 ), + m_pIsFinalListeners( 0 ) +{ +} + +ResultSetBase::~ResultSetBase() +{ + delete m_pIsFinalListeners; + delete m_pRowCountListeners; + delete m_pDisposeEventListeners; +} + + +// XInterface + +void SAL_CALL +ResultSetBase::acquire( + void ) + throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL +ResultSetBase::release( + void ) + throw() +{ + OWeakObject::release(); +} + + + +uno::Any SAL_CALL +ResultSetBase::queryInterface( + const uno::Type& rType ) + throw( uno::RuntimeException ) +{ + uno::Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( lang::XComponent*, this), + SAL_STATIC_CAST( sdbc::XRow*, this), + SAL_STATIC_CAST( sdbc::XResultSet*, this), + SAL_STATIC_CAST( sdbc::XResultSetMetaDataSupplier*, this), + SAL_STATIC_CAST( beans::XPropertySet*, this ), + SAL_STATIC_CAST( ucb::XContentAccess*, this) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + + +// XComponent + + +void SAL_CALL +ResultSetBase::addEventListener( + const uno::Reference< lang::XEventListener >& Listener ) + throw( uno::RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( ! m_pDisposeEventListeners ) + m_pDisposeEventListeners = + new cppu::OInterfaceContainerHelper( m_aMutex ); + + m_pDisposeEventListeners->addInterface( Listener ); +} + + +void SAL_CALL +ResultSetBase::removeEventListener( + const uno::Reference< lang::XEventListener >& Listener ) + throw( uno::RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + if ( m_pDisposeEventListeners ) + m_pDisposeEventListeners->removeInterface( Listener ); +} + + + +void SAL_CALL +ResultSetBase::dispose() + throw( uno::RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + lang::EventObject aEvt; + aEvt.Source = static_cast< lang::XComponent * >( this ); + + if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() ) + { + m_pDisposeEventListeners->disposeAndClear( aEvt ); + } + if( m_pRowCountListeners && m_pRowCountListeners->getLength() ) + { + m_pRowCountListeners->disposeAndClear( aEvt ); + } + if( m_pIsFinalListeners && m_pIsFinalListeners->getLength() ) + { + m_pIsFinalListeners->disposeAndClear( aEvt ); + } +} + + + +// XResultSet + +sal_Bool SAL_CALL +ResultSetBase::next( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + sal_Bool test; + m_nRow++; + if( sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + test = true; + else + test = false; + return test; +} + + +sal_Bool SAL_CALL +ResultSetBase::isBeforeFirst( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return m_nRow == -1; +} + + +sal_Bool SAL_CALL +ResultSetBase::isAfterLast( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return sal::static_int_cast<sal_uInt32>( m_nRow ) >= m_aItems.size(); // Cannot happen, if m_aFolder.isOpen() +} + + +sal_Bool SAL_CALL +ResultSetBase::isFirst( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return m_nRow == 0; +} + + +sal_Bool SAL_CALL +ResultSetBase::isLast( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( sal::static_int_cast<sal_uInt32>( m_nRow ) == m_aItems.size() - 1 ) + return true; + else + return false; +} + + +void SAL_CALL +ResultSetBase::beforeFirst( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + m_nRow = -1; +} + + +void SAL_CALL +ResultSetBase::afterLast( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + m_nRow = m_aItems.size(); +} + + +sal_Bool SAL_CALL +ResultSetBase::first( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + m_nRow = -1; + return next(); +} + + +sal_Bool SAL_CALL +ResultSetBase::last( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + m_nRow = m_aItems.size() - 1; + return true; +} + + +sal_Int32 SAL_CALL +ResultSetBase::getRow( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + // Test, whether behind last row + if( -1 == m_nRow || sal::static_int_cast<sal_uInt32>( m_nRow ) >= m_aItems.size() ) + return 0; + else + return m_nRow+1; +} + + +sal_Bool SAL_CALL ResultSetBase::absolute( sal_Int32 row ) + throw( sdbc::SQLException, uno::RuntimeException) +{ + if( row >= 0 ) + m_nRow = row - 1; + else + { + last(); + m_nRow += ( row + 1 ); + if( m_nRow < -1 ) + m_nRow = -1; + } + + return 0<= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size(); +} + + + + +sal_Bool SAL_CALL +ResultSetBase::relative( + sal_Int32 row ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( isAfterLast() || isBeforeFirst() ) + throw sdbc::SQLException(); + + if( row > 0 ) + while( row-- ) + next(); + else if( row < 0 ) + while( row++ && m_nRow > -1 ) + previous(); + + return 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size(); +} + + + +sal_Bool SAL_CALL +ResultSetBase::previous( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ + if( sal::static_int_cast<sal_uInt32>( m_nRow ) > m_aItems.size() ) + m_nRow = m_aItems.size(); // Correct Handling of afterLast + if( 0 <= m_nRow ) -- m_nRow; + + return 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size(); +} + + +void SAL_CALL +ResultSetBase::refreshRow( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ +} + + +sal_Bool SAL_CALL +ResultSetBase::rowUpdated( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return false; +} + +sal_Bool SAL_CALL +ResultSetBase::rowInserted( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return false; +} + +sal_Bool SAL_CALL +ResultSetBase::rowDeleted( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + return false; +} + + +uno::Reference< uno::XInterface > SAL_CALL +ResultSetBase::getStatement( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + uno::Reference< uno::XInterface > test( 0 ); + return test; +} + + +// XCloseable + +void SAL_CALL +ResultSetBase::close( + void ) + throw( sdbc::SQLException, + uno::RuntimeException) +{ +} + + +rtl::OUString SAL_CALL +ResultSetBase::queryContentIdentifierString( + void ) + throw( uno::RuntimeException ) +{ + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aPath[m_nRow]; + else + return rtl::OUString(); +} + + +uno::Reference< ucb::XContentIdentifier > SAL_CALL +ResultSetBase::queryContentIdentifier( + void ) + throw( uno::RuntimeException ) +{ + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + { + rtl::OUString url = queryContentIdentifierString(); + if( ! m_aIdents[m_nRow].is() && url.getLength() ) + m_aIdents[m_nRow] = uno::Reference< ucb::XContentIdentifier >( + new ::ucbhelper::ContentIdentifier( m_xMSF,url ) ); + return m_aIdents[m_nRow]; + } + + return uno::Reference< ucb::XContentIdentifier >(); +} + + +uno::Reference< ucb::XContent > SAL_CALL +ResultSetBase::queryContent( + void ) + throw( uno::RuntimeException ) +{ + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_xProvider->queryContent( queryContentIdentifier() ); + else + return uno::Reference< ucb::XContent >(); +} + + + +class XPropertySetInfoImpl + : public cppu::OWeakObject, + public beans::XPropertySetInfo +{ +public: + + XPropertySetInfoImpl( const uno::Sequence< beans::Property >& aSeq ) + : m_aSeq( aSeq ) + { + } + + void SAL_CALL acquire( void ) + throw() + { + OWeakObject::acquire(); + } + + + void SAL_CALL release( void ) + throw() + { + OWeakObject::release(); + } + + uno::Any SAL_CALL queryInterface( const uno::Type& rType ) + throw( uno::RuntimeException ) + { + uno::Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( beans::XPropertySetInfo*, this ) ); + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); + } + + uno::Sequence< beans::Property > SAL_CALL getProperties() + throw( uno::RuntimeException ) + { + return m_aSeq; + } + + beans::Property SAL_CALL getPropertyByName( const ::rtl::OUString& aName ) + throw( beans::UnknownPropertyException, + uno::RuntimeException) + { + for( int i = 0; i < m_aSeq.getLength(); ++i ) + if( aName == m_aSeq[i].Name ) + return m_aSeq[i]; + throw beans::UnknownPropertyException(); + } + + sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& Name ) + throw( uno::RuntimeException ) + { + for( int i = 0; i < m_aSeq.getLength(); ++i ) + if( Name == m_aSeq[i].Name ) + return true; + return false; + } + +private: + + uno::Sequence< beans::Property > m_aSeq; +}; + + + +// XPropertySet +uno::Reference< beans::XPropertySetInfo > SAL_CALL +ResultSetBase::getPropertySetInfo() + throw( uno::RuntimeException) +{ + uno::Sequence< beans::Property > seq(2); + seq[0].Name = rtl::OUString::createFromAscii( "RowCount" ); + seq[0].Handle = -1; + seq[0].Type = getCppuType( static_cast< sal_Int32* >(0) ); + seq[0].Attributes = beans::PropertyAttribute::READONLY; + + seq[1].Name = rtl::OUString::createFromAscii( "IsRowCountFinal" ); + seq[1].Handle = -1; + seq[1].Type = getCppuType( static_cast< sal_Bool* >(0) ); + seq[1].Attributes = beans::PropertyAttribute::READONLY; + + //t + return uno::Reference< beans::XPropertySetInfo > ( new XPropertySetInfoImpl( seq ) ); +} + + + +void SAL_CALL ResultSetBase::setPropertyValue( + const rtl::OUString& aPropertyName, const uno::Any& aValue ) + throw( beans::UnknownPropertyException, + beans::PropertyVetoException, + lang::IllegalArgumentException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + (void)aValue; + + if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) || + aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) ) + return; + + throw beans::UnknownPropertyException(); +} + + +uno::Any SAL_CALL ResultSetBase::getPropertyValue( + const rtl::OUString& PropertyName ) + throw( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + if( PropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) ) + { + uno::Any aAny; + aAny <<= m_bRowCountFinal; + return aAny; + } + else if ( PropertyName == rtl::OUString::createFromAscii( "RowCount" ) ) + { + uno::Any aAny; + sal_Int32 count = m_aItems.size(); + aAny <<= count; + return aAny; + } + else + throw beans::UnknownPropertyException(); +} + + +void SAL_CALL ResultSetBase::addPropertyChangeListener( + const rtl::OUString& aPropertyName, + const uno::Reference< beans::XPropertyChangeListener >& xListener ) + throw( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) ) + { + osl::MutexGuard aGuard( m_aMutex ); + if ( ! m_pIsFinalListeners ) + m_pIsFinalListeners = + new cppu::OInterfaceContainerHelper( m_aMutex ); + + m_pIsFinalListeners->addInterface( xListener ); + } + else if ( aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) ) + { + osl::MutexGuard aGuard( m_aMutex ); + if ( ! m_pRowCountListeners ) + m_pRowCountListeners = + new cppu::OInterfaceContainerHelper( m_aMutex ); + m_pRowCountListeners->addInterface( xListener ); + } + else + throw beans::UnknownPropertyException(); +} + + +void SAL_CALL ResultSetBase::removePropertyChangeListener( + const rtl::OUString& aPropertyName, + const uno::Reference< beans::XPropertyChangeListener >& aListener ) + throw( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + if( aPropertyName == rtl::OUString::createFromAscii( "IsRowCountFinal" ) && + m_pIsFinalListeners ) + { + osl::MutexGuard aGuard( m_aMutex ); + m_pIsFinalListeners->removeInterface( aListener ); + } + else if ( aPropertyName == rtl::OUString::createFromAscii( "RowCount" ) && + m_pRowCountListeners ) + { + osl::MutexGuard aGuard( m_aMutex ); + m_pRowCountListeners->removeInterface( aListener ); + } + else + throw beans::UnknownPropertyException(); +} + + +void SAL_CALL ResultSetBase::addVetoableChangeListener( + const rtl::OUString& PropertyName, + const uno::Reference< beans::XVetoableChangeListener >& aListener ) + throw( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + (void)PropertyName; + (void)aListener; +} + + +void SAL_CALL ResultSetBase::removeVetoableChangeListener( + const rtl::OUString& PropertyName, + const uno::Reference< beans::XVetoableChangeListener >& aListener ) + throw( beans::UnknownPropertyException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + (void)PropertyName; + (void)aListener; +} + + + +// XResultSetMetaDataSupplier +uno::Reference< sdbc::XResultSetMetaData > SAL_CALL +ResultSetBase::getMetaData( + void ) + throw( sdbc::SQLException, + uno::RuntimeException ) +{ + ::ucbhelper::ResultSetMetaData* p = + new ::ucbhelper::ResultSetMetaData( + m_xMSF, m_sProperty ); + return uno::Reference< sdbc::XResultSetMetaData >( p ); +} diff --git a/xmlhelp/source/cxxhelp/provider/resultsetbase.hxx b/xmlhelp/source/cxxhelp/provider/resultsetbase.hxx new file mode 100644 index 000000000000..49d24f756b74 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultsetbase.hxx @@ -0,0 +1,579 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: resultsetbase.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _RESULTSETBASE_HXX +#define _RESULTSETBASE_HXX + +#ifndef INCLUDED_STL_VECTOR +#include <vector> +#define INCLUDED_STL_VECTOR +#endif +#include <cppuhelper/weak.hxx> +#include <cppuhelper/interfacecontainer.hxx> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/ucb/XContentAccess.hpp> +#include <com/sun/star/sdbc/XCloseable.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/sdbc/XResultSet.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> +#include <com/sun/star/ucb/NumberedSortingInfo.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> +#include <com/sun/star/ucb/XContentIdentifier.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/beans/Property.hpp> + + +namespace chelp { + + class ResultSetBase + : public cppu::OWeakObject, + public com::sun::star::lang::XComponent, + public com::sun::star::sdbc::XRow, + public com::sun::star::sdbc::XResultSet, + public com::sun::star::sdbc::XCloseable, + public com::sun::star::sdbc::XResultSetMetaDataSupplier, + public com::sun::star::beans::XPropertySet, + public com::sun::star::ucb::XContentAccess + { + public: + + ResultSetBase( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xMSF, + const com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider >& xProvider, + sal_Int32 nOpenMode, + const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& seq, + const com::sun::star::uno::Sequence< com::sun::star::ucb::NumberedSortingInfo >& seqSort ); + + virtual ~ResultSetBase(); + + // XInterface + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& aType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + // XComponent + virtual void SAL_CALL + dispose( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + addEventListener( + const com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >& xListener ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL + removeEventListener( const com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >& aListener ) + throw( com::sun::star::uno::RuntimeException ); + + + // XRow + virtual sal_Bool SAL_CALL + wasNull( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ) + { + if( 0<= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + m_nWasNull = m_aItems[m_nRow]->wasNull(); + else + m_nWasNull = true; + return m_nWasNull; + } + + virtual rtl::OUString SAL_CALL + getString( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getString( columnIndex ); + else + return rtl::OUString(); + } + + virtual sal_Bool SAL_CALL + getBoolean( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getBoolean( columnIndex ); + else + return false; + } + + virtual sal_Int8 SAL_CALL + getByte( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getByte( columnIndex ); + else + return sal_Int8( 0 ); + } + + virtual sal_Int16 SAL_CALL + getShort( + sal_Int32 columnIndex ) + throw( + com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getShort( columnIndex ); + else + return sal_Int16( 0 ); + } + + virtual sal_Int32 SAL_CALL + getInt( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getInt( columnIndex ); + else + return sal_Int32( 0 ); + } + + virtual sal_Int64 SAL_CALL + getLong( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getLong( columnIndex ); + else + return sal_Int64( 0 ); + } + + virtual float SAL_CALL + getFloat( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getFloat( columnIndex ); + else + return float( 0 ); + } + + virtual double SAL_CALL + getDouble( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getDouble( columnIndex ); + else + return double( 0 ); + } + + virtual com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL + getBytes( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException ) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getBytes( columnIndex ); + else + return com::sun::star::uno::Sequence< sal_Int8 >(); + } + + virtual com::sun::star::util::Date SAL_CALL + getDate( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getDate( columnIndex ); + else + return com::sun::star::util::Date(); + } + + virtual com::sun::star::util::Time SAL_CALL + getTime( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getTime( columnIndex ); + else + return com::sun::star::util::Time(); + } + + virtual com::sun::star::util::DateTime SAL_CALL + getTimestamp( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getTimestamp( columnIndex ); + else + return com::sun::star::util::DateTime(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL + getBinaryStream( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getBinaryStream( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::io::XInputStream >(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::io::XInputStream > SAL_CALL + getCharacterStream( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getCharacterStream( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::io::XInputStream >(); + } + + virtual com::sun::star::uno::Any SAL_CALL + getObject( + sal_Int32 columnIndex, + const com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& typeMap ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getObject( columnIndex,typeMap ); + else + return com::sun::star::uno::Any(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XRef > SAL_CALL + getRef( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getRef( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::sdbc::XRef >(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XBlob > SAL_CALL + getBlob( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getBlob( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::sdbc::XBlob >(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XClob > SAL_CALL + getClob( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getClob( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::sdbc::XClob >(); + } + + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XArray > SAL_CALL + getArray( + sal_Int32 columnIndex ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException) + { + if( 0 <= m_nRow && sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aItems.size() ) + return m_aItems[m_nRow]->getArray( columnIndex ); + else + return com::sun::star::uno::Reference< com::sun::star::sdbc::XArray >(); + } + + + // XResultSet + + virtual sal_Bool SAL_CALL + next( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + isBeforeFirst( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + isAfterLast( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + isFirst( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + isLast( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + beforeFirst( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + afterLast( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + first( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + last( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL + getRow( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + absolute( + sal_Int32 row ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + relative( + sal_Int32 rows ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + previous( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + refreshRow( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + rowUpdated( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + rowInserted( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + rowDeleted( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + + virtual com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL + getStatement( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + // XCloseable + + virtual void SAL_CALL + close( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + // XContentAccess + + virtual rtl::OUString SAL_CALL + queryContentIdentifierString( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > SAL_CALL + queryContentIdentifier( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Reference< com::sun::star::ucb::XContent > SAL_CALL + queryContent( + void ) + throw( com::sun::star::uno::RuntimeException ); + + // XResultSetMetaDataSupplier + virtual com::sun::star::uno::Reference< com::sun::star::sdbc::XResultSetMetaData > SAL_CALL + getMetaData( + void ) + throw( com::sun::star::sdbc::SQLException, + com::sun::star::uno::RuntimeException); + + + // XPropertySet + virtual com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL setPropertyValue( + const rtl::OUString& aPropertyName, + const com::sun::star::uno::Any& aValue ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::beans::PropertyVetoException, + com::sun::star::lang::IllegalArgumentException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Any SAL_CALL + getPropertyValue( + const rtl::OUString& PropertyName ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + addPropertyChangeListener( + const rtl::OUString& aPropertyName, + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertyChangeListener >& xListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + removePropertyChangeListener( + const rtl::OUString& aPropertyName, + const com::sun::star::uno::Reference< com::sun::star::beans::XPropertyChangeListener >& aListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + addVetoableChangeListener( + const rtl::OUString& PropertyName, + const com::sun::star::uno::Reference< com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL removeVetoableChangeListener( + const rtl::OUString& PropertyName, + const com::sun::star::uno::Reference< com::sun::star::beans::XVetoableChangeListener >& aListener ) + throw( com::sun::star::beans::UnknownPropertyException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + protected: + + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xMSF; + com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider > m_xProvider; + sal_Int32 m_nRow; + sal_Bool m_nWasNull; + sal_Int32 m_nOpenMode; + sal_Bool m_bRowCountFinal; + + typedef std::vector< com::sun::star::uno::Reference< com::sun::star::ucb::XContentIdentifier > > IdentSet; + typedef std::vector< com::sun::star::uno::Reference< com::sun::star::sdbc::XRow > > ItemSet; + typedef std::vector< rtl::OUString > PathSet; + + IdentSet m_aIdents; + ItemSet m_aItems; + PathSet m_aPath; + + com::sun::star::uno::Sequence< com::sun::star::beans::Property > m_sProperty; + com::sun::star::uno::Sequence< com::sun::star::ucb::NumberedSortingInfo > m_sSortingInfo; + + osl::Mutex m_aMutex; + cppu::OInterfaceContainerHelper* m_pDisposeEventListeners; + + cppu::OInterfaceContainerHelper* m_pRowCountListeners; + cppu::OInterfaceContainerHelper* m_pIsFinalListeners; + }; + + +} // end namespace fileaccess + + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/resultsetfactory.hxx b/xmlhelp/source/cxxhelp/provider/resultsetfactory.hxx new file mode 100644 index 000000000000..502fe162e54c --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultsetfactory.hxx @@ -0,0 +1,27 @@ +#ifndef _RESULTSETFACTORY_HXX +#define _RESULTSETFACTORY_HXX + + +#include "resultsetbase.hxx" + + +namespace chelp { + + class ResultSetBase; + + class ResultSetFactory + { + public: + + virtual ~ResultSetFactory() { }; + + virtual ResultSetBase* createResultSet() = 0; + }; + + + +} + + + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/resultsetforquery.cxx b/xmlhelp/source/cxxhelp/provider/resultsetforquery.cxx new file mode 100644 index 000000000000..5a16b3a8d8f8 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultsetforquery.cxx @@ -0,0 +1,452 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: resultsetforquery.cxx,v $ + * $Revision: 1.17 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <com/sun/star/ucb/Command.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/i18n/XExtendedTransliteration.hpp> +#include <com/sun/star/ucb/XCommandProcessor.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/script/XInvocation.hpp> + +#ifndef INCLUDED_STL_ALGORITHM +#include <algorithm> +#define INCLUDED_STL_ALGORITHM +#endif +#ifndef INCLUDED_STL_SET +#include <set> +#define INCLUDED_STL_SET +#endif + +#include <qe/Query.hxx>
+#include <qe/DocGenerator.hxx>
+#include "resultsetforquery.hxx" +#include "databases.hxx" + +// For testing +// #define LOGGING + +using namespace std; +using namespace chelp; +using namespace xmlsearch::excep; +using namespace xmlsearch::qe; +using namespace com::sun::star; +using namespace com::sun::star::ucb; +using namespace com::sun::star::i18n; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; + +struct HitItem +{ + rtl::OUString m_aURL; + float m_fScore; + + HitItem( void ) {} + HitItem( const rtl::OUString& aURL, float fScore ) + : m_aURL( aURL ) + , m_fScore( fScore ) + {} + bool operator < ( const HitItem& rHitItem ) const + { + return rHitItem.m_fScore < m_fScore; + } +}; + +ResultSetForQuery::ResultSetForQuery( const uno::Reference< lang::XMultiServiceFactory >& xMSF, + const uno::Reference< XContentProvider >& xProvider, + sal_Int32 nOpenMode, + const uno::Sequence< beans::Property >& seq, + const uno::Sequence< NumberedSortingInfo >& seqSort, + URLParameter& aURLParameter, + Databases* pDatabases ) + : ResultSetBase( xMSF,xProvider,nOpenMode,seq,seqSort ), + m_pDatabases( pDatabases ), + m_aURLParameter( aURLParameter ) +{ + Reference< XTransliteration > xTrans( + xMSF->createInstance( rtl::OUString::createFromAscii( "com.sun.star.i18n.Transliteration" ) ), + UNO_QUERY ); + Locale aLocale( aURLParameter.get_language(), + rtl::OUString(), + rtl::OUString() ); + if(xTrans.is()) + xTrans->loadModule(TransliterationModules_UPPERCASE_LOWERCASE, + aLocale ); + + // Access Lucene via XInvocation + Reference< script::XInvocation > xInvocation( + xMSF->createInstance( rtl::OUString::createFromAscii( "com.sun.star.help.HelpSearch" ) ), + UNO_QUERY ); + + vector< vector< rtl::OUString > > queryList; + { + sal_Int32 idx; + rtl::OUString query = m_aURLParameter.get_query(); + while( query.getLength() ) + { + idx = query.indexOf( sal_Unicode( ' ' ) ); + if( idx == -1 ) + idx = query.getLength(); + + vector< rtl::OUString > currentQuery; + rtl::OUString tmp(query.copy( 0,idx )); + rtl:: OUString toliterate = tmp; + if(xTrans.is()) { + Sequence<sal_Int32> aSeq; + toliterate = xTrans->transliterate( + tmp,0,tmp.getLength(),aSeq); + } + + currentQuery.push_back( toliterate ); + queryList.push_back( currentQuery ); + + int nCpy = 1 + idx; + if( nCpy >= query.getLength() ) + query = rtl::OUString(); + else + query = query.copy( 1 + idx ); + } + } + + vector< rtl::OUString > aCompleteResultVector; + if( xInvocation.is() ) + { + rtl::OUString scope = m_aURLParameter.get_scope(); + bool bCaptionsOnly = ( scope.compareToAscii( "Heading" ) == 0 ); + sal_Int32 hitCount = m_aURLParameter.get_hitCount(); + +#ifdef LOGGING + FILE* pFile = fopen( "d:\\resultset_out.txt", "w" ); +#endif + + IndexFolderIterator aIndexFolderIt( *pDatabases, m_aURLParameter.get_module(), m_aURLParameter.get_language() ); + rtl::OUString idxDir; + bool bExtension = false; + int iDir = 0; + vector< vector<HitItem>* > aIndexFolderResultVectorVector; + + bool bTemporary; + while( (idxDir = aIndexFolderIt.nextIndexFolder( bExtension, bTemporary )).getLength() > 0 ) + { + vector<HitItem> aIndexFolderResultVector; + + try + { + vector< vector<HitItem>* > aQueryListResultVectorVector; + set< rtl::OUString > aSet,aCurrent,aResultSet;
+
+ int nQueryListSize = queryList.size(); + if( nQueryListSize > 1 ) + hitCount = 2000; + + for( int i = 0; i < nQueryListSize; ++i ) + { + vector<HitItem>* pQueryResultVector; + if( nQueryListSize > 1 ) + { + pQueryResultVector = new vector<HitItem>(); + aQueryListResultVectorVector.push_back( pQueryResultVector ); + } + else + { + pQueryResultVector = &aIndexFolderResultVector; + } + pQueryResultVector->reserve( hitCount ); + + int nParamCount = bCaptionsOnly ? 7 : 6;
+ Sequence<uno::Any> aParamsSeq( nParamCount );
+
+ aParamsSeq[0] = uno::makeAny( rtl::OUString::createFromAscii( "-lang" ) );
+ aParamsSeq[1] = uno::makeAny( m_aURLParameter.get_language() );
+
+ aParamsSeq[2] = uno::makeAny( rtl::OUString::createFromAscii( "-index" ) );
+ rtl::OUString aSystemPath;
+ osl::FileBase::getSystemPathFromFileURL( idxDir, aSystemPath );
+ aParamsSeq[3] = uno::makeAny( aSystemPath );
+
+ aParamsSeq[4] = uno::makeAny( rtl::OUString::createFromAscii( "-query" ) );
+
+ const std::vector< rtl::OUString >& aListItem = queryList[i];
+ ::rtl::OUString aNewQueryStr = aListItem[0];
+ aParamsSeq[5] = uno::makeAny( aNewQueryStr );
+
+ if( bCaptionsOnly )
+ aParamsSeq[6] = uno::makeAny( rtl::OUString::createFromAscii( "-caption" ) );
+ + Sequence< sal_Int16 > aOutParamIndex; + Sequence< uno::Any > aOutParam; + + uno::Any aRet = xInvocation->invoke( rtl::OUString::createFromAscii( "search" ), + aParamsSeq, aOutParamIndex, aOutParam ); + + Sequence< float > aScoreSeq; + int nScoreCount = 0; + int nOutParamCount = aOutParam.getLength(); + if( nOutParamCount == 1 ) + { + const uno::Any* pScoreAnySeq = aOutParam.getConstArray(); + if( pScoreAnySeq[0] >>= aScoreSeq ) + nScoreCount = aScoreSeq.getLength(); + } + + Sequence<rtl::OUString> aRetSeq; + if( aRet >>= aRetSeq ) + { + if( nQueryListSize > 1 ) + aSet.clear(); + + const rtl::OUString* pRetSeq = aRetSeq.getConstArray(); + int nCount = aRetSeq.getLength(); + if( nCount > hitCount ) + nCount = hitCount; + for( int j = 0 ; j < nCount ; ++j ) + { + float fScore = 0.0; + if( j < nScoreCount ) + fScore = aScoreSeq[j]; + + rtl::OUString aURL = pRetSeq[j]; + pQueryResultVector->push_back( HitItem( aURL, fScore ) ); + if( nQueryListSize > 1 ) + aSet.insert( aURL ); + +#ifdef LOGGING + if( pFile ) + { + rtl::OString tmp(rtl::OUStringToOString( aURL, RTL_TEXTENCODING_UTF8)); + fprintf( pFile, "Dir %d, Query %d, Item: score=%f, URL=%s\n", iDir, i, fScore, tmp.getStr() ); + } +#endif + } + } + + // intersect
+ if( nQueryListSize > 1 ) + { + if( i == 0 )
+ {
+ aResultSet = aSet;
+ }
+ else
+ {
+ aCurrent = aResultSet;
+ aResultSet.clear();
+ set_intersection( aSet.begin(),aSet.end(),
+ aCurrent.begin(),aCurrent.end(),
+ inserter(aResultSet,aResultSet.begin()));
+ }
+ }
+ } + + // Combine results in aIndexFolderResultVector + if( nQueryListSize > 1 ) + { + for( int n = 0 ; n < nQueryListSize ; ++n ) + { + vector<HitItem>* pQueryResultVector = aQueryListResultVectorVector[n]; + vector<HitItem>& rQueryResultVector = *pQueryResultVector; + + int nItemCount = rQueryResultVector.size(); + for( int i = 0 ; i < nItemCount ; ++i ) + { + const HitItem& rItem = rQueryResultVector[ i ]; + set< rtl::OUString >::iterator it; + if( (it = aResultSet.find( rItem.m_aURL )) != aResultSet.end() ) + { + HitItem aItemCopy( rItem ); + aItemCopy.m_fScore /= nQueryListSize; // To get average score + if( n == 0 ) + { + // Use first pass to create entry + aIndexFolderResultVector.push_back( aItemCopy ); + +#ifdef LOGGING + if( pFile ) + { + rtl::OString tmp(rtl::OUStringToOString( aItemCopy.m_aURL, RTL_TEXTENCODING_UTF8)); + fprintf( pFile, "Combine: Query %d (first pass), Item %d: score=%f (%f), URL=%s\n", n, i, aItemCopy.m_fScore, rItem.m_fScore, tmp.getStr() ); + } +#endif + } + else + { + // Find entry in vector + int nCount = aIndexFolderResultVector.size(); + for( int j = 0 ; j < nCount ; ++j ) + { + HitItem& rFindItem = aIndexFolderResultVector[ j ]; + if( rFindItem.m_aURL.equals( aItemCopy.m_aURL ) ) + { +#ifdef LOGGING + if( pFile ) + { + rtl::OString tmp(rtl::OUStringToOString( aItemCopy.m_aURL, RTL_TEXTENCODING_UTF8)); + fprintf( pFile, "Combine: Query %d, Item %d: score=%f + %f = %f, URL=%s\n", n, i, + rFindItem.m_fScore, aItemCopy.m_fScore, rFindItem.m_fScore + aItemCopy.m_fScore, tmp.getStr() ); + } +#endif + + rFindItem.m_fScore += aItemCopy.m_fScore; + break; + } + } + } + } + } + + delete pQueryResultVector; + } + + sort( aIndexFolderResultVector.begin(), aIndexFolderResultVector.end() ); + } + + vector<HitItem>* pIndexFolderHitItemVector = new vector<HitItem>( aIndexFolderResultVector ); + aIndexFolderResultVectorVector.push_back( pIndexFolderHitItemVector ); + aIndexFolderResultVector.clear(); + } + catch( const Exception& ) + { + } + + ++iDir; + + if( bTemporary ) + aIndexFolderIt.deleteTempIndexFolder( idxDir ); + + } // Iterator + + + int nVectorCount = aIndexFolderResultVectorVector.size(); + vector<HitItem>::size_type* pCurrentVectorIndex = new vector<HitItem>::size_type[nVectorCount]; + for( int j = 0 ; j < nVectorCount ; ++j ) + pCurrentVectorIndex[j] = 0; + +#ifdef LOGGING + if( pFile ) + { + for( int k = 0 ; k < nVectorCount ; ++k ) + { + vector<HitItem>& rIndexFolderVector = *aIndexFolderResultVectorVector[k]; + int nItemCount = rIndexFolderVector.size(); + + fprintf( pFile, "Vector %d, %d elements\n", k, nItemCount ); + + for( int i = 0 ; i < nItemCount ; ++i ) + { + const HitItem& rItem = rIndexFolderVector[ i ]; + rtl::OString tmp(rtl::OUStringToOString(rItem.m_aURL, RTL_TEXTENCODING_UTF8)); + fprintf( pFile, " Item_vector%d, %d/%d: score=%f, URL=%s\n", k, i, nItemCount, rItem.m_fScore, tmp.getStr() ); + } + } + } +#endif + + sal_Int32 nTotalHitCount = m_aURLParameter.get_hitCount(); + sal_Int32 nHitCount = 0; + while( nHitCount < nTotalHitCount ) + { + int iVectorWithBestScore = -1; + float fBestScore = 0.0; + for( int k = 0 ; k < nVectorCount ; ++k ) + { + vector<HitItem>& rIndexFolderVector = *aIndexFolderResultVectorVector[k]; + if( pCurrentVectorIndex[k] < rIndexFolderVector.size() ) + { + const HitItem& rItem = rIndexFolderVector[ pCurrentVectorIndex[k] ]; + + if( fBestScore < rItem.m_fScore ) + { + fBestScore = rItem.m_fScore; + iVectorWithBestScore = k; + } + } + } + + if( iVectorWithBestScore == -1 ) // No item left at all + break; + + vector<HitItem>& rIndexFolderVector = *aIndexFolderResultVectorVector[iVectorWithBestScore]; + const HitItem& rItem = rIndexFolderVector[ pCurrentVectorIndex[iVectorWithBestScore] ]; + + pCurrentVectorIndex[iVectorWithBestScore]++; + + aCompleteResultVector.push_back( rItem.m_aURL ); + ++nHitCount; + } + + delete[] pCurrentVectorIndex; + for( int n = 0 ; n < nVectorCount ; ++n ) + { + vector<HitItem>* pIndexFolderVector = aIndexFolderResultVectorVector[n]; + delete pIndexFolderVector; + } + +#ifdef LOGGING + fclose( pFile ); +#endif + } + + sal_Int32 replIdx = rtl::OUString::createFromAscii( "#HLP#" ).getLength(); + rtl::OUString replWith = rtl::OUString::createFromAscii( "vnd.sun.star.help://" ); + + int nResultCount = aCompleteResultVector.size(); + for( int r = 0 ; r < nResultCount ; ++r ) + { + rtl::OUString aURL = aCompleteResultVector[r]; + rtl::OUString aResultStr = replWith + aURL.copy(replIdx); + m_aPath.push_back( aResultStr ); + } + + m_aItems.resize( m_aPath.size() ); + m_aIdents.resize( m_aPath.size() ); + + Command aCommand; + aCommand.Name = rtl::OUString::createFromAscii( "getPropertyValues" ); + aCommand.Argument <<= m_sProperty; + + for( m_nRow = 0; sal::static_int_cast<sal_uInt32>( m_nRow ) < m_aPath.size(); ++m_nRow ) + { + m_aPath[m_nRow] = + m_aPath[m_nRow] + + rtl::OUString::createFromAscii( "?Language=" ) + + m_aURLParameter.get_language() + + rtl::OUString::createFromAscii( "&System=" ) + + m_aURLParameter.get_system(); + + uno::Reference< XContent > content = queryContent(); + if( content.is() ) + { + uno::Reference< XCommandProcessor > cmd( content,uno::UNO_QUERY ); + cmd->execute( aCommand,0,uno::Reference< XCommandEnvironment >( 0 ) ) >>= m_aItems[m_nRow]; //TODO: check return value of operator >>= + } + } + m_nRow = 0xffffffff; +} diff --git a/xmlhelp/source/cxxhelp/provider/resultsetforquery.hxx b/xmlhelp/source/cxxhelp/provider/resultsetforquery.hxx new file mode 100644 index 000000000000..6a800b146b3f --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultsetforquery.hxx @@ -0,0 +1,68 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: resultsetforquery.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _RESULTSETFORQUERY_HXX +#define _RESULTSETFORQUERY_HXX + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> +#include <com/sun/star/beans/Property.hpp> +#include <com/sun/star/ucb/NumberedSortingInfo.hpp> + +#include "resultsetbase.hxx" +#include "urlparameter.hxx" + +namespace chelp { + + class Databases; + + class ResultSetForQuery + : public ResultSetBase + { + public: + + ResultSetForQuery( const com::sun::star::uno::Reference<com::sun::star::lang::XMultiServiceFactory>& xMSF, + const com::sun::star::uno::Reference<com::sun::star::ucb::XContentProvider>& xProvider, + sal_Int32 nOpenMode, + const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& seq, + const com::sun::star::uno::Sequence< com::sun::star::ucb::NumberedSortingInfo >& seqSort, + URLParameter& aURLParameter, + Databases* pDatabases ); + + + private: + + Databases* m_pDatabases; + URLParameter m_aURLParameter; + }; + +} + + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/resultsetforroot.cxx b/xmlhelp/source/cxxhelp/provider/resultsetforroot.cxx new file mode 100644 index 000000000000..3aa4892548a0 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultsetforroot.cxx @@ -0,0 +1,85 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: resultsetforroot.cxx,v $ + * $Revision: 1.8 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <com/sun/star/ucb/Command.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/ucb/XCommandProcessor.hpp> + +#include "resultsetforroot.hxx" +#include "databases.hxx" + +using namespace chelp; +using namespace com::sun::star; +using namespace com::sun::star::ucb; + + + +ResultSetForRoot::ResultSetForRoot( const uno::Reference< lang::XMultiServiceFactory >& xMSF, + const uno::Reference< XContentProvider >& xProvider, + sal_Int32 nOpenMode, + const uno::Sequence< beans::Property >& seq, + const uno::Sequence< NumberedSortingInfo >& seqSort, + URLParameter& aURLParameter, + Databases* pDatabases ) + : ResultSetBase( xMSF,xProvider,nOpenMode,seq,seqSort ), + m_aURLParameter( aURLParameter ), + m_pDatabases( pDatabases ) +{ + m_aPath = m_pDatabases->getModuleList( m_aURLParameter.get_language() ); + m_aItems.resize( m_aPath.size() ); + m_aIdents.resize( m_aPath.size() ); + + Command aCommand; + aCommand.Name = rtl::OUString::createFromAscii( "getPropertyValues" ); + aCommand.Argument <<= m_sProperty; + + for( sal_uInt32 i = 0; i < m_aPath.size(); ++i ) + { + m_aPath[i] = + rtl::OUString::createFromAscii( "vnd.sun.star.help://" ) + + m_aPath[i] + + rtl::OUString::createFromAscii( "?Language=" ) + + m_aURLParameter.get_language() + + rtl::OUString::createFromAscii( "&System=" ) + + m_aURLParameter.get_system(); + + m_nRow = sal_Int32( i ); + + uno::Reference< XContent > content = queryContent(); + if( content.is() ) + { + uno::Reference< XCommandProcessor > cmd( content,uno::UNO_QUERY ); + cmd->execute( aCommand,0,uno::Reference< XCommandEnvironment >( 0 ) ) >>= m_aItems[i]; //TODO: check return value of operator >>= + } + m_nRow = 0xffffffff; + } +} diff --git a/xmlhelp/source/cxxhelp/provider/resultsetforroot.hxx b/xmlhelp/source/cxxhelp/provider/resultsetforroot.hxx new file mode 100644 index 000000000000..d3920e5587bc --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/resultsetforroot.hxx @@ -0,0 +1,68 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: resultsetforroot.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _RESULTSETFORROOT_HXX +#define _RESULTSETFORROOT_HXX + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> +#include <com/sun/star/beans/Property.hpp> +#include <com/sun/star/ucb/NumberedSortingInfo.hpp> + +#include "resultsetbase.hxx" +#include "urlparameter.hxx" + +namespace chelp { + + class Databases; + + class ResultSetForRoot + : public ResultSetBase + { + public: + + ResultSetForRoot( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xMSF, + const com::sun::star::uno::Reference< com::sun::star::ucb::XContentProvider >& xProvider, + sal_Int32 nOpenMode, + const com::sun::star::uno::Sequence< com::sun::star::beans::Property >& seq, + const com::sun::star::uno::Sequence< com::sun::star::ucb::NumberedSortingInfo >& seqSort, + URLParameter& aURLParameter, + Databases* pDatabases ); + + + private: + + URLParameter m_aURLParameter; + Databases* m_pDatabases; + }; + +} + + +#endif diff --git a/xmlhelp/source/cxxhelp/provider/services.cxx b/xmlhelp/source/cxxhelp/provider/services.cxx new file mode 100644 index 000000000000..5d2ec412e3df --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/services.cxx @@ -0,0 +1,135 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: services.cxx,v $ + * $Revision: 1.8 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> + +#include "provider.hxx" + +using namespace com::sun::star; + +//========================================================================= +static sal_Bool writeInfo( + void * pRegistryKey, + const rtl::OUString & rImplementationName, + uno::Sequence< rtl::OUString > const & rServiceNames ) +{ + rtl::OUString aKeyName( rtl::OUString::createFromAscii( "/" ) ); + aKeyName += rImplementationName; + aKeyName += rtl::OUString::createFromAscii( "/UNO/SERVICES" ); + + uno::Reference< registry::XRegistryKey > xKey; + try + { + xKey = static_cast< registry::XRegistryKey * >( + pRegistryKey )->createKey( aKeyName ); + } + catch ( registry::InvalidRegistryException const & ) + { + } + + if ( !xKey.is() ) + return sal_False; + + sal_Bool bSuccess = sal_True; + + for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n ) + { + try + { + xKey->createKey( rServiceNames[ n ] ); + } + catch ( registry::InvalidRegistryException const & ) + { + bSuccess = sal_False; + break; + } + } + return bSuccess; +} + +//========================================================================= +extern "C" void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +//========================================================================= +extern "C" sal_Bool SAL_CALL component_writeInfo( + void * /*pServiceManager*/, void * pRegistryKey ) +{ + return pRegistryKey && + + ////////////////////////////////////////////////////////////////////// + // Write info into registry. + ////////////////////////////////////////////////////////////////////// + + writeInfo( pRegistryKey, + ::chelp::ContentProvider::getImplementationName_Static(), + ::chelp::ContentProvider::getSupportedServiceNames_Static() ); +} + +//========================================================================= +extern "C" void * SAL_CALL component_getFactory( + const sal_Char * pImplName, + void * pServiceManager, + void * /*pRegistryKey*/ ) +{ + void * pRet = 0; + + uno::Reference< lang::XMultiServiceFactory > xSMgr( + reinterpret_cast< lang::XMultiServiceFactory * >( pServiceManager ) ); + uno::Reference< lang::XSingleServiceFactory > xFactory; + + ////////////////////////////////////////////////////////////////////// + // Create factory, if implementation name matches. + ////////////////////////////////////////////////////////////////////// + + if ( ::chelp::ContentProvider::getImplementationName_Static(). + compareToAscii( pImplName ) == 0 ) + { + xFactory = ::chelp::ContentProvider::createServiceFactory( xSMgr ); + } + + ////////////////////////////////////////////////////////////////////// + + if ( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + + return pRet; +} + diff --git a/xmlhelp/source/cxxhelp/provider/urlparameter.cxx b/xmlhelp/source/cxxhelp/provider/urlparameter.cxx new file mode 100644 index 000000000000..b9521c85dc89 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/urlparameter.cxx @@ -0,0 +1,1251 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: urlparameter.cxx,v $ + * $Revision: 1.44 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" + +#define WORKAROUND_98119 + +#ifdef WORKAROUND_98119 +#include "bufferedinputstream.hxx" +#endif + +#include <string.h> +#ifndef _VOS_DIAGNOSE_HXX_ +#include <vos/diagnose.hxx> +#endif +#include <osl/thread.h> +#include <rtl/memory.h> +#include <osl/file.hxx> +#include <cppuhelper/weak.hxx> +#include <cppuhelper/queryinterface.hxx> +#include <comphelper/processfactory.hxx> +#include <rtl/uri.hxx> +#include <rtl/ustrbuf.hxx> +#include <libxslt/xslt.h> +#include <libxslt/transform.h> +#include <libxslt/xsltutils.h> +#include "db.hxx" +#include <com/sun/star/io/XActiveDataSink.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/ucb/OpenCommandArgument2.hpp> +#include <com/sun/star/ucb/OpenMode.hpp> +#include <com/sun/star/ucb/XCommandProcessor.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/ucb/XContentIdentifier.hpp> +#include <com/sun/star/ucb/XContentProvider.hpp> +#include <com/sun/star/ucb/XContentIdentifierFactory.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> + +#include "urlparameter.hxx" +#include "databases.hxx" + +namespace chelp { + + inline bool ascii_isDigit( sal_Unicode ch ) + { + return ((ch >= 0x0030) && (ch <= 0x0039)); + } + + inline bool ascii_isLetter( sal_Unicode ch ) + { + return ( ( (ch >= 0x0041) && (ch <= 0x005A) ) || + ( (ch >= 0x0061) && (ch <= 0x007A) ) ); + } + + inline bool isLetterOrDigit( sal_Unicode ch ) + { + return ascii_isLetter( ch ) || ascii_isDigit( ch ); + } + +} + +using namespace cppu; +using namespace com::sun::star::io; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::ucb; +using namespace com::sun::star::beans; +using namespace com::sun::star::container; +using namespace berkeleydbproxy; +using namespace chelp; + + +URLParameter::URLParameter( const rtl::OUString& aURL, + Databases* pDatabases ) + throw( com::sun::star::ucb::IllegalIdentifierException ) + : m_pDatabases( pDatabases ), + m_aURL( aURL ) +{ + init( false ); + parse(); +} + + +bool URLParameter::isErrorDocument() +{ + bool bErrorDoc = false; + + if( isFile() ) + { + Reference< XHierarchicalNameAccess > xNA = + m_pDatabases->findJarFileForPath( get_jar(), get_language(), get_path() ); + bErrorDoc = !xNA.is(); + } + + return bErrorDoc; +} + + +rtl::OString URLParameter::getByName( const char* par ) +{ + rtl::OUString val; + + if( strcmp( par,"Program" ) == 0 ) + val = get_program(); + else if( strcmp( par,"Database" ) == 0 ) + val = get_module(); + else if( strcmp( par,"DatabasePar" ) == 0 ) + val = get_dbpar(); + else if( strcmp( par,"Id" ) == 0 ) + val = get_id(); + else if( strcmp( par,"Path" ) == 0 ) + val = get_path(); + else if( strcmp( par,"Language" ) == 0 ) + val = get_language(); + else if( strcmp( par,"System" ) == 0 ) + val = get_system(); + else if( strcmp( par,"HelpPrefix" ) == 0 ) + val = get_prefix(); + + return rtl::OString( val.getStr(),val.getLength(),RTL_TEXTENCODING_UTF8 ); +} + + +rtl::OUString URLParameter::get_id() +{ + if( m_aId.compareToAscii("start") == 0 ) + { // module is set + StaticModuleInformation* inf = + m_pDatabases->getStaticInformationForModule( get_module(), + get_language() ); + if( inf ) + m_aId = inf->get_id(); + + m_bStart = true; + } + + return m_aId; +} + +rtl::OUString URLParameter::get_tag() +{ + if( isFile() ) + return get_the_tag(); + else + return m_aTag; +} + + +rtl::OUString URLParameter::get_title() +{ + if( isFile() ) + return get_the_title(); + else if( m_aModule.compareToAscii("") != 0 ) + { + StaticModuleInformation* inf = + m_pDatabases->getStaticInformationForModule( get_module(), + get_language() ); + if( inf ) + m_aTitle = inf->get_title(); + } + else // This must be the root + m_aTitle = rtl::OUString::createFromAscii("root"); + + return m_aTitle; +} + + +rtl::OUString URLParameter::get_language() +{ + if( m_aLanguage.getLength() == 0 ) + return m_aDefaultLanguage; + + return m_aLanguage; +} + + +rtl::OUString URLParameter::get_program() +{ + if( ! m_aProgram.getLength() ) + { + StaticModuleInformation* inf = + m_pDatabases->getStaticInformationForModule( get_module(), + get_language() ); + if( inf ) + m_aProgram = inf->get_program(); + } + return m_aProgram; +} + + +void URLParameter::init( bool bDefaultLanguageIsInitialized ) +{ + (void)bDefaultLanguageIsInitialized; + + m_bBerkeleyRead = false; + m_bStart = false; + m_bUseDB = true; + m_nHitCount = 100; // The default maximum hitcount +} + + +rtl::OUString URLParameter::get_the_tag() +{ + if(m_bUseDB) { + if( ! m_bBerkeleyRead ) + readBerkeley(); + + m_bBerkeleyRead = true; + + return m_aTag; + } + else + return rtl::OUString(); +} + + + +rtl::OUString URLParameter::get_the_path() +{ + if(m_bUseDB) { + if( ! m_bBerkeleyRead ) + readBerkeley(); + m_bBerkeleyRead = true; + + return m_aPath; + } + else + return get_id(); +} + + + +rtl::OUString URLParameter::get_the_title() +{ + if(m_bUseDB) { + if( ! m_bBerkeleyRead ) + readBerkeley(); + m_bBerkeleyRead = true; + + return m_aTitle; + } + else + return rtl::OUString(); +} + + +rtl::OUString URLParameter::get_the_jar() +{ + if(m_bUseDB) { + if( ! m_bBerkeleyRead ) + readBerkeley(); + m_bBerkeleyRead = true; + + return m_aJar; + } + else + return get_module() + rtl::OUString::createFromAscii(".jar"); +} + + + + +void URLParameter::readBerkeley() +{ + static rtl::OUString aQuestionMark( rtl::OUString::createFromAscii( "?" ) ); + + if( get_id().compareToAscii("") == 0 ) + return; + + rtl::OUString aModule = get_module(); + rtl::OUString aLanguage = get_language(); + + DataBaseIterator aDbIt( *m_pDatabases, aModule, aLanguage, false ); + bool bSuccess = false; + + int nSize = 0; + const sal_Char* pData = NULL; + + Dbt data; + DBData aDBData; + rtl::OUString aExtensionPath; + while( true ) + { + Db* db = aDbIt.nextDb( &aExtensionPath ); + if( !db ) + break; + + rtl::OString keyStr( m_aId.getStr(),m_aId.getLength(),RTL_TEXTENCODING_UTF8 ); + + DBHelp* pDBHelp = db->getDBHelp(); + if( pDBHelp != NULL ) + { + bSuccess = pDBHelp->getValueForKey( keyStr, aDBData ); + if( bSuccess ) + { + nSize = aDBData.getSize(); + pData = aDBData.getData(); + break; + } + } + else + { + Dbt key( static_cast< void* >( const_cast< sal_Char* >( keyStr.getStr() ) ), + keyStr.getLength() ); + int err = db->get( 0,&key,&data,0 ); + if( err == 0 ) + { + bSuccess = true; + nSize = data.get_size(); + pData = static_cast<sal_Char*>( data.get_data() ); + break; + } + } + } + + if( bSuccess ) + { + DbtToStringConverter converter( pData, nSize ); + m_aTitle = converter.getTitle(); + m_pDatabases->replaceName( m_aTitle ); + m_aPath = converter.getFile(); + m_aJar = converter.getDatabase(); + if( aExtensionPath.getLength() > 0 ) + { + rtl::OUStringBuffer aExtendedJarStrBuf; + aExtendedJarStrBuf.append( aQuestionMark ); + aExtendedJarStrBuf.append( aExtensionPath ); + aExtendedJarStrBuf.append( aQuestionMark ); + aExtendedJarStrBuf.append( m_aJar ); + m_aJar = aExtendedJarStrBuf.makeStringAndClear(); + } + m_aTag = converter.getHash(); + } +} + + + +// Class encapsulating the transformation of the XInputStream to XHTML + + +class InputStreamTransformer + : public OWeakObject, + public XInputStream, + public XSeekable +{ +public: + + InputStreamTransformer( URLParameter* urlParam, + Databases* pDatatabases, + bool isRoot = false ); + + ~InputStreamTransformer(); + + virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException ); + virtual void SAL_CALL acquire( void ) throw(); + virtual void SAL_CALL release( void ) throw(); + + virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException); + + virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException); + + virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException ); + + virtual sal_Int32 SAL_CALL available( void ) throw( NotConnectedException, + IOException, + RuntimeException ); + + virtual void SAL_CALL closeInput( void ) throw( NotConnectedException, + IOException, + RuntimeException ); + + virtual void SAL_CALL seek( sal_Int64 location ) throw( IllegalArgumentException, + IOException, + RuntimeException ); + + virtual sal_Int64 SAL_CALL getPosition( void ) throw( IOException,RuntimeException ); + + virtual sal_Int64 SAL_CALL getLength( void ) throw( IOException,RuntimeException ); + + void addToBuffer( const char* buffer,int len ); + + sal_Int8* getData() const { return (sal_Int8*) buffer; } + + sal_Int32 getLen() const { return sal_Int32( len ); } + +private: + + osl::Mutex m_aMutex; + + int len,pos; + char *buffer; +}; + + + +void URLParameter::open( const Reference< XMultiServiceFactory >& rxSMgr, + const Command& aCommand, + sal_Int32 CommandId, + const Reference< XCommandEnvironment >& Environment, + const Reference< XOutputStream >& xDataSink ) +{ + (void)rxSMgr; + (void)aCommand; + (void)CommandId; + (void)Environment; + + if( ! xDataSink.is() ) + return; + + if( isPicture() ) + { + Reference< XInputStream > xStream; + Reference< XHierarchicalNameAccess > xNA = + m_pDatabases->jarFile( rtl::OUString::createFromAscii( "picture.jar" ), + get_language() ); + + rtl::OUString path = get_path(); + if( xNA.is() ) + { + try + { + Any aEntry = xNA->getByHierarchicalName( path ); + Reference< XActiveDataSink > xSink; + if( ( aEntry >>= xSink ) && xSink.is() ) + xStream = xSink->getInputStream(); + } + catch ( NoSuchElementException & ) + { + } + } + if( xStream.is() ) + { + sal_Int32 ret; + Sequence< sal_Int8 > aSeq( 4096 ); + while( true ) + { + try + { + ret = xStream->readBytes( aSeq,4096 ); + xDataSink->writeBytes( aSeq ); + if( ret < 4096 ) + break; + } + catch( const Exception& ) + { + break; + } + } + } + } + else + { + // a standard document or else an active help text, plug in the new input stream + InputStreamTransformer* p = new InputStreamTransformer( this,m_pDatabases,isRoot() ); + try + { + xDataSink->writeBytes( Sequence< sal_Int8 >( p->getData(),p->getLen() ) ); + } + catch( const Exception& ) + { + } + delete p; + } + xDataSink->closeOutput(); +} + + + +void URLParameter::open( const Reference< XMultiServiceFactory >& rxSMgr, + const Command& aCommand, + sal_Int32 CommandId, + const Reference< XCommandEnvironment >& Environment, + const Reference< XActiveDataSink >& xDataSink ) +{ + (void)rxSMgr; + (void)aCommand; + (void)CommandId; + (void)Environment; + + if( isPicture() ) + { + Reference< XInputStream > xStream; + Reference< XHierarchicalNameAccess > xNA = + m_pDatabases->jarFile( rtl::OUString::createFromAscii( "picture.jar" ), + get_language() ); + + rtl::OUString path = get_path(); + if( xNA.is() ) + { + try + { + Any aEntry = xNA->getByHierarchicalName( path ); + Reference< XActiveDataSink > xSink; + if( ( aEntry >>= xSink ) && xSink.is() ) + xStream = xSink->getInputStream(); + } + catch ( NoSuchElementException & ) + { + } + } +#ifdef WORKAROUND_98119 + xDataSink->setInputStream( turnToSeekable(xStream) ); +#else + xDataSink->setInputStream( xStream ); +#endif + } + else + // a standard document or else an active help text, plug in the new input stream + xDataSink->setInputStream( new InputStreamTransformer( this,m_pDatabases,isRoot() ) ); +} + + +// #include <stdio.h> + +void URLParameter::parse() throw( com::sun::star::ucb::IllegalIdentifierException ) +{ + // fprintf(stdout,"url send to xmlhelp: %s\n",(rtl::OUStringToOString(m_aURL,RTL_TEXTENCODING_UTF8).getStr())); + m_aExpr = m_aURL; + + sal_Int32 lstIdx = m_aExpr.lastIndexOf( sal_Unicode( '#' ) ); + if( lstIdx != -1 ) + m_aExpr = m_aExpr.copy( 0,lstIdx ); + + if( ! scheme() || + ! name( module() ) || + ! query() || + ! m_aLanguage.getLength() || + ! m_aSystem.getLength() ) + throw com::sun::star::ucb::IllegalIdentifierException(); +} + + +bool URLParameter::scheme() +{ + // Correct extension help links as sometimes the + // module is missing resulting in a misformed URL + if( m_aExpr.compareToAscii( "vnd.sun.star.help:///", 21 ) == 0 ) + { + sal_Int32 nLen = m_aExpr.getLength(); + rtl::OUString aLastStr = m_aExpr.copy( nLen - 6 ); + if( aLastStr.compareToAscii( "DbPAR=" ) == 0 ) + { + rtl::OUString aNewExpr = m_aExpr.copy( 0, 20 ); + rtl::OUString aSharedStr = rtl::OUString::createFromAscii( "shared" ); + aNewExpr += aSharedStr; + aNewExpr += m_aExpr.copy( 20 ); + aNewExpr += aSharedStr; + m_aExpr = aNewExpr; + } + } + + for( sal_Int32 nPrefixLen = 20 ; nPrefixLen >= 18 ; --nPrefixLen ) + { + if( m_aExpr.compareToAscii( "vnd.sun.star.help://", nPrefixLen ) == 0 ) + { + m_aExpr = m_aExpr.copy( nPrefixLen ); + return true; + } + } + return false; +} + + +bool URLParameter::module() +{ + sal_Int32 idx = 0,length = m_aExpr.getLength(); + + while( idx < length && isLetterOrDigit( (m_aExpr.getStr())[idx] ) ) + ++idx; + + if( idx != 0 ) + { + m_aModule = m_aExpr.copy( 0,idx ); + m_aExpr = m_aExpr.copy( idx ); + return true; + } + else + return false; +} + + + +bool URLParameter::name( bool modulePresent ) +{ + // if modulepresent, a name may be present, but must not + + sal_Int32 length = m_aExpr.getLength(); + + if( length != 0 && (m_aExpr.getStr())[0] == sal_Unicode( '/' ) ) + { + sal_Int32 idx = 1; + while( idx < length && (m_aExpr.getStr())[idx] != '?' ) +// ( isLetterOrDigit( (m_aExpr.getStr())[idx] ) +// || (m_aExpr.getStr())[idx] == '/' +// || (m_aExpr.getStr())[idx] == '.' )) + ++idx; + + if( idx != 1 && ! modulePresent ) + return false; + else + { + m_aId = m_aExpr.copy( 1,idx-1 ); + m_aExpr = m_aExpr.copy( idx ); + } + } + +// fprintf(stdout,"id %s\n",(rtl::OUStringToOString(m_aId,RTL_TEXTENCODING_UTF8).getStr())); + return true; +} + + +bool URLParameter::query() +{ + rtl::OUString query_; + + if( ! m_aExpr.getLength() ) + return true; + else if( (m_aExpr.getStr())[0] == sal_Unicode( '?' ) ) + query_ = m_aExpr.copy( 1 ).trim(); + else + return false; + + + bool ret = true; + sal_Int32 delimIdx,equalIdx; + rtl::OUString parameter,value; + + while( query_.getLength() != 0 ) + { + delimIdx = query_.indexOf( sal_Unicode( '&' ) ); + equalIdx = query_.indexOf( sal_Unicode( '=' ) ); + parameter = query_.copy( 0,equalIdx ).trim(); + if( delimIdx == -1 ) + { + value = query_.copy( equalIdx + 1 ).trim(); + query_ = rtl::OUString(); + } + else + { + value = query_.copy( equalIdx+1,delimIdx - equalIdx - 1 ).trim(); + query_ = query_.copy( delimIdx+1 ).trim(); + } + + if( parameter.compareToAscii( "Language" ) == 0 ) + m_aLanguage = value; + else if( parameter.compareToAscii( "Device" ) == 0 ) + m_aDevice = value; + else if( parameter.compareToAscii( "Program" ) == 0 ) + m_aProgram = value; + else if( parameter.compareToAscii( "Eid" ) == 0 ) + m_aEid = value; + else if( parameter.compareToAscii( "UseDB" ) == 0 ) + m_bUseDB = ! ( value.compareToAscii("no") == 0 ); + else if( parameter.compareToAscii( "DbPAR" ) == 0 ) + m_aDbPar = value; + else if( parameter.compareToAscii( "Query" ) == 0 ) + { + if( ! m_aQuery.getLength() ) + m_aQuery = value; + else + m_aQuery += ( rtl::OUString::createFromAscii( " " ) + value ); + } + else if( parameter.compareToAscii( "Scope" ) == 0 ) + m_aScope = value; + else if( parameter.compareToAscii( "System" ) == 0 ) + m_aSystem = value; + else if( parameter.compareToAscii( "HelpPrefix" ) == 0 ) + m_aPrefix = rtl::Uri::decode( + value, + rtl_UriDecodeWithCharset, + RTL_TEXTENCODING_UTF8 ); + else if( parameter.compareToAscii( "HitCount" ) == 0 ) + m_nHitCount = value.toInt32(); + else if( parameter.compareToAscii( "Active" ) == 0 ) + m_aActive = value; + else + ret = false; + } + + return ret; +} + +struct UserData { + + UserData( InputStreamTransformer* pTransformer, + URLParameter* pInitial, + Databases* pDatabases ) + : m_pTransformer( pTransformer ), + m_pDatabases( pDatabases ), + m_pInitial( pInitial ) + { + } + + InputStreamTransformer* m_pTransformer; + Databases* m_pDatabases; + URLParameter* m_pInitial; +}; + +UserData *ugblData = 0; + +extern "C" { + +static int +fileMatch(const char * URI) { + if ((URI != NULL) && !strncmp(URI, "file:/", 6)) + return 1; + return 0; +} + +static int +zipMatch(const char * URI) { + if ((URI != NULL) && !strncmp(URI, "vnd.sun.star.zip:/", 18)) + return 1; + return 0; +} + +static int +helpMatch(const char * URI) { + if ((URI != NULL) && !strncmp(URI, "vnd.sun.star.help:/", 19)) + return 1; + return 0; +} + +static void * +fileOpen(const char *URI) { + osl::File *pRet = new osl::File(rtl::OUString(URI, strlen(URI), RTL_TEXTENCODING_UTF8)); + pRet->open(OpenFlag_Read); + return pRet; +} + +static void * +zipOpen(const char * /*URI*/) { + rtl::OUString language,jar,path; + + if( ugblData->m_pInitial->get_eid().getLength() ) + return (void*)(new Reference< XHierarchicalNameAccess >); + else + { + jar = ugblData->m_pInitial->get_jar(); + language = ugblData->m_pInitial->get_language(); + path = ugblData->m_pInitial->get_path(); + } + + Reference< XHierarchicalNameAccess > xNA = + ugblData->m_pDatabases->findJarFileForPath( jar, language, path ); + + Reference< XInputStream > xInputStream; + + if( xNA.is() ) + { + try + { + Any aEntry = xNA->getByHierarchicalName( path ); + Reference< XActiveDataSink > xSink; + if( ( aEntry >>= xSink ) && xSink.is() ) + xInputStream = xSink->getInputStream(); + } + catch ( NoSuchElementException & ) + { + } + } + + if( xInputStream.is() ) + { + return new Reference<XInputStream>(xInputStream); + } + return 0; +} + +static void * +helpOpen(const char * URI) { + rtl::OUString language,jar,path; + + URLParameter urlpar( rtl::OUString::createFromAscii( URI ), + ugblData->m_pDatabases ); + + jar = urlpar.get_jar(); + language = urlpar.get_language(); + path = urlpar.get_path(); + + Reference< XHierarchicalNameAccess > xNA = + ugblData->m_pDatabases->findJarFileForPath( jar, language, path ); + + Reference< XInputStream > xInputStream; + + if( xNA.is() ) + { + try + { + Any aEntry = xNA->getByHierarchicalName( path ); + Reference< XActiveDataSink > xSink; + if( ( aEntry >>= xSink ) && xSink.is() ) + xInputStream = xSink->getInputStream(); + } + catch ( NoSuchElementException & ) + { + } + } + + if( xInputStream.is() ) + return new Reference<XInputStream>(xInputStream); + return 0; +} + +static int +helpRead(void * context, char * buffer, int len) { + Reference< XInputStream > *pRef = (Reference< XInputStream >*)context; + + Sequence< sal_Int8 > aSeq; + len = (*pRef)->readBytes( aSeq,len); + memcpy(buffer, aSeq.getConstArray(), len); + + return len; +} + +static int +zipRead(void * context, char * buffer, int len) { + if( ugblData->m_pInitial->get_eid().getLength() ) + { + ugblData->m_pDatabases->popupDocument( ugblData->m_pInitial,&buffer,&len); + return len; + } + else + return helpRead(context, buffer, len); +} + +static int +fileRead(void * context, char * buffer, int len) { + int nRead = 0; + osl::File *pFile = (osl::File*)context; + if (pFile) + { + sal_uInt64 uRead = 0; + if (osl::FileBase::E_None == pFile->read(buffer, len, uRead)) + nRead = static_cast<int>(uRead); + } + return nRead; +} + +static int +uriClose(void * context) { + Reference< XInputStream > *pRef = (Reference< XInputStream >*)context; + delete pRef; + return 0; +} + +static int +fileClose(void * context) { + osl::File *pFile = (osl::File*)context; + if (pFile) + { + pFile->close(); + delete pFile; + } + return 0; +} + +} // extern "C" + +/* +// For debugging only +extern "C" void StructuredXMLErrorFunction(void *userData, xmlErrorPtr error) +{ + (void)userData; + (void)error; + + // Reset error handler + xmlSetStructuredErrorFunc( NULL, NULL ); +} +*/ + +InputStreamTransformer::InputStreamTransformer( URLParameter* urlParam, + Databases* pDatabases, + bool isRoot ) + : len( 0 ), + pos( 0 ), + buffer( new char[1] ) // Initializing with one element to avoid gcc compiler warning +{ + if( isRoot ) + { + delete[] buffer; + pDatabases->cascadingStylesheet( urlParam->get_language(), + &buffer, + &len ); + } + else if( urlParam->isActive() ) + { + delete[] buffer; + pDatabases->setActiveText( urlParam->get_module(), + urlParam->get_language(), + urlParam->get_id(), + &buffer, + &len ); + } + else + { + UserData userData( this,urlParam,pDatabases ); + + // Uses the implementation detail, that rtl::OString::getStr returns a zero terminated character-array + + const char* parameter[47]; + rtl::OString parString[46]; + int last = 0; + + parString[last++] = "Program"; + rtl::OString aPureProgramm( urlParam->getByName( "Program" ) ); + parString[last++] = rtl::OString('\'') + aPureProgramm + rtl::OString('\''); + parString[last++] = "Database"; + parString[last++] = rtl::OString('\'') + urlParam->getByName( "DatabasePar" ) + rtl::OString('\''); + parString[last++] = "Id"; + parString[last++] = rtl::OString('\'') + urlParam->getByName( "Id" ) + rtl::OString('\''); + parString[last++] = "Path"; + rtl::OString aPath( urlParam->getByName( "Path" ) ); + parString[last++] = rtl::OString('\'') + aPath + rtl::OString('\''); + + rtl::OString aPureLanguage = urlParam->getByName( "Language" ); + parString[last++] = "Language"; + parString[last++] = rtl::OString('\'') + aPureLanguage + rtl::OString('\''); + parString[last++] = "System"; + parString[last++] = rtl::OString('\'') + urlParam->getByName( "System" ) + rtl::OString('\''); + parString[last++] = "productname"; + parString[last++] = rtl::OString('\'') + rtl::OString( + pDatabases->getProductName().getStr(), + pDatabases->getProductName().getLength(), + RTL_TEXTENCODING_UTF8 ) + rtl::OString('\''); + parString[last++] = "productversion"; + parString[last++] = rtl::OString('\'') + + rtl::OString( pDatabases->getProductVersion().getStr(), + pDatabases->getProductVersion().getLength(), + RTL_TEXTENCODING_UTF8 ) + rtl::OString('\''); + + parString[last++] = "imgrepos"; + parString[last++] = rtl::OString('\'') + pDatabases->getImagesZipFileURL() + rtl::OString('\''); + parString[last++] = "hp"; + parString[last++] = rtl::OString('\'') + urlParam->getByName( "HelpPrefix" ) + rtl::OString('\''); + + if( parString[last-1].getLength() ) + { + parString[last++] = "sm"; + parString[last++] = "'vnd.sun.star.help%3A%2F%2F'"; + parString[last++] = "qm"; + parString[last++] = "'%3F'"; + parString[last++] = "es"; + parString[last++] = "'%3D'"; + parString[last++] = "am"; + parString[last++] = "'%26'"; + parString[last++] = "cl"; + parString[last++] = "'%3A'"; + parString[last++] = "sl"; + parString[last++] = "'%2F'"; + parString[last++] = "hm"; + parString[last++] = "'%23'"; + parString[last++] = "cs"; + parString[last++] = "'css'"; + + parString[last++] = "vendorname"; + parString[last++] = rtl::OString('\'') + + rtl::OString( pDatabases->getVendorName().getStr(), + pDatabases->getVendorName().getLength(), + RTL_TEXTENCODING_UTF8 ) + rtl::OString('\''); + parString[last++] = "vendorversion"; + parString[last++] = rtl::OString('\'') + + rtl::OString( pDatabases->getVendorVersion().getStr(), + pDatabases->getVendorVersion().getLength(), + RTL_TEXTENCODING_UTF8 ) + rtl::OString('\''); + parString[last++] = "vendorshort"; + parString[last++] = rtl::OString('\'') + + rtl::OString( pDatabases->getVendorShort().getStr(), + pDatabases->getVendorShort().getLength(), + RTL_TEXTENCODING_UTF8 ) + rtl::OString('\''); + } + + // Do we need to add extension path? + ::rtl::OUString aExtensionPath; + rtl::OUString aJar = urlParam->get_jar(); + + bool bAddExtensionPath = false; + sal_Int32 nQuestionMark1 = aJar.indexOf( sal_Unicode('?') ); + sal_Int32 nQuestionMark2 = aJar.lastIndexOf( sal_Unicode('?') ); + if( nQuestionMark1 != -1 && nQuestionMark2 != -1 && nQuestionMark1 != nQuestionMark2 ) + { + aExtensionPath = aJar.copy( nQuestionMark1 + 1, nQuestionMark2 - nQuestionMark1 - 1 ); + bAddExtensionPath = true; + } + else + { + // Path not yet specified, search directly + Reference< XHierarchicalNameAccess > xNA = pDatabases->findJarFileForPath + ( aJar, urlParam->get_language(), urlParam->get_path(), &aExtensionPath ); + if( xNA.is() && aExtensionPath.getLength() ) + bAddExtensionPath = true; + } + + if( bAddExtensionPath ) + { + Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory(); + Reference< XPropertySet > xProps( xFactory, UNO_QUERY ); + OSL_ASSERT( xProps.is() ); + Reference< XComponentContext > xContext; + if (xProps.is()) + { + xProps->getPropertyValue( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext; + } + if( !xContext.is() ) + { + throw RuntimeException( + ::rtl::OUString::createFromAscii( "InputStreamTransformer::InputStreamTransformer(), no XComponentContext" ), + Reference< XInterface >() ); + } + + rtl::OUString aOUExpandedExtensionPath = Databases::expandURL( aExtensionPath, xContext ); + rtl::OString aExpandedExtensionPath = rtl::OUStringToOString( aOUExpandedExtensionPath, osl_getThreadTextEncoding() ); + + parString[last++] = "ExtensionPath"; + parString[last++] = rtl::OString('\'') + aExpandedExtensionPath + rtl::OString('\''); + + // ExtensionId + rtl::OString aPureExtensionId; + sal_Int32 iSlash = aPath.indexOf( '/' ); + if( iSlash != -1 ) + aPureExtensionId = aPath.copy( 0, iSlash ); + + parString[last++] = "ExtensionId"; + parString[last++] = rtl::OString('\'') + aPureExtensionId + rtl::OString('\''); + } + + for( int i = 0; i < last; ++i ) + parameter[i] = parString[i].getStr(); + parameter[last] = 0; + + rtl::OUString xslURL = pDatabases->getInstallPathAsURL(); + + rtl::OString xslURLascii( + xslURL.getStr(), + xslURL.getLength(), + RTL_TEXTENCODING_UTF8); + xslURLascii += "main_transform.xsl"; + + ugblData = &userData; + + xmlInitParser(); + xmlRegisterInputCallbacks(zipMatch, zipOpen, zipRead, uriClose); + xmlRegisterInputCallbacks(helpMatch, helpOpen, helpRead, uriClose); + xmlRegisterInputCallbacks(fileMatch, fileOpen, fileRead, fileClose); + //xmlSetStructuredErrorFunc( NULL, (xmlStructuredErrorFunc)StructuredXMLErrorFunction ); + + xsltStylesheetPtr cur = + xsltParseStylesheetFile((const xmlChar *)xslURLascii.getStr()); + + xmlDocPtr doc = xmlParseFile("vnd.sun.star.zip:/"); + + xmlDocPtr res = xsltApplyStylesheet(cur, doc, parameter); + if (res) + { + xmlChar *doc_txt_ptr=0; + int doc_txt_len; + xsltSaveResultToString(&doc_txt_ptr, &doc_txt_len, res, cur); + addToBuffer((const char*)doc_txt_ptr, doc_txt_len); + xmlFree(doc_txt_ptr); + } + xmlPopInputCallbacks(); //filePatch + xmlPopInputCallbacks(); //helpPatch + xmlPopInputCallbacks(); //zipMatch + xmlFreeDoc(res); + xmlFreeDoc(doc); + xsltFreeStylesheet(cur); + } +} + + +InputStreamTransformer::~InputStreamTransformer() +{ + delete[] buffer; +} + + +Any SAL_CALL InputStreamTransformer::queryInterface( const Type& rType ) throw( RuntimeException ) +{ + Any aRet = ::cppu::queryInterface( rType, + SAL_STATIC_CAST( XInputStream*,this ), + SAL_STATIC_CAST( XSeekable*,this ) ); + + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + + +void SAL_CALL InputStreamTransformer::acquire( void ) throw() +{ + OWeakObject::acquire(); +} + + + +void SAL_CALL InputStreamTransformer::release( void ) throw() +{ + OWeakObject::release(); +} + + + +sal_Int32 SAL_CALL InputStreamTransformer::readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException) +{ + osl::MutexGuard aGuard( m_aMutex ); + + int curr,available_ = len-pos; + if( nBytesToRead <= available_ ) + curr = nBytesToRead; + else + curr = available_; + + if( 0 <= curr && aData.getLength() < curr ) + aData.realloc( curr ); + + for( int k = 0; k < curr; ++k ) + aData[k] = buffer[pos++]; + + return curr > 0 ? curr : 0; +} + + +sal_Int32 SAL_CALL InputStreamTransformer::readSomeBytes( Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead ) + throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException) +{ + return readBytes( aData,nMaxBytesToRead ); +} + + + +void SAL_CALL InputStreamTransformer::skipBytes( sal_Int32 nBytesToSkip ) throw( NotConnectedException, + BufferSizeExceededException, + IOException, + RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + while( nBytesToSkip-- ) ++pos; +} + + + +sal_Int32 SAL_CALL InputStreamTransformer::available( void ) throw( NotConnectedException, + IOException, + RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + return len-pos > 0 ? len - pos : 0 ; +} + + + +void SAL_CALL InputStreamTransformer::closeInput( void ) throw( NotConnectedException, + IOException, + RuntimeException ) +{ +} + + + +void SAL_CALL InputStreamTransformer::seek( sal_Int64 location ) throw( IllegalArgumentException, + IOException, + RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + if( location < 0 ) + throw IllegalArgumentException(); + else + pos = sal::static_int_cast<sal_Int32>( location ); + + if( pos > len ) + pos = len; +} + + + +sal_Int64 SAL_CALL InputStreamTransformer::getPosition( void ) throw( IOException, + RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + return sal_Int64( pos ); +} + + + +sal_Int64 SAL_CALL InputStreamTransformer::getLength( void ) throw( IOException,RuntimeException ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + return len; +} + + +void InputStreamTransformer::addToBuffer( const char* buffer_,int len_ ) +{ + osl::MutexGuard aGuard( m_aMutex ); + + char* tmp = buffer; + buffer = new char[ len+len_ ]; + rtl_copyMemory( (void*)(buffer),(void*)(tmp),sal_uInt32( len ) ); + rtl_copyMemory( (void*)(buffer+len),(void*)(buffer_),sal_uInt32( len_ ) ); + delete[] tmp; + len += len_; +} diff --git a/xmlhelp/source/cxxhelp/provider/urlparameter.hxx b/xmlhelp/source/cxxhelp/provider/urlparameter.hxx new file mode 100644 index 000000000000..7a6df8523f59 --- /dev/null +++ b/xmlhelp/source/cxxhelp/provider/urlparameter.hxx @@ -0,0 +1,258 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: urlparameter.hxx,v $ + * $Revision: 1.4 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _URLPARAMETER_HXX_ +#define _URLPARAMETER_HXX_ + +#include <rtl/ustring.hxx> +#include <rtl/string.hxx> +#include <com/sun/star/ucb/IllegalIdentifierException.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/ucb/XCommandEnvironment.hpp> +#include <com/sun/star/io/XActiveDataSink.hpp> +#include <com/sun/star/io/XOutputStream.hpp> +#include <com/sun/star/ucb/Command.hpp> + +namespace chelp { + + + class Databases; + + + class DbtToStringConverter + { + public: + + DbtToStringConverter( const sal_Char* ptr,sal_Int32 len ) + : m_len( len ), + m_ptr( ptr ) + { + } + + + rtl::OUString getHash() + { + if( m_ptr ) + { + sal_Int32 sizeOfFile = ( sal_Int32 ) m_ptr[0]; + rtl::OUString Hash( m_ptr+1,sizeOfFile,RTL_TEXTENCODING_UTF8 ); + sal_Int32 idx; + if( ( idx = Hash.indexOf( sal_Unicode( '#' ) ) ) != -1 ) + return Hash.copy( 1+idx ); + } + return rtl::OUString(); + } + + + rtl::OUString getFile() + { + if( ! m_ptr ) + return rtl::OUString(); + + sal_Int32 sizeOfFile = ( sal_Int32 ) m_ptr[0]; + rtl::OUString File( m_ptr+1,sizeOfFile,RTL_TEXTENCODING_UTF8 ); + sal_Int32 idx; + if( ( idx = File.indexOf( sal_Unicode( '#' ) ) ) != -1 ) + return File.copy( 0,idx ); + else + return File; + } + + + rtl::OUString getDatabase() + { + if( ! m_ptr ) + return rtl::OUString(); + + sal_Int32 sizeOfDatabase = ( int ) m_ptr[ 1+ ( sal_Int32 ) m_ptr[0] ]; + return rtl::OUString( m_ptr + 2 + ( sal_Int32 ) m_ptr[0],sizeOfDatabase,RTL_TEXTENCODING_UTF8 ); + } + + + rtl::OUString getTitle() + { + if( ! m_ptr ) // || getHash().getLength() ) + return rtl::OUString(); + + sal_Int32 sizeOfTitle = + ( sal_Int32 ) m_ptr[ 2 + m_ptr[0] + ( sal_Int32 ) m_ptr[ 1+ ( sal_Int32 ) m_ptr[0] ] ]; + return rtl::OUString( m_ptr + 3 + m_ptr[0] + ( sal_Int32 ) m_ptr[ 1+ ( sal_Int32 ) m_ptr[0] ], + sizeOfTitle, + RTL_TEXTENCODING_UTF8 ); + } + + + private: + + sal_Int32 m_len; + + const sal_Char* m_ptr; + + }; + + + + + class URLParameter + { + public: + + URLParameter( const rtl::OUString& aURL, + Databases* pDatabases ) + throw( com::sun::star::ucb::IllegalIdentifierException ); + + bool isPicture() { return m_aModule.compareToAscii("picture") == 0; } + bool isActive() { return m_aActive.getLength() > 0 && m_aActive.compareToAscii( "true" ) == 0; } + bool isQuery() { return m_aId.compareToAscii("") == 0 && m_aQuery.compareToAscii("") != 0; } + bool isEntryForModule() { return m_aId.compareToAscii("start") == 0 || m_bStart; } + bool isFile() { return m_aId.compareToAscii( "" ) != 0; } + bool isModule() { return m_aId.compareToAscii("") == 0 && m_aModule.compareToAscii("") != 0; } + bool isRoot() { return m_aModule.compareToAscii("") == 0; } + bool isErrorDocument(); + + rtl::OUString get_url() { return m_aURL; } + + rtl::OUString get_id(); + + rtl::OUString get_tag(); + + // Not called for an directory + + rtl::OUString get_path() { return get_the_path(); } + + rtl::OUString get_eid() { return m_aEid; } + + rtl::OUString get_title(); + + rtl::OUString get_jar() { return get_the_jar(); } // BerkeleyDb + + rtl::OUString get_module() { return m_aModule; } + + rtl::OUString get_dbpar() { + if( m_aDbPar.getLength() ) return m_aDbPar; + else return m_aModule; + } + + rtl::OUString get_prefix() { return m_aPrefix; } + + rtl::OUString get_language(); + + rtl::OUString get_device() { return m_aDevice; } + + rtl::OUString get_program(); + + rtl::OUString get_query() { return m_aQuery; } + + rtl::OUString get_scope() { return m_aScope; } + + rtl::OUString get_system() { return m_aSystem; } + + sal_Int32 get_hitCount() { return m_nHitCount; } + + rtl::OString getByName( const char* par ); + + void open( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + const com::sun::star::ucb::Command& aCommand, + sal_Int32 CommandId, + const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& Environment, + const com::sun::star::uno::Reference< com::sun::star::io::XActiveDataSink >& xDataSink ); + + void open( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxSMgr, + const com::sun::star::ucb::Command& aCommand, + sal_Int32 CommandId, + const com::sun::star::uno::Reference< com::sun::star::ucb::XCommandEnvironment >& Environment, + const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xDataSink ); + + private: + + Databases* m_pDatabases; + + bool m_bBerkeleyRead; + bool m_bStart; + bool m_bUseDB; + + rtl::OUString m_aURL; + + rtl::OUString m_aTag; + rtl::OUString m_aId; + rtl::OUString m_aPath; + rtl::OUString m_aModule; + rtl::OUString m_aTitle; + rtl::OUString m_aJar; + rtl::OUString m_aEid; + rtl::OUString m_aDbPar; + + rtl::OUString m_aDefaultLanguage; + rtl::OUString m_aLanguage; + + rtl::OUString m_aPrefix; + rtl::OUString m_aDevice; + rtl::OUString m_aProgram; + rtl::OUString m_aSystem; + rtl::OUString m_aActive; + + rtl::OUString m_aQuery; + rtl::OUString m_aScope; + + rtl::OUString m_aExpr; + + sal_Int32 m_nHitCount; // The default maximum hitcount + + + // private methods + + void init( bool bDefaultLanguageIsInitialized ); + + rtl::OUString get_the_tag(); + + rtl::OUString get_the_path(); + + rtl::OUString get_the_title(); + + rtl::OUString get_the_jar(); + + void readBerkeley(); + + void parse() throw( com::sun::star::ucb::IllegalIdentifierException ); + + bool scheme(); + + bool module(); + + bool name( bool modulePresent ); + + bool query(); + + }; // end class URLParameter + + +} // end namespace chelp + +#endif diff --git a/xmlhelp/source/cxxhelp/qe/DocGenerator.cxx b/xmlhelp/source/cxxhelp/qe/DocGenerator.cxx new file mode 100644 index 000000000000..7492e66f9e9b --- /dev/null +++ b/xmlhelp/source/cxxhelp/qe/DocGenerator.cxx @@ -0,0 +1,64 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DocGenerator.cxx,v $ + * $Revision: 1.10 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <qe/DocGenerator.hxx> +#include <qe/Query.hxx> + + +using namespace xmlsearch; +using namespace xmlsearch::qe; + + +const sal_Int32 NonnegativeIntegerGenerator::END = -1; + + +RoleFiller RoleFiller::roleFiller_; + + +RoleFiller::RoleFiller() + : m_nRefcount( 0 ), + fixedRole_( 0 ), + filled_( 0 ), + begin_( 0 ), + end_( 0 ), + parentContext_( 0 ), + limit_( 0 ), + next_( 0 ), + fillers_( 0 ) +{ +} + + +RoleFiller::~RoleFiller() +{ + +} diff --git a/xmlhelp/source/cxxhelp/qe/makefile.mk b/xmlhelp/source/cxxhelp/qe/makefile.mk new file mode 100644 index 000000000000..249950c4f02a --- /dev/null +++ b/xmlhelp/source/cxxhelp/qe/makefile.mk @@ -0,0 +1,53 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.9 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME= xmlhelp +TARGET= jaqe +AUTOSEG= TRUE + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +.IF "$(GUI)"=="WNT" +CFLAGS+=-GR +.ENDIF + +SLOFILES=$(SLO)$/DocGenerator.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/xmlhelp/source/cxxhelp/test/abidebug.hxx b/xmlhelp/source/cxxhelp/test/abidebug.hxx new file mode 100644 index 000000000000..00b3815d693e --- /dev/null +++ b/xmlhelp/source/cxxhelp/test/abidebug.hxx @@ -0,0 +1,35 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: abidebug.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <iostream> +#ifndef _RTL_USTRING_ +#include <rtl/ustring> +#endif +ostream& operator<<( ostream& out,const rtl::OUString& bla ); + diff --git a/xmlhelp/source/cxxhelp/test/makefile.mk b/xmlhelp/source/cxxhelp/test/makefile.mk new file mode 100644 index 000000000000..357aae6af044 --- /dev/null +++ b/xmlhelp/source/cxxhelp/test/makefile.mk @@ -0,0 +1,73 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.5 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=xmlhelp +TARGET=searchdemo +TARGETTYPE = CUI +LIBTARGET=NO + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings --- + +.INCLUDE : settings.mk + + +.IF "$(GUI)"=="WNT" +CFLAGS+=-GR +.ENDIF + +# --- Files --- + +OBJFILES=\ + $(OBJ)$/searchdemo.obj + +APP1TARGET= searchdemo +APP1OBJS=\ + $(OBJ)$/searchdemo.obj + +APP1STDLIBS=\ + $(SALLIB) \ + $(VOSLIB) + +APP1LIBS=\ + $(SLB)/jaqe.lib \ + $(SLB)/jadb.lib \ + $(SLB)/jautil.lib + +APP1DEF= $(MISC)\$(APP1TARGET).def + +# --- Targets --- + +.INCLUDE : target.mk + diff --git a/xmlhelp/source/cxxhelp/test/searchdemo.cxx b/xmlhelp/source/cxxhelp/test/searchdemo.cxx new file mode 100644 index 000000000000..d78229b036db --- /dev/null +++ b/xmlhelp/source/cxxhelp/test/searchdemo.cxx @@ -0,0 +1,120 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: searchdemo.cxx,v $ + * $Revision: 1.8 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <rtl/string.hxx> +#include <osl/file.hxx> +#include <db/Block.hxx> +#include <db/BtreeDictParameters.hxx> +#include <db/BtreeDict.hxx> +#include <util/RandomAccessStream.hxx> +#include <db/DBEnv.hxx> +#include <qe/QueryProcessor.hxx> + +#ifdef ABIDEBUG +#include <abidebug.hxx> +#endif + + +using namespace xmlsearch::util; +using namespace xmlsearch::db; +using namespace xmlsearch::qe; + + + +extern RandomAccessStream* theFile(); + + + +void print_rtl_OUString( const rtl::OUString bla ) +{ + rtl::OString bluber = rtl::OString( bla.getStr(),bla.getLength(),RTL_TEXTENCODING_UTF8 ); + char* bluberChr = new char[ 1+bluber.getLength() ]; + const sal_Char* jux = bluber.getStr(); + + for( int i = 0; i < bluber.getLength(); ++i ) + bluberChr[i] = jux[i]; + + bluberChr[ bluber.getLength() ] = 0; + printf( "%s\n",bluberChr ); + delete[] bluberChr; +} + + +extern void bla(); +extern void blu(); + + +int main( int argc,char* argv[] ) +{ + + QueryResults* queryResults = 0; + + try + { + rtl::OUString installDir = rtl::OUString::createFromAscii( "//./e|/index/" ); + QueryProcessor queryProcessor( installDir ); + + std::vector<rtl::OUString> Query(2); + Query[0] = rtl::OUString::createFromAscii( "text*" ); + Query[1] = rtl::OUString::createFromAscii( "abbildung" ); + rtl::OUString Scope = rtl::OUString::createFromAscii( "headingheading" ); + int HitCount = 40; + + QueryStatement queryStatement( HitCount,Query,Scope ); + queryResults = queryProcessor.processQuery( queryStatement ); + + rtl::OUString translations[2]; + translations[0] = rtl::OUString::createFromAscii( "#HLP#" ); + translations[1] = rtl::OUString::createFromAscii( "vnd.sun.star.help://" ); + + PrefixTranslator* translator = PrefixTranslator::makePrefixTranslator( translations,2 ); + + QueryHitIterator* it = queryResults->makeQueryHitIterator(); + sal_Int32 j = 0; + while( j < 10 && it->next() ) + { + printf( "Ergebnis %2d ",j ); + QueryHitData* qhd = it->getHit( translator ); + printf( "Penalty = %10.4f ",qhd->getPenalty() ); + print_rtl_OUString( qhd->getDocument() ); + ++j; + } + + delete it; + } + catch( ... ) + { + printf( "catched exception" ); + throw; + } + return 0; +} diff --git a/xmlhelp/source/cxxhelp/util/Decompressor.cxx b/xmlhelp/source/cxxhelp/util/Decompressor.cxx new file mode 100644 index 000000000000..ee21df9cd101 --- /dev/null +++ b/xmlhelp/source/cxxhelp/util/Decompressor.cxx @@ -0,0 +1,58 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: Decompressor.cxx,v $ + * $Revision: 1.5 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <util/Decompressor.hxx> +#include <util/CompressorIterator.hxx> + +using namespace xmlsearch; +using namespace xmlsearch::util; + +const sal_Int32 Decompressor::BitsInByte = 8; +const sal_Int32 Decompressor::NBits = 32; + +inline sal_Int32 getInteger_( const sal_Int8* v ) +{ + return (((((( (v[0]&0xFF) ) << 8 ) + | (v[1]&0xFF) ) << 8 ) + | (v[2]&0xFF) ) << 8 ) + | (v[3]&0xFF); +} + +sal_Int32 StreamDecompressor::getNextByte() +{ + sal_Int8 a[4]; + a[0] = a[1] = a[2] = 0; + if( in_->readBytes( &a[3],1 ) != -1 ) + return getInteger_( a ); + else + return -1; +} diff --git a/xmlhelp/source/cxxhelp/util/makefile.mk b/xmlhelp/source/cxxhelp/util/makefile.mk new file mode 100644 index 000000000000..8e25c8584cd2 --- /dev/null +++ b/xmlhelp/source/cxxhelp/util/makefile.mk @@ -0,0 +1,54 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.9 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME= xmlhelp +TARGET= jautil +AUTOSEG= TRUE + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +.IF "$(GUI)"=="WNT" +CFLAGS+=-GR +.ENDIF + +SLOFILES=\ + $(SLO)$/Decompressor.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/xmlhelp/source/treeview/makefile.mk b/xmlhelp/source/treeview/makefile.mk new file mode 100644 index 000000000000..4541a1745b53 --- /dev/null +++ b/xmlhelp/source/treeview/makefile.mk @@ -0,0 +1,73 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.9 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/.. +PRJNAME=xmlhelp +TARGET=tvhlp +USE_DEFFILE=TRUE +ENABLE_EXCEPTIONS=TRUE +NO_BSYMBOLIC=TRUE + +# Version +TVHLP_MAJOR=1 + +.INCLUDE: settings.mk + +.IF "$(SYSTEM_EXPAT)" == "YES" +CFLAGS+=-DSYSTEM_EXPAT +.ENDIF + +SLOFILES=\ + $(SLO)$/tvfactory.obj \ + $(SLO)$/tvread.obj + +LIB1TARGET=$(SLB)$/_$(TARGET).lib +LIB1OBJFILES=$(SLOFILES) + +SHL1TARGET=$(TARGET)$(TVHLP_MAJOR) +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +SHL1LIBS=$(LIB1TARGET) +SHL1IMPLIB=i$(TARGET) +SHL1STDLIBS=\ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(COMPHELPERLIB) \ + $(EXPATASCII3RDLIB) \ + $(SALLIB) +SHL1VERSIONMAP= $(TARGET).map + +DEF1NAME=$(SHL1TARGET) +DEF1DES=UCB : Treeview help + + +.INCLUDE: target.mk + + diff --git a/xmlhelp/source/treeview/tvfactory.cxx b/xmlhelp/source/treeview/tvfactory.cxx new file mode 100644 index 000000000000..8a02238cfe56 --- /dev/null +++ b/xmlhelp/source/treeview/tvfactory.cxx @@ -0,0 +1,358 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tvfactory.cxx,v $ + * $Revision: 1.7 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include "tvfactory.hxx" +#include "tvread.hxx" + + +using namespace treeview; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::container; + + + +TVFactory::TVFactory( const uno::Reference< XMultiServiceFactory >& xMSF ) + : m_xMSF( xMSF ) +{ +} + + +TVFactory::~TVFactory() +{ +} + + +////////////////////////////////////////////////////////////////////////// +// XInterface +////////////////////////////////////////////////////////////////////////// + +void SAL_CALL +TVFactory::acquire( + void ) + throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL +TVFactory::release( + void ) + throw() +{ + OWeakObject::release(); +} + + +Any SAL_CALL +TVFactory::queryInterface( + const Type& rType ) + throw( RuntimeException ) +{ + Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( XServiceInfo*, this ), + SAL_STATIC_CAST( XTypeProvider*, this ), + SAL_STATIC_CAST( XMultiServiceFactory*, this ) ); + + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// XTypeProvider methods. + +XTYPEPROVIDER_IMPL_3( TVFactory, + XServiceInfo, + XTypeProvider, + XMultiServiceFactory ); + + + +//////////////////////////////////////////////////////////////////////////////// + +// XServiceInfo methods. + +rtl::OUString SAL_CALL +TVFactory::getImplementationName() + throw( RuntimeException ) +{ + return TVFactory::getImplementationName_static(); +} + + +sal_Bool SAL_CALL +TVFactory::supportsService( + const rtl::OUString& ServiceName ) + throw( RuntimeException ) +{ + return + ServiceName.compareToAscii( "com.sun.star.help.TreeView" ) == 0 || + ServiceName.compareToAscii( "com.sun.star.ucb.HiearchyDataSource" ) == 0; +} + + +Sequence< rtl::OUString > SAL_CALL +TVFactory::getSupportedServiceNames( void ) + throw( RuntimeException ) +{ + return TVFactory::getSupportedServiceNames_static(); +} + + + +// XMultiServiceFactory + +Reference< XInterface > SAL_CALL +TVFactory::createInstance( + const rtl::OUString& aServiceSpecifier ) + throw( Exception, + RuntimeException ) +{ + Any aAny; + aAny <<= rtl::OUString(); + Sequence< Any > seq( 1 ); + seq[0] <<= PropertyValue( + rtl::OUString::createFromAscii( "nodepath" ), + -1, + aAny, + PropertyState_DIRECT_VALUE ); + + return createInstanceWithArguments( aServiceSpecifier, + seq ); +} + + +Reference< XInterface > SAL_CALL +TVFactory::createInstanceWithArguments( + const rtl::OUString& ServiceSpecifier, + const Sequence< Any >& Arguments ) + throw( Exception, + RuntimeException ) +{ + (void)ServiceSpecifier; + + if( ! m_xHDS.is() ) + { + cppu::OWeakObject* p = new TVChildTarget( m_xMSF ); + m_xHDS = Reference< XInterface >( p ); + } + + Reference< XInterface > ret = m_xHDS; + + rtl::OUString hierview; + for( int i = 0; i < Arguments.getLength(); ++i ) + { + PropertyValue pV; + if( ! ( Arguments[i] >>= pV ) ) + continue; + + if( pV.Name.compareToAscii( "nodepath" ) ) + continue; + + if( ! ( pV.Value >>= hierview ) ) + continue; + + break; + } + + if( hierview.getLength() ) + { + Reference< XHierarchicalNameAccess > xhieraccess( m_xHDS,UNO_QUERY ); + Any aAny = xhieraccess->getByHierarchicalName( hierview ); + Reference< XInterface > xInterface; + aAny >>= xInterface; + return xInterface; + } + else + return m_xHDS; +} + + +Sequence< rtl::OUString > SAL_CALL +TVFactory::getAvailableServiceNames( ) + throw( RuntimeException ) +{ + Sequence< rtl::OUString > seq( 1 ); + seq[0] = rtl::OUString::createFromAscii( "com.sun.star.ucb.HierarchyDataReadAccess" ); + return seq; +} + + + +// static + + +rtl::OUString SAL_CALL +TVFactory::getImplementationName_static() +{ + return rtl::OUString::createFromAscii( "com.sun.star.help.TreeViewImpl" ); +} + + +Sequence< rtl::OUString > SAL_CALL +TVFactory::getSupportedServiceNames_static() +{ + Sequence< rtl::OUString > seq( 2 ); + seq[0] = rtl::OUString::createFromAscii( "com.sun.star.help.TreeView" ); + seq[1] = rtl::OUString::createFromAscii( "com.sun.star.ucb.HiearchyDataSource" ); + return seq; +} + + +Reference< XSingleServiceFactory > SAL_CALL +TVFactory::createServiceFactory( + const Reference< XMultiServiceFactory >& rxServiceMgr ) +{ + return Reference< XSingleServiceFactory > ( + cppu::createSingleFactory( + rxServiceMgr, + TVFactory::getImplementationName_static(), + TVFactory::CreateInstance, + TVFactory::getSupportedServiceNames_static() ) ); +} + + + +Reference< XInterface > SAL_CALL +TVFactory::CreateInstance( + const Reference< XMultiServiceFactory >& xMultiServiceFactory ) +{ + XServiceInfo* xP = (XServiceInfo*) new TVFactory( xMultiServiceFactory ); + return Reference< XInterface >::query( xP ); +} + + + +//========================================================================= +static sal_Bool writeInfo( void * pRegistryKey, + const rtl::OUString & rImplementationName, + Sequence< rtl::OUString > const & rServiceNames ) +{ + rtl::OUString aKeyName( rtl::OUString::createFromAscii( "/" ) ); + aKeyName += rImplementationName; + aKeyName += rtl::OUString::createFromAscii( "/UNO/SERVICES" ); + + Reference< registry::XRegistryKey > xKey; + try + { + xKey = static_cast< registry::XRegistryKey * >( + pRegistryKey )->createKey( aKeyName ); + } + catch ( registry::InvalidRegistryException const & ) + { + } + + if ( !xKey.is() ) + return sal_False; + + sal_Bool bSuccess = sal_True; + + for ( sal_Int32 n = 0; n < rServiceNames.getLength(); ++n ) + { + try + { + xKey->createKey( rServiceNames[ n ] ); + } + catch ( registry::InvalidRegistryException const & ) + { + bSuccess = sal_False; + break; + } + } + return bSuccess; +} + + + +//========================================================================= +extern "C" void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv ) +{ + (void)ppEnv; + + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + + + +//========================================================================= +extern "C" sal_Bool SAL_CALL component_writeInfo( + void * pServiceManager, void * pRegistryKey ) +{ + (void)pServiceManager; + + return pRegistryKey && writeInfo( pRegistryKey, + TVFactory::getImplementationName_static(), + TVFactory::getSupportedServiceNames_static() ); +} + + +//========================================================================= +extern "C" void * SAL_CALL component_getFactory( + const sal_Char * pImplName,void * pServiceManager,void * pRegistryKey ) +{ + (void)pRegistryKey; + + void * pRet = 0; + + Reference< XMultiServiceFactory > xSMgr( + reinterpret_cast< XMultiServiceFactory * >( pServiceManager ) ); + + Reference< XSingleServiceFactory > xFactory; + + ////////////////////////////////////////////////////////////////////// + // File Content Provider. + ////////////////////////////////////////////////////////////////////// + + if ( TVFactory::getImplementationName_static().compareToAscii( pImplName ) == 0 ) + { + xFactory = TVFactory::createServiceFactory( xSMgr ); + } + + ////////////////////////////////////////////////////////////////////// + + if ( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + + return pRet; +} diff --git a/xmlhelp/source/treeview/tvfactory.hxx b/xmlhelp/source/treeview/tvfactory.hxx new file mode 100644 index 000000000000..251e47a34dd0 --- /dev/null +++ b/xmlhelp/source/treeview/tvfactory.hxx @@ -0,0 +1,141 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tvfactory.hxx,v $ + * $Revision: 1.3 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _TREEVIEW_TVFACTORY_HXX_ +#define _TREEVIEW_TVFACTORY_HXX_ + +#include <rtl/ref.hxx> +#include <rtl/ustring.hxx> +#include <cppuhelper/weak.hxx> +#include <ucbhelper/macros.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + + + +namespace treeview { + + class TVFactory: + public cppu::OWeakObject, + public com::sun::star::lang::XServiceInfo, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::lang::XMultiServiceFactory + { + public: + + TVFactory( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xMSF ); + + ~TVFactory(); + + // XInterface + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& aType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + + // XTypeProvider + + XTYPEPROVIDER_DECL() + + + // XServiceInfo + virtual rtl::OUString SAL_CALL + getImplementationName( + void ) + throw( com::sun::star::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL + supportsService( + const rtl::OUString& ServiceName ) + throw(com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames( + void ) + throw( com::sun::star::uno::RuntimeException ); + + // XMultiServiceFactory + + virtual com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL + createInstance( + const rtl::OUString& aServiceSpecifier ) + throw( com::sun::star::uno::Exception, + com::sun::star::uno::RuntimeException ); + + virtual com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL + createInstanceWithArguments( + const rtl::OUString& ServiceSpecifier, + const com::sun::star::uno::Sequence< com::sun::star::uno::Any >& Arguments ) + throw( com::sun::star::uno::Exception, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL + getAvailableServiceNames( ) + throw( com::sun::star::uno::RuntimeException ); + + // Other + + static rtl::OUString SAL_CALL getImplementationName_static(); + + static com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames_static(); + + static com::sun::star::uno::Reference< com::sun::star::lang::XSingleServiceFactory > SAL_CALL + createServiceFactory( + const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& rxServiceMgr ); + + static com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL + CreateInstance( + const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xMultiServiceFactory ); + + + private: + + // Members + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xMSF; + com::sun::star::uno::Reference< com::sun::star::uno::XInterface > m_xHDS; + }; + +} + + +#endif diff --git a/xmlhelp/source/treeview/tvhlp.map b/xmlhelp/source/treeview/tvhlp.map new file mode 100644 index 000000000000..d432afe36358 --- /dev/null +++ b/xmlhelp/source/treeview/tvhlp.map @@ -0,0 +1,9 @@ +TVHLP_1_0 { + global: + GetVersionInfo; + component_getImplementationEnvironment; + component_writeInfo; + component_getFactory; + local: + *; +};
\ No newline at end of file diff --git a/xmlhelp/source/treeview/tvread.cxx b/xmlhelp/source/treeview/tvread.cxx new file mode 100644 index 000000000000..a35b494c5742 --- /dev/null +++ b/xmlhelp/source/treeview/tvread.cxx @@ -0,0 +1,1309 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tvread.cxx,v $ + * $Revision: 1.26 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlhelp.hxx" + +#include <string.h> +#include <rtl/ustrbuf.hxx> +#ifndef _VOS_DIAGNOSE_HXX_ +#include <vos/diagnose.hxx> +#endif +#include "tvread.hxx" +#include <expat.h> +#include <osl/file.hxx> +#include <com/sun/star/frame/XConfigManager.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/beans/PropertyState.hpp> + +#include <comphelper/processfactory.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include "com/sun/star/deployment/thePackageManagerFactory.hpp" +#include <com/sun/star/util/XMacroExpander.hpp> +#include <com/sun/star/uri/XUriReferenceFactory.hpp> +#include <com/sun/star/uri/XVndSunStarExpandUrl.hpp> +#include <comphelper/locale.hxx> + +namespace treeview { + + + class TVDom + { + friend class TVChildTarget; + friend class TVRead; + + public: + + TVDom( TVDom* arent = 0 ) + : kind( other ), + parent( arent ), + childs( 0 ) + { + } + + ~TVDom() + { + for( unsigned i = 0; i < childs.size(); ++i ) + delete childs[i]; + } + + + TVDom* newChild() + { + childs.push_back( new TVDom( this ) ); + return childs.back(); + } + + + TVDom* getParent() const + { + if( parent ) + return parent; + else + return const_cast<TVDom*>(this); // I am my own parent, if I am the root + } + + enum Kind { + tree_view, + tree_node, + tree_leaf, + other + }; + + bool isLeaf() const { return kind == TVDom::tree_leaf; } + void setKind( Kind ind ) { kind = ind; } + Kind getKind( ) const { return kind; } + + + void setApplication( const char* appl ) + { + application = rtl::OUString( (sal_Char*)(appl), + strlen( appl ), + RTL_TEXTENCODING_UTF8 ); + } + + void setTitle( const char* itle ) + { + title += rtl::OUString( (sal_Char*)(itle), + strlen( itle ), + RTL_TEXTENCODING_UTF8 ); + } + + void setTitle( const XML_Char* itle,int len ) + { + title += rtl::OUString( (sal_Char*)(itle), + len, + RTL_TEXTENCODING_UTF8 ); + } + + void setId( const char* d ) + { + id = rtl::OUString( (sal_Char*)(d), + strlen( d ), + RTL_TEXTENCODING_UTF8 ); + } + + void setAnchor( const char* nchor ) + { + anchor = rtl::OUString( (sal_Char*)(nchor), + strlen( nchor ), + RTL_TEXTENCODING_UTF8 ); + } + + rtl::OUString getTargetURL() + { + if( ! targetURL.getLength() ) + { + sal_Int32 len; + for ( const TVDom* p = this;; p = p->parent ) + { + len = p->application.getLength(); + if ( len != 0 ) + break; + } + + rtl::OUStringBuffer strBuff( 22 + len + id.getLength() ); + strBuff.appendAscii( + "vnd.sun.star.help://" + ).append(id); + + targetURL = strBuff.makeStringAndClear(); + } + + return targetURL; + } + + private: + + Kind kind; + rtl::OUString application; + rtl::OUString title; + rtl::OUString id; + rtl::OUString anchor; + rtl::OUString targetURL; + + TVDom *parent; + std::vector< TVDom* > childs; + }; + +} + + + +using namespace treeview; +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace com::sun::star::util; +using namespace com::sun::star::frame; +using namespace com::sun::star::container; +using namespace com::sun::star::deployment; + + +ConfigData::ConfigData() + : prodName( rtl::OUString::createFromAscii( "%PRODUCTNAME" ) ), + prodVersion( rtl::OUString::createFromAscii( "%PRODUCTVERSION" ) ), + vendName( rtl::OUString::createFromAscii( "%VENDORNAME" ) ), + vendVersion( rtl::OUString::createFromAscii( "%VENDORVERSION" ) ), + vendShort( rtl::OUString::createFromAscii( "%VENDORSHORT" ) ) +{ +} + +void SAL_CALL ConfigData::replaceName( rtl::OUString& oustring ) const +{ + sal_Int32 idx = -1,k = 0,off; + bool cap = false; + rtl::OUStringBuffer aStrBuf( 0 ); + + while( ( idx = oustring.indexOf( sal_Unicode('%'),++idx ) ) != -1 ) + { + if( oustring.indexOf( prodName,idx ) == idx ) + off = PRODUCTNAME; + else if( oustring.indexOf( prodVersion,idx ) == idx ) + off = PRODUCTVERSION; + else if( oustring.indexOf( vendName,idx ) == idx ) + off = VENDORNAME; + else if( oustring.indexOf( vendVersion,idx ) == idx ) + off = VENDORVERSION; + else if( oustring.indexOf( vendShort,idx ) == idx ) + off = VENDORSHORT; + else + off = -1; + + if( off != -1 ) + { + if( ! cap ) + { + cap = true; + aStrBuf.ensureCapacity( 256 ); + } + + aStrBuf.append( &oustring.getStr()[k],idx - k ); + aStrBuf.append( m_vReplacement[off] ); + k = idx + m_vAdd[off]; + } + } + + if( cap ) + { + if( k < oustring.getLength() ) + aStrBuf.append( &oustring.getStr()[k],oustring.getLength()-k ); + oustring = aStrBuf.makeStringAndClear(); + } +} + + + + +////////////////////////////////////////////////////////////////////////// +// XInterface +////////////////////////////////////////////////////////////////////////// + + +void SAL_CALL +TVBase::acquire( + void ) + throw() +{ + OWeakObject::acquire(); +} + + +void SAL_CALL +TVBase::release( + void ) + throw() +{ + OWeakObject::release(); +} + + +Any SAL_CALL +TVBase::queryInterface( + const Type& rType ) + throw( RuntimeException ) +{ + Any aRet = cppu::queryInterface( rType, + SAL_STATIC_CAST( XTypeProvider*, this ), + SAL_STATIC_CAST( XNameAccess*, this ), + SAL_STATIC_CAST( XHierarchicalNameAccess*, this ), + SAL_STATIC_CAST( XChangesNotifier*, this ), + SAL_STATIC_CAST( XComponent*, this ) ); + + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// XTypeProvider methods. + +XTYPEPROVIDER_IMPL_5( TVBase, + XTypeProvider, + XNameAccess, + XHierarchicalNameAccess, + XChangesNotifier, + XComponent ); + + + + + + +// TVRead + + +TVRead::TVRead( const ConfigData& configData,TVDom* tvDom ) +{ + if( ! tvDom ) + return; + + Title = tvDom->title; + configData.replaceName( Title ); + if( tvDom->isLeaf() ) + { + TargetURL = ( tvDom->getTargetURL() + configData.appendix ); + if( tvDom->anchor.getLength() ) + TargetURL += ( rtl::OUString::createFromAscii( "#" ) + + tvDom->anchor ); + } + else + Children = new TVChildTarget( configData,tvDom ); +} + + + +TVRead::~TVRead() +{ +} + + + + + + +// XNameAccess + +Any SAL_CALL +TVRead::getByName( const rtl::OUString& aName ) + throw( NoSuchElementException, + WrappedTargetException, + RuntimeException ) +{ + bool found( true ); + Any aAny; + if( aName.compareToAscii( "Title" ) == 0 ) + aAny <<= Title; + else if( aName.compareToAscii( "TargetURL" ) == 0 ) + aAny <<= TargetURL; + else if( aName.compareToAscii( "Children" ) == 0 ) + { + cppu::OWeakObject* p = Children.get(); + aAny <<= Reference< XInterface >( p ); + } + else + found = false; + + if( found ) + return aAny; + + throw NoSuchElementException(); +} + + + + +Sequence< rtl::OUString > SAL_CALL +TVRead::getElementNames( ) + throw( RuntimeException ) +{ + Sequence< rtl::OUString > seq( 3 ); + + seq[0] = rtl::OUString::createFromAscii( "Title" ); + seq[1] = rtl::OUString::createFromAscii( "TargetURL" ); + seq[2] = rtl::OUString::createFromAscii( "Children" ); + + return seq; +} + + + +sal_Bool SAL_CALL +TVRead::hasByName( const rtl::OUString& aName ) + throw( RuntimeException ) +{ + if( aName.compareToAscii( "Title" ) == 0 || + aName.compareToAscii( "TargetURL" ) == 0 || + aName.compareToAscii( "Children" ) == 0 ) + return true; + + return false; +} + + +// XHierarchicalNameAccess + +Any SAL_CALL +TVRead::getByHierarchicalName( const rtl::OUString& aName ) + throw( NoSuchElementException, + RuntimeException ) +{ + sal_Int32 idx; + rtl::OUString name( aName ); + + if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1 && + name.copy( 0,idx ).compareToAscii( "Children" ) == 0 ) + return Children->getByHierarchicalName( name.copy( 1 + idx ) ); + + return getByName( name ); +} + + + + +sal_Bool SAL_CALL +TVRead::hasByHierarchicalName( const rtl::OUString& aName ) + throw( RuntimeException ) +{ + sal_Int32 idx; + rtl::OUString name( aName ); + + if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1 && + name.copy( 0,idx ).compareToAscii( "Children" ) == 0 ) + return Children->hasByHierarchicalName( name.copy( 1 + idx ) ); + + return hasByName( name ); +} + + + +/**************************************************************************/ +/* */ +/* TVChildTarget */ +/* */ +/**************************************************************************/ + + + + +extern "C" void start_handler(void *userData, + const XML_Char *name, + const XML_Char **atts) +{ + TVDom::Kind kind; + + if( strcmp( name,"help_section" ) == 0 || + strcmp( name,"node" ) == 0 ) + kind = TVDom::tree_node; + else if( strcmp( name,"topic" ) == 0 ) + kind = TVDom::tree_leaf; + else + return; + + TVDom **tvDom = static_cast< TVDom** >( userData ); + TVDom *p; + p = *tvDom; + + *tvDom = p->newChild(); + p = *tvDom; + + p->setKind( kind ); + while( *atts ) + { + if( strcmp( *atts,"application" ) == 0 ) + p->setApplication( *(atts+1) ); + else if( strcmp( *atts,"title" ) == 0 ) + p->setTitle( *(atts+1) ); + else if( strcmp( *atts,"id" ) == 0 ) + p->setId( *(atts+1) ); + else if( strcmp( *atts,"anchor" ) == 0 ) + p->setAnchor( *(atts+1) ); + + atts+=2; + } +} + + +extern "C" void end_handler(void *userData, + const XML_Char *name ) +{ + (void)name; + + TVDom **tvDom = static_cast< TVDom** >( userData ); + *tvDom = (*tvDom)->getParent(); +} + + +extern "C" void data_handler( void *userData, + const XML_Char *s, + int len) +{ + TVDom **tvDom = static_cast< TVDom** >( userData ); + if( (*tvDom)->isLeaf() ) + (*tvDom)->setTitle( s,len ); +} + + + +TVChildTarget::TVChildTarget( const ConfigData& configData,TVDom* tvDom ) +{ + Elements.resize( tvDom->childs.size() ); + for( unsigned i = 0; i < Elements.size(); ++i ) + Elements[i] = new TVRead( configData,tvDom->childs[i] ); +} + + + + + +TVChildTarget::TVChildTarget( const Reference< XMultiServiceFactory >& xMSF ) +{ + ConfigData configData = init( xMSF ); + + if( ! configData.locale.getLength() || + ! configData.system.getLength() ) + return; + + sal_uInt64 ret,len = 0; + int j = configData.vFileURL.size(); + + TVDom tvDom; + TVDom* pTVDom = &tvDom; + + while( j ) + { + len = configData.vFileLen[--j]; + char* s = new char[ int(len) ]; // the buffer to hold the installed files + osl::File aFile( configData.vFileURL[j] ); + aFile.open( OpenFlag_Read ); + aFile.read( s,len,ret ); + aFile.close(); + + XML_Parser parser = XML_ParserCreate( 0 ); + XML_SetElementHandler( parser, + start_handler, + end_handler ); + XML_SetCharacterDataHandler( parser, + data_handler); + XML_SetUserData( parser,&pTVDom ); // does not return this + + int parsed = XML_Parse( parser,s,int( len ),j==0 ); + (void)parsed; + OSL_ENSURE( parsed, "TVChildTarget::TVChildTarget(): Tree file parsing failed" ); + + XML_ParserFree( parser ); + delete[] s; + } + + // now TVDom holds the relevant information + + Elements.resize( tvDom.childs.size() ); + for( unsigned i = 0; i < Elements.size(); ++i ) + Elements[i] = new TVRead( configData,tvDom.childs[i] ); +} + + +TVChildTarget::~TVChildTarget() +{ +} + + + +Any SAL_CALL +TVChildTarget::getByName( const rtl::OUString& aName ) + throw( NoSuchElementException, + WrappedTargetException, + RuntimeException ) +{ + rtl::OUString num( aName.getStr()+2,aName.getLength()-4 ); + sal_Int32 idx = num.toInt32() - 1; + if( idx < 0 || Elements.size() <= sal_uInt32( idx ) ) + throw NoSuchElementException(); + + Any aAny; + cppu::OWeakObject* p = Elements[idx].get(); + aAny <<= Reference< XInterface >( p ); + return aAny; +} + + + + +Sequence< rtl::OUString > SAL_CALL +TVChildTarget::getElementNames( ) + throw( RuntimeException ) +{ + Sequence< rtl::OUString > seq( Elements.size() ); + for( unsigned i = 0; i < Elements.size(); ++i ) + seq[i] = rtl::OUString::valueOf( sal_Int32( 1+i ) ); + + return seq; +} + + + +sal_Bool SAL_CALL +TVChildTarget::hasByName( const rtl::OUString& aName ) + throw( RuntimeException ) +{ + rtl::OUString num( aName.getStr()+2,aName.getLength()-4 ); + sal_Int32 idx = num.toInt32() - 1; + if( idx < 0 || Elements.size() <= sal_uInt32( idx ) ) + return false; + + return true; +} + + + +// XHierarchicalNameAccess + +Any SAL_CALL +TVChildTarget::getByHierarchicalName( const rtl::OUString& aName ) + throw( NoSuchElementException, + RuntimeException ) +{ + sal_Int32 idx; + rtl::OUString name( aName ); + + if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1 ) + { + rtl::OUString num( name.getStr()+2,idx-4 ); + sal_Int32 pref = num.toInt32() - 1; + + if( pref < 0 || Elements.size() <= sal_uInt32( pref ) ) + throw NoSuchElementException(); + + return Elements[pref]->getByHierarchicalName( name.copy( 1 + idx ) ); + } + else + return getByName( name ); +} + + + +sal_Bool SAL_CALL +TVChildTarget::hasByHierarchicalName( const rtl::OUString& aName ) + throw( RuntimeException ) +{ + sal_Int32 idx; + rtl::OUString name( aName ); + + if( ( idx = name.indexOf( sal_Unicode( '/' ) ) ) != -1 ) + { + rtl::OUString num( name.getStr()+2,idx-4 ); + sal_Int32 pref = num.toInt32() - 1; + if( pref < 0 || Elements.size() <= sal_uInt32( pref ) ) + return false; + + return Elements[pref]->hasByHierarchicalName( name.copy( 1 + idx ) ); + } + else + return hasByName( name ); +} + + + + + + +ConfigData TVChildTarget::init( const Reference< XMultiServiceFactory >& xSMgr ) +{ + ConfigData configData; + Reference< XMultiServiceFactory > sProvider( getConfiguration(xSMgr) ); + + /**********************************************************************/ + /* reading Office.Common */ + /**********************************************************************/ + + Reference< XHierarchicalNameAccess > xHierAccess( getHierAccess( sProvider, + "org.openoffice.Office.Common" ) ); + rtl::OUString system( getKey( xHierAccess,"Help/System" ) ); + sal_Bool showBasic( getBooleanKey(xHierAccess,"Help/ShowBasic") ); + rtl::OUString instPath( getKey( xHierAccess,"Path/Current/Help" ) ); + if( ! instPath.getLength() ) + // try to determine path from default + instPath = rtl::OUString::createFromAscii( "$(instpath)/help" ); + + // replace anything like $(instpath); + subst( xSMgr,instPath ); + + + /**********************************************************************/ + /* reading Webtop.Common */ + /**********************************************************************/ + + xHierAccess = getHierAccess( sProvider, + "org.openoffice.Webtop.Common" ); + rtl::OUString vendorName( getKey( xHierAccess,"Product/ooName" ) ); + + rtl::OUString setupversion( getKey( xHierAccess,"Product/ooSetupVersion" ) ); + rtl::OUString setupextension( getKey( xHierAccess,"Product/ooSetupExtension") ); + rtl::OUString vendorVersion( setupversion + + rtl::OUString::createFromAscii( " " ) + + setupextension ); + rtl::OUString vendorShort = vendorName; + + /**********************************************************************/ + /* reading setup */ + /**********************************************************************/ + + xHierAccess = getHierAccess( sProvider, + "org.openoffice.Setup" ); + + rtl::OUString productName( getKey( xHierAccess,"Product/ooName" ) ); + setupversion = getKey( xHierAccess,"Product/ooSetupVersion" ); + setupextension = rtl::OUString(); + + try + { + uno::Reference< lang::XMultiServiceFactory > xConfigProvider( + xSMgr ->createInstance(::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationProvider")), uno::UNO_QUERY_THROW); + + uno::Sequence < uno::Any > lParams(1); + beans::PropertyValue aParam ; + aParam.Name = ::rtl::OUString::createFromAscii("nodepath"); + aParam.Value <<= ::rtl::OUString::createFromAscii("/org.openoffice.Setup/Product"); + lParams[0] = uno::makeAny(aParam); + + // open it + uno::Reference< uno::XInterface > xCFG( xConfigProvider->createInstanceWithArguments( + ::rtl::OUString::createFromAscii("com.sun.star.configuration.ConfigurationAccess"), + lParams) ); + + uno::Reference< container::XNameAccess > xDirectAccess(xCFG, uno::UNO_QUERY); + uno::Any aRet = xDirectAccess->getByName(::rtl::OUString::createFromAscii("ooSetupExtension")); + + aRet >>= setupextension; + } + catch ( uno::Exception& ) + { + } + + rtl::OUString productVersion( setupversion + + rtl::OUString::createFromAscii( " " ) + + setupextension ); + rtl::OUString locale( getKey( xHierAccess,"L10N/ooLocale" ) ); + + + // Determine fileurl from url and locale + rtl::OUString url; + osl::FileBase::RC errFile = osl::FileBase::getFileURLFromSystemPath( instPath,url ); + if( errFile != osl::FileBase::E_None ) return configData; + if( url.lastIndexOf( sal_Unicode( '/' ) ) != url.getLength() - 1 ) + url += rtl::OUString::createFromAscii( "/" ); + rtl::OUString ret; + sal_Int32 idx; + osl::DirectoryItem aDirItem; + if( osl::FileBase::E_None == osl::DirectoryItem::get( url + locale,aDirItem ) ) + ret = locale; + else if( ( ( idx = locale.indexOf( '-' ) ) != -1 || + ( idx = locale.indexOf( '_' ) ) != -1 ) && + osl::FileBase::E_None == osl::DirectoryItem::get( url + locale.copy( 0,idx ), + aDirItem ) ) + ret = locale.copy( 0,idx ); + else + { + locale = rtl::OUString::createFromAscii( "en-US" ); + ret = rtl::OUString::createFromAscii("en"); + } + url = url + ret; + + // first of all, try do determine whether there are any *.tree files present + + // Start with extensions to set them at the end of the list + TreeFileIterator aTreeIt( locale ); + rtl::OUString aTreeFile; + sal_Int32 nFileSize; + while( (aTreeFile = aTreeIt.nextTreeFile( nFileSize ) ).getLength() > 0 ) + { + configData.vFileLen.push_back( nFileSize ); + configData.vFileURL.push_back( aTreeFile ); + } + + osl::Directory aDirectory( url ); + osl::FileStatus aFileStatus( FileStatusMask_FileName | FileStatusMask_FileSize | FileStatusMask_FileURL ); + if( osl::Directory::E_None == aDirectory.open() ) + { + int idx_ = 0; + rtl::OUString aFileUrl, aFileName; + while( aDirectory.getNextItem( aDirItem ) == osl::FileBase::E_None && + aDirItem.getFileStatus( aFileStatus ) == osl::FileBase::E_None && + aFileStatus.isValid( FileStatusMask_FileURL ) && + aFileStatus.isValid( FileStatusMask_FileName ) ) + { + aFileUrl = aFileStatus.getFileURL(); + aFileName = aFileStatus.getFileName(); + idx_ = aFileName.lastIndexOf( sal_Unicode( '.' ) ); + if( idx_ == -1 ) + continue; + + const sal_Unicode* str = aFileName.getStr(); + + if( aFileName.getLength() == idx_ + 5 && + ( str[idx_ + 1] == 't' || str[idx_ + 1] == 'T' ) && + ( str[idx_ + 2] == 'r' || str[idx_ + 2] == 'R' ) && + ( str[idx_ + 3] == 'e' || str[idx_ + 3] == 'E' ) && + ( str[idx_ + 4] == 'e' || str[idx_ + 4] == 'E' ) ) + { + OSL_ENSURE( aFileStatus.isValid( FileStatusMask_FileSize ), + "invalid file size" ); + + rtl::OUString baseName = aFileName.copy(0,idx_).toAsciiLowerCase(); + if(! showBasic && baseName.compareToAscii("sbasic") == 0 ) + continue; + + configData.vFileLen.push_back( aFileStatus.getFileSize() ); + configData.vFileURL.push_back( aFileUrl ); + } + } + aDirectory.close(); + } + + configData.m_vAdd[0] = 12; + configData.m_vAdd[1] = 15; + configData.m_vAdd[2] = 11; + configData.m_vAdd[3] = 14; + configData.m_vAdd[4] = 12; + configData.m_vReplacement[0] = productName; + configData.m_vReplacement[1] = productVersion; + configData.m_vReplacement[2] = vendorName; + configData.m_vReplacement[3] = vendorVersion; + configData.m_vReplacement[4] = vendorShort; + + configData.system = system; + configData.locale = locale; + configData.appendix = + rtl::OUString::createFromAscii( "?Language=" ) + + configData.locale + + rtl::OUString::createFromAscii( "&System=" ) + + configData.system + + rtl::OUString::createFromAscii( "&UseDB=no" ) ; + + return configData; +} + + + + + + + + + +Reference< XMultiServiceFactory > +TVChildTarget::getConfiguration(const Reference< XMultiServiceFactory >& m_xSMgr) const +{ + Reference< XMultiServiceFactory > sProvider; + if( m_xSMgr.is() ) + { + Any aAny; + aAny <<= rtl::OUString::createFromAscii( "plugin" ); + PropertyValue aProp( rtl::OUString::createFromAscii( "servertype" ), + -1, + aAny, + PropertyState_DIRECT_VALUE ); + + Sequence< Any > seq(1); + seq[0] <<= aProp; + + try + { + rtl::OUString sProviderService = + rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationProvider" ); + sProvider = + Reference< XMultiServiceFactory >( + m_xSMgr->createInstanceWithArguments( sProviderService,seq ), + UNO_QUERY ); + } + catch( const com::sun::star::uno::Exception& ) + { + OSL_ENSURE( sProvider.is(),"cant instantiate configuration" ); + } + } + + return sProvider; +} + + + +Reference< XHierarchicalNameAccess > +TVChildTarget::getHierAccess( const Reference< XMultiServiceFactory >& sProvider, + const char* file ) const +{ + Reference< XHierarchicalNameAccess > xHierAccess; + + if( sProvider.is() ) + { + Sequence< Any > seq(1); + rtl::OUString sReaderService = + rtl::OUString::createFromAscii( "com.sun.star.configuration.ConfigurationAccess" ); + + seq[0] <<= rtl::OUString::createFromAscii( file ); + + try + { + xHierAccess = + Reference< XHierarchicalNameAccess > + ( sProvider->createInstanceWithArguments( sReaderService,seq ), + UNO_QUERY ); + } + catch( const com::sun::star::uno::Exception& ) + { + } + } + + return xHierAccess; +} + + + +rtl::OUString +TVChildTarget::getKey( const Reference< XHierarchicalNameAccess >& xHierAccess, + const char* key ) const +{ + rtl::OUString instPath; + if( xHierAccess.is() ) + { + Any aAny; + try + { + aAny = + xHierAccess->getByHierarchicalName( rtl::OUString::createFromAscii( key ) ); + } + catch( const com::sun::star::container::NoSuchElementException& ) + { + } + aAny >>= instPath; + } + return instPath; +} + + +sal_Bool +TVChildTarget::getBooleanKey(const Reference< + XHierarchicalNameAccess >& xHierAccess, + const char* key) const +{ + sal_Bool ret = sal_False; + if( xHierAccess.is() ) + { + Any aAny; + try + { + aAny = + xHierAccess->getByHierarchicalName( + rtl::OUString::createFromAscii(key)); + } + catch( const com::sun::star::container::NoSuchElementException& ) + { + } + aAny >>= ret; + } + return ret; +} + + +void TVChildTarget::subst( const Reference< XMultiServiceFactory >& m_xSMgr, + rtl::OUString& instpath ) const +{ + Reference< XConfigManager > xCfgMgr; + if( m_xSMgr.is() ) + { + try + { + xCfgMgr = + Reference< XConfigManager >( + m_xSMgr->createInstance( rtl::OUString::createFromAscii( "com.sun.star.config.SpecialConfigManager" ) ), + UNO_QUERY ); + } + catch( const com::sun::star::uno::Exception& ) + { + OSL_ENSURE( xCfgMgr.is()," cant instantiate the special config manager " ); + } + } + + OSL_ENSURE( xCfgMgr.is(), "specialconfigmanager not found\n" ); + + if( xCfgMgr.is() ) + instpath = xCfgMgr->substituteVariables( instpath ); +} + + +//=================================================================== +// class ExtensionIteratorBase + +static rtl::OUString aSlash( rtl::OUString::createFromAscii( "/" ) ); +static rtl::OUString aHelpFilesBaseName( rtl::OUString::createFromAscii( "help" ) ); +static rtl::OUString aHelpMediaType( rtl::OUString::createFromAscii( "application/vnd.sun.star.help" ) ); + +ExtensionIteratorBase::ExtensionIteratorBase( const rtl::OUString& aLanguage ) + : m_eState( USER_EXTENSIONS ) + , m_aLanguage( aLanguage ) +{ + init(); +} + +void ExtensionIteratorBase::init() +{ + Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory(); + Reference< XPropertySet > xProps( xFactory, UNO_QUERY ); + OSL_ASSERT( xProps.is() ); + if (xProps.is()) + { + xProps->getPropertyValue( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= m_xContext; + OSL_ASSERT( m_xContext.is() ); + } + if( !m_xContext.is() ) + { + throw RuntimeException( + ::rtl::OUString::createFromAscii( "ExtensionIteratorBase::init(), no XComponentContext" ), + Reference< XInterface >() ); + } + + Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); + m_xSFA = Reference< ucb::XSimpleFileAccess >( + xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), + m_xContext ), UNO_QUERY_THROW ); + + m_bUserPackagesLoaded = false; + m_bSharedPackagesLoaded = false; + m_iUserPackage = 0; + m_iSharedPackage = 0; +} + +Reference< deployment::XPackage > ExtensionIteratorBase::implGetHelpPackageFromPackage + ( Reference< deployment::XPackage > xPackage, Reference< deployment::XPackage >& o_xParentPackageBundle ) +{ + o_xParentPackageBundle.clear(); + + Reference< deployment::XPackage > xHelpPackage; + if( !xPackage.is() ) + return xHelpPackage; + + // Check if parent package is registered + beans::Optional< beans::Ambiguous<sal_Bool> > option( xPackage->isRegistered + ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ) ); + bool bRegistered = false; + if( option.IsPresent ) + { + beans::Ambiguous<sal_Bool> const & reg = option.Value; + if( !reg.IsAmbiguous && reg.Value ) + bRegistered = true; + } + if( !bRegistered ) + return xHelpPackage; + + if( xPackage->isBundle() ) + { + Sequence< Reference< deployment::XPackage > > aPkgSeq = xPackage->getBundle + ( Reference<task::XAbortChannel>(), Reference<ucb::XCommandEnvironment>() ); + sal_Int32 nPkgCount = aPkgSeq.getLength(); + const Reference< deployment::XPackage >* pSeq = aPkgSeq.getConstArray(); + for( sal_Int32 iPkg = 0 ; iPkg < nPkgCount ; ++iPkg ) + { + const Reference< deployment::XPackage > xSubPkg = pSeq[ iPkg ]; + const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xSubPkg->getPackageType(); + rtl::OUString aMediaType = xPackageTypeInfo->getMediaType(); + if( aMediaType.equals( aHelpMediaType ) ) + { + xHelpPackage = xSubPkg; + o_xParentPackageBundle = xPackage; + break; + } + } + } + else + { + const Reference< deployment::XPackageTypeInfo > xPackageTypeInfo = xPackage->getPackageType(); + rtl::OUString aMediaType = xPackageTypeInfo->getMediaType(); + if( aMediaType.equals( aHelpMediaType ) ) + xHelpPackage = xPackage; + } + + return xHelpPackage; +} + +Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextUserHelpPackage + ( Reference< deployment::XPackage >& o_xParentPackageBundle ) +{ + Reference< deployment::XPackage > xHelpPackage; + + if( !m_bUserPackagesLoaded ) + { + Reference< XPackageManager > xUserManager = + thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("user") ); + m_aUserPackagesSeq = xUserManager->getDeployedPackages + ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); + + m_bUserPackagesLoaded = true; + } + + if( m_iUserPackage == m_aUserPackagesSeq.getLength() ) + { + m_eState = SHARED_EXTENSIONS; // Later: SHARED_MODULE + } + else + { + const Reference< deployment::XPackage >* pUserPackages = m_aUserPackagesSeq.getConstArray(); + Reference< deployment::XPackage > xPackage = pUserPackages[ m_iUserPackage++ ]; + VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextUserHelpPackage(): Invalid package" ); + xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle ); + } + + return xHelpPackage; +} + +Reference< deployment::XPackage > ExtensionIteratorBase::implGetNextSharedHelpPackage + ( Reference< deployment::XPackage >& o_xParentPackageBundle ) +{ + Reference< deployment::XPackage > xHelpPackage; + + if( !m_bSharedPackagesLoaded ) + { + Reference< XPackageManager > xSharedManager = + thePackageManagerFactory::get( m_xContext )->getPackageManager( rtl::OUString::createFromAscii("shared") ); + m_aSharedPackagesSeq = xSharedManager->getDeployedPackages + ( Reference< task::XAbortChannel >(), Reference< ucb::XCommandEnvironment >() ); + + m_bSharedPackagesLoaded = true; + } + + if( m_iSharedPackage == m_aSharedPackagesSeq.getLength() ) + { + m_eState = END_REACHED; + } + else + { + const Reference< deployment::XPackage >* pSharedPackages = m_aSharedPackagesSeq.getConstArray(); + Reference< deployment::XPackage > xPackage = pSharedPackages[ m_iSharedPackage++ ]; + VOS_ENSURE( xPackage.is(), "ExtensionIteratorBase::implGetNextSharedHelpPackage(): Invalid package" ); + xHelpPackage = implGetHelpPackageFromPackage( xPackage, o_xParentPackageBundle ); + } + + return xHelpPackage; +} + +inline bool isLetter( sal_Unicode c ) +{ + bool bLetter = ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); + return bLetter; +} + +void ExtensionIteratorBase::implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv, + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage ) +{ + rv.clear(); + rtl::OUString aExtensionPath = xPackage->getURL(); + Sequence< rtl::OUString > aEntrySeq = m_xSFA->getFolderContents( aExtensionPath, true ); + + const rtl::OUString* pSeq = aEntrySeq.getConstArray(); + sal_Int32 nCount = aEntrySeq.getLength(); + for( sal_Int32 i = 0 ; i < nCount ; ++i ) + { + rtl::OUString aEntry = pSeq[i]; + if( m_xSFA->isFolder( aEntry ) ) + { + sal_Int32 nLastSlash = aEntry.lastIndexOf( '/' ); + if( nLastSlash != -1 ) + { + rtl::OUString aPureEntry = aEntry.copy( nLastSlash + 1 ); + + // Check language sceme + int nLen = aPureEntry.getLength(); + const sal_Unicode* pc = aPureEntry.getStr(); + bool bStartCanBeLanguage = ( nLen >= 2 && isLetter( pc[0] ) && isLetter( pc[1] ) ); + bool bIsLanguage = bStartCanBeLanguage && + ( nLen == 2 || (nLen == 5 && pc[2] == '-' && isLetter( pc[3] ) && isLetter( pc[4] )) ); + if( bIsLanguage ) + rv.push_back( aPureEntry ); + } + } + } +} + + +//=================================================================== +// class TreeFileIterator + +rtl::OUString TreeFileIterator::nextTreeFile( sal_Int32& rnFileSize ) +{ + rtl::OUString aRetFile; + + while( !aRetFile.getLength() && m_eState != END_REACHED ) + { + switch( m_eState ) + { + case USER_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextUserHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + aRetFile = implGetTreeFileFromPackage( rnFileSize, xHelpPackage ); + break; + } + + case SHARED_EXTENSIONS: + { + Reference< deployment::XPackage > xParentPackageBundle; + Reference< deployment::XPackage > xHelpPackage = implGetNextSharedHelpPackage( xParentPackageBundle ); + if( !xHelpPackage.is() ) + break; + + aRetFile = implGetTreeFileFromPackage( rnFileSize, xHelpPackage ); + break; + } + case END_REACHED: + VOS_ENSURE( false, "DataBaseIterator::nextTreeFile(): Invalid case END_REACHED" ); + break; + } + } + + return aRetFile; +} + +rtl::OUString TreeFileIterator::expandURL( const rtl::OUString& aURL ) +{ + static Reference< util::XMacroExpander > xMacroExpander; + static Reference< uri::XUriReferenceFactory > xFac; + + osl::MutexGuard aGuard( m_aMutex ); + + if( !xMacroExpander.is() || !xFac.is() ) + { + Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY ); + + xFac = Reference< uri::XUriReferenceFactory >( + xSMgr->createInstanceWithContext( rtl::OUString::createFromAscii( + "com.sun.star.uri.UriReferenceFactory"), m_xContext ) , UNO_QUERY ); + if( !xFac.is() ) + { + throw RuntimeException( + ::rtl::OUString::createFromAscii( "Databases::expand(), could not instatiate UriReferenceFactory." ), + Reference< XInterface >() ); + } + + xMacroExpander = Reference< util::XMacroExpander >( + m_xContext->getValueByName( + ::rtl::OUString::createFromAscii( "/singletons/com.sun.star.util.theMacroExpander" ) ), + UNO_QUERY_THROW ); + } + + rtl::OUString aRetURL = aURL; + if( xMacroExpander.is() ) + { + Reference< uri::XUriReference > uriRef; + for (;;) + { + uriRef = Reference< uri::XUriReference >( xFac->parse( aRetURL ), UNO_QUERY ); + if ( uriRef.is() ) + { + Reference < uri::XVndSunStarExpandUrl > sxUri( uriRef, UNO_QUERY ); + if( !sxUri.is() ) + break; + + aRetURL = sxUri->expand( xMacroExpander ); + } + } + } + return aRetURL; +} + +rtl::OUString TreeFileIterator::implGetTreeFileFromPackage + ( sal_Int32& rnFileSize, Reference< deployment::XPackage > xPackage ) +{ + rtl::OUString aRetFile; + rtl::OUString aLanguage = m_aLanguage; + for( sal_Int32 iPass = 0 ; iPass < 2 ; ++iPass ) + { + rtl::OUStringBuffer aStrBuf; + aStrBuf.append( xPackage->getURL() ); + aStrBuf.append( aSlash ); + aStrBuf.append( aLanguage ); + aStrBuf.append( aSlash ); + aStrBuf.append( aHelpFilesBaseName ); + aStrBuf.appendAscii( ".tree" ); + + aRetFile = expandURL( aStrBuf.makeStringAndClear() ); + if( iPass == 0 ) + { + if( m_xSFA->exists( aRetFile ) ) + break; + + ::std::vector< ::rtl::OUString > av; + implGetLanguageVectorFromPackage( av, xPackage ); + ::std::vector< ::rtl::OUString >::const_iterator pFound = av.end(); + try + { + pFound = ::comphelper::Locale::getFallback( av, m_aLanguage ); + } + catch( ::comphelper::Locale::MalFormedLocaleException& ) + {} + if( pFound != av.end() ) + aLanguage = *pFound; + } + } + + rnFileSize = 0; + if( m_xSFA->exists( aRetFile ) ) + rnFileSize = m_xSFA->getSize( aRetFile ); + else + aRetFile = rtl::OUString(); + + return aRetFile; +} + + + diff --git a/xmlhelp/source/treeview/tvread.hxx b/xmlhelp/source/treeview/tvread.hxx new file mode 100644 index 000000000000..e96e09ed97f0 --- /dev/null +++ b/xmlhelp/source/treeview/tvread.hxx @@ -0,0 +1,398 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tvread.hxx,v $ + * $Revision: 1.16 $ + * + * 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 + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _TREEVIEW_TVREAD_HXX_ +#define _TREEVIEW_TVREAD_HXX_ + +#ifndef INCLUDED_STL_VECTOR +#include <vector> +#define INCLUDED_STL_VECTOR +#endif +#include <rtl/ref.hxx> +#include <rtl/ustring.hxx> +#include <ucbhelper/macros.hxx> +#include <com/sun/star/uno/Type.hxx> +#include <cppuhelper/weak.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/util/XChangesNotifier.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/deployment/XPackage.hpp> +#include "com/sun/star/ucb/XSimpleFileAccess.hpp" + +namespace treeview { + + + class ConfigData + { + public: + enum { + PRODUCTNAME, PRODUCTVERSION, VENDORNAME, VENDORVERSION, + VENDORSHORT }; + ConfigData(); + int m_vAdd[5]; + rtl::OUString m_vReplacement[5]; + rtl::OUString prodName,prodVersion,vendName,vendVersion,vendShort; + + std::vector< sal_uInt64 > vFileLen; + std::vector< rtl::OUString > vFileURL; + rtl::OUString locale,system; + rtl::OUString appendix; + + void SAL_CALL replaceName( rtl::OUString& oustring ) const; + }; + + + class TVDom; + class TVChildTarget; + + class TVBase + : public cppu::OWeakObject, + public com::sun::star::lang::XTypeProvider, + public com::sun::star::container::XNameAccess, + public com::sun::star::container::XHierarchicalNameAccess, + public com::sun::star::util::XChangesNotifier, + public com::sun::star::lang::XComponent + { + friend class TVChildTarget; + + public: + + virtual ~TVBase() { } + + // XInterface + virtual com::sun::star::uno::Any SAL_CALL + queryInterface( + const com::sun::star::uno::Type& aType ) + throw( com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL + acquire( + void ) + throw(); + + virtual void SAL_CALL + release( + void ) + throw(); + + + // XTypeProvider + + XTYPEPROVIDER_DECL() + + + // XNameAccess + + virtual com::sun::star::uno::Type SAL_CALL + getElementType( ) + throw( com::sun::star::uno::RuntimeException ) + { + return getCppuVoidType(); + } + + + virtual sal_Bool SAL_CALL hasElements() + throw( com::sun::star::uno::RuntimeException ) + { + return true; + } + + // XChangesNotifier + + virtual void SAL_CALL + addChangesListener( + const com::sun::star::uno::Reference< com::sun::star::util::XChangesListener >& aListener ) + throw( com::sun::star::uno::RuntimeException ) + { + // read only + (void)aListener; + } + + virtual void SAL_CALL + removeChangesListener( + const com::sun::star::uno::Reference< com::sun::star::util::XChangesListener >& aListener ) + throw( com::sun::star::uno::RuntimeException ) + { + // read only + (void)aListener; + } + + + // XComponent + + virtual void SAL_CALL dispose( ) + throw( com::sun::star::uno::RuntimeException ) + { + } + + virtual void SAL_CALL addEventListener( + const com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >& xListener ) + throw( com::sun::star::uno::RuntimeException ) + { + (void)xListener; + } + + virtual void SAL_CALL + removeEventListener( + const com::sun::star::uno::Reference< com::sun::star::lang::XEventListener >& aListener ) + throw( com::sun::star::uno::RuntimeException ) + { + (void)aListener; + } + + + // Abstract functions + // XNameAccess + + virtual com::sun::star::uno::Any SAL_CALL + getByName( const rtl::OUString& aName ) + throw( com::sun::star::container::NoSuchElementException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException) = 0; + + virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL + getElementNames( ) + throw( com::sun::star::uno::RuntimeException ) = 0; + + virtual sal_Bool SAL_CALL + hasByName( const rtl::OUString& aName ) + throw( com::sun::star::uno::RuntimeException ) = 0; + + + // XHierarchicalNameAccess + + virtual com::sun::star::uno::Any SAL_CALL + getByHierarchicalName( const rtl::OUString& aName ) + throw( com::sun::star::container::NoSuchElementException, + com::sun::star::uno::RuntimeException ) = 0; + + virtual sal_Bool SAL_CALL + hasByHierarchicalName( const rtl::OUString& aName ) + throw( com::sun::star::uno::RuntimeException ) = 0; + + }; // end class TVBase + + + + + + class TVRead + : public TVBase + { + friend class TVChildTarget; + + public: + TVRead( const ConfigData& configData,TVDom* tvDom = 0 ); + + ~TVRead(); + + // XNameAccess + + virtual com::sun::star::uno::Any SAL_CALL + getByName( const rtl::OUString& aName ) + throw( com::sun::star::container::NoSuchElementException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL + getElementNames( ) + throw( com::sun::star::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL + hasByName( const rtl::OUString& aName ) + throw( com::sun::star::uno::RuntimeException ); + + + // XHierarchicalNameAccess + + virtual com::sun::star::uno::Any SAL_CALL + getByHierarchicalName( const rtl::OUString& aName ) + throw( com::sun::star::container::NoSuchElementException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL + hasByHierarchicalName( const rtl::OUString& aName ) + throw( com::sun::star::uno::RuntimeException ); + + + private: + + rtl::OUString Title; + rtl::OUString TargetURL; + rtl::Reference< TVChildTarget > Children; + + }; // end class TVRead + + + + + + + class TVChildTarget + : public TVBase + { + public: + + TVChildTarget( const ConfigData& configData,TVDom* tvDom ); + + TVChildTarget( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xMSF ); + + ~TVChildTarget(); + + virtual com::sun::star::uno::Any SAL_CALL + getByName( const rtl::OUString& aName ) + throw( com::sun::star::container::NoSuchElementException, + com::sun::star::lang::WrappedTargetException, + com::sun::star::uno::RuntimeException); + + virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL + getElementNames( ) + throw( com::sun::star::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL + hasByName( const rtl::OUString& aName ) + throw( com::sun::star::uno::RuntimeException ); + + + // XHierarchicalNameAccess + + virtual com::sun::star::uno::Any SAL_CALL + getByHierarchicalName( const rtl::OUString& aName ) + throw( com::sun::star::container::NoSuchElementException, + com::sun::star::uno::RuntimeException ); + + virtual sal_Bool SAL_CALL + hasByHierarchicalName( const rtl::OUString& aName ) + throw( com::sun::star::uno::RuntimeException ); + + + private: + std::vector< rtl::Reference< TVRead > > Elements; + + ConfigData init( + const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xMSF ); + + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > + getConfiguration( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xMSgr ) const; + + ::com::sun::star::uno::Reference< ::com::sun::star::container::XHierarchicalNameAccess > + getHierAccess( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& sProvider, + const char* file ) const; + + ::rtl::OUString + getKey( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XHierarchicalNameAccess >& xHierAccess, + const char* key ) const; + + sal_Bool + getBooleanKey( + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XHierarchicalNameAccess >& xHierAccess, + const char* key) const; + + void subst( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xMSgr, + rtl::OUString& instpath ) const; + + }; // end class TVChildTarget + + + enum IteratorState + { + USER_EXTENSIONS, + SHARED_EXTENSIONS, + END_REACHED + }; + + class ExtensionIteratorBase + { + public: + ExtensionIteratorBase( const rtl::OUString& aLanguage ); + void init( void ); + + private: + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetHelpPackageFromPackage + ( const com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage, + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle ); + + protected: + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetNextUserHelpPackage + ( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle ); + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > implGetNextSharedHelpPackage + ( com::sun::star::uno::Reference< com::sun::star::deployment::XPackage >& o_xParentPackageBundle ); + void implGetLanguageVectorFromPackage( ::std::vector< ::rtl::OUString > &rv, + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage ); + + osl::Mutex m_aMutex; + com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > m_xContext; + com::sun::star::uno::Reference< com::sun::star::ucb::XSimpleFileAccess > m_xSFA; + + IteratorState m_eState; + rtl::OUString m_aLanguage; + + com::sun::star::uno::Sequence< com::sun::star::uno::Reference + < com::sun::star::deployment::XPackage > > m_aUserPackagesSeq; + bool m_bUserPackagesLoaded; + + com::sun::star::uno::Sequence< com::sun::star::uno::Reference + < com::sun::star::deployment::XPackage > > m_aSharedPackagesSeq; + bool m_bSharedPackagesLoaded; + + int m_iUserPackage; + int m_iSharedPackage; + + }; // end class ExtensionIteratorBase + + + //=================================================================== + class TreeFileIterator : public ExtensionIteratorBase + { + public: + TreeFileIterator( const rtl::OUString& aLanguage ) + : ExtensionIteratorBase( aLanguage ) + {} + + rtl::OUString nextTreeFile( sal_Int32& rnFileSize ); + + private: + rtl::OUString expandURL( const rtl::OUString& aURL ); + rtl::OUString implGetTreeFileFromPackage( sal_Int32& rnFileSize, + com::sun::star::uno::Reference< com::sun::star::deployment::XPackage > xPackage ); + + }; // end class TreeFileIterator + + +} + + +#endif diff --git a/xmlhelp/util/exports.map b/xmlhelp/util/exports.map new file mode 100644 index 000000000000..14a2531f23ad --- /dev/null +++ b/xmlhelp/util/exports.map @@ -0,0 +1,8 @@ +VERS_1_0 { + global: + component_getImplementationEnvironment; + component_writeInfo; + component_getFactory; + local: + *; +}; diff --git a/xmlhelp/util/makefile.mk b/xmlhelp/util/makefile.mk new file mode 100644 index 000000000000..a16e7958d796 --- /dev/null +++ b/xmlhelp/util/makefile.mk @@ -0,0 +1,82 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2008 by Sun Microsystems, Inc. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.15 $ +# +# 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 +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +UCP_VERSION=1 +UCP_NAME=chelp + +PRJ=.. +PRJNAME=xmlhelp +TARGET=ucp$(UCP_NAME) +UCPHELP_MAJOR=1 + +ENABLE_EXCEPTIONS=TRUE +USE_DEFFILE=TRUE +NO_BSYMBOLIC=TRUE + +# --- Settings --------------------------------------------------------- + +.INCLUDE: settings.mk + +.IF "$(GUI)"=="WNT" +CFLAGS+=-GR +.ENDIF + +# --- Shared-Library --------------------------------------------------- + +SHL1TARGET=$(TARGET)$(UCP_VERSION) +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +SHL1IMPLIB=i$(TARGET) +SHL1VERSIONMAP=exports.map + +# Add additional libs here. +SHL1STDLIBS= \ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(COMPHELPERLIB) \ + $(SALLIB) \ + $(EXPATASCII3RDLIB) \ + $(UCBHELPERLIB) \ + $(BERKELEYLIB) \ + $(XSLTLIB) + +SHL1LIBS = \ + $(SLB)$/jaqe.lib \ + $(SLB)$/jautil.lib \ + $(SLB)$/chelp.lib + +# --- Def-File --------------------------------------------------------- + +DEF1NAME=$(SHL1TARGET) + +# --- Targets ---------------------------------------------------------- + +.INCLUDE: target.mk + diff --git a/xmlhelp/util/ucpchelp.xml b/xmlhelp/util/ucpchelp.xml new file mode 100644 index 000000000000..7897b0db8151 --- /dev/null +++ b/xmlhelp/util/ucpchelp.xml @@ -0,0 +1,97 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + + <module-name> + ucpchelp + </module-name> + + <component-description> + <author> + Andreas Bille + </author> + <name> + CHelpContentProvider + </name> + <description> + This component implements a Content Provider for the Universal + Content Broker. It provides access to help content and an index of those files + </description> + <loader-name> + com.sun.star.loader.SharedLibrary + </loader-name> + <language> + c++ + </language> + <status value="final"/> + <supported-service> + com.sun.star.ucb.HelpContentProvider + </supported-service> + + <service-dependency> + com.sun.star.i18n.Collator + </service-dependency> + <service-dependency> + com.sun.star.configuration.ConfigurationProvider + </service-dependency> + </component-description> + + <project-build-dependency> sablot </project-build-dependency> + <project-build-dependency> unoil </project-build-dependency> + <project-build-dependency> offuh </project-build-dependency> + <project-build-dependency> external </project-build-dependency> + <project-build-dependency> XmlSearch </project-build-dependency> + <project-build-dependency> ucbhelper </project-build-dependency> + <project-build-dependency> berkeleydb </project-build-dependency> + + <runtime-module-dependency> sal3 </runtime-module-dependency> + <runtime-module-dependency> cppu3 </runtime-module-dependency> + <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency> + <runtime-module-dependency> libdb32 </runtime-module-dependency> + <runtime-module-dependency> ucbhelper4$(COM) </runtime-module-dependency> + + <type>com.sun.star.beans.Property</type> + <type>com.sun.star.beans.PropertyAttribute</type> + <type>com.sun.star.beans.PropertyValue</type> + <type>com.sun.star.beans.PropertyState</type> + <type>com.sun.star.beans.XPropertyAccess</type> + <type>com.sun.star.beans.XPropertySet</type> + <type>com.sun.star.container.XHierarchicalNameAccess</type> + <type>com.sun.star.frame.XConfigManager</type> + <type>com.sun.star.i18n.XCollator</type> + <type>com.sun.star.io.XOutputStream</type> + <type>com.sun.star.io.XActiveDataStreamer</type> + <type>com.sun.star.io.XInputStream</type> + <type>com.sun.star.io.XActiveDataSink</type> + <type>com.sun.star.io.XSeekable</type> + <type>com.sun.star.lang.Locale</type> + <type>com.sun.star.lang.XComponent</type> + <type>com.sun.star.lang.XMultiServiceFactory</type> + <type>com.sun.star.lang.XSingleServiceFactory</type> + <type>com.sun.star.registry.XRegistryKey</type> + <type>com.sun.star.sdbc.XRow</type> + <type>com.sun.star.sdbc.XResultSet</type> + <type>com.sun.star.sdbc.XCloseable</type> + <type>com.sun.star.sdbc.XResultSetMetaDataSupplier</type> + <type>com.sun.star.ucb.OpenCommandArgument2</type> + <type>com.sun.star.ucb.OpenMode</type> + <type>com.sun.star.ucb.UnsupportedDataSinkException</type> + <type>com.sun.star.ucb.Command</type> + <type>com.sun.star.ucb.CommandInfo</type> + <type>com.sun.star.ucb.OpenCommandArgument2</type> + <type>com.sun.star.ucb.NumberedSortingInfo</type> + <type>com.sun.star.ucb.ListActionType</type> + <type>com.sun.star.ucb.IllegalIdentifierException</type> + <type>com.sun.star.ucb.XContentProvider</type> + <type>com.sun.star.ucb.XContent</type> + <type>com.sun.star.ucb.XContentIdentifier</type> + <type>com.sun.star.ucb.XContentIdentifierFactory</type> + <type>com.sun.star.ucb.XContentAccess</type> + <type>com.sun.star.ucb.XPersistentPropertySet</type> + <type>com.sun.star.ucb.XSourceInitialization</type> + <type>com.sun.star.ucb.XCommandEnvironment</type> + <type>com.sun.star.ucb.XCommandProcessor</type> + <type>com.sun.star.ucb.XCommandInfo</type> + <type>com.sun.star.uno.XInterface</type> + +</module-description> |