1 package org.openoffice.idesupport; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.util.ArrayList; 6 import java.util.Enumeration; 7 import java.util.Vector; 8 import java.lang.reflect.Method; 9 import java.lang.reflect.Modifier; 10 import java.net.URL; 11 import java.net.URLClassLoader; 12 import java.net.MalformedURLException; 13 import org.openoffice.idesupport.zip.ParcelZipper; 14 15 import com.sun.star.script.framework.container.ScriptEntry; 16 17 public class JavaFinder implements MethodFinder { 18 19 private static JavaFinder finder; 20 private static final String JAVA_SUFFIX = ".java"; 21 private static final String CLASS_SUFFIX = ".class"; 22 private static final String LANGUAGE = "Java"; 23 private static final String FIRST_PARAM = 24 "drafts.com.sun.star.script.framework.runtime.XScriptContext"; 25 26 private Vector classpath = null; 27 28 private JavaFinder() {} 29 30 private JavaFinder(Vector classpath) { 31 this.classpath = classpath; 32 } 33 34 public static JavaFinder getInstance() { 35 if (finder == null) { 36 synchronized(JavaFinder.class) { 37 if (finder == null) 38 finder = new JavaFinder(); 39 } 40 } 41 return finder; 42 } 43 44 public static JavaFinder getInstance(Vector classpath) { 45 return new JavaFinder(classpath); 46 } 47 48 public ScriptEntry[] findMethods(File basedir) { 49 String parcelName; 50 ArrayList result = new ArrayList(10); 51 ScriptEntry[] empty = new ScriptEntry[0]; 52 53 if (basedir == null || basedir.exists() == false || 54 basedir.isDirectory() == false) 55 return empty; 56 57 parcelName = basedir.getName(); 58 if (parcelName.equals(ParcelZipper.CONTENTS_DIRNAME)) 59 parcelName = basedir.getParentFile().getName(); 60 61 String[] classNames = findClassNames(basedir); 62 if (classNames != null && classNames.length != 0) { 63 64 ClassLoader classloader; 65 66 if (classpath == null) 67 classloader = getClassLoader(basedir); 68 else 69 classloader = getClassLoader(); 70 71 for (int i = 0; i < classNames.length; i++) 72 { 73 try 74 { 75 Class clazz = classloader.loadClass(classNames[i]); 76 Method[] methods = clazz.getDeclaredMethods(); 77 for (int k = 0; k < methods.length; k++) 78 { 79 if (Modifier.isPublic(methods[k].getModifiers())) 80 { 81 Class[] params = methods[k].getParameterTypes(); 82 if(params.length > 0) 83 { 84 if(params[0].getName().equals(FIRST_PARAM)) 85 { 86 ScriptEntry entry = 87 new ScriptEntry(classNames[i] + "." + 88 methods[k].getName(), parcelName); 89 result.add(entry); 90 } 91 } 92 } 93 } 94 } 95 catch (ClassNotFoundException e) 96 { 97 System.err.println("Caught ClassNotFoundException loading: " 98 + classNames[i]); 99 continue; 100 } 101 catch (NoClassDefFoundError nc) 102 { 103 System.err.println("Caught NoClassDefFoundErr loading: " + 104 classNames[i]); 105 continue; 106 } 107 } 108 } 109 110 if (result.size() != 0) 111 return (ScriptEntry[])result.toArray(empty); 112 return empty; 113 } 114 115 private ClassLoader getClassLoader() { 116 int len = classpath.size(); 117 ArrayList urls = new ArrayList(len); 118 119 for (int i = 0; i < len; i++) { 120 try { 121 String s = (String)classpath.elementAt(i); 122 s = SVersionRCFile.toFileURL(s); 123 124 if (s != null) 125 urls.add(new URL(s)); 126 } 127 catch (MalformedURLException mue) { 128 } 129 } 130 131 return new URLClassLoader((URL[])urls.toArray(new URL[0])); 132 } 133 134 private ClassLoader getClassLoader(File basedir) { 135 ArrayList files = findFiles(basedir, ".jar"); 136 files.add(basedir); 137 138 try { 139 Enumeration offices = SVersionRCFile.createInstance().getVersions(); 140 141 while (offices.hasMoreElements()) { 142 OfficeInstallation oi = (OfficeInstallation)offices.nextElement(); 143 String unoil = SVersionRCFile.getPathForUnoil(oi.getPath()); 144 145 if (unoil != null) { 146 files.add(new File(unoil, "unoil.jar")); 147 break; 148 } 149 } 150 } 151 catch (IOException ioe) { 152 return null; 153 } 154 155 URL[] urls = new URL[files.size()]; 156 String urlpath; 157 File f; 158 for (int i = 0; i < urls.length; i++) { 159 try { 160 f = (File)files.get(i); 161 urlpath = SVersionRCFile.toFileURL(f.getAbsolutePath()); 162 163 if (urlpath != null) 164 urls[i] = new URL(urlpath); 165 } 166 catch (MalformedURLException mue) { 167 // do nothing, go on to next file 168 } 169 } 170 171 return new URLClassLoader(urls); 172 } 173 174 private ArrayList findFiles(File basedir, String suffix) { 175 ArrayList result = new ArrayList(); 176 File[] children = basedir.listFiles(); 177 178 for (int i = 0; i < children.length; i++) { 179 if (children[i].isDirectory()) 180 result.addAll(findFiles(children[i], suffix)); 181 else if (children[i].getName().endsWith(suffix)) 182 result.add(children[i]); 183 } 184 return result; 185 } 186 187 private String[] findClassNames(File basedir) 188 { 189 ArrayList classFiles = findFiles(basedir, CLASS_SUFFIX); 190 if(classFiles == null || classFiles.size() == 0) 191 return null; 192 193 ArrayList javaFiles = findFiles(basedir, JAVA_SUFFIX); 194 if(javaFiles == null || javaFiles.size() == 0) 195 return null; 196 197 ArrayList result = new ArrayList(); 198 for (int i = 0; i < classFiles.size(); i++) 199 { 200 File classFile = (File)classFiles.get(i); 201 String className = classFile.getName(); 202 className = className.substring(0, className.lastIndexOf(CLASS_SUFFIX)); 203 boolean finished = false; 204 205 206 for (int j = 0; j < javaFiles.size() && finished == false; j++) 207 { 208 File javaFile = (File)javaFiles.get(j); 209 String javaName = javaFile.getName(); 210 javaName = javaName.substring(0, javaName.lastIndexOf(JAVA_SUFFIX)); 211 212 if (javaName.equals(className)) 213 { 214 String path = classFile.getAbsolutePath(); 215 path = path.substring(basedir.getAbsolutePath().length() + 1); 216 path = path.replace(File.separatorChar, '.'); 217 path = path.substring(0, path.lastIndexOf(CLASS_SUFFIX)); 218 219 result.add(path); 220 javaFiles.remove(j); 221 finished = true; 222 } 223 } 224 } 225 return (String[])result.toArray(new String[0]); 226 } 227 } 228