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