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 package complex.ofopxmlstorages;
23 
24 import com.sun.star.uno.UnoRuntime;
25 import com.sun.star.uno.XInterface;
26 import com.sun.star.uno.AnyConverter;
27 
28 import com.sun.star.lang.*;
29 import com.sun.star.embed.*;
30 import com.sun.star.packages.*;
31 import com.sun.star.io.*;
32 import com.sun.star.beans.*;
33 
34 import share.LogWriter;
35 
36 public class TestHelper  {
37 
38 	LogWriter m_aLogWriter;
39 	String m_sTestPrefix;
40 
41 	public TestHelper( LogWriter aLogWriter, String sTestPrefix )
42 	{
43 		m_aLogWriter = aLogWriter;
44 		m_sTestPrefix = sTestPrefix;
45 	}
46 
47 	public boolean WriteBytesToStream( XStream xStream,
48 										String sStreamName,
49 										String sMediaType,
50 										boolean bCompressed,
51 										byte[] pBytes,
52 										StringPair[][] aRelations )
53 	{
54 		// get output stream of substream
55 		XOutputStream xOutput = xStream.getOutputStream();
56 		if ( xOutput == null )
57 		{
58 			Error( "Can't get XOutputStream implementation from substream '" + sStreamName + "'!" );
59 			return false;
60 		}
61 
62 		// get XTrucate implementation from output stream
63 		XTruncate xTruncate = (XTruncate) UnoRuntime.queryInterface( XTruncate.class, xOutput );
64 		if ( xTruncate == null )
65 		{
66 			Error( "Can't get XTruncate implementation from substream '" + sStreamName + "'!" );
67 			return false;
68 		}
69 
70 		// write requested byte sequence
71 		try
72 		{
73 			xTruncate.truncate();
74 			xOutput.writeBytes( pBytes );
75 		}
76 		catch( Exception e )
77 		{
78 			Error( "Can't write to stream '" + sStreamName + "', exception: " + e );
79 			return false;
80 		}
81 
82 		// get access to the XPropertySet interface
83 		XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xStream );
84 		if ( xPropSet == null )
85 		{
86 			Error( "Can't get XPropertySet implementation from substream '" + sStreamName + "'!" );
87 			return false;
88 		}
89 
90 		// set properties to the stream
91 		try
92 		{
93 			xPropSet.setPropertyValue( "MediaType", sMediaType );
94 			xPropSet.setPropertyValue( "Compressed", new Boolean( bCompressed ) );
95 		}
96 		catch( Exception e )
97 		{
98 			Error( "Can't set properties to substream '" + sStreamName + "', exception: " + e );
99 			return false;
100 		}
101 
102 		// check size property of the stream
103 		try
104 		{
105 			int nSize = AnyConverter.toInt( xPropSet.getPropertyValue( "Size" ) );
106 			if ( nSize != pBytes.length )
107 			{
108 				Error( "The 'Size' property of substream '" + sStreamName + "' contains wrong value!" );
109 				return false;
110 			}
111 		}
112 		catch( Exception e )
113 		{
114 			Error( "Can't get 'Size' property from substream '" + sStreamName + "', exception: " + e );
115 			return false;
116 		}
117 
118 		// get access to the relationship information
119 		XRelationshipAccess xRelAccess = (XRelationshipAccess) UnoRuntime.queryInterface( XRelationshipAccess.class, xStream );
120 		if ( xRelAccess == null )
121 		{
122 			Error( "Can't get XRelationshipAccess implementation from substream '" + sStreamName + "'!" );
123 			return false;
124 		}
125 
126 		// set the relationship information
127 		try
128 		{
129 			xRelAccess.insertRelationships( aRelations, false );
130 		}
131 		catch( Exception e )
132 		{
133 			Error( "Can't set relationships to substream '" + sStreamName + "', exception: " + e );
134 			return false;
135 		}
136 
137 		// free the stream resources, garbage collector may remove the object too late
138 		if ( !disposeStream( xStream, sStreamName ) )
139 			return false;
140 
141 		return true;
142 	}
143 
144 	public boolean WriteBytesToSubstream( XStorage xStorage,
145 										  String sStreamName,
146 										  String sMediaType,
147 										  boolean bCompressed,
148 										  byte[] pBytes,
149 										  StringPair[][] aRelations )
150 	{
151 		// open substream element
152 		XStream xSubStream = null;
153 		try
154 		{
155 			Object oSubStream = xStorage.openStreamElement( sStreamName, ElementModes.WRITE );
156 			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
157 			if ( xSubStream == null )
158 			{
159 				Error( "Can't create substream '" + sStreamName + "'!" );
160 				return false;
161 			}
162 		}
163 		catch( Exception e )
164 		{
165 			Error( "Can't create substream '" + sStreamName + "', exception : " + e + "!" );
166 			return false;
167 		}
168 
169 		return WriteBytesToStream( xSubStream, sStreamName, sMediaType, bCompressed, pBytes, aRelations );
170 	}
171 
172 	public boolean setStorageTypeAndCheckProps( XStorage xStorage,
173 												boolean bIsRoot,
174 												int nMode,
175 												StringPair[][] aRelations )
176 	{
177 		boolean bOk = false;
178 
179 		// get access to the XPropertySet interface
180 		XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xStorage );
181 		if ( xPropSet != null )
182 		{
183 			try
184 			{
185 				// get "IsRoot" and "OpenMode" properties and control there values
186 				boolean bPropIsRoot = AnyConverter.toBoolean( xPropSet.getPropertyValue( "IsRoot" ) );
187 				int nPropMode = AnyConverter.toInt( xPropSet.getPropertyValue( "OpenMode" ) );
188 
189 				bOk = true;
190 				if ( bPropIsRoot != bIsRoot )
191 				{
192 					Error( "'IsRoot' property contains wrong value!" );
193 					bOk = false;
194 				}
195 
196 				if ( ( bIsRoot
197 				  && ( nPropMode | ElementModes.READ ) != ( nMode | ElementModes.READ ) )
198 				  || ( !bIsRoot && ( nPropMode & nMode ) != nMode ) )
199 				{
200 					Error( "'OpenMode' property contains wrong value, expected " + nMode + ", in reality " + nPropMode + "!" );
201 					bOk = false;
202 				}
203 			}
204 			catch( Exception e )
205 			{
206 				Error( "Can't control properties of substorage, exception: " + e );
207 			}
208 		}
209 		else
210 		{
211 			Error( "Can't get XPropertySet implementation from storage!" );
212 		}
213 
214 		// get access to the relationship information
215 		XRelationshipAccess xRelAccess = (XRelationshipAccess) UnoRuntime.queryInterface( XRelationshipAccess.class, xStorage );
216 
217 		if ( xRelAccess == null )
218 		{
219 			Error( "Can't get XRelationshipAccess implementation from the storage!" );
220 			return false;
221 		}
222 
223 		// set the relationship information
224 		try
225 		{
226 			xRelAccess.insertRelationships( aRelations, false );
227 		}
228 		catch( Exception e )
229 		{
230 			Error( "Can't set relationships to the storage, exception: " + e );
231 			return false;
232 		}
233 
234 
235 		return bOk;
236 	}
237 
238 	public boolean checkRelations( StringPair[][] aStorRels, StringPair[][] aTestRels )
239 	{
240 		// Message( "StorageRels:" );
241 		// PrintRelations( aStorRels );
242 		// Message( "TestRels:" );
243 		// PrintRelations( aTestRels );
244 
245 		if ( aStorRels.length != aTestRels.length )
246 		{
247 			Error( "The provided relations sequence has different size than the storage's one!" );
248 			return false;
249 		}
250 
251 		for ( int nStorInd = 0; nStorInd < aStorRels.length; nStorInd++ )
252 		{
253 			int nStorIDInd = -1;
254 			for ( int nStorTagInd = 0; nStorTagInd < aStorRels[nStorInd].length; nStorTagInd++ )
255 			{
256 				if ( aStorRels[nStorInd][nStorTagInd].First.equals( "Id" ) )
257 				{
258 					nStorIDInd = nStorTagInd;
259 					break;
260 				}
261 			}
262 
263 			if ( nStorIDInd == -1 )
264 			{
265 				Error( "One of the storage relations entries has no ID!" );
266 				return false;
267 			}
268 
269 			for ( int nInd = 0; nInd < aTestRels.length; nInd++ )
270 			{
271 				int nIDInd = -1;
272 				for ( int nTagInd = 0; nTagInd < aTestRels[nInd].length; nTagInd++ )
273 				{
274 					if ( aTestRels[nInd][nTagInd].First.equals( "Id" ) )
275 					{
276 						nIDInd = nTagInd;
277 						break;
278 					}
279 				}
280 
281 				if ( nIDInd == -1 )
282 				{
283 					Error( "One of the test hardcoded entries has no ID, num = " + nInd + ", length = " + aTestRels[nInd].length + ", global length = " + aTestRels.length + "!" );
284 					return false;
285 				}
286 
287 				if ( aStorRels[nStorInd][nStorIDInd].Second.equals( aTestRels[nInd][nIDInd].Second ) )
288 				{
289 					boolean[] pRelCheckMark = new boolean[ aTestRels[nInd].length ];
290 					for ( int nCheckInd = 0; nCheckInd < pRelCheckMark.length; nCheckInd++ )
291 					{
292 						pRelCheckMark[nCheckInd] = false;
293 					}
294 
295 					for ( int nStorTagInd = 0; nStorTagInd < aStorRels[nStorInd].length; nStorTagInd++ )
296 					{
297 						boolean bFound = false;
298 						for ( int nTagInd = 0; nTagInd < aTestRels[nInd].length; nTagInd++ )
299 						{
300 							if ( aTestRels[nInd][nTagInd].First.equals( aStorRels[nStorInd][nStorTagInd].First ) )
301 							{
302 								if ( !aTestRels[nInd][nTagInd].Second.equals( aStorRels[nStorInd][nStorTagInd].Second ) )
303 								{
304 									Error( "Test rel. num. " + nInd + " has different tag \"" + aTestRels[nInd][nTagInd].First + "\" value!" );
305 									return false;
306 								}
307 
308 								bFound = true;
309 								pRelCheckMark[nTagInd] = true;
310 								break;
311 							}
312 						}
313 
314 						if ( !bFound )
315 						{
316 							Error( "Stor rel. num. " + nStorInd + " has unexpected tag \"" + aStorRels[nStorInd][nStorTagInd].First + "\", ID = \"" + aStorRels[nStorInd][nStorIDInd].Second + "\"!" );
317 							return false;
318 						}
319 					}
320 
321 					for ( int nCheckInd = 0; nCheckInd < pRelCheckMark.length; nCheckInd++ )
322 					{
323 						if ( !pRelCheckMark[nCheckInd] && !aTestRels[nInd][nCheckInd].Second.equals( "" ) )
324 						{
325 							Error( "Test rel. num. " + nInd + " has unexpected tag \"" + aTestRels[nInd][nCheckInd].First + "\" with nonempty value!" );
326 							return false;
327 						}
328 					}
329 
330 					break;
331 				}
332 			}
333 		}
334 
335 		return true;
336 	}
337 
338 	public boolean checkStorageProperties( XStorage xStorage,
339 											boolean bIsRoot,
340 											int nMode,
341 											StringPair[][] aRelations )
342 	{
343 		boolean bOk = false;
344 
345 		// get access to the XPropertySet interface
346 		XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xStorage );
347 		if ( xPropSet != null )
348 		{
349 			try
350 			{
351 				// get "IsRoot" and "OpenMode" properties and control there values
352 				boolean bPropIsRoot = AnyConverter.toBoolean( xPropSet.getPropertyValue( "IsRoot" ) );
353 				int nPropMode = AnyConverter.toInt( xPropSet.getPropertyValue( "OpenMode" ) );
354 
355 				bOk = true;
356 				if ( bPropIsRoot != bIsRoot )
357 				{
358 					Error( "'IsRoot' property contains wrong value!" );
359 					bOk = false;
360 				}
361 
362 				if ( ( bIsRoot
363 				  && ( nPropMode | ElementModes.READ ) != ( nMode | ElementModes.READ ) )
364 				  || ( !bIsRoot && ( nPropMode & nMode ) != nMode ) )
365 				{
366 					Error( "'OpenMode' property contains wrong value, expected " + nMode + ", in reality " + nPropMode + "!" );
367 					bOk = false;
368 				}
369 			}
370 			catch( Exception e )
371 			{
372 				Error( "Can't get properties of substorage, exception: " + e );
373 			}
374 		}
375 		else
376 		{
377 			Error( "Can't get XPropertySet implementation from storage!" );
378 		}
379 
380 		// get access to the relationship information
381 		XRelationshipAccess xRelAccess = (XRelationshipAccess) UnoRuntime.queryInterface( XRelationshipAccess.class, xStorage );
382 
383 		if ( xRelAccess == null )
384 		{
385 			Error( "Can't get XRelationshipAccess implementation from the checked storage!" );
386 			return false;
387 		}
388 
389 		// get the relationship information
390 		StringPair[][] aStorRels;
391 		try
392 		{
393 			aStorRels = xRelAccess.getAllRelationships();
394 		}
395 		catch( Exception e )
396 		{
397 			Error( "Can't get relationships of the checked storage, exception: " + e );
398 			return false;
399 		}
400 
401 		if ( !checkRelations( aStorRels, aRelations ) )
402 		{
403 			Error( "StorageRelationsChecking has failed!" );
404 			return false;
405 		}
406 
407 		return bOk;
408 	}
409 
410 	public boolean InternalCheckStream( XStream xStream,
411 										String sName,
412 										String sMediaType,
413 										byte[] pBytes,
414 										StringPair[][] aRelations )
415 	{
416 		// get input stream of substream
417 		XInputStream xInput = xStream.getInputStream();
418 		if ( xInput == null )
419 		{
420 			Error( "Can't get XInputStream implementation from substream '" + sName + "'!" );
421 			return false;
422 		}
423 
424 		byte pContents[][] = new byte[1][]; // ???
425 
426 		// read contents
427 		try
428 		{
429 			xInput.readBytes( pContents, pBytes.length + 1 );
430 		}
431 		catch( Exception e )
432 		{
433 			Error( "Can't read from stream '" + sName + "', exception: " + e );
434 			return false;
435 		}
436 
437 		// check size of stream data
438 		if ( pContents.length == 0 )
439 		{
440 			Error( "SubStream '" + sName + "' reading produced disaster!"  );
441 			return false;
442 		}
443 
444 		if ( pBytes.length != pContents[0].length )
445 		{
446 			Error( "SubStream '" + sName + "' contains wrong amount of data! (" + pContents[0].length + "/" + pBytes.length + ")" );
447 			return false;
448 		}
449 
450 		// check stream data
451 		for ( int ind = 0; ind < pBytes.length; ind++ )
452 		{
453 			if ( pBytes[ind] != pContents[0][ind] )
454 			{
455 				Error( "SubStream '" + sName + "' contains wrong data! ( byte num. "
456 						+ ind + " should be" + pBytes[ind] + " but it is " + pContents[0][ind] + ")" );
457 				return false;
458 			}
459 		}
460 
461 		// check properties
462 		boolean bOk = false;
463 
464 		// get access to the XPropertySet interface
465 		XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, xStream );
466 		if ( xPropSet != null )
467 		{
468 			try
469 			{
470 				// get "MediaType" and "Size" properties and control there values
471 				String sPropMediaType = AnyConverter.toString( xPropSet.getPropertyValue( "MediaType" ) );
472 				int nPropSize = AnyConverter.toInt( xPropSet.getPropertyValue( "Size" ) );
473 
474 				bOk = true;
475 				if ( !sPropMediaType.equals( sMediaType ) )
476 				{
477 					Error( "'MediaType' property contains wrong value for stream '" + sName + "',\nexpected: '"
478 							+ sMediaType + "', set: '" + sPropMediaType + "'!" );
479 					bOk = false;
480 				}
481 
482 				if ( nPropSize != pBytes.length )
483 				{
484 					Error( "'Size' property contains wrong value for stream'" + sName + "'!" );
485 					bOk = false;
486 				}
487 			}
488 			catch( Exception e )
489 			{
490 				Error( "Can't get properties of substream '" + sName + "', exception: " + e );
491 			}
492 		}
493 		else
494 		{
495 			Error( "Can't get XPropertySet implementation from stream '" + sName + "'!" );
496 		}
497 
498 
499 		// get access to the relationship information
500 		XRelationshipAccess xRelAccess = (XRelationshipAccess) UnoRuntime.queryInterface( XRelationshipAccess.class, xStream );
501 
502 		if ( xRelAccess == null )
503 		{
504 			Error( "Can't get XRelationshipAccess implementation from the stream\"" + sName + "\"!" );
505 			return false;
506 		}
507 
508 		// get the relationship information
509 		StringPair[][] aStorRels;
510 		try
511 		{
512 			aStorRels = xRelAccess.getAllRelationships();
513 		}
514 		catch( Exception e )
515 		{
516 			Error( "Can't get relationships of the substream '" + sName + "', exception: " + e );
517 			return false;
518 		}
519 
520 		if ( !checkRelations( aStorRels, aRelations ) )
521 		{
522 			Error( "Stream '" + sName + "' RelationsChecking has failed!" );
523 			return false;
524 		}
525 
526 		return bOk;
527 	}
528 
529 	public boolean checkStream( XStorage xParentStorage,
530 								String sName,
531 								String sMediaType,
532 								byte[] pBytes,
533 								StringPair[][] aRelations )
534 	{
535 		// open substream element first
536 		XStream xSubStream = null;
537 		try
538 		{
539 			Object oSubStream = xParentStorage.openStreamElement( sName, ElementModes.READ );
540 			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
541 			if ( xSubStream == null )
542 			{
543 				Error( "Can't open substream '" + sName + "'!" );
544 				return false;
545 			}
546 		}
547 		catch( Exception e )
548 		{
549 			Error( "Can't open substream '" + sName + "', exception : " + e + "!" );
550 			return false;
551 		}
552 
553 		boolean bResult = InternalCheckStream( xSubStream, sName, sMediaType, pBytes, aRelations );
554 
555 		// free the stream resources, garbage collector may remove the object too late
556 		if ( !disposeStream( xSubStream, sName ) )
557 			return false;
558 
559 		return bResult;
560 	}
561 
562 	public boolean copyStorage( XStorage xSourceStorage, XStorage xDestStorage )
563 	{
564 		// copy xSourceStorage to xDestStorage
565 		try
566 		{
567 			xSourceStorage.copyToStorage( xDestStorage );
568 		}
569 		catch( Exception e )
570 		{
571 			Error( "Storage copying failed, exception: " + e );
572 			return false;
573 		}
574 
575 		return true;
576 	}
577 
578 	public boolean commitStorage( XStorage xStorage )
579 	{
580 		// XTransactedObject must be supported by storages
581 		XTransactedObject xTransact = (XTransactedObject) UnoRuntime.queryInterface( XTransactedObject.class, xStorage );
582 		if ( xTransact == null )
583 		{
584 			Error( "Storage doesn't implement transacted access!" );
585 			return false;
586 		}
587 
588 		try
589 		{
590 			xTransact.commit();
591 		}
592 		catch( Exception e )
593 		{
594 			Error( "Storage commit failed, exception:" + e );
595 			return false;
596 		}
597 
598 		return true;
599 	}
600 
601 	public boolean disposeStream( XStream xStream, String sStreamName )
602 	{
603 		XComponent xComponent = (XComponent) UnoRuntime.queryInterface( XComponent.class, xStream );
604 		if ( xComponent == null )
605 		{
606 			Error( "Can't get XComponent implementation from substream '" + sStreamName + "'!" );
607 			return false;
608 		}
609 
610 		try
611 		{
612 			xComponent.dispose();
613 		}
614 		catch( Exception e )
615 		{
616 			Error( "Substream '" + sStreamName + "' disposing throws exception: " + e );
617 			return false;
618 		}
619 
620 		return true;
621 	}
622 
623 	public boolean disposeStorage( XStorage xStorage )
624 	{
625 		// dispose the storage
626 		XComponent xComponent = (XComponent) UnoRuntime.queryInterface( XComponent.class, xStorage );
627 		if ( xComponent == null )
628 		{
629 			Error( "Can't retrieve XComponent implementation from storage!" );
630 			return false;
631 		}
632 
633 		try
634 		{
635 			xComponent.dispose();
636 		}
637 		catch( Exception e )
638 		{
639 			Error( "Storage disposing failed!" );
640 			return false;
641 		}
642 
643 		return true;
644 	}
645 
646 	public XInputStream getInputStream( XStream xStream )
647 	{
648 		XInputStream xInTemp = null;
649 		try
650 		{
651 			xInTemp = xStream.getInputStream();
652 			if ( xInTemp == null )
653 				Error( "Can't get the input part of a stream!" );
654 		}
655 		catch ( Exception e )
656 		{
657 			Error( "Can't get the input part of a stream, exception :" + e );
658 		}
659 
660 		return xInTemp;
661 	}
662 
663 	public boolean closeOutput( XStream xStream )
664 	{
665 		XOutputStream xOutTemp = null;
666 		try
667 		{
668 			xOutTemp = xStream.getOutputStream();
669 			if ( xOutTemp == null )
670 			{
671 				Error( "Can't get the output part of a stream!" );
672 				return false;
673 			}
674 		}
675 		catch ( Exception e )
676 		{
677 			Error( "Can't get the output part of a stream, exception :" + e );
678 			return false;
679 		}
680 
681 		try
682 		{
683 			xOutTemp.closeOutput();
684 		}
685 		catch ( Exception e )
686 		{
687 			Error( "Can't close output part of a stream, exception :" + e );
688 			return false;
689 		}
690 
691 		return true;
692 	}
693 
694 	public XStorage openSubStorage( XStorage xStorage, String sName, int nMode )
695 	{
696 		// open existing substorage
697 		try
698 		{
699 			Object oSubStorage = xStorage.openStorageElement( sName, nMode );
700 			XStorage xSubStorage = (XStorage) UnoRuntime.queryInterface( XStorage.class, oSubStorage );
701 			return xSubStorage;
702 		}
703 		catch( Exception e )
704 		{
705 			Error( "Can't open substorage '" + sName + "', exception: " + e );
706 		}
707 
708 		return null;
709 	}
710 
711 	public XStream CreateTempFileStream( XMultiServiceFactory xMSF )
712 	{
713 		// try to get temporary file representation
714 		XStream xTempFileStream = null;
715 		try
716 		{
717 			Object oTempFile = xMSF.createInstance( "com.sun.star.io.TempFile" );
718 			xTempFileStream = (XStream)UnoRuntime.queryInterface( XStream.class, oTempFile );
719 		}
720 		catch( Exception e )
721 		{}
722 
723 		if ( xTempFileStream == null )
724 			Error( "Can't create temporary file!" );
725 
726 		return xTempFileStream;
727 	}
728 
729 	public String CreateTempFile( XMultiServiceFactory xMSF )
730 	{
731 		String sResult = null;
732 
733 		// try to get temporary file representation
734 		XPropertySet xTempFileProps = null;
735 		try
736 		{
737 			Object oTempFile = xMSF.createInstance( "com.sun.star.io.TempFile" );
738 			xTempFileProps = (XPropertySet)UnoRuntime.queryInterface( XPropertySet.class, oTempFile );
739 		}
740 		catch( Exception e )
741 		{}
742 
743 		if ( xTempFileProps != null )
744 		{
745 			try
746 			{
747 				xTempFileProps.setPropertyValue( "RemoveFile", new Boolean( false ) );
748 				sResult = AnyConverter.toString( xTempFileProps.getPropertyValue( "Uri" ) );
749 			}
750 			catch( Exception e )
751 			{
752 				Error( "Can't control TempFile properties, exception: " + e );
753 			}
754 		}
755 		else
756 		{
757 			Error( "Can't create temporary file representation!" );
758 		}
759 
760 		// close temporary file explicitly
761 		try
762 		{
763 			XStream xStream = (XStream)UnoRuntime.queryInterface( XStream.class, xTempFileProps );
764 			if ( xStream != null )
765 			{
766 				XOutputStream xOut = xStream.getOutputStream();
767 				if ( xOut != null )
768 					xOut.closeOutput();
769 
770 				XInputStream xIn = xStream.getInputStream();
771 				if ( xIn != null )
772 					xIn.closeInput();
773 			}
774 			else
775 				Error( "Can't close TempFile!" );
776 		}
777 		catch( Exception e )
778 		{
779 			Error( "Can't close TempFile, exception: " + e );
780 		}
781 
782 		return sResult;
783 	}
784 
785 	public boolean copyElementTo( XStorage xSource, String sName, XStorage xDest )
786 	{
787 		// copy element with name sName from xSource to xDest
788 		try
789 		{
790 			xSource.copyElementTo( sName, xDest, sName );
791 		}
792 		catch( Exception e )
793 		{
794 			Error( "Element copying failed, exception: " + e );
795 			return false;
796 		}
797 
798 		return true;
799 	}
800 
801 	public boolean copyElementTo( XStorage xSource, String sName, XStorage xDest, String sTargetName )
802 	{
803 		// copy element with name sName from xSource to xDest
804 		try
805 		{
806 			xSource.copyElementTo( sName, xDest, sTargetName );
807 		}
808 		catch( Exception e )
809 		{
810 			Error( "Element copying failed, exception: " + e );
811 			return false;
812 		}
813 
814 		return true;
815 	}
816 
817 	public boolean moveElementTo( XStorage xSource, String sName, XStorage xDest )
818 	{
819 		// move element with name sName from xSource to xDest
820 		try
821 		{
822 			xSource.moveElementTo( sName, xDest, sName );
823 		}
824 		catch( Exception e )
825 		{
826 			Error( "Element moving failed, exception: " + e );
827 			return false;
828 		}
829 
830 		return true;
831 	}
832 
833 	public boolean renameElement( XStorage xStorage, String sOldName, String sNewName )
834 	{
835 		// rename element with name sOldName to sNewName
836 		try
837 		{
838 			xStorage.renameElement( sOldName, sNewName );
839 		}
840 		catch( Exception e )
841 		{
842 			Error( "Element renaming failed, exception: " + e );
843 			return false;
844 		}
845 
846 		return true;
847 	}
848 
849 	public boolean removeElement( XStorage xStorage, String sName )
850 	{
851 		// remove element with name sName
852 		try
853 		{
854 			xStorage.removeElement( sName );
855 		}
856 		catch( Exception e )
857 		{
858 			Error( "Element removing failed, exception: " + e );
859 			return false;
860 		}
861 
862 		return true;
863 	}
864 
865 	public XStream OpenStream( XStorage xStorage,
866 								String sStreamName,
867 								int nMode )
868 	{
869 		// open substream element
870 		XStream xSubStream = null;
871 		try
872 		{
873 			Object oSubStream = xStorage.openStreamElement( sStreamName, nMode );
874 			xSubStream = (XStream) UnoRuntime.queryInterface( XStream.class, oSubStream );
875 			if ( xSubStream == null )
876 				Error( "Can't create substream '" + sStreamName + "'!" );
877 		}
878 		catch( Exception e )
879 		{
880 			Error( "Can't create substream '" + sStreamName + "', exception : " + e + "!" );
881 		}
882 
883 		return xSubStream;
884 	}
885 
886 	public boolean cantOpenStorage( XStorage xStorage, String sName )
887 	{
888 		// try to open an opened substorage, open call must fail
889 		try
890 		{
891 			Object oDummyStorage = xStorage.openStorageElement( sName, ElementModes.READ );
892 			Error( "The trying to reopen opened substorage '" + sName + "' must fail!" );
893 		}
894 		catch( Exception e )
895 		{
896 			return true;
897 		}
898 
899 		return false;
900 	}
901 
902 	public boolean cantOpenStream( XStorage xStorage, String sName, int nMode )
903 	{
904 		// try to open the substream with specified mode must fail
905 		try
906 		{
907 			Object oDummyStream = xStorage.openStreamElement( sName, nMode );
908 			Error( "The trying to open substoream '" + sName + "' must fail!" );
909 		}
910 		catch( Exception e )
911 		{
912 			return true;
913 		}
914 
915 		return false;
916 	}
917 
918 	public XStorage createStorageFromURL(
919 								XSingleServiceFactory xFactory,
920 								String aURL,
921 								int nMode )
922 	{
923 		XStorage xResult = null;
924 
925 		try
926 		{
927 			PropertyValue[] aAddArgs = new PropertyValue[1];
928 			aAddArgs[0] = new PropertyValue();
929 			aAddArgs[0].Name = "StorageFormat";
930 			aAddArgs[0].Value = "OFOPXMLFormat";
931 
932 			Object pArgs[] = new Object[3];
933 			pArgs[0] = (Object) aURL;
934 			pArgs[1] = new Integer( nMode );
935 			pArgs[2] = (Object) aAddArgs;
936 
937 			Object oTempStorage = xFactory.createInstanceWithArguments( pArgs );
938 			xResult = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
939 		}
940 		catch( Exception e )
941 		{
942 			Error( "Can't create storage from URL, exception: " + e );
943 			return null;
944 		}
945 
946 		if ( xResult == null )
947 			Error( "Can't create storage from URL!" );
948 
949 		return xResult;
950 	}
951 
952 	public XStorage createStorageFromStream(
953 								XSingleServiceFactory xFactory,
954 								XStream xStream,
955 								int nMode )
956 	{
957 		XStorage xResult = null;
958 
959 		try
960 		{
961 			PropertyValue[] aAddArgs = new PropertyValue[1];
962 			aAddArgs[0] = new PropertyValue();
963 			aAddArgs[0].Name = "StorageFormat";
964 			aAddArgs[0].Value = "OFOPXMLFormat";
965 
966 			Object pArgs[] = new Object[3];
967 			pArgs[0] = (Object) xStream;
968 			pArgs[1] = new Integer( nMode );
969 			pArgs[2] = (Object) aAddArgs;
970 
971 			Object oTempStorage = xFactory.createInstanceWithArguments( pArgs );
972 			xResult = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
973 		}
974 		catch( Exception e )
975 		{
976 			Error( "Can't create storage from stream, exception: " + e );
977 			return null;
978 		}
979 
980 		if ( xResult == null )
981 			Error( "Can't create storage from stream!" );
982 
983 		return xResult;
984 	}
985 
986 	public XStorage createStorageFromInputStream(
987 								XSingleServiceFactory xFactory,
988 								XInputStream xInStream )
989 	{
990 		XStorage xResult = null;
991 
992 		try
993 		{
994 			PropertyValue[] aAddArgs = new PropertyValue[1];
995 			aAddArgs[0] = new PropertyValue();
996 			aAddArgs[0].Name = "StorageFormat";
997 			aAddArgs[0].Value = "OFOPXMLFormat";
998 
999 			Object pArgs[] = new Object[3];
1000 			pArgs[0] = (Object) xInStream;
1001 			pArgs[1] = new Integer( ElementModes.READ );
1002 			pArgs[2] = (Object) aAddArgs;
1003 
1004 			Object oTempStorage = xFactory.createInstanceWithArguments( pArgs );
1005 			xResult = (XStorage) UnoRuntime.queryInterface( XStorage.class, oTempStorage );
1006 		}
1007 		catch( Exception e )
1008 		{
1009 			Error( "Can't create storage from input stream, exception: " + e );
1010 			return null;
1011 		}
1012 
1013 		if ( xResult == null )
1014 			Error( "Can't create storage from input stream!" );
1015 
1016 		return xResult;
1017 	}
1018 
1019 	public XStorage createTempStorage( XMultiServiceFactory xMSF, XSingleServiceFactory xFactory )
1020 	{
1021 		// create a temporary storage
1022 		XStorage xResult = null;
1023 		XStream xStream = CreateTempFileStream( xMSF );
1024 		if ( xStream == null )
1025 		{
1026 			Error( "Can't create temp file stream!" );
1027 			return null;
1028 		}
1029 
1030 		try
1031 		{
1032 			xResult = createStorageFromStream( xFactory, xStream, ElementModes.WRITE );
1033 		}
1034 		catch( Exception e )
1035 		{
1036 			Error( "Can't create temp storage, exception: " + e );
1037 		}
1038 
1039 		return xResult;
1040 	}
1041 
1042 	public XStorage cloneStorage( XMultiServiceFactory xMSF, XSingleServiceFactory xFactory, XStorage xStorage )
1043 	{
1044 		// create a copy of a last commited version of specified storage
1045 		XStorage xResult = null;
1046 		try
1047 		{
1048 			xResult = createTempStorage( xMSF, xFactory );
1049 			if ( xResult != null )
1050 				xStorage.copyLastCommitTo( xResult );
1051 		}
1052 		catch( Exception e )
1053 		{
1054 			Error( "Can't clone storage, exception: " + e );
1055 			return null;
1056 		}
1057 
1058 		return xResult;
1059 	}
1060 
1061 	public XStorage cloneSubStorage( XMultiServiceFactory xMSF, XSingleServiceFactory xFactory, XStorage xStorage, String sName )
1062 	{
1063 		// create a copy of a last commited version of specified substorage
1064 		XStorage xResult = null;
1065 		try
1066 		{
1067 			xResult = createTempStorage( xMSF, xFactory );
1068 			if ( xResult != null )
1069 				xStorage.copyStorageElementLastCommitTo( sName, xResult );
1070 		}
1071 		catch( Exception e )
1072 		{
1073 			Error( "Can't clone substorage '" + sName + "', exception: " + e );
1074 			return null;
1075 		}
1076 
1077 		return xResult;
1078 	}
1079 
1080 	public XStream cloneSubStream( XStorage xStorage, String sName )
1081 	{
1082 		// clone existing substream
1083 		try
1084 		{
1085 			XStream xStream = xStorage.cloneStreamElement( sName );
1086 			return xStream;
1087 		}
1088 		catch( Exception e )
1089 		{
1090 			Error( "Can't clone substream '" + sName + "', exception: " + e );
1091 		}
1092 
1093 		return null;
1094 	}
1095 
1096 	public void Error( String sError )
1097 	{
1098 		m_aLogWriter.println( m_sTestPrefix + "Error: " + sError );
1099 	}
1100 
1101 	public void Message( String sMessage )
1102 	{
1103 		m_aLogWriter.println( m_sTestPrefix + sMessage );
1104 	}
1105 
1106 	public void PrintRelations( StringPair[][] aRels )
1107 	{
1108 		m_aLogWriter.println( "========" );
1109 		for ( int nInd1 = 0; nInd1 < aRels.length; nInd1++ )
1110 		{
1111 			for ( int nInd2 = 0; nInd2 < aRels[nInd1].length; nInd2++ )
1112 			{
1113 				m_aLogWriter.println( "\"" + aRels[nInd1][nInd2].First + "\" = \"" + aRels[nInd1][nInd2].Second + "\", " );
1114 			}
1115 			m_aLogWriter.println( "========" );
1116 		}
1117 	}
1118 }
1119 
1120