/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
package helper;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;
import java.util.jar.JarEntry;
import share.DescEntry;
import share.DescGetter;
/**
* This is the Office-API specific DescGetter
*
* Examples:
* -o sw.SwXBodyText
* runs the module test of Sw.SwXBodyText
*
* -o sw.SwXBodyText::com::sun::star::text::Text
* runs only the interface test com.sun.star.textText of the module Sw.SwXBodyText
*
* -o sw.SwXBodyText::com::sun::star::text::Text,com::sun::star::text::XSimpleText
* runs only the interfaces test com.sun.star.textText and com.sun.star.text.XSimpleText of the module Sw.SwXBodyText
*
* -p sw
* runs all modules of the project sw
*
* -p listall
* lists all known module tests
*
* -sce SCENARIO_FILE
* A scenario file is a property file which could contain -o and -p properties
*
* -sce sw.SwXBodyText,sw.SwXBookmark
* runs the module test of Sw.SwXBodyText and sw.SwXBookmark
*/
public class APIDescGetter extends DescGetter
{
private static String fullJob = null;
/*
* gets the needed information about a StarOffice component
* @param descPath Path to the ComponentDescription
* @param entry contains the entry name, e.g. sw.SwXBodyText
* @param debug if true some debug information is displayed on standard out
*/
@Override
public DescEntry[] getDescriptionFor(String job, String descPath,
boolean debug)
{
if (job.startsWith("-o"))
{
job = job.substring(3, job.length()).trim();
if (job.indexOf('.') < 0)
{
return null;
}
// special in case several Interfaces are given comma separated
if (job.indexOf(',') < 0)
{
DescEntry entry = getDescriptionForSingleJob(job, descPath,
debug);
if (entry != null)
{
return new DescEntry[]
{
entry
};
}
else
{
return null;
}
}
else
{
ArrayList subs = getSubInterfaces(job);
String partjob = job.substring(0, job.indexOf(',')).trim();
DescEntry entry = getDescriptionForSingleJob(partjob, descPath,
debug);
if (entry != null)
{
for (int i = 0; i < entry.SubEntryCount; i++)
{
String subEntry = entry.SubEntries[i].longName;
int cpLength = entry.longName.length();
subEntry = subEntry.substring(cpLength + 2,
subEntry.length());
if (subs.contains(subEntry))
{
entry.SubEntries[i].isToTest = true;
}
}
return new DescEntry[]
{
entry
};
}
else
{
return null;
}
}
}
if (job.startsWith("-p"))
{
job = job.substring(3, job.length()).trim();
String[] scenario = createScenario(descPath, job, debug);
if (scenario == null)
{
return null;
}
DescEntry[] entries = new DescEntry[scenario.length];
for (int i = 0; i < scenario.length; i++)
{
entries[i] = getDescriptionForSingleJob(
scenario[i].substring(3).trim(), descPath, debug);
}
if (job.equals("listall"))
{
util.dbg.printArray(scenario);
System.exit(0);
}
return entries;
}
if (job.startsWith("-sce"))
{
job = job.substring(5, job.length()).trim();
File sceFile = new File(job);
if (sceFile.exists())
{
return getScenario(job, descPath, debug);
}
else
{
//look the scenario like this? :
// sw.SwXBodyText,sw.SwXTextCursor
ArrayList subs = getSubObjects(job);
DescEntry[] entries = new DescEntry[subs.size()];
for (int i = 0; i < subs.size(); i++)
{
entries[i] = getDescriptionForSingleJob(
subs.get(i), descPath, debug);
}
return entries;
}
}
else
{
return null;
}
}
@Override
protected DescEntry getDescriptionForSingleJob(String job, String descPath,
boolean debug)
{
boolean isSingleInterface = job.indexOf("::") > 0;
fullJob = job;
if (isSingleInterface)
{
job = job.substring(0, job.indexOf("::"));
}
if (job.startsWith("bugs"))
{
DescEntry Entry = new DescEntry();
Entry.entryName = job;
Entry.longName = job;
Entry.EntryType = "bugdoc";
Entry.isOptional = false;
Entry.isToTest = true;
Entry.SubEntryCount = 0;
Entry.hasErrorMsg = false;
Entry.State = "non possible";
return Entry;
}
DescEntry entry = null;
if (descPath != null)
{
if (debug)
{
System.out.println("## reading from File " + descPath);
}
entry = getFromDirectory(descPath, job, debug);
}
else
{
if (debug)
{
System.out.println("## reading from jar");
}
entry = getFromClassPath(job);
}
boolean foundInterface = false;
if (isSingleInterface && (entry != null))
{
for (int i = 0; i < entry.SubEntryCount; i++)
{
if (!(entry.SubEntries[i].longName).equals(fullJob))
{
entry.SubEntries[i].isToTest = false;
}
else
{
foundInterface = true;
entry.SubEntries[i].isToTest = true;
}
}
}
if (isSingleInterface && !foundInterface || entry == null)
{
return setErrorDescription(entry,
"couldn't find a description for test '" + fullJob + "'");
}
return entry;
}
private static DescEntry[] getSubEntries(BufferedReader cvsFile,
DescEntry parent)
{
String line = "";
String old_ifc_name = "";
ArrayList ifc_names = new ArrayList();
ArrayList meth_names = new ArrayList();
DescEntry ifcDesc = null;
while (line != null)
{
try
{
line = cvsFile.readLine();
if (line == null)
{
continue;
}
if (line.startsWith("#"))
{
continue;
}
if (line.length() <= 0)
{
continue;
}
// TODO Problem here
String ifc_name = ""; // = line.substring(line.indexOf(";") + 2, line.lastIndexOf(";") - 1);
String meth_name = ""; // = line.substring(line.lastIndexOf(";") + 2, line.length() - 1);
StringTokenizer aToken = new StringTokenizer(line, ";");
if (aToken.countTokens() < 3)
{
System.out.println("Wrong format: Line '" + line + "' is not supported.");
continue;
}
if (aToken.hasMoreTokens())
{
aToken.nextToken();
}
if (aToken.hasMoreTokens())
{
ifc_name = StringHelper.removeQuoteIfExists(aToken.nextToken());
}
if (aToken.hasMoreTokens())
{
meth_name = StringHelper.removeQuoteIfExists(aToken.nextToken());
}
DescEntry methDesc = createDescEntry(meth_name, ifc_name, parent);
if (!ifc_name.equals(old_ifc_name))
{
if (ifcDesc != null)
{
ifcDesc.SubEntries = getDescArray(meth_names.toArray());
ifcDesc.SubEntryCount = meth_names.size();
//mark service/interface as optional if all methods/properties are optional
boolean allOptional = true;
for (int k = 0; k < ifcDesc.SubEntryCount; k++)
{
if (!ifcDesc.SubEntries[k].isOptional)
{
allOptional = false;
}
}
if (!ifcDesc.isOptional && allOptional)
{
ifcDesc.isOptional = allOptional;
}
meth_names.clear();
ifc_names.add(ifcDesc);
}
ifcDesc = new DescEntry();
ifcDesc.isToTest = true;
old_ifc_name = ifc_name;
if (ifc_name.indexOf("#optional") > 0)
{
ifcDesc.isOptional = true;
ifc_name = ifc_name.substring(0, ifc_name.indexOf('#'));
}
String className = createClassName(ifc_name);
ifcDesc.EntryType = entryType;
ifcDesc.entryName = "ifc" + className;
ifcDesc.longName = parent.entryName + "::" + ifc_name;
}
meth_names.add(methDesc);
}
catch (java.io.IOException ioe)
{
parent.hasErrorMsg = true;
parent.ErrorMsg = "IOException while reading the description";
break;
}
}
if (ifcDesc == null) {
return null;
}
ifcDesc.SubEntries = getDescArray(meth_names.toArray());
ifcDesc.SubEntryCount = meth_names.size();
//mark service/interface as optional if all methods/properties are optional
boolean allOptional = true;
for (int k = 0; k < ifcDesc.SubEntryCount; k++)
{
if (!ifcDesc.SubEntries[k].isOptional)
{
allOptional = false;
}
}
if (!ifcDesc.isOptional && allOptional)
{
ifcDesc.isOptional = allOptional;
}
ifc_names.add(ifcDesc);
return getDescArray(makeArray(ifc_names));
}
private static String createClassName(String _ifc_name)
{
StringTokenizer st = new StringTokenizer(_ifc_name, ":");
int count = 3;
if (_ifc_name.startsWith("drafts"))
{
count = 4;
}
StringBuilder className = new StringBuilder();
for (int i = 0; st.hasMoreTokens(); i++)
{
String token = st.nextToken();
// skipping (drafts.)com.sun.star
if (i >= count)
{
if (!st.hasMoreTokens())
{
// inserting '_' before the last token
token = "_" + token;
}
className.append(".").append(token);
}
}
return className.toString();
}
private static String entryType;
private static DescEntry createDescEntry(String meth_name, String ifc_name, DescEntry parent)
{
entryType = "service";
DescEntry methDesc = new DescEntry();
if (meth_name.indexOf("#optional") > 0)
{
methDesc.isOptional = true;
meth_name = meth_name.substring(0, meth_name.indexOf('#'));
}
if (meth_name.endsWith("()"))
{
methDesc.EntryType = "method";
entryType = "interface";
}
else
{
methDesc.EntryType = "property";
entryType = "service";
}
methDesc.entryName = meth_name;
methDesc.isToTest = true;
String withoutHash = ifc_name;
if (ifc_name.indexOf("#optional") > 0)
{
withoutHash = ifc_name.substring(0, ifc_name.indexOf('#'));
}
methDesc.longName = parent.entryName + "::" + withoutHash + "::" + meth_name;
return methDesc;
}
/**
* This method ensures that XComponent will be the last in the list of interfaces
*/
private static Object[] makeArray(ArrayList entries)
{
Object[] entriesArray = entries.toArray();
ArrayList