]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/source/repository/ModuleBrowsingUtil.java
Fixing a deadlock. Some improvements to ModuleSourceRepository API
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / source / repository / ModuleBrowsingUtil.java
1 package org.simantics.scl.compiler.source.repository;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.net.JarURLConnection;
6 import java.net.URL;
7 import java.net.URLConnection;
8 import java.util.ArrayList;
9 import java.util.Collection;
10 import java.util.Enumeration;
11 import java.util.jar.JarEntry;
12 import java.util.jar.JarFile;
13
14 import org.junit.Test;
15 import org.simantics.scl.runtime.SCLContext;
16
17 public class ModuleBrowsingUtil {
18     
19     public static final String SCL_EXTENSION = ".scl";
20     public static final int SCL_EXTENSION_LENGTH = SCL_EXTENSION.length();
21     
22     public static void collectModuleSourcesAt(Collection<String> result, URL url) throws IOException {
23         String protocol = url.getProtocol();
24         if("jar".equals(protocol)) {
25             URLConnection connection = url.openConnection(); 
26             if(!(connection instanceof JarURLConnection))
27                 throw new UnsupportedOperationException("Expected JarURLConnection when opening connection to " + url + ".");
28             JarURLConnection jarConnection = (JarURLConnection)connection;
29             collectModuleSourcesAt(result, jarConnection.getEntryName(), jarConnection.getJarFile());
30         }
31         else if("file".equals(protocol)) {
32             File file = new File(url.getPath());
33             if(!file.exists())
34                 throw new UnsupportedOperationException("File " + url + " not found.");
35             collectModuleSourcesAt(result, file);
36         }
37         else if("bundleresource".equals(protocol)) {
38             URLConnection connection = url.openConnection();
39             Class<?> connectionClass = connection.getClass();
40             // We don't want an explicit dependency to osgi, therefore using reflection
41             if(!connectionClass.getSimpleName().equals("BundleURLConnection")) {
42                 throw new UnsupportedOperationException("Expected BundleURLConnection when opening connection to " + url + ".");
43             }
44             URL localURL;
45             try {
46                 localURL = (URL) connectionClass.getMethod("getLocalURL").invoke(connection);
47             } catch (Exception e) {
48                 throw new UnsupportedOperationException("Couldn't browse " + url + ".", e);
49             }
50             collectModuleSourcesAt(result, localURL);
51         }
52         else
53             throw new UnsupportedOperationException("Protocol of " + url + " does not support directory browsing.");
54     }       
55     
56     public static void collectModuleSourcesAt(Collection<String> result, File file) {
57         for(File child : file.listFiles()) {
58             String name = child.getName();
59             if(child.isDirectory())
60                 collectModuleSourcesAt(result, name + "/", child);
61             else
62                 if(name.endsWith(SCL_EXTENSION))
63                     result.add(name.substring(0, name.length()-SCL_EXTENSION_LENGTH));
64         }
65     }
66     
67     private static void collectModuleSourcesAt(Collection<String> result, String prefix, File file) {
68         for(File child : file.listFiles()) {
69             String name = child.getName();
70             if(child.isDirectory())
71                 collectModuleSourcesAt(result, prefix + name + "/", child);
72             else
73                 if(name.endsWith(SCL_EXTENSION))
74                     result.add(prefix + name.substring(0, name.length()-SCL_EXTENSION_LENGTH));
75         }
76     }
77     
78     private static void collectModuleSourcesAt(Collection<String> result, String entryName, JarFile jarFile) throws IOException {
79         int entryNameLength = entryName.length();
80         JarEntry entry;
81         for(Enumeration<JarEntry> e = jarFile.entries();e.hasMoreElements()
82                 && (entry = e.nextElement()) != null;) {
83             String name = entry.getName();
84             if(name.startsWith(entryName) && name.endsWith(SCL_EXTENSION))
85                 result.add(name.substring(entryNameLength+1, name.length()-SCL_EXTENSION_LENGTH));
86         }
87     }
88     
89     @Test
90     public void osgiTest() throws IOException {
91         ArrayList<String> l = new ArrayList<String>();
92         collectModuleSourcesAt(l, SCLContext.class.getResource("prelude"));
93         System.out.println(l);
94     }
95
96     public static File toFile(URL url) {
97         String protocol = url.getProtocol();
98         if("file".equals(protocol)) {
99             File file = new File(url.getPath());
100             if(file.exists())
101                 return file;
102         }
103         return null;
104     }
105     
106 }