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