1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_embeddedobj.hxx"
30 #include <com/sun/star/embed/ElementModes.hpp>
31 #include <com/sun/star/embed/EntryInitModes.hpp>
32 #include <com/sun/star/beans/PropertyValue.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/container/XNameAccess.hpp>
35 #include <com/sun/star/embed/Aspects.hpp>
36 
37 #include <rtl/logfile.hxx>
38 
39 
40 #include "xolefactory.hxx"
41 #include "oleembobj.hxx"
42 
43 
44 using namespace ::com::sun::star;
45 
46 // TODO: do not create OLE objects that represent OOo documents
47 
48 //-------------------------------------------------------------------------
49 uno::Sequence< ::rtl::OUString > SAL_CALL OleEmbeddedObjectFactory::impl_staticGetSupportedServiceNames()
50 {
51     uno::Sequence< ::rtl::OUString > aRet(2);
52     aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.embed.OLEEmbeddedObjectFactory");
53     aRet[1] = ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.OLEEmbeddedObjectFactory");
54     return aRet;
55 }
56 
57 //-------------------------------------------------------------------------
58 ::rtl::OUString SAL_CALL OleEmbeddedObjectFactory::impl_staticGetImplementationName()
59 {
60     return ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.OLEEmbeddedObjectFactory");
61 }
62 
63 //-------------------------------------------------------------------------
64 uno::Reference< uno::XInterface > SAL_CALL OleEmbeddedObjectFactory::impl_staticCreateSelfInstance(
65 			const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
66 {
67 	return uno::Reference< uno::XInterface >( *new OleEmbeddedObjectFactory( xServiceManager ) );
68 }
69 
70 //-------------------------------------------------------------------------
71 uno::Reference< uno::XInterface > SAL_CALL OleEmbeddedObjectFactory::createInstanceInitFromEntry(
72 																	const uno::Reference< embed::XStorage >& xStorage,
73 																	const ::rtl::OUString& sEntName,
74 																	const uno::Sequence< beans::PropertyValue >& aMedDescr,
75 																	const uno::Sequence< beans::PropertyValue >& lObjArgs )
76 	throw ( lang::IllegalArgumentException,
77 			container::NoSuchElementException,
78 			io::IOException,
79 			uno::Exception,
80 			uno::RuntimeException)
81 {
82 	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObjectFactory::createInstanceInitFromEntry" );
83 
84 	if ( !xStorage.is() )
85 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
86 											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
87 											1 );
88 
89 	if ( !sEntName.getLength() )
90 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
91 											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
92 											2 );
93 
94 	uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
95 	if ( !xNameAccess.is() )
96 		throw uno::RuntimeException(); //TODO
97 
98 	// detect entry existence
99 	if ( !xNameAccess->hasByName( sEntName ) )
100 		throw container::NoSuchElementException();
101 
102 	if ( !xStorage->isStreamElement( sEntName ) )
103 	{
104 		// if it is not an OLE object throw an exception
105 		throw io::IOException(); // TODO:
106 	}
107 
108 	uno::Reference< uno::XInterface > xResult(
109 					static_cast< ::cppu::OWeakObject* > ( new OleEmbeddedObject( m_xFactory, sal_False ) ),
110 					uno::UNO_QUERY );
111 
112 	uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY );
113 
114 	if ( !xPersist.is() )
115 		throw uno::RuntimeException(); // TODO: the interface must be supported by own document objects
116 
117 	xPersist->setPersistentEntry( xStorage,
118 									sEntName,
119 									embed::EntryInitModes::DEFAULT_INIT,
120 									aMedDescr,
121 									lObjArgs );
122 
123     for ( sal_Int32 nInd = 0; nInd < lObjArgs.getLength(); nInd++ )
124 	{
125         if ( lObjArgs[nInd].Name.equalsAscii( "CloneFrom" ) )
126         {
127             try
128             {
129                 uno::Reference < embed::XEmbeddedObject > xObj;
130                 uno::Reference < embed::XEmbeddedObject > xNew( xResult, uno::UNO_QUERY );
131                 lObjArgs[nInd].Value >>= xObj;
132                 if ( xObj.is() )
133                     xNew->setVisualAreaSize( embed::Aspects::MSOLE_CONTENT, xObj->getVisualAreaSize( embed::Aspects::MSOLE_CONTENT ) );
134             }
135             catch ( uno::Exception& ) {};
136             break;
137         }
138     }
139 
140 	return xResult;
141 }
142 
143 //-------------------------------------------------------------------------
144 uno::Reference< uno::XInterface > SAL_CALL OleEmbeddedObjectFactory::createInstanceInitFromMediaDescriptor(
145 		const uno::Reference< embed::XStorage >& xStorage,
146 		const ::rtl::OUString& sEntName,
147 		const uno::Sequence< beans::PropertyValue >& aMediaDescr,
148 		const uno::Sequence< beans::PropertyValue >& lObjArgs )
149 	throw ( lang::IllegalArgumentException,
150 			io::IOException,
151 			uno::Exception,
152 			uno::RuntimeException)
153 {
154 	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObjectFactory::createInstanceInitFromMediaDescriptor" );
155 
156 	if ( !xStorage.is() )
157 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
158 											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
159 											1 );
160 
161 	if ( !sEntName.getLength() )
162 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
163 											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
164 											2 );
165 
166 	uno::Reference< uno::XInterface > xResult(
167 					static_cast< ::cppu::OWeakObject* > ( new OleEmbeddedObject( m_xFactory, sal_False ) ),
168 					uno::UNO_QUERY );
169 
170 	uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY );
171 
172 	if ( !xPersist.is() )
173 		throw uno::RuntimeException(); // TODO: the interface must be supported ( what about applets? )
174 
175 	xPersist->setPersistentEntry( xStorage,
176 									sEntName,
177 									embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT,
178 									aMediaDescr,
179 									lObjArgs );
180 
181 	return xResult;
182 }
183 
184 //-------------------------------------------------------------------------
185 uno::Reference< uno::XInterface > SAL_CALL OleEmbeddedObjectFactory::createInstanceInitNew(
186 											const uno::Sequence< sal_Int8 >& aClassID,
187 											const ::rtl::OUString& aClassName,
188 											const uno::Reference< embed::XStorage >& xStorage,
189 											const ::rtl::OUString& sEntName,
190 											const uno::Sequence< beans::PropertyValue >& lObjArgs )
191 	throw ( lang::IllegalArgumentException,
192 			io::IOException,
193 			uno::Exception,
194 			uno::RuntimeException)
195 {
196 	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObjectFactory::createInstanceInitNew" );
197 
198 	if ( !xStorage.is() )
199 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
200 											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
201 											3 );
202 
203 	if ( !sEntName.getLength() )
204 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
205 											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
206 											4 );
207 
208 	uno::Reference< uno::XInterface > xResult(
209 					static_cast< ::cppu::OWeakObject* > ( new OleEmbeddedObject( m_xFactory, aClassID, aClassName ) ),
210 					uno::UNO_QUERY );
211 
212 	uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY );
213 
214 	if ( !xPersist.is() )
215 		throw uno::RuntimeException(); // TODO: the interface must be supported by own document objects
216 
217 	xPersist->setPersistentEntry( xStorage,
218 									sEntName,
219 									embed::EntryInitModes::TRUNCATE_INIT,
220 									uno::Sequence< beans::PropertyValue >(),
221 									lObjArgs );
222 
223 	return xResult;
224 }
225 
226 //-------------------------------------------------------------------------
227 uno::Reference< uno::XInterface > SAL_CALL OleEmbeddedObjectFactory::createInstanceLink(
228 											const uno::Reference< embed::XStorage >& xStorage,
229 											const ::rtl::OUString& sEntName,
230 											const uno::Sequence< beans::PropertyValue >& aMediaDescr,
231 											const uno::Sequence< beans::PropertyValue >& lObjArgs )
232 		throw ( lang::IllegalArgumentException,
233 				io::IOException,
234 				uno::Exception,
235 				uno::RuntimeException )
236 {
237 	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObjectFactory::createInstanceLink" );
238 
239 	if ( !xStorage.is() )
240 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
241 											uno::Reference< uno::XInterface >(
242 												static_cast< ::cppu::OWeakObject* >(this) ),
243 											1 );
244 
245 	if ( !sEntName.getLength() )
246 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
247 											uno::Reference< uno::XInterface >(
248 												static_cast< ::cppu::OWeakObject* >(this) ),
249 											2 );
250 
251 	uno::Reference< uno::XInterface > xResult(
252 				static_cast< ::cppu::OWeakObject* > ( new OleEmbeddedObject( m_xFactory, sal_True ) ),
253 				uno::UNO_QUERY );
254 
255 	uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY );
256 
257 	if ( !xPersist.is() )
258 		throw uno::RuntimeException(); // TODO: the interface must be supported by own document objects
259 
260 	xPersist->setPersistentEntry( xStorage,
261 									sEntName,
262 									embed::EntryInitModes::MEDIA_DESCRIPTOR_INIT,
263 									aMediaDescr,
264 									lObjArgs );
265 
266 	return xResult;
267 }
268 
269 //-------------------------------------------------------------------------
270 uno::Reference< uno::XInterface > SAL_CALL OleEmbeddedObjectFactory::createInstanceUserInit(
271 			const uno::Sequence< sal_Int8 >& aClassID,
272 			const ::rtl::OUString& aClassName,
273 			const uno::Reference< embed::XStorage >& xStorage,
274 			const ::rtl::OUString& sEntName,
275 			sal_Int32 /*nEntryConnectionMode*/,
276 			const uno::Sequence< beans::PropertyValue >& /*lArguments*/,
277 			const uno::Sequence< beans::PropertyValue >& lObjArgs )
278 	throw ( lang::IllegalArgumentException,
279 			io::IOException,
280 			uno::Exception,
281 			uno::RuntimeException )
282 {
283 	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) OleEmbeddedObjectFactory::createInstanceUserInit" );
284 
285 	// the initialization is completelly controlled by user
286 	if ( !xStorage.is() )
287 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
288 											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
289 											1 );
290 
291 	if ( !sEntName.getLength() )
292 		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
293 											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
294 											2 );
295 
296 	uno::Reference< uno::XInterface > xResult(
297 				static_cast< ::cppu::OWeakObject* > ( new OleEmbeddedObject( m_xFactory, aClassID, aClassName ) ),
298 				uno::UNO_QUERY );
299 
300 	uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY );
301 	if ( xPersist.is() )
302 	{
303 		xPersist->setPersistentEntry( xStorage,
304 									sEntName,
305 									embed::EntryInitModes::DEFAULT_INIT,
306 									uno::Sequence< beans::PropertyValue >(),
307 									lObjArgs );
308 
309 	}
310 	else
311 		throw uno::RuntimeException(); // TODO:
312 
313 	return xResult;
314 }
315 
316 //-------------------------------------------------------------------------
317 ::rtl::OUString SAL_CALL OleEmbeddedObjectFactory::getImplementationName()
318 	throw ( uno::RuntimeException )
319 {
320 	return impl_staticGetImplementationName();
321 }
322 
323 //-------------------------------------------------------------------------
324 sal_Bool SAL_CALL OleEmbeddedObjectFactory::supportsService( const ::rtl::OUString& ServiceName )
325 	throw ( uno::RuntimeException )
326 {
327 	uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames();
328 
329 	for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
330     	if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
331         	return sal_True;
332 
333 	return sal_False;
334 }
335 
336 //-------------------------------------------------------------------------
337 uno::Sequence< ::rtl::OUString > SAL_CALL OleEmbeddedObjectFactory::getSupportedServiceNames()
338 	throw ( uno::RuntimeException )
339 {
340 	return impl_staticGetSupportedServiceNames();
341 }
342 
343