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 package complex.filter.detection.typeDetection;
24 
25 import com.sun.star.beans.PropertyValue;
26 import com.sun.star.document.XTypeDetection;
27 import com.sun.star.io.NotConnectedException;
28 import com.sun.star.io.XInputStream;
29 import com.sun.star.lang.XMultiServiceFactory;
30 import com.sun.star.uno.UnoRuntime;
31 import com.sun.star.uno.XInterface;
32 import complexlib.ComplexTestCase;
33 import java.io.File;
34 
35 import java.util.Enumeration;
36 import java.util.Hashtable;
37 import java.util.Vector;
38 import util.utils;
39 
40 
41 
42 /** Check "TypeDetection"
43  * <p>
44  * This test will check the file type detection. This will be done by filling
45  * properties of a <code>MediaDescriptor</code>.
46  *
47  * In the test method <code>checkByURLonly</code> the
48  * <code>MediaDescriptor</code> was filled at once with the URL of a test
49  * file. At second it was filled with a <code>XInputStream</code> from test
50  * file. In both subtests the returned file type must match with an expected
51  * type.
52  *
53  * In the test method <code>checkPreselectedType</code> the
54  * <code>MediaDescriptor</code> was filled with the URL of the test file and
55  * with the name of a type which should be used. The returned type of the
56  * <code>TypeDetection<code> must match with an expected type.
57  *
58  * In the test method <code>checkPreselectedFilter</code> the
59  * <code>MediaDescriptor</code> was filled with the URL of the test file and
60  * with the name of a filter which should be used. The returned type of the
61  * <code>TypeDetection<code> must match with an expected type.
62  *
63  * In the test method <code>checkPreselectedDocService</code> the
64  * <code>MediaDescriptor</code> was filled with the URL of the test file and
65  * with the name of a document service which should be used. The returned type
66  * of the <code>TypeDetection<code> must match with an expected type.
67  *
68  *
69  * To get information which test file should support which type, filter and
70  * document service, this information was collect from configuration files:
71  * <UL>
72  * <LI><a href="#TypeDetection.props">TypeDetection.props</a></LI>
73  * <LI><a href="#files.csv">files.csv</a></LI>
74  * <LI><a href="#preselectedFilter.csv">preselectedFilter.csv</a></LI>
75  * <LI><a href="#preselectedType.csv">preselectedType.csv</a></LI>
76  * <LI><a href="#serviceName.csv">serviceName.csv</a></LI>
77  * </UL>
78  * <p>
79  * <h3><A name="TypeDetection.props"></A>
80  * <code>typeDetection.props</code></h3>
81  * At fist there will be the <code>typeDetection.props</code>. Here the following
82  * properties should be set (with example values):
83  *
84  * TestDocumentPath=file:///path/to/my/testdocuments
85  * placeHolder=%
86  * %SO6productname=StarOffice
87  * %SO6formatversion=6.0
88  *
89  * <code>TestDocumentPath</code>: this is the path to your test documents. If
90  * you have grouped your documents ie. by writer, calc, ... then it should be
91  * the root path. To specify the particular sub folders you have to use
92  * <code>csv.files</code>
93  * <p>
94  * <code>files.csv</code>: In this file all test documents are listed.
95  * Syntax: fileAlias;fileURL;defaultURLFileType;StreamFileTypes
96  * Example:
97  *
98  * Writer6_1;Writer/Writer6.sxw;writer_StarOffice_XML_Writer;writer_StarOffice_XML_Writer
99  * text1;Writer/Text.txt;writer_Text_encoded:writer_Text;writer_Text_encoded:writer_Text
100  *
101  * The first example shows you the following:
102  * <code>Writer6_1</code> is a free chosen name
103  * <code>Writer/Writer6.sxw</code> is the document path. This will be assembled
104  * by <code>TestDocumentPath</code> from <code>typeDetection.props</code>.
105  * <code>writer_StarOffice_XML_Writer</code>: this is the default file type of
106  * this file
107  *
108  * The second example displays two document types for <code>XInputStream</CODE>
109  * (<code>writer_Text_encoded</CODE> and <code>writer_Text</CODE>. This two
110  * document types are listed by a colon ':' as separator. This is needed because
111  * XInputStream can detect a text file as writer_Text_encoded as well as
112  * writer_Text.
113  * <p>
114  *
115  * <H3><A name="preselectedFilter.csv"</a>
116  * <code>preselectedFilter.csv</code></H3>
117  * In this file you can choose a special
118  * filter to detect the document. This make sense ie. for csv-files: You can
119  * open csv files as Writer or as Calc. To check this case you have to specify
120  * in <code>csv.files</code> a fileAlias like ?csv_writer? and ?csv_calc? with
121  * the same fileURL and it's specific defaultFileType.
122  * The returned file type by <code>TypeDetection</code> must equal to
123  * correspond <code>defaultFileType</code> from <code>csv.files</code>
124  *
125  * Syntax: fileAlias;FilterName;FilterOptions;FilterData
126  * Example: Writer6_1;%SO6productname %SO6formatversion Textdokument;;
127  *
128  * The example shows the following:
129  * <code>Writer6_1</code> is the same as in <code>csv.files</code>
130  * <code>%SO6productname %SO6formatversion Textdokument</code> is the filter
131  * name which should be used. Here we have a special: <code>%SO6productname
132  * %SO6formatversion</code> will be replaced by the equals of
133  * <code>typeDetection.props</code>. The filter names depends on the Office
134  * name and version. So a future Office could called ?StarSuite 8?.
135  * <code>FilterOptions</code> is not relevant for this filter. But ie. for csv
136  * filter this entry could be used to specify the separator of the csv file.
137  * <code>FilterData<code> if filter needs some FilterData arguments you can
138  * specify it here
139  *
140  * <p>
141  * <H3><a name="preselectedType.csv"></A>
142  * <code>preselectedType.csv</code></H3>
143  * In this file you can preselect the type
144  * <code>TypeDetection</code> should use.
145  * The returned file type by <code>TypeDetection</code> must equal to the
146  * preselected file type.
147  * Note: If you try to use invalid types you will get a failed test because
148  * <code>TypeDetection</code> tries to find out the type itself.
149  *
150  * Syntax: fileAlias;fileType
151  * Example: Writer6_1;writer_StarOffice_XML_Writer
152  *
153  * This example shows the following:
154  * <code>Writer6_1</code> is the same as in <code>csv.files</code>
155  * <code>writer_StarOffice_XML_Writer</code> is the file type which was used as
156  * parameter in <code>MediaDescriptor</code>. This type must be returned from
157  * <code>TypeDetection</code>
158  *
159  * <p>
160  * <H3><a name="serviceName.csv"></A>
161  * <code>serviceName.csv</code></H3> In this file you can preselect a service name
162  * to detect the file type. The returned file type by
163  * <code>TypeDetection</code> must equal to correspond
164  * <code>defaultFileType</code> from <code>csv.files</code>
165  *
166  * Syntax: fileAlias;serviceName
167  * Example: Writer6_1;com.sun.star.text.FormatDetector
168  *
169  * This example shows the following:
170  * <code>Writer6_1</code> is the same as in <code>csv.files</code>
171  * <code>com.sun.star.text.FormatDetector</code> is the service name which was
172  * used as parameter in <code>MediaDescriptor</code>.
173  *
174  *
175  * <p>
176  * All these files will be copied by make file beside of
177  * <code>typeDetection.class</code>.
178  * @see com.sun.star.document.XTypeDetection
179  * @see com.sun.star.document.MediaDescriptor
180  */
181 public class TypeDetection extends ComplexTestCase {
182 
183     /**
184      * @member m_xDetection     the object to test
185      * @member helper           instacne of helper class
186      */
187 
188     static XTypeDetection   m_xDetection;
189     static Helper helper = null;
190 
191     /**
192      * A function to tell the framework, which test functions are available.
193      * @return All test methods.
194      */
getTestMethodNames()195     public String[] getTestMethodNames() {
196         return new String[]{"checkByURLonly",
197                             "checkPreselectedType",
198                             "checkPreselectedFilter",
199                             "checkPreselectedDocService",
200                             "checkStreamLoader",
201                             "checkStreamLoader"};
202 
203     }
204 
205     /** Create the environment for following tests.
206      * Use either a component loader from desktop or
207      * from frame
208      * @throws Exception Exception
209      */
before()210     public void before() throws Exception {
211 
212         // create TypeDetection
213         XMultiServiceFactory xMSF = (XMultiServiceFactory)param.getMSF();
214         assure("Could not get XMultiServiceFactory", xMSF != null);
215 
216         Object oInterface = xMSF.createInstance(
217                                         "com.sun.star.document.TypeDetection");
218 
219         if (oInterface == null) {
220             failed("Service wasn't created") ;
221         }
222 
223         XInterface oObj = (XInterface) oInterface ;
224         log.println("ImplName: "+utils.getImplName(oObj));
225 
226         m_xDetection = (XTypeDetection)
227                 UnoRuntime.queryInterface(XTypeDetection.class, oInterface);
228         Enumeration k = param.keys();
229         while (k.hasMoreElements()){
230             String kName = ((String)k.nextElement()).toString();
231             log.println(kName + ":" + param.get(kName).toString());
232         }
233         // create instrace of helper class
234         helper = new Helper(param, log);
235 
236     }
237 
238     /**
239      * close the environment
240      */
after()241     public void after() {
242     }
243 
244     /**
245      * The <code>MediaDescriptor</code> was filled with the URL of a file. The
246      * <code>type</code> of the file is kown and must be returned by
247      * <code>MediaDescriptor</code>
248      *
249      * Syntax of files.csv:
250      * fileAlias;fileURL;fileType
251      *
252      */
checkByURLonly()253     public void checkByURLonly() {
254         try{
255             log.println("### checkByURLonly() ###");
256             Vector CSVData =  helper.getToDoList(
257                                     (String)param.get("csv.files"));
258             Enumeration allToDos = CSVData.elements();
259 
260             while (allToDos.hasMoreElements()){
261                 Vector toDo = (Vector) allToDos.nextElement();
262 
263                 String fileAlias = (String) toDo.get(0);
264                 String fileURL  = (String) toDo.get(1);
265                 String URLfileType = (String) toDo.get(2);
266                 String StreamfileType = (String) toDo.get(3);
267 
268                 fileURL =  utils.getFullURL(helper.ensureEndingFileSep(
269                               (String)param.get("TestDocumentPath")) + fileURL);
270 
271                 log.println("actual '"+ fileAlias +
272                                         "' ['" + URLfileType + "']: '" + fileURL);
273 
274                 checkMediaDescriptorURL(fileAlias, fileURL, URLfileType);
275                 checkMediaDescriptorXInputStream(fileAlias, fileURL, StreamfileType);
276             }
277 
278         } catch (ClassCastException e){
279             failed(e.toString(), true);
280         }
281     }
282 
283     /** To check the <CODE>TypeDedection</CODE> by URL the <CODE>MediaDescriptor</CODE>
284      * was filled at fist with the URL only, at second with <CODE>XInputStream</CODE>
285      * only. The <CODE>TypeDetection</CODE> must return the expected value
286      * @param fileAlias the alias name of the test file
287      * @param fileURL the URL of the test file
288      * @param fileType the expected type of the test file
289      * @see com.sun.star.document.MediaDescriptor
290      */
checkMediaDescriptorURL( String fileAlias, String fileURL, String fileType)291     private void checkMediaDescriptorURL(
292                             String fileAlias, String fileURL, String fileType){
293 
294         PropertyValue[] MediaDescriptor = helper.createMediaDescriptor(
295             new String[] {"URL"},
296             new Object[] {fileURL});
297             log.println("check only by URL...");
298 
299             String type = m_xDetection.queryTypeByDescriptor(
300                                helper.createInOutPropertyValue(MediaDescriptor), true);
301 
302             boolean fileTypeOK = helper.checkFileType(type, fileType);
303 
304             assure("\nURL-test         : " + fileAlias + ":\n\treturned type: '" + type +
305                    "'\n\texpected type: '" + fileType + "'",fileTypeOK ,true);
306     }
307 
308     /** Filles a MediaDescriptor with a <code>XInputStream</code> of the test
309      * file given by URL.
310      * Then the MediaDescriptor was used as parameter for TypeDetection.
311      * The TypeDetection must return expected type
312      * @param fileAlias the alias name of the test file
313      * @param fileURL the URL of the test file
314      * @param fileType the expected type of the test file
315      * @see com.sun.star.document.MediaDescriptor
316      * @see com.sun.star.io.XInputStream
317      */
checkMediaDescriptorXInputStream( String fileAlias, String fileURL, String fileType)318     private void checkMediaDescriptorXInputStream(
319                              String fileAlias, String fileURL, String fileType){
320 
321         XInputStream xStream = null;
322 
323         try{
324             xStream = helper.getFileStream( fileURL );
325         } catch (NotConnectedException e) {
326             failed("Could not get XInputStream from file :'" + fileURL + "'",true);
327             return;
328         }
329 
330         PropertyValue[] MediaDescriptor = helper.createMediaDescriptor(
331             new String[] {"InputStream"},
332             new Object[] {xStream});
333             log.println("check only by XInputStream...");
334 
335             String type = m_xDetection.queryTypeByDescriptor(
336                                helper.createInOutPropertyValue(MediaDescriptor), true);
337 
338             boolean fileTypeOK = helper.checkFileType(type, fileType);
339 
340             assure("\nXInputStream-test: " + fileAlias + ":\n\treturned type: '" + type +
341                    "'\n\texpected type: '" + fileType + "'", fileTypeOK, true);
342 
343     }
344 
345     /**
346      * The <code>MediaDescriptor</code> was filled with the URL of a file. The
347      * <code>type</code> of the file is kown and must be returned by
348      * <code>MediaDescriptor</code>
349      *
350      * Syntax of files.csv:
351      * fileAlias;fileURL;fileType
352      *
353      */
checkPreselectedType()354     public void checkPreselectedType() {
355         try{
356             log.println("### checkPreselectedType() ###");
357 
358             Vector CSVData =  helper.getToDoList(
359                                     (String)param.get("csv.preselectedType"));
360             Enumeration allToDos = CSVData.elements();
361 
362             while (allToDos.hasMoreElements()){
363                 try{
364                     Vector toDo = (Vector) allToDos.nextElement();
365 
366                     String fileAlias = (String) toDo.get(0);
367                     String fileURL  = helper.getURLforfileAlias(fileAlias);
368                     String preselectFileType = (String) toDo.get(1);
369                     String expectedFileType = (String) toDo.get(2);
370 
371                     PropertyValue[] MediaDescriptor = helper.createMediaDescriptor(
372                         new String[] {"URL", "MediaType"},
373                         new Object[] {fileURL, preselectFileType});
374                     log.println("check '" + fileAlias + "' with MediaType: '" +
375                                 preselectFileType + "'");
376 
377                     String type = m_xDetection.queryTypeByDescriptor(
378                                    helper.createInOutPropertyValue(MediaDescriptor), true);
379 
380                     boolean fileTypeOK = helper.checkFileType(type, expectedFileType);
381 
382                     assure("\n" + fileAlias + ":\n\treturned type: '" + type +
383                                     "'\n\texpected type: '" + expectedFileType + "'",
384                                     fileTypeOK, true);
385 
386                     } catch (FileAliasNotFoundException e){
387                         failed(e.toString(),true);
388                     }
389 
390             }
391 
392         } catch (ClassCastException e){
393             failed(e.toString(), true);
394         }
395     }
396 
397 
398     /**
399      * Check loading from a stream. The source for the stream is the
400      * first fileAlias that matches "*.txt" in the file list
401      * of the given directory.
402      */
checkPreselectedFilter()403     public void checkPreselectedFilter() {
404         try{
405             log.println("### checkPreselectedFilter() ###");
406 
407             Vector CSVData =  helper.getToDoList(
408                                     (String)param.get("csv.preselectedFilter"));
409 
410             Enumeration allToDos = CSVData.elements();
411 
412             while (allToDos.hasMoreElements()){
413                 try{
414                     Vector toDo = (Vector) allToDos.nextElement();
415 
416                     String fileAlias = (String) toDo.get(0);
417                     String fileURL  = helper.getURLforfileAlias(fileAlias);
418                     String filterName = (String) toDo.get(1);
419                     String filterOptions = (String) toDo.get(2);
420                     String filterData = (String) toDo.get(3);
421                     String expectedType = (String) toDo.get(4);
422 
423                     PropertyValue[] MediaDescriptor = helper.createMediaDescriptor(
424                         new String[] {"URL","FilterName",
425                                                   "FilterOptions","FilterData"},
426                         new Object[] {fileURL, filterName,
427                                                    filterOptions, filterData});
428 
429                     log.println("check '" + fileAlias + "' with filter: '" +
430                                 filterName + "'");
431 
432                     String type = m_xDetection.queryTypeByDescriptor(
433                                helper.createInOutPropertyValue(MediaDescriptor), true);
434 
435                     boolean fileTypeOK = helper.checkFileType(type, expectedType);
436 
437                     assure("\n" + fileAlias + ":\n\treturned type: '" + type +
438                                     "'\n\texpected type: '" + expectedType + "'",
439                                     fileTypeOK,true);
440 
441                 } catch (FileAliasNotFoundException e){
442                     failed(e.toString(),true);
443                 }
444 
445             }
446 
447         } catch (ClassCastException e){
448             failed(e.toString(), true);
449         }
450     }
451 
452     /**
453      * Check URL encoding. The first fileAlias that matches "*.sxw"
454      * is used as source for several encodings.
455      */
checkPreselectedDocService()456      public void checkPreselectedDocService() {
457         try{
458             log.println("### checkPreselectedDocService() ###");
459 
460             Vector CSVData =  helper.getToDoList((String)param.get("csv.serviceName"));
461             Enumeration allToDos = CSVData.elements();
462 
463             while (allToDos.hasMoreElements()){
464                 try{
465                     Vector toDo = (Vector) allToDos.nextElement();
466 
467                     String fileAlias = (String) toDo.get(0);
468                     String fileURL  = helper.getURLforfileAlias(fileAlias);
469                     String serviceName = (String) toDo.get(1);
470                     String fileType = helper.getTypeforfileAlias(fileAlias);
471 
472                     PropertyValue[] MediaDescriptor = helper.createMediaDescriptor(
473                         new String[] {"URL", "DocumentSerivce"},
474                         new Object[] {fileURL, serviceName});
475                     log.println("check " + fileAlias);
476 
477                     String type = m_xDetection.queryTypeByDescriptor(
478                                    helper.createInOutPropertyValue(MediaDescriptor), true);
479 
480                     boolean fileTypeOK = helper.checkFileType(type, fileType);
481 
482                     assure("\n" + fileAlias + ":\n\treturned type: '" + type +
483                                     "'\t\nexpected type: '" + fileType + "'",
484                                     fileTypeOK, true);
485 
486                 } catch (FileAliasNotFoundException e){
487                     failed(e.toString(),true);
488                 }
489 
490             }
491 
492         } catch (ClassCastException e){
493             failed(e.toString(), true);
494         }
495      }
496 
checkStreamLoader()497      public void checkStreamLoader(){
498          try{
499 
500             /*
501              *als Dateien die typeDetection.props und eine der csv-Dateien
502              *benutzten. diese k�nnen per dmake einfach auf andere Rechte setzten
503              *
504              */
505             log.println("### checkStreamLoader() ###");
506             String[] urls = new String[2];
507 
508             urls[0] = helper.getClassURLString("TypeDetection.props");
509             urls[1] = helper.getClassURLString("files.csv");
510 
511             for (int j=0; j<urls.length; j++){
512                 String fileURL  = urls[j];
513                 File file = new File(fileURL);
514                 fileURL =  utils.getFullURL(fileURL);
515 
516                 PropertyValue[] MediaDescriptor = helper.createMediaDescriptor(
517                                                         new String[] {"URL"},
518                                                         new Object[] {fileURL});
519 
520                 if (file.canWrite()) log.println("check writable file...");
521                 else log.println("check readonly file...");
522 
523                 PropertyValue[][] inOut = helper.createInOutPropertyValue(MediaDescriptor);
524                 PropertyValue[] in = inOut[0];
525                 log.println("in-Parameter:");
526                 for (int i=0; i < in.length; i++){
527                     log.println("["+i+"] '" + in[i].Name + "':'" + in[i].Value.toString()+"'");
528                 }
529 
530                 String type = m_xDetection.queryTypeByDescriptor(inOut, true);
531 
532                 PropertyValue[] out = inOut[0];
533 
534                 boolean bStream = false;
535                 log.println("out-Parameter");
536                 boolean bReadOnly = false;
537                 for (int i=0; i < out.length; i++){
538                     if ((out[i].Name.equals("ReadOnly")) && (out[i].Value.toString().equals("true"))) bReadOnly = true;
539                     log.println("["+i+"] '" + out[i].Name + "':'" + out[i].Value.toString()+"'");
540                 }
541 
542                 if (file.canWrite() && bReadOnly)
543                     assure("\nStreamLoader: file '"+ fileURL +"' is writable but out-Parameter does contain 'ReadOnly' property",false ,true);
544                 else if ((!file.canWrite()) && (!bReadOnly))
545                     assure("\nStreamLoader: file '"+ fileURL +"'is readonly but out-Parameter does not contain 'ReadOnly' property",false ,true);
546                 else assure("all ok",true,true);
547 
548             }
549 
550          } catch (ClassCastException e){
551             failed(e.toString(), true);
552         }
553 
554      }
555 }