/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #include "filterdetect.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace rtl; using namespace com::sun::star::uno; using namespace com::sun::star::document; using namespace com::sun::star::lang; using namespace com::sun::star::io; using namespace com::sun::star::beans; using namespace com::sun::star::xml::sax; using namespace com::sun::star::xml; using namespace com::sun::star::task; using namespace com::sun::star::frame; using namespace com::sun::star::container; using namespace com::sun::star::ucb; OUString SAL_CALL FilterDetect::detect(Sequence< PropertyValue >& aArguments ) throw( RuntimeException ) { // type name to return OUString sOriginalTypeName; OUString sTypeName; OUString sURL; // stream of the document to be detected Reference< XInputStream > xInStream; for ( sal_Int32 i = 0 ; i < aArguments.getLength(); i++) { OUString aName = aArguments[i].Name; if (aName.equalsAscii("TypeName" ) ) aArguments[i].Value >>= sOriginalTypeName; if (aName.equalsAscii("URL" ) ) aArguments[i].Value >>= sURL; if (aName.equalsAscii("InputStream" ) ) aArguments[i].Value >>= xInStream; } if (!xInStream.is()) { // open the stream if it was not suplied by the framework Reference< XSimpleFileAccess > xSFI(mxMSF->createInstance( OUString::createFromAscii("com.sun.star.ucb.SimpleFileAccess" )), UNO_QUERY); if (sURL.getLength() > 0 && xSFI.is()) { try { xInStream = xSFI->openFileRead( sURL); } catch( Exception& ) { return sTypeName; } } else { // failed to access UCB return sTypeName; } } // flatxml starts with an office:document element. this element // conatains a clas="..." attribut by which we can deduct the // type of document that is to be loaded // // WARNING: // parsing the plain text of the document is an easy way to do this // but not the purest solution, since namespaces and other xml details // may lead to another syntactic expression of the same document. // this example works for the way the office serializes it's XML stream // but might need extension for other data sources... static OString aDocToken("office:document"); // static OString aClassToken("office:class=\""); static OString aMimeTypeToken("office:mimetype=\""); sal_Int32 nHeadSize = 4096; Sequence< sal_Int8 > aHeadData(nHeadSize); // rewind seekable stream Reference< XSeekable > xSeek(xInStream, UNO_QUERY); if (xSeek.is()) xSeek->seek(0); long bytestRead = xInStream->readBytes(aHeadData, nHeadSize); OString aHead = OString((const sal_Char *)aHeadData.getConstArray(), bytestRead).toAsciiLowerCase(); // check for document element of flatxml format if (aHead.indexOf(aDocToken) >= 0) { // read document class sal_Int32 n = aHead.indexOf(aMimeTypeToken); if (n >= 0) { n += aMimeTypeToken.getLength(); OString aMimeType = aHead.copy(n, aHead.indexOf('\"', n) - n); // return type for class found if (aMimeType.equals("application/x-vnd.oasis.opendocument.text") || aMimeType.equals("application/vnd.oasis.opendocument.text")) sTypeName = OUString::createFromAscii("devguide_FlatXMLType_Cpp_writer"); else if (aMimeType.equals("application/x-vnd.oasis.opendocument.text-master") || aMimeType.equals("application/vnd.oasis.opendocument.text-master")) sTypeName = OUString::createFromAscii("devguide_FlatXMLType_Cpp_master"); else if (aMimeType.equals("application/x-vnd.oasis.openoffice.text-global") || aMimeType.equals("application/vnd.oasis.openoffice.text-global")) sTypeName = OUString::createFromAscii("devguide_FlatXMLType_Cpp_master"); else if (aMimeType.equals("application/x-vnd.oasis.opendocument.spreadsheet") || aMimeType.equals("application/vnd.oasis.opendocument.spreadsheet")) sTypeName = OUString::createFromAscii("devguide_FlatXMLType_Cpp_calc"); else if (aMimeType.equals("application/x-vnd.oasis.opendocument.drawing") || aMimeType.equals("application/vnd.oasis.opendocument.drawing")) sTypeName = OUString::createFromAscii("devguide_FlatXMLType_Cpp_draw"); else if (aMimeType.equals("application/x-vnd.oasis.opendocument.presentation") || aMimeType.equals("application/vnd.oasis.opendocument.presentation")) sTypeName = OUString::createFromAscii("devguide_FlatXMLType_Cpp_impress"); else if (aMimeType.equals("application/x-vnd.oasis.opendocument.presentation") || aMimeType.equals("application/vnd.oasis.opendocument.presentation")) sTypeName = OUString::createFromAscii("devguide_FlatXMLType_Cpp_impress"); } } return sTypeName; } // XInitialization void SAL_CALL FilterDetect::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException) { Sequence < PropertyValue > aAnySeq; sal_Int32 nLength = aArguments.getLength(); if ( nLength && ( aArguments[0] >>= aAnySeq ) ) { const PropertyValue * pValue = aAnySeq.getConstArray(); nLength = aAnySeq.getLength(); for ( sal_Int32 i = 0 ; i < nLength; i++) { if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "Type" ) ) ) { pValue[i].Value >>= msFilterName; } else if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "UserData" ) ) ) { pValue[i].Value >>= msUserData; } else if ( pValue[i].Name.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "TemplateName" ) ) ) { pValue[i].Value>>=msTemplateName; } } } } OUString FilterDetect_getImplementationName () throw (RuntimeException) { return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "devguide.officedev.samples.filter.FlatXmlDetect" ) ); } #define SERVICE_NAME1 "com.sun.star.document.ExtendedTypeDetection" sal_Bool SAL_CALL FilterDetect_supportsService( const OUString& ServiceName ) throw (RuntimeException) { return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME1 ) ); } Sequence< OUString > SAL_CALL FilterDetect_getSupportedServiceNames( ) throw (RuntimeException) { Sequence < OUString > aRet(2); OUString* pArray = aRet.getArray(); pArray[0] = OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME1 ) ); return aRet; } #undef SERVICE_NAME1 #undef SERVICE_NAME2 Reference< XInterface > SAL_CALL FilterDetect_createInstance( const Reference< XMultiServiceFactory > & rSMgr) throw( Exception ) { return (cppu::OWeakObject*) new FilterDetect( rSMgr ); } // XServiceInfo OUString SAL_CALL FilterDetect::getImplementationName( ) throw (RuntimeException) { return FilterDetect_getImplementationName(); } sal_Bool SAL_CALL FilterDetect::supportsService( const OUString& rServiceName ) throw (RuntimeException) { return FilterDetect_supportsService( rServiceName ); } Sequence< OUString > SAL_CALL FilterDetect::getSupportedServiceNames( ) throw (RuntimeException) { return FilterDetect_getSupportedServiceNames(); }