1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: APIDescGetter.java,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
32 import java
.io
.BufferedReader
;
34 import java
.io
.FileReader
;
35 import java
.io
.InputStream
;
36 import java
.io
.InputStreamReader
;
38 import java
.util
.ArrayList
;
39 import java
.util
.Collections
;
40 import java
.util
.StringTokenizer
;
42 import share
.DescEntry
;
43 import share
.DescGetter
;
46 * This is the Office-API specific DescGetter<br>
49 * -o sw.SwXBodyText<br>
50 * runs the module test of <B>Sw.SwXBodyText</B><br>
52 * -o sw.SwXBodyText::com::sun::star::text::Text<br>
53 * runs only the interface test <B>com.sun.star.textText</B> of the module <B>Sw.SwXBodyText</B><br>
55 * -o sw.SwXBodyText::com::sun::star::text::Text,com::sun::star::text::XSimpleText<br>
56 * 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>
59 * runs all modules of the project <B>sw</B><br>
62 * lists all known module tests<br>
64 * -sce SCENARIO_FILE<br>
65 * A scenario file is a property file which could cotain <B>-o</B> and <B>-p</B> properties<br>
67 * -sce sw.SwXBodyText,sw.SwXBookmark<br>
68 * runs the module test of <B>Sw.SwXBodyText</B> and <B>sw.SwXBookmark</B><br>
70 public class APIDescGetter
extends DescGetter
73 private static String fullJob
= null;
76 * gets the needed information about a StarOffice component
77 * @param descPath Path to the ComponentDescription
78 * @param entry contains the entry name, e.g. sw.SwXBodyText
79 * @param debug if true some debug information is displayed on standard out
81 public DescEntry
[] getDescriptionFor(String job
, String descPath
,
85 if (job
.startsWith("-o"))
87 job
= job
.substring(3, job
.length()).trim();
89 if (job
.indexOf(".") < 0)
94 // special in case several Interfaces are given comma separated
95 if (job
.indexOf(",") < 0)
97 DescEntry entry
= getDescriptionForSingleJob(job
, descPath
,
102 return new DescEntry
[]
114 ArrayList subs
= getSubInterfaces(job
);
115 String partjob
= job
.substring(0, job
.indexOf(",")).trim();
116 DescEntry entry
= getDescriptionForSingleJob(partjob
, descPath
,
121 for (int i
= 0; i
< entry
.SubEntryCount
; i
++)
123 String subEntry
= entry
.SubEntries
[i
].longName
;
124 int cpLength
= entry
.longName
.length();
125 subEntry
= subEntry
.substring(cpLength
+ 2,
128 if (subs
.contains(subEntry
))
130 entry
.SubEntries
[i
].isToTest
= true;
134 return new DescEntry
[]
146 if (job
.startsWith("-p"))
148 job
= job
.substring(3, job
.length()).trim();
150 String
[] scenario
= createScenario(descPath
, job
, debug
);
151 if (scenario
== null)
155 DescEntry
[] entries
= new DescEntry
[scenario
.length
];
156 for (int i
= 0; i
< scenario
.length
; i
++)
158 entries
[i
] = getDescriptionForSingleJob(
159 scenario
[i
].substring(3).trim(), descPath
, debug
);
161 if (job
.equals("listall"))
163 util
.dbg
.printArray(scenario
);
169 if (job
.startsWith("-sce"))
171 job
= job
.substring(5, job
.length()).trim();
173 File sceFile
= new File(job
);
174 if (sceFile
.exists())
176 return getScenario(job
, descPath
, debug
);
180 //look the scenarion like this? :
181 // sw.SwXBodyText,sw.SwXTextCursor
182 ArrayList subs
= getSubObjects(job
);
183 DescEntry
[] entries
= new DescEntry
[subs
.size()];
185 for (int i
= 0; i
< subs
.size(); i
++)
187 entries
[i
] = getDescriptionForSingleJob(
188 (String
) subs
.get(i
), descPath
, debug
);
199 protected DescEntry
getDescriptionForSingleJob(String job
, String descPath
,
202 boolean isSingleInterface
= job
.indexOf("::") > 0;
205 if (isSingleInterface
)
207 job
= job
.substring(0, job
.indexOf("::"));
210 if (job
.startsWith("bugs"))
212 DescEntry Entry
= new DescEntry();
213 Entry
.entryName
= job
;
214 Entry
.longName
= job
;
215 Entry
.EntryType
= "bugdoc";
216 Entry
.isOptional
= false;
217 Entry
.isToTest
= true;
218 Entry
.SubEntryCount
= 0;
219 Entry
.hasErrorMsg
= false;
220 Entry
.State
= "non possible";
225 DescEntry entry
= null;
227 if (descPath
!= null)
231 System
.out
.println("## reading from File " + descPath
);
234 entry
= getFromDirectory(descPath
, job
, debug
);
240 System
.out
.println("## reading from jar");
243 entry
= getFromClassPath(job
, debug
);
246 boolean foundInterface
= false;
248 if (isSingleInterface
&& (entry
!= null))
250 for (int i
= 0; i
< entry
.SubEntryCount
; i
++)
252 if (!(entry
.SubEntries
[i
].longName
).equals(fullJob
))
254 entry
.SubEntries
[i
].isToTest
= false;
258 foundInterface
= true;
259 entry
.SubEntries
[i
].isToTest
= true;
264 if (isSingleInterface
&& !foundInterface
|| entry
== null)
266 return setErrorDescription(entry
,
267 "couldn't find a description for test '" + fullJob
+ "'");
273 protected static DescEntry
[] getSubEntries(BufferedReader cvsFile
,
274 DescEntry parent
, boolean debug
)
277 String old_ifc_name
= "";
278 ArrayList ifc_names
= new ArrayList();
279 ArrayList meth_names
= new ArrayList();
280 DescEntry ifcDesc
= null;
286 line
= cvsFile
.readLine();
291 if (line
.startsWith("#"))
295 if (line
.length() <= 0)
299 // TODO Probleme here
300 // int nFirstSemicolon = line.indexOf(";");
301 // int nLastSemicolon = line.lastIndexOf(";");
304 String ifc_name
= ""; // = line.substring(line.indexOf(";") + 2, line.lastIndexOf(";") - 1);
305 String meth_name
= ""; // = line.substring(line.lastIndexOf(";") + 2, line.length() - 1);
306 StringTokenizer aToken
= new StringTokenizer(line
, ";");
307 if (aToken
.countTokens() < 3)
309 System
.out
.println("Wrong format: Line '" + line
+ "' is not supported.");
312 if (aToken
.hasMoreTokens())
314 unknown
= StringHelper
.removeQuoteIfExists(aToken
.nextToken());
316 if (aToken
.hasMoreTokens())
318 ifc_name
= StringHelper
.removeQuoteIfExists(aToken
.nextToken());
320 if (aToken
.hasMoreTokens())
322 meth_name
= StringHelper
.removeQuoteIfExists(aToken
.nextToken());
325 // String ifc_name = line.substring(line.indexOf(";") + 2, line.lastIndexOf(";") - 1);
326 // String meth_name = line.substring(line.lastIndexOf(";") + 2, line.length() - 1);
328 DescEntry methDesc
= createDescEntry(meth_name
, ifc_name
, parent
);
330 if (!ifc_name
.equals(old_ifc_name
))
334 ifcDesc
.SubEntries
= getDescArray(meth_names
.toArray());
335 ifcDesc
.SubEntryCount
= meth_names
.size();
337 //mark service/interface as optional if all methods/properties are optional
338 boolean allOptional
= true;
340 for (int k
= 0; k
< ifcDesc
.SubEntryCount
; k
++)
342 if (!ifcDesc
.SubEntries
[k
].isOptional
)
348 if (!ifcDesc
.isOptional
&& allOptional
)
350 ifcDesc
.isOptional
= allOptional
;
354 ifc_names
.add(ifcDesc
);
357 ifcDesc
= new DescEntry();
358 ifcDesc
.isToTest
= true;
359 old_ifc_name
= ifc_name
;
361 if (ifc_name
.indexOf("#optional") > 0)
363 ifcDesc
.isOptional
= true;
364 ifc_name
= ifc_name
.substring(0, ifc_name
.indexOf("#"));
367 String className
= createClassName(ifc_name
);
369 ifcDesc
.EntryType
= entryType
;
370 ifcDesc
.entryName
= "ifc" + className
;
371 ifcDesc
.longName
= parent
.entryName
+ "::" + ifc_name
;
373 meth_names
.add(methDesc
);
376 catch (java
.io
.IOException ioe
)
378 parent
.hasErrorMsg
= true;
379 parent
.ErrorMsg
= "IOException while reading the description";
385 ifcDesc
.SubEntries
= getDescArray(meth_names
.toArray());
386 ifcDesc
.SubEntryCount
= meth_names
.size();
388 //mark service/interface as optional if all methods/properties are optional
389 boolean allOptional
= true;
391 for (int k
= 0; k
< ifcDesc
.SubEntryCount
; k
++)
393 if (!ifcDesc
.SubEntries
[k
].isOptional
)
399 if (!ifcDesc
.isOptional
&& allOptional
)
401 ifcDesc
.isOptional
= allOptional
;
404 ifc_names
.add(ifcDesc
);
406 return getDescArray(makeArray(ifc_names
));
408 private static String
createClassName(String _ifc_name
)
410 StringTokenizer st
= new StringTokenizer(_ifc_name
, ":");
411 String className
= "";
415 if (_ifc_name
.startsWith("drafts"))
420 for (int i
= 0; st
.hasMoreTokens(); i
++)
422 String token
= st
.nextToken();
424 // skipping (drafts.)com.sun.star
427 if (!st
.hasMoreTokens())
429 // inserting '_' before the last token
433 className
+= ("." + token
);
439 private static String entryType
;
441 private static DescEntry
createDescEntry(String meth_name
, String ifc_name
, DescEntry parent
)
443 entryType
= "service";
444 DescEntry methDesc
= new DescEntry();
446 if (meth_name
.indexOf("#optional") > 0)
448 methDesc
.isOptional
= true;
449 meth_name
= meth_name
.substring(0, meth_name
.indexOf("#"));
452 if (meth_name
.endsWith("()"))
454 methDesc
.EntryType
= "method";
455 entryType
= "interface";
459 methDesc
.EntryType
= "property";
460 entryType
= "service";
463 methDesc
.entryName
= meth_name
;
464 methDesc
.isToTest
= true;
467 String withoutHash
= ifc_name
;
469 if (ifc_name
.indexOf("#optional") > 0)
471 withoutHash
= ifc_name
.substring(0, ifc_name
.indexOf("#"));
474 methDesc
.longName
= parent
.entryName
+ "::" + withoutHash
+ "::" + meth_name
;
479 private static void createIfcName(String ifc_name
, ArrayList meth_names
, DescEntry ifcDesc
)
484 * This method ensures that XComponent will be the last in the list of interfaces
486 protected static Object
[] makeArray(ArrayList entries
)
488 Object
[] entriesArray
= entries
.toArray();
489 ArrayList returnArray
= new ArrayList();
490 Object addAtEnd
= null;
492 for (int k
= 0; k
< entriesArray
.length
; k
++)
494 DescEntry entry
= (DescEntry
) entriesArray
[k
];
496 if (entry
.entryName
.equals("ifc.lang._XComponent"))
502 returnArray
.add(entry
);
506 if (addAtEnd
!= null)
508 returnArray
.add(addAtEnd
);
511 return returnArray
.toArray();
514 protected static DescEntry
setErrorDescription(DescEntry entry
,
519 entry
= new DescEntry();
521 entry
.hasErrorMsg
= true;
522 entry
.ErrorMsg
= "Error while getting description for test '" +
523 fullJob
+ "' as an API test: " + ErrorMsg
;
528 protected static DescEntry
[] getDescArray(Object
[] list
)
530 DescEntry
[] entries
= new DescEntry
[list
.length
];
532 for (int i
= 0; i
< list
.length
; i
++)
534 entries
[i
] = (DescEntry
) list
[i
];
540 protected DescEntry
getFromClassPath(String aEntry
, boolean debug
)
542 int dotindex
= aEntry
.indexOf('.');
549 String module
= null;
550 String shortName
= null;
552 if (aEntry
.indexOf(".uno") == -1)
554 module
= aEntry
.substring(0, aEntry
.indexOf('.'));
555 shortName
= aEntry
.substring(aEntry
.indexOf('.') + 1);
559 module
= aEntry
.substring(0, aEntry
.lastIndexOf('.'));
560 shortName
= aEntry
.substring(aEntry
.lastIndexOf('.') + 1);
563 DescEntry theEntry
= new DescEntry();
564 theEntry
.entryName
= aEntry
;
565 theEntry
.longName
= aEntry
;
566 theEntry
.isOptional
= false;
567 theEntry
.EntryType
= "component";
568 theEntry
.isToTest
= true;
570 BufferedReader csvFile
= null;
572 java
.net
.URL url
= this.getClass().getResource("/objdsc/" + module
);
576 return setErrorDescription(theEntry
,
577 "couldn't find module '" + module
+ "'");
582 java
.net
.URLConnection con
= url
.openConnection();
584 String sEndsWithCSVName
= "." + shortName
.trim() + ".csv";
585 if (con
instanceof java
.net
.JarURLConnection
)
587 // get Jar file from connection
588 java
.util
.jar
.JarFile f
= ((java
.net
.JarURLConnection
) con
).getJarFile();
590 // Enumerate over all entries
591 java
.util
.Enumeration e
= f
.entries();
593 String sStartModule
= "/" + module
+ "/";
594 while (e
.hasMoreElements())
597 String entry
= e
.nextElement().toString();
600 // System.out.println("### Read from connetion: " + entry);
603 if ((entry
.lastIndexOf(sStartModule
) != -1) &&
604 entry
.endsWith(sEndsWithCSVName
))
606 InputStream input
= this.getClass().getResourceAsStream("/" + entry
);
607 csvFile
= new BufferedReader(new InputStreamReader(input
));
614 InputStream in
= con
.getInputStream();
615 java
.io
.BufferedReader buf
= new java
.io
.BufferedReader(new InputStreamReader(in
));
616 boolean found
= false;
618 while (buf
.ready() && !found
)
620 String entry
= buf
.readLine();
622 if (entry
.endsWith(sEndsWithCSVName
))
624 System
.out
.println("FOUND ####");
625 InputStream input
= this.getClass().getResourceAsStream("/objdsc/" +
629 csvFile
= new BufferedReader(
630 new InputStreamReader(input
));
638 catch (java
.io
.IOException e
)
645 return setErrorDescription(theEntry
,
646 "couldn't find component '" +
647 theEntry
.entryName
+ "'");
650 DescEntry
[] subEntries
= getSubEntries(csvFile
, theEntry
, debug
);
652 theEntry
.SubEntryCount
= subEntries
.length
;
653 theEntry
.SubEntries
= subEntries
;
658 protected static DescEntry
getFromDirectory(String descPath
, String entry
,
661 int dotindex
= entry
.indexOf('.');
668 String fs
= System
.getProperty("file.separator");
669 String module
= null;
670 String shortName
= null;
672 if (entry
.indexOf(".uno") == -1)
674 module
= entry
.substring(0, entry
.indexOf('.'));
675 shortName
= entry
.substring(entry
.indexOf('.') + 1);
679 module
= entry
.substring(0, entry
.lastIndexOf('.'));
680 shortName
= entry
.substring(entry
.lastIndexOf('.') + 1);
683 DescEntry aEntry
= new DescEntry();
684 aEntry
.entryName
= entry
;
685 aEntry
.longName
= entry
;
686 aEntry
.isOptional
= false;
687 aEntry
.EntryType
= "component";
688 aEntry
.isToTest
= true;
692 System
.out
.println("Parsing Description Path: " + descPath
);
693 System
.out
.println("Searching module: " + module
);
694 System
.out
.println("For the Component " + shortName
);
697 File modPath
= new File(descPath
+ fs
+ module
);
699 if (!modPath
.exists())
701 return setErrorDescription(aEntry
,
702 "couldn't find module '" + module
+ "'");
705 String
[] files
= modPath
.list();
706 String found
= "none";
708 for (int i
= 0; i
< files
.length
; i
++)
710 if (files
[i
].endsWith("." + shortName
+ ".csv"))
713 System
.out
.println("found " + found
);
718 if (found
.equals("none"))
720 return setErrorDescription(aEntry
,
721 "couldn't find component '" + entry
+ "'");
724 String aUrl
= descPath
+ fs
+ module
+ fs
+ found
;
726 BufferedReader csvFile
= null;
730 csvFile
= new BufferedReader(new FileReader(aUrl
));
732 catch (java
.io
.FileNotFoundException fnfe
)
734 return setErrorDescription(aEntry
, "couldn't find file '" + aUrl
+ "'");
737 DescEntry
[] subEntries
= getSubEntries(csvFile
, aEntry
, debug
);
739 aEntry
.SubEntryCount
= subEntries
.length
;
740 aEntry
.SubEntries
= subEntries
;
745 protected ArrayList
getSubInterfaces(String job
)
747 ArrayList namesList
= new ArrayList();
748 StringTokenizer st
= new StringTokenizer(job
, ",");
750 for (int i
= 0; st
.hasMoreTokens(); i
++)
752 String token
= st
.nextToken();
754 if (token
.indexOf(".") < 0)
756 namesList
.add(token
);
763 protected ArrayList
getSubObjects(String job
)
765 ArrayList namesList
= new ArrayList();
766 StringTokenizer st
= new StringTokenizer(job
, ",");
768 for (int i
= 0; st
.hasMoreTokens(); i
++)
770 namesList
.add(st
.nextToken());
776 protected String
[] createScenario(String descPath
, String job
,
779 String
[] scenario
= null;
781 if (descPath
!= null)
785 System
.out
.println("## reading from File " + descPath
);
788 scenario
= getScenarioFromDirectory(descPath
, job
, debug
);
794 System
.out
.println("## reading from jar");
797 scenario
= getScenarioFromClassPath(job
, debug
);
803 protected String
[] getScenarioFromDirectory(String descPath
, String job
,
806 String
[] modules
= null;
807 ArrayList componentList
= new ArrayList();
809 if (!job
.equals("unknown") && !job
.equals("listall"))
811 modules
= new String
[]
818 File dirs
= new File(descPath
);
826 modules
= dirs
.list();
830 for (int i
= 0; i
< modules
.length
; i
++)
832 if (!isUnusedModule(modules
[i
]))
834 File moduleDir
= new File(descPath
+ System
.getProperty("file.separator") + modules
[i
]);
835 if (moduleDir
.exists())
837 String
[] components
= moduleDir
.list();
838 for (int j
= 0; j
< components
.length
; j
++)
840 if (components
[j
].endsWith(".csv"))
842 String toAdd
= getComponentForString(components
[j
], modules
[i
]);
843 toAdd
= "-o " + modules
[i
] + "." + toAdd
;
844 componentList
.add(toAdd
);
851 String
[] scenario
= new String
[componentList
.size()];
852 Collections
.sort(componentList
);
854 for (int i
= 0; i
< componentList
.size(); i
++)
856 scenario
[i
] = (String
) componentList
.get(i
);
863 protected String
[] getScenarioFromClassPath(String job
, boolean debug
)
867 if (!job
.equals("unknown") && !job
.equals("listall"))
872 java
.net
.URL url
= this.getClass().getResource("/objdsc" + subdir
);
879 ArrayList scenarioList
= new ArrayList();
883 java
.net
.URLConnection con
= url
.openConnection();
885 if (con
instanceof java
.net
.JarURLConnection
)
887 // get Jar file from connection
888 java
.util
.jar
.JarFile f
= ((java
.net
.JarURLConnection
) con
).getJarFile();
890 // Enumerate over all entries
891 java
.util
.Enumeration e
= f
.entries();
893 while (e
.hasMoreElements())
895 String entry
= e
.nextElement().toString();
897 if (entry
.startsWith("objdsc" + subdir
) &&
898 (entry
.indexOf("CVS") < 0) &&
899 !entry
.endsWith("/"))
901 int startMod
= entry
.indexOf("/");
902 int endMod
= entry
.lastIndexOf("/");
903 String module
= entry
.substring(startMod
+ 1, endMod
);
904 String component
= getComponentForString(
905 entry
.substring(endMod
+ 1,
909 if (!isUnusedModule(module
))
911 scenarioList
.add("-o " + module
+ "." +
918 catch (java
.io
.IOException e
)
923 String
[] scenario
= new String
[scenarioList
.size()];
924 Collections
.sort(scenarioList
);
926 for (int i
= 0; i
< scenarioList
.size(); i
++)
928 scenario
[i
] = (String
) scenarioList
.get(i
);
934 protected String
getComponentForString(String full
, String module
)
936 String component
= "";
940 full
= full
.substring(0, full
.length() - 4);
943 int lastdot
= full
.lastIndexOf(".");
944 component
= full
.substring(lastdot
+ 1, full
.length());
946 if (module
.equals("file") || module
.equals("xmloff"))
948 String withoutComponent
= full
.substring(0, lastdot
);
949 int preLastDot
= withoutComponent
.lastIndexOf(".");
950 component
= withoutComponent
.substring(preLastDot
+ 1,
951 withoutComponent
.length()) +
958 protected boolean isUnusedModule(String moduleName
)
960 ArrayList removed
= new ArrayList();
961 removed
.add("acceptor");
962 removed
.add("brdgfctr");
963 removed
.add("connectr");
964 removed
.add("corefl");
966 removed
.add("defreg");
967 removed
.add("dynamicloader");
968 removed
.add("impreg");
971 removed
.add("invadp");
972 removed
.add("javaloader");
974 removed
.add("namingservice");
975 removed
.add("proxyfac");
976 removed
.add("rdbtdp");
977 removed
.add("remotebridge");
978 removed
.add("simreg");
982 removed
.add("tdmgr");
983 removed
.add("ucprmt");
984 removed
.add("uuresolver");
986 return removed
.contains(moduleName
);