View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.argeo.slc.osgi;
17  
18  import java.io.File;
19  import java.util.HashSet;
20  import java.util.Properties;
21  import java.util.Set;
22  import java.util.jar.JarFile;
23  import java.util.jar.Manifest;
24  
25  import org.apache.commons.io.IOUtils;
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.osgi.framework.Constants;
29  
30  /** <b>Experimental</b> */
31  public class FileSystemBundleRegister implements BundleRegister {
32  	private final static Log log = LogFactory
33  			.getLog(FileSystemBundleRegister.class);
34  	private Properties packagesBundles = null;
35  
36  	public String bundleProvidingPackage(String pkg, String version) {
37  		if (packagesBundles == null)
38  			return null;
39  		return packagesBundles.getProperty(pkg);
40  	}
41  
42  	protected void scan(File baseDirectory) {
43  		long begin = System.currentTimeMillis();
44  		int bundleCount = 0;
45  		int packageCount = 0;
46  
47  		packagesBundles = new Properties();
48  
49  		File[] files = baseDirectory.listFiles();
50  		for (File file : files) {
51  			if (file.isDirectory()) {
52  
53  			} else {
54  				JarFile jarFile = null;
55  				try {
56  					jarFile = new JarFile(file);
57  					Manifest manifest = jarFile.getManifest();
58  					String symbolicName = manifest.getMainAttributes()
59  							.getValue(Constants.BUNDLE_SYMBOLICNAME);
60  					String exportPackage = manifest.getMainAttributes()
61  							.getValue(Constants.EXPORT_PACKAGE);
62  
63  					// List exported packages
64  					Set<String> exportedPackages = exportPackageToPackageNames(exportPackage);
65  
66  					for (String exportedPackage : exportedPackages) {
67  						packagesBundles.put(exportedPackage, symbolicName);
68  						packageCount++;
69  						if (log.isTraceEnabled())
70  							log.trace("Register " + exportedPackage + "="
71  									+ symbolicName);
72  					}
73  					bundleCount++;
74  				} catch (Exception e) {
75  					log.warn("Cannot scan " + file, e);
76  					if (log.isTraceEnabled())
77  						e.printStackTrace();
78  				} finally {
79  					IOUtils.closeQuietly(jarFile);
80  				}
81  			}
82  		}
83  		if (log.isDebugEnabled())
84  			log.debug("Scanned " + bundleCount + " bundles with "
85  					+ packageCount + " packages in "
86  					+ (System.currentTimeMillis() - begin) + " ms");
87  	}
88  
89  	protected Set<String> exportPackageToPackageNames(String exportPackage) {
90  		Set<String> exportedPackages = new HashSet<String>();
91  		if (exportPackage == null)
92  			return exportedPackages;
93  		char[] arr = exportPackage.toCharArray();
94  
95  		StringBuffer currentPkg = new StringBuffer("");
96  		boolean skip = false;
97  		boolean inQuote = false;
98  		for (char c : arr) {
99  			if (c == ' ' || c == '\n') {
100 				// ignore
101 			} else if (c == ';') {
102 				if (!skip)
103 					skip = true;
104 			} else if (c == ',') {
105 				if (skip && !inQuote) {
106 					skip = false;
107 					// add new package
108 					exportedPackages.add(currentPkg.toString());
109 					currentPkg = new StringBuffer("");
110 				}
111 			} else if (c == '\"') {
112 				inQuote = inQuote ? false : true;
113 			} else {
114 				if (!skip)
115 					currentPkg.append(c);
116 			}
117 		}
118 
119 		return exportedPackages;
120 	}
121 
122 	public static void main(String[] args) {
123 		FileSystemBundleRegister fsbr = new FileSystemBundleRegister();
124 		fsbr.scan(new File(
125 				"/home/mbaudier/dev/src/slc/dist/org.argeo.slc.sdk/target/lib"));
126 
127 	}
128 }