1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
29 import java
.io
.BufferedReader
;
31 import java
.io
.FileReader
;
32 import java
.io
.InputStream
;
33 import java
.io
.InputStreamReader
;
35 import java
.util
.ArrayList
;
36 import java
.util
.Collections
;
37 import java
.util
.StringTokenizer
;
39 import share
.DescEntry
;
40 import share
.DescGetter
;
43 * This is the Office-API specific DescGetter<br>
46 * -o sw.SwXBodyText<br>
47 * runs the module test of <B>Sw.SwXBodyText</B><br>
49 * -o sw.SwXBodyText::com::sun::star::text::Text<br>
50 * runs only the interface test <B>com.sun.star.textText</B> of the module <B>Sw.SwXBodyText</B><br>
52 * -o sw.SwXBodyText::com::sun::star::text::Text,com::sun::star::text::XSimpleText<br>
53 * runs only the interfaces test <B>com.sun.star.textText</B> and <B>com.sun.star.text.XSimpleText</B> of the module <B>Sw.SwXBodyText</B><br>
56 * runs all modules of the project <B>sw</B><br>
59 * lists all known module tests<br>
61 * -sce SCENARIO_FILE<br>
62 * A scenario file is a property file which could cotain <B>-o</B> and <B>-p</B> properties<br>
64 * -sce sw.SwXBodyText,sw.SwXBookmark<br>
65 * runs the module test of <B>Sw.SwXBodyText</B> and <B>sw.SwXBookmark</B><br>
67 public class APIDescGetter
extends DescGetter
70 private static String fullJob
= null;
73 * gets the needed information about a StarOffice component
74 * @param descPath Path to the ComponentDescription
75 * @param entry contains the entry name, e.g. sw.SwXBodyText
76 * @param debug if true some debug information is displayed on standard out
78 public DescEntry
[] getDescriptionFor(String job
, String descPath
,
82 if (job
.startsWith("-o"))
84 job
= job
.substring(3, job
.length()).trim();
86 if (job
.indexOf(".") < 0)
91 // special in case several Interfaces are given comma separated
92 if (job
.indexOf(",") < 0)
94 DescEntry entry
= getDescriptionForSingleJob(job
, descPath
,
99 return new DescEntry
[]
111 ArrayList subs
= getSubInterfaces(job
);
112 String partjob
= job
.substring(0, job
.indexOf(",")).trim();
113 DescEntry entry
= getDescriptionForSingleJob(partjob
, descPath
,
118 for (int i
= 0; i
< entry
.SubEntryCount
; i
++)
120 String subEntry
= entry
.SubEntries
[i
].longName
;
121 int cpLength
= entry
.longName
.length();
122 subEntry
= subEntry
.substring(cpLength
+ 2,
125 if (subs
.contains(subEntry
))
127 entry
.SubEntries
[i
].isToTest
= true;
131 return new DescEntry
[]
143 if (job
.startsWith("-p"))
145 job
= job
.substring(3, job
.length()).trim();
147 String
[] scenario
= createScenario(descPath
, job
, debug
);
148 if (scenario
== null)
152 DescEntry
[] entries
= new DescEntry
[scenario
.length
];
153 for (int i
= 0; i
< scenario
.length
; i
++)
155 entries
[i
] = getDescriptionForSingleJob(
156 scenario
[i
].substring(3).trim(), descPath
, debug
);
158 if (job
.equals("listall"))
160 util
.dbg
.printArray(scenario
);
166 if (job
.startsWith("-sce"))
168 job
= job
.substring(5, job
.length()).trim();
170 File sceFile
= new File(job
);
171 if (sceFile
.exists())
173 return getScenario(job
, descPath
, debug
);
177 //look the scenarion like this? :
178 // sw.SwXBodyText,sw.SwXTextCursor
179 ArrayList subs
= getSubObjects(job
);
180 DescEntry
[] entries
= new DescEntry
[subs
.size()];
182 for (int i
= 0; i
< subs
.size(); i
++)
184 entries
[i
] = getDescriptionForSingleJob(
185 (String
) subs
.get(i
), descPath
, debug
);
196 protected DescEntry
getDescriptionForSingleJob(String job
, String descPath
,
199 boolean isSingleInterface
= job
.indexOf("::") > 0;
202 if (isSingleInterface
)
204 job
= job
.substring(0, job
.indexOf("::"));
207 if (job
.startsWith("bugs"))
209 DescEntry Entry
= new DescEntry();
210 Entry
.entryName
= job
;
211 Entry
.longName
= job
;
212 Entry
.EntryType
= "bugdoc";
213 Entry
.isOptional
= false;
214 Entry
.isToTest
= true;
215 Entry
.SubEntryCount
= 0;
216 Entry
.hasErrorMsg
= false;
217 Entry
.State
= "non possible";
222 DescEntry entry
= null;
224 if (descPath
!= null)
228 System
.out
.println("## reading from File " + descPath
);
231 entry
= getFromDirectory(descPath
, job
, debug
);
237 System
.out
.println("## reading from jar");
240 entry
= getFromClassPath(job
, debug
);
243 boolean foundInterface
= false;
245 if (isSingleInterface
&& (entry
!= null))
247 for (int i
= 0; i
< entry
.SubEntryCount
; i
++)
249 if (!(entry
.SubEntries
[i
].longName
).equals(fullJob
))
251 entry
.SubEntries
[i
].isToTest
= false;
255 foundInterface
= true;
256 entry
.SubEntries
[i
].isToTest
= true;
261 if (isSingleInterface
&& !foundInterface
|| entry
== null)
263 return setErrorDescription(entry
,
264 "couldn't find a description for test '" + fullJob
+ "'");
270 protected static DescEntry
[] getSubEntries(BufferedReader cvsFile
,
271 DescEntry parent
, boolean debug
)
274 String old_ifc_name
= "";
275 ArrayList ifc_names
= new ArrayList();
276 ArrayList meth_names
= new ArrayList();
277 DescEntry ifcDesc
= null;
283 line
= cvsFile
.readLine();
288 if (line
.startsWith("#"))
292 if (line
.length() <= 0)
296 // TODO Probleme here
297 // int nFirstSemicolon = line.indexOf(";");
298 // int nLastSemicolon = line.lastIndexOf(";");
301 String ifc_name
= ""; // = line.substring(line.indexOf(";") + 2, line.lastIndexOf(";") - 1);
302 String meth_name
= ""; // = line.substring(line.lastIndexOf(";") + 2, line.length() - 1);
303 StringTokenizer aToken
= new StringTokenizer(line
, ";");
304 if (aToken
.countTokens() < 3)
306 System
.out
.println("Wrong format: Line '" + line
+ "' is not supported.");
309 if (aToken
.hasMoreTokens())
311 unknown
= StringHelper
.removeQuoteIfExists(aToken
.nextToken());
313 if (aToken
.hasMoreTokens())
315 ifc_name
= StringHelper
.removeQuoteIfExists(aToken
.nextToken());
317 if (aToken
.hasMoreTokens())
319 meth_name
= StringHelper
.removeQuoteIfExists(aToken
.nextToken());
322 // String ifc_name = line.substring(line.indexOf(";") + 2, line.lastIndexOf(";") - 1);
323 // String meth_name = line.substring(line.lastIndexOf(";") + 2, line.length() - 1);
325 DescEntry methDesc
= createDescEntry(meth_name
, ifc_name
, parent
);
327 if (!ifc_name
.equals(old_ifc_name
))
331 ifcDesc
.SubEntries
= getDescArray(meth_names
.toArray());
332 ifcDesc
.SubEntryCount
= meth_names
.size();
334 //mark service/interface as optional if all methods/properties are optional
335 boolean allOptional
= true;
337 for (int k
= 0; k
< ifcDesc
.SubEntryCount
; k
++)
339 if (!ifcDesc
.SubEntries
[k
].isOptional
)
345 if (!ifcDesc
.isOptional
&& allOptional
)
347 ifcDesc
.isOptional
= allOptional
;
351 ifc_names
.add(ifcDesc
);
354 ifcDesc
= new DescEntry();
355 ifcDesc
.isToTest
= true;
356 old_ifc_name
= ifc_name
;
358 if (ifc_name
.indexOf("#optional") > 0)
360 ifcDesc
.isOptional
= true;
361 ifc_name
= ifc_name
.substring(0, ifc_name
.indexOf("#"));
364 String className
= createClassName(ifc_name
);
366 ifcDesc
.EntryType
= entryType
;
367 ifcDesc
.entryName
= "ifc" + className
;
368 ifcDesc
.longName
= parent
.entryName
+ "::" + ifc_name
;
370 meth_names
.add(methDesc
);
373 catch (java
.io
.IOException ioe
)
375 parent
.hasErrorMsg
= true;
376 parent
.ErrorMsg
= "IOException while reading the description";
382 ifcDesc
.SubEntries
= getDescArray(meth_names
.toArray());
383 ifcDesc
.SubEntryCount
= meth_names
.size();
385 //mark service/interface as optional if all methods/properties are optional
386 boolean allOptional
= true;
388 for (int k
= 0; k
< ifcDesc
.SubEntryCount
; k
++)
390 if (!ifcDesc
.SubEntries
[k
].isOptional
)
396 if (!ifcDesc
.isOptional
&& allOptional
)
398 ifcDesc
.isOptional
= allOptional
;
401 ifc_names
.add(ifcDesc
);
403 return getDescArray(makeArray(ifc_names
));
405 private static String
createClassName(String _ifc_name
)
407 StringTokenizer st
= new StringTokenizer(_ifc_name
, ":");
408 String className
= "";
412 if (_ifc_name
.startsWith("drafts"))
417 for (int i
= 0; st
.hasMoreTokens(); i
++)
419 String token
= st
.nextToken();
421 // skipping (drafts.)com.sun.star
424 if (!st
.hasMoreTokens())
426 // inserting '_' before the last token
430 className
+= ("." + token
);
436 private static String entryType
;
438 private static DescEntry
createDescEntry(String meth_name
, String ifc_name
, DescEntry parent
)
440 entryType
= "service";
441 DescEntry methDesc
= new DescEntry();
443 if (meth_name
.indexOf("#optional") > 0)
445 methDesc
.isOptional
= true;
446 meth_name
= meth_name
.substring(0, meth_name
.indexOf("#"));
449 if (meth_name
.endsWith("()"))
451 methDesc
.EntryType
= "method";
452 entryType
= "interface";
456 methDesc
.EntryType
= "property";
457 entryType
= "service";
460 methDesc
.entryName
= meth_name
;
461 methDesc
.isToTest
= true;
464 String withoutHash
= ifc_name
;
466 if (ifc_name
.indexOf("#optional") > 0)
468 withoutHash
= ifc_name
.substring(0, ifc_name
.indexOf("#"));
471 methDesc
.longName
= parent
.entryName
+ "::" + withoutHash
+ "::" + meth_name
;
476 private static void createIfcName(String ifc_name
, ArrayList meth_names
, DescEntry ifcDesc
)
481 * This method ensures that XComponent will be the last in the list of interfaces
483 protected static Object
[] makeArray(ArrayList entries
)
485 Object
[] entriesArray
= entries
.toArray();
486 ArrayList returnArray
= new ArrayList();
487 Object addAtEnd
= null;
489 for (int k
= 0; k
< entriesArray
.length
; k
++)
491 DescEntry entry
= (DescEntry
) entriesArray
[k
];
493 if (entry
.entryName
.equals("ifc.lang._XComponent"))
499 returnArray
.add(entry
);
503 if (addAtEnd
!= null)
505 returnArray
.add(addAtEnd
);
508 return returnArray
.toArray();
511 protected static DescEntry
setErrorDescription(DescEntry entry
,
516 entry
= new DescEntry();
518 entry
.hasErrorMsg
= true;
519 entry
.ErrorMsg
= "Error while getting description for test '" +
520 fullJob
+ "' as an API test: " + ErrorMsg
;
525 protected static DescEntry
[] getDescArray(Object
[] list
)
527 DescEntry
[] entries
= new DescEntry
[list
.length
];
529 for (int i
= 0; i
< list
.length
; i
++)
531 entries
[i
] = (DescEntry
) list
[i
];
537 protected DescEntry
getFromClassPath(String aEntry
, boolean debug
)
539 int dotindex
= aEntry
.indexOf('.');
546 String module
= null;
547 String shortName
= null;
549 if (aEntry
.indexOf(".uno") == -1)
551 module
= aEntry
.substring(0, aEntry
.indexOf('.'));
552 shortName
= aEntry
.substring(aEntry
.indexOf('.') + 1);
556 module
= aEntry
.substring(0, aEntry
.lastIndexOf('.'));
557 shortName
= aEntry
.substring(aEntry
.lastIndexOf('.') + 1);
560 DescEntry theEntry
= new DescEntry();
561 theEntry
.entryName
= aEntry
;
562 theEntry
.longName
= aEntry
;
563 theEntry
.isOptional
= false;
564 theEntry
.EntryType
= "component";
565 theEntry
.isToTest
= true;
567 BufferedReader csvFile
= null;
569 java
.net
.URL url
= this.getClass().getResource("/objdsc/" + module
);
573 return setErrorDescription(theEntry
,
574 "couldn't find module '" + module
+ "'");
579 java
.net
.URLConnection con
= url
.openConnection();
581 String sEndsWithCSVName
= "." + shortName
.trim() + ".csv";
582 if (con
instanceof java
.net
.JarURLConnection
)
584 // get Jar file from connection
585 java
.util
.jar
.JarFile f
= ((java
.net
.JarURLConnection
) con
).getJarFile();
587 // Enumerate over all entries
588 java
.util
.Enumeration e
= f
.entries();
590 String sStartModule
= "/" + module
+ "/";
591 while (e
.hasMoreElements())
594 String entry
= e
.nextElement().toString();
597 // System.out.println("### Read from connetion: " + entry);
600 if ((entry
.lastIndexOf(sStartModule
) != -1) &&
601 entry
.endsWith(sEndsWithCSVName
))
603 InputStream input
= this.getClass().getResourceAsStream("/" + entry
);
604 csvFile
= new BufferedReader(new InputStreamReader(input
));
611 InputStream in
= con
.getInputStream();
612 java
.io
.BufferedReader buf
= new java
.io
.BufferedReader(new InputStreamReader(in
));
613 boolean found
= false;
615 while (buf
.ready() && !found
)
617 String entry
= buf
.readLine();
619 if (entry
.endsWith(sEndsWithCSVName
))
621 System
.out
.println("FOUND ####");
622 InputStream input
= this.getClass().getResourceAsStream("/objdsc/" +
626 csvFile
= new BufferedReader(
627 new InputStreamReader(input
));
635 catch (java
.io
.IOException e
)
642 return setErrorDescription(theEntry
,
643 "couldn't find component '" +
644 theEntry
.entryName
+ "'");
647 DescEntry
[] subEntries
= getSubEntries(csvFile
, theEntry
, debug
);
649 theEntry
.SubEntryCount
= subEntries
.length
;
650 theEntry
.SubEntries
= subEntries
;
655 protected static DescEntry
getFromDirectory(String descPath
, String entry
,
658 int dotindex
= entry
.indexOf('.');
665 String fs
= System
.getProperty("file.separator");
666 String module
= null;
667 String shortName
= null;
669 if (entry
.indexOf(".uno") == -1)
671 module
= entry
.substring(0, entry
.indexOf('.'));
672 shortName
= entry
.substring(entry
.indexOf('.') + 1);
676 module
= entry
.substring(0, entry
.lastIndexOf('.'));
677 shortName
= entry
.substring(entry
.lastIndexOf('.') + 1);
680 DescEntry aEntry
= new DescEntry();
681 aEntry
.entryName
= entry
;
682 aEntry
.longName
= entry
;
683 aEntry
.isOptional
= false;
684 aEntry
.EntryType
= "component";
685 aEntry
.isToTest
= true;
689 System
.out
.println("Parsing Description Path: " + descPath
);
690 System
.out
.println("Searching module: " + module
);
691 System
.out
.println("For the Component " + shortName
);
694 File modPath
= new File(descPath
+ fs
+ module
);
696 if (!modPath
.exists())
698 return setErrorDescription(aEntry
,
699 "couldn't find module '" + module
+ "'");
702 String
[] files
= modPath
.list();
703 String found
= "none";
705 for (int i
= 0; i
< files
.length
; i
++)
707 if (files
[i
].endsWith("." + shortName
+ ".csv"))
710 System
.out
.println("found " + found
);
715 if (found
.equals("none"))
717 return setErrorDescription(aEntry
,
718 "couldn't find component '" + entry
+ "'");
721 String aUrl
= descPath
+ fs
+ module
+ fs
+ found
;
723 BufferedReader csvFile
= null;
727 csvFile
= new BufferedReader(new FileReader(aUrl
));
729 catch (java
.io
.FileNotFoundException fnfe
)
731 return setErrorDescription(aEntry
, "couldn't find file '" + aUrl
+ "'");
734 DescEntry
[] subEntries
= getSubEntries(csvFile
, aEntry
, debug
);
736 aEntry
.SubEntryCount
= subEntries
.length
;
737 aEntry
.SubEntries
= subEntries
;
742 protected ArrayList
getSubInterfaces(String job
)
744 ArrayList namesList
= new ArrayList();
745 StringTokenizer st
= new StringTokenizer(job
, ",");
747 for (int i
= 0; st
.hasMoreTokens(); i
++)
749 String token
= st
.nextToken();
751 if (token
.indexOf(".") < 0)
753 namesList
.add(token
);
760 protected ArrayList
getSubObjects(String job
)
762 ArrayList namesList
= new ArrayList();
763 StringTokenizer st
= new StringTokenizer(job
, ",");
765 for (int i
= 0; st
.hasMoreTokens(); i
++)
767 namesList
.add(st
.nextToken());
773 protected String
[] createScenario(String descPath
, String job
,
776 String
[] scenario
= null;
778 if (descPath
!= null)
782 System
.out
.println("## reading from File " + descPath
);
785 scenario
= getScenarioFromDirectory(descPath
, job
, debug
);
791 System
.out
.println("## reading from jar");
794 scenario
= getScenarioFromClassPath(job
, debug
);
800 protected String
[] getScenarioFromDirectory(String descPath
, String job
,
803 String
[] modules
= null;
804 ArrayList componentList
= new ArrayList();
806 if (!job
.equals("unknown") && !job
.equals("listall"))
808 modules
= new String
[]
815 File dirs
= new File(descPath
);
823 modules
= dirs
.list();
827 for (int i
= 0; i
< modules
.length
; i
++)
829 if (!isUnusedModule(modules
[i
]))
831 File moduleDir
= new File(descPath
+ System
.getProperty("file.separator") + modules
[i
]);
832 if (moduleDir
.exists())
834 String
[] components
= moduleDir
.list();
835 for (int j
= 0; j
< components
.length
; j
++)
837 if (components
[j
].endsWith(".csv"))
839 String toAdd
= getComponentForString(components
[j
], modules
[i
]);
840 toAdd
= "-o " + modules
[i
] + "." + toAdd
;
841 componentList
.add(toAdd
);
848 String
[] scenario
= new String
[componentList
.size()];
849 Collections
.sort(componentList
);
851 for (int i
= 0; i
< componentList
.size(); i
++)
853 scenario
[i
] = (String
) componentList
.get(i
);
860 protected String
[] getScenarioFromClassPath(String job
, boolean debug
)
864 if (!job
.equals("unknown") && !job
.equals("listall"))
869 java
.net
.URL url
= this.getClass().getResource("/objdsc" + subdir
);
876 ArrayList scenarioList
= new ArrayList();
880 java
.net
.URLConnection con
= url
.openConnection();
882 if (con
instanceof java
.net
.JarURLConnection
)
884 // get Jar file from connection
885 java
.util
.jar
.JarFile f
= ((java
.net
.JarURLConnection
) con
).getJarFile();
887 // Enumerate over all entries
888 java
.util
.Enumeration e
= f
.entries();
890 while (e
.hasMoreElements())
892 String entry
= e
.nextElement().toString();
894 if (entry
.startsWith("objdsc" + subdir
) &&
895 (entry
.indexOf("CVS") < 0) &&
896 !entry
.endsWith("/"))
898 int startMod
= entry
.indexOf("/");
899 int endMod
= entry
.lastIndexOf("/");
900 String module
= entry
.substring(startMod
+ 1, endMod
);
901 String component
= getComponentForString(
902 entry
.substring(endMod
+ 1,
906 if (!isUnusedModule(module
))
908 scenarioList
.add("-o " + module
+ "." +
915 catch (java
.io
.IOException e
)
920 String
[] scenario
= new String
[scenarioList
.size()];
921 Collections
.sort(scenarioList
);
923 for (int i
= 0; i
< scenarioList
.size(); i
++)
925 scenario
[i
] = (String
) scenarioList
.get(i
);
931 protected String
getComponentForString(String full
, String module
)
933 String component
= "";
937 full
= full
.substring(0, full
.length() - 4);
940 int lastdot
= full
.lastIndexOf(".");
941 component
= full
.substring(lastdot
+ 1, full
.length());
943 if (module
.equals("file") || module
.equals("xmloff"))
945 String withoutComponent
= full
.substring(0, lastdot
);
946 int preLastDot
= withoutComponent
.lastIndexOf(".");
947 component
= withoutComponent
.substring(preLastDot
+ 1,
948 withoutComponent
.length()) +
955 protected boolean isUnusedModule(String moduleName
)
957 ArrayList removed
= new ArrayList();
958 removed
.add("acceptor");
959 removed
.add("brdgfctr");
960 removed
.add("connectr");
961 removed
.add("corefl");
963 removed
.add("defreg");
964 removed
.add("dynamicloader");
965 removed
.add("impreg");
968 removed
.add("invadp");
969 removed
.add("javaloader");
971 removed
.add("namingservice");
972 removed
.add("proxyfac");
973 removed
.add("rdbtdp");
974 removed
.add("remotebridge");
975 removed
.add("simreg");
979 removed
.add("tdmgr");
980 removed
.add("ucprmt");
981 removed
.add("uuresolver");
983 return removed
.contains(moduleName
);