1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include <cppuhelper/implementationentry.hxx>
25 #include <WriterFilterDetection.hxx>
26 #include <comphelper/storagehelper.hxx>
27 #include <com/sun/star/io/XInputStream.hpp>
28 #include <sot/storage.hxx>
29 //#ifndef _SFXDOCFILE_HXX //todo: remove sfx2!
30 //#include <sfx2/docfile.hxx>
31 //#endif
32 #include <unotools/ucbstreamhelper.hxx>
33 
34 using namespace ::rtl;
35 using namespace ::cppu;
36 using namespace ::com::sun::star;
37 
38 /*-- 22.02.2007 12:17:53---------------------------------------------------
39 
40   -----------------------------------------------------------------------*/
WriterFilterDetection(const uno::Reference<uno::XComponentContext> & rxContext)41 WriterFilterDetection::WriterFilterDetection(
42     const uno::Reference< uno::XComponentContext >& rxContext) :
43     m_xContext( rxContext )
44 {
45 }
46 /*-- 22.02.2007 12:17:53---------------------------------------------------
47 
48   -----------------------------------------------------------------------*/
~WriterFilterDetection()49 WriterFilterDetection::~WriterFilterDetection()
50 {
51 }
52 /*-- 22.02.2007 12:11:38---------------------------------------------------
53 
54   -----------------------------------------------------------------------*/
WriterFilterDetection_getImplementationName()55 OUString WriterFilterDetection_getImplementationName () throw (uno::RuntimeException)
56 {
57    return OUString ( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.comp.Writer.WriterFilterDetector" ) );
58 }
59 
60 #define SERVICE_NAME1 "com.sun.star.document.ExtendedTypeDetection"
61 /*-- 22.02.2007 12:11:38---------------------------------------------------
62 
63   -----------------------------------------------------------------------*/
detect(uno::Sequence<beans::PropertyValue> & rDescriptor)64 OUString WriterFilterDetection::detect( uno::Sequence< beans::PropertyValue >& rDescriptor )
65    throw( uno::RuntimeException )
66 {
67     OUString sTypeName;
68     bool bWord = false;
69     sal_Int32 nPropertyCount = rDescriptor.getLength();
70     const beans::PropertyValue* pValues = rDescriptor.getConstArray();
71     rtl::OUString sURL;
72     uno::Reference < io::XStream > xStream;
73     uno::Reference < io::XInputStream > xInputStream;
74     for( sal_Int32 nProperty = 0; nProperty < nPropertyCount; ++nProperty )
75     {
76         if( pValues[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("TypeName")) )
77             rDescriptor[nProperty].Value >>= sTypeName;
78         else if( pValues[nProperty].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM ( "URL" )) )
79             pValues[nProperty].Value >>= sURL;
80         else if( pValues[nProperty].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM ( "Stream" )) )
81             pValues[nProperty].Value >>= xStream;
82         else if( pValues[nProperty].Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM ( "InputStream" )) )
83             pValues[nProperty].Value >>= xInputStream;
84     }
85     bool bBinary = sTypeName.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "writer_MS_Word_97" )) ||
86                    sTypeName.equalsAsciiL ( RTL_CONSTASCII_STRINGPARAM ( "writer_MS_Word_97_Vorlage" ));
87 
88     try
89     {
90         if(bBinary)
91         {
92             SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( xInputStream );
93             if ( pStream && SotStorage::IsStorageFile(pStream) )
94 
95             {
96                 SotStorageRef xStg = new SotStorage( pStream, sal_False );
97 
98                 bool bTable2 = xStg->IsContained( rtl::OUString::createFromAscii("1Table" ));
99                 SotStorageStreamRef xRef =
100 
101                     xStg->OpenSotStream(rtl::OUString::createFromAscii("WordDocument"),
102 
103                             STREAM_STD_READ | STREAM_NOCREATE );
104 
105                 if(bTable2 && xStg.Is())
106                 {
107                     xRef->Seek(2);
108                     sal_Int16 nWord;
109                     *xRef >> nWord;
110                     //version detection
111                     bWord = nWord >= 0x6a && nWord <= 0xc1;
112                 }
113             }
114         }
115         else
116         {
117             uno::Reference< embed::XStorage > xDocStorage;
118             if( sURL.equalsAscii( "private:stream" ) )
119                 xDocStorage = comphelper::OStorageHelper::GetStorageFromInputStream( xInputStream );
120             else
121                 xDocStorage = comphelper::OStorageHelper::GetStorageFromURL(
122                                             sURL, embed::ElementModes::READ );
123             if( xDocStorage.is() )
124             {
125                 uno::Sequence< ::rtl::OUString > aNames = xDocStorage->getElementNames();
126                 const ::rtl::OUString* pNames = aNames.getConstArray();
127                 for(sal_Int32 nName = 0; nName < aNames.getLength(); ++nName)
128                 {
129                     if(pNames[nName].equalsAsciiL(RTL_CONSTASCII_STRINGPARAM ( "word" )))
130                     {
131                         bWord = true;
132                         if( !sTypeName.getLength() )
133                             sTypeName = ::rtl::OUString(
134                                     RTL_CONSTASCII_STRINGPARAM( "writer_MS_Word_2007" ), RTL_TEXTENCODING_ASCII_US);
135                         break;
136                     }
137                 }
138             }
139         }
140     }
141     catch(const uno::Exception&)
142     {
143         OSL_ASSERT("exception while opening storage");
144     }
145     if( !bWord )
146         sTypeName = ::rtl::OUString();
147    return sTypeName;
148 }
149 /*-- 22.02.2007 12:11:38---------------------------------------------------
150 
151   -----------------------------------------------------------------------*/
WriterFilterDetection_supportsService(const OUString & ServiceName)152 sal_Bool WriterFilterDetection_supportsService( const OUString& ServiceName ) throw (uno::RuntimeException)
153 {
154    return (ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME1 ) ) );
155 }
156 /*-- 22.02.2007 12:11:38---------------------------------------------------
157 
158   -----------------------------------------------------------------------*/
WriterFilterDetection_getSupportedServiceNames()159 uno::Sequence< OUString > WriterFilterDetection_getSupportedServiceNames(  ) throw (uno::RuntimeException)
160 {
161    uno::Sequence < OUString > aRet(1);
162    OUString* pArray = aRet.getArray();
163    pArray[0] =  OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME1 ) );
164    return aRet;
165 }
166 #undef SERVICE_NAME1
167 /*-- 22.02.2007 12:11:38---------------------------------------------------
168 
169   -----------------------------------------------------------------------*/
WriterFilterDetection_createInstance(const uno::Reference<uno::XComponentContext> & xContext)170 uno::Reference< uno::XInterface > WriterFilterDetection_createInstance( const uno::Reference< uno::XComponentContext >& xContext)
171                 throw( uno::Exception )
172 {
173    return (cppu::OWeakObject*) new WriterFilterDetection( xContext );
174 }
175 /*-- 22.02.2007 12:11:38---------------------------------------------------
176 
177   -----------------------------------------------------------------------*/
getImplementationName()178 OUString WriterFilterDetection::getImplementationName(  ) throw (uno::RuntimeException)
179 {
180    return WriterFilterDetection_getImplementationName();
181 }
182 /*-- 22.02.2007 12:11:38---------------------------------------------------
183 
184   -----------------------------------------------------------------------*/
supportsService(const OUString & rServiceName)185 sal_Bool WriterFilterDetection::supportsService( const OUString& rServiceName ) throw (uno::RuntimeException)
186 {
187     return WriterFilterDetection_supportsService( rServiceName );
188 }
189 /*-- 22.02.2007 12:11:38---------------------------------------------------
190 
191   -----------------------------------------------------------------------*/
getSupportedServiceNames()192 uno::Sequence< OUString > WriterFilterDetection::getSupportedServiceNames(  ) throw (uno::RuntimeException)
193 {
194     return WriterFilterDetection_getSupportedServiceNames();
195 }
196 
197