blob: cea1b4c6cf28575df92966820f212f4c7dd4c47c [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
package org.openoffice.idesupport;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Vector;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.MalformedURLException;
import org.openoffice.idesupport.zip.ParcelZipper;
import com.sun.star.script.framework.container.ScriptEntry;
public class JavaFinder implements MethodFinder {
private static JavaFinder finder;
private static final String JAVA_SUFFIX = ".java";
private static final String CLASS_SUFFIX = ".class";
private static final String LANGUAGE = "Java";
private static final String FIRST_PARAM =
"drafts.com.sun.star.script.framework.runtime.XScriptContext";
private Vector classpath = null;
private JavaFinder() {}
private JavaFinder(Vector classpath) {
this.classpath = classpath;
}
public static JavaFinder getInstance() {
if (finder == null) {
synchronized(JavaFinder.class) {
if (finder == null)
finder = new JavaFinder();
}
}
return finder;
}
public static JavaFinder getInstance(Vector classpath) {
return new JavaFinder(classpath);
}
public ScriptEntry[] findMethods(File basedir) {
String parcelName;
ArrayList result = new ArrayList(10);
ScriptEntry[] empty = new ScriptEntry[0];
if (basedir == null || basedir.exists() == false ||
basedir.isDirectory() == false)
return empty;
parcelName = basedir.getName();
if (parcelName.equals(ParcelZipper.CONTENTS_DIRNAME))
parcelName = basedir.getParentFile().getName();
String[] classNames = findClassNames(basedir);
if (classNames != null && classNames.length != 0) {
ClassLoader classloader;
if (classpath == null)
classloader = getClassLoader(basedir);
else
classloader = getClassLoader();
for (int i = 0; i < classNames.length; i++)
{
try
{
Class clazz = classloader.loadClass(classNames[i]);
Method[] methods = clazz.getDeclaredMethods();
for (int k = 0; k < methods.length; k++)
{
if (Modifier.isPublic(methods[k].getModifiers()))
{
Class[] params = methods[k].getParameterTypes();
if(params.length > 0)
{
if(params[0].getName().equals(FIRST_PARAM))
{
ScriptEntry entry =
new ScriptEntry(classNames[i] + "." +
methods[k].getName(), parcelName);
result.add(entry);
}
}
}
}
}
catch (ClassNotFoundException e)
{
System.err.println("Caught ClassNotFoundException loading: "
+ classNames[i]);
continue;
}
catch (NoClassDefFoundError nc)
{
System.err.println("Caught NoClassDefFoundErr loading: " +
classNames[i]);
continue;
}
}
}
if (result.size() != 0)
return (ScriptEntry[])result.toArray(empty);
return empty;
}
private ClassLoader getClassLoader() {
int len = classpath.size();
ArrayList urls = new ArrayList(len);
for (int i = 0; i < len; i++) {
try {
String s = (String)classpath.elementAt(i);
s = SVersionRCFile.toFileURL(s);
if (s != null)
urls.add(new URL(s));
}
catch (MalformedURLException mue) {
}
}
return new URLClassLoader((URL[])urls.toArray(new URL[0]));
}
private ClassLoader getClassLoader(File basedir) {
ArrayList files = findFiles(basedir, ".jar");
files.add(basedir);
try {
Enumeration offices = SVersionRCFile.createInstance().getVersions();
while (offices.hasMoreElements()) {
OfficeInstallation oi = (OfficeInstallation)offices.nextElement();
String unoil = SVersionRCFile.getPathForUnoil(oi.getPath());
if (unoil != null) {
files.add(new File(unoil, "unoil.jar"));
break;
}
}
}
catch (IOException ioe) {
return null;
}
URL[] urls = new URL[files.size()];
String urlpath;
File f;
for (int i = 0; i < urls.length; i++) {
try {
f = (File)files.get(i);
urlpath = SVersionRCFile.toFileURL(f.getAbsolutePath());
if (urlpath != null)
urls[i] = new URL(urlpath);
}
catch (MalformedURLException mue) {
// do nothing, go on to next file
}
}
return new URLClassLoader(urls);
}
private ArrayList findFiles(File basedir, String suffix) {
ArrayList result = new ArrayList();
File[] children = basedir.listFiles();
for (int i = 0; i < children.length; i++) {
if (children[i].isDirectory())
result.addAll(findFiles(children[i], suffix));
else if (children[i].getName().endsWith(suffix))
result.add(children[i]);
}
return result;
}
private String[] findClassNames(File basedir)
{
ArrayList classFiles = findFiles(basedir, CLASS_SUFFIX);
if(classFiles == null || classFiles.size() == 0)
return null;
ArrayList javaFiles = findFiles(basedir, JAVA_SUFFIX);
if(javaFiles == null || javaFiles.size() == 0)
return null;
ArrayList result = new ArrayList();
for (int i = 0; i < classFiles.size(); i++)
{
File classFile = (File)classFiles.get(i);
String className = classFile.getName();
className = className.substring(0, className.lastIndexOf(CLASS_SUFFIX));
boolean finished = false;
for (int j = 0; j < javaFiles.size() && finished == false; j++)
{
File javaFile = (File)javaFiles.get(j);
String javaName = javaFile.getName();
javaName = javaName.substring(0, javaName.lastIndexOf(JAVA_SUFFIX));
if (javaName.equals(className))
{
String path = classFile.getAbsolutePath();
path = path.substring(basedir.getAbsolutePath().length() + 1);
path = path.replace(File.separatorChar, '.');
path = path.substring(0, path.lastIndexOf(CLASS_SUFFIX));
result.add(path);
javaFiles.remove(j);
finished = true;
}
}
}
return (String[])result.toArray(new String[0]);
}
}