mirror of https://github.com/pf4j/pf4j.git
Decebal Suiu
11 years ago
8 changed files with 326 additions and 188 deletions
@ -0,0 +1,102 @@
|
||||
/* |
||||
* Copyright 2012 Decebal Suiu |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with |
||||
* the License. You may obtain a copy of the License in the LICENSE file, or at: |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
*/ |
||||
package ro.fortsoft.pf4j; |
||||
|
||||
import java.io.File; |
||||
import java.io.FileInputStream; |
||||
import java.io.FileNotFoundException; |
||||
import java.io.IOException; |
||||
import java.util.jar.Attributes; |
||||
import java.util.jar.Manifest; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
import ro.fortsoft.pf4j.util.StringUtils; |
||||
|
||||
/** |
||||
* Read the plugin descriptor from the manifest file. |
||||
* |
||||
* @author Decebal Suiu |
||||
*/ |
||||
public class ManifestPluginDescriptorFinder implements PluginDescriptorFinder { |
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ManifestPluginDescriptorFinder.class); |
||||
|
||||
private PluginClasspath pluginClasspath; |
||||
|
||||
public ManifestPluginDescriptorFinder(PluginClasspath pluginClasspath) { |
||||
this.pluginClasspath = pluginClasspath; |
||||
} |
||||
|
||||
@Override |
||||
public PluginDescriptor find(File pluginRepository) throws PluginException { |
||||
// TODO it's ok with first classes directory? Another idea is to specify in PluginClasspath the folder.
|
||||
String classes = pluginClasspath.getClassesDirectories().get(0); |
||||
File manifestFile = new File(pluginRepository, classes + "/META-INF/MANIFEST.MF"); |
||||
log.debug("Lookup plugin descriptor in '{}'", manifestFile); |
||||
if (!manifestFile.exists()) { |
||||
throw new PluginException("Cannot find '" + manifestFile + "' file"); |
||||
} |
||||
|
||||
FileInputStream input = null; |
||||
try { |
||||
input = new FileInputStream(manifestFile); |
||||
} catch (FileNotFoundException e) { |
||||
// not happening
|
||||
} |
||||
|
||||
Manifest manifest = null; |
||||
try { |
||||
manifest = new Manifest(input); |
||||
} catch (IOException e) { |
||||
throw new PluginException(e.getMessage(), e); |
||||
} finally { |
||||
try { |
||||
input.close(); |
||||
} catch (IOException e) { |
||||
throw new PluginException(e.getMessage(), e); |
||||
} |
||||
} |
||||
|
||||
PluginDescriptor pluginDescriptor = new PluginDescriptor(); |
||||
|
||||
// TODO validate !!!
|
||||
Attributes attrs = manifest.getMainAttributes(); |
||||
String id = attrs.getValue("Plugin-Id"); |
||||
if (StringUtils.isEmpty(id)) { |
||||
throw new PluginException("Plugin-Id cannot be empty"); |
||||
} |
||||
pluginDescriptor.setPluginId(id); |
||||
|
||||
String clazz = attrs.getValue("Plugin-Class"); |
||||
if (StringUtils.isEmpty(clazz)) { |
||||
throw new PluginException("Plugin-Class cannot be empty"); |
||||
} |
||||
pluginDescriptor.setPluginClass(clazz); |
||||
|
||||
String version = attrs.getValue("Plugin-Version"); |
||||
if (StringUtils.isEmpty(version)) { |
||||
throw new PluginException("Plugin-Version cannot be empty"); |
||||
} |
||||
pluginDescriptor.setPluginVersion(PluginVersion.createVersion(version)); |
||||
|
||||
String provider = attrs.getValue("Plugin-Provider"); |
||||
pluginDescriptor.setProvider(provider); |
||||
String dependencies = attrs.getValue("Plugin-Dependencies"); |
||||
pluginDescriptor.setDependencies(dependencies); |
||||
|
||||
return pluginDescriptor; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,59 @@
|
||||
/* |
||||
* Copyright 2013 Decebal Suiu |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with |
||||
* the License. You may obtain a copy of the License in the LICENSE file, or at: |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
*/ |
||||
package ro.fortsoft.pf4j; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* The classpath of the plugin after it was unpacked. |
||||
* It contains classes directories and lib directories (directories that contains jars). |
||||
* All directories are relativ to plugin repository. |
||||
* The default values are "classes" and "lib". |
||||
* |
||||
* @author Decebal Suiu |
||||
*/ |
||||
public class PluginClasspath { |
||||
|
||||
private static final String DEFAULT_CLASSES_DIRECTORY = "classes"; |
||||
private static final String DEFAULT_LIB_DIRECTORY = "lib"; |
||||
|
||||
private List<String> classesDirectories; |
||||
private List<String> libDirectories; |
||||
|
||||
public PluginClasspath() { |
||||
classesDirectories = new ArrayList<String>(); |
||||
libDirectories = new ArrayList<String>(); |
||||
|
||||
// add defaults
|
||||
classesDirectories.add(DEFAULT_CLASSES_DIRECTORY); |
||||
libDirectories.add(DEFAULT_LIB_DIRECTORY); |
||||
} |
||||
|
||||
public List<String> getClassesDirectories() { |
||||
return classesDirectories; |
||||
} |
||||
|
||||
public void setClassesDirectories(List<String> classesDirectories) { |
||||
this.classesDirectories = classesDirectories; |
||||
} |
||||
|
||||
public List<String> getLibDirectories() { |
||||
return libDirectories; |
||||
} |
||||
|
||||
public void setLibDirectories(List<String> libDirectories) { |
||||
this.libDirectories = libDirectories; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,80 @@
|
||||
/* |
||||
* Copyright 2012 Decebal Suiu |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with |
||||
* the License. You may obtain a copy of the License in the LICENSE file, or at: |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||
* specific language governing permissions and limitations under the License. |
||||
*/ |
||||
package ro.fortsoft.pf4j; |
||||
|
||||
import java.lang.reflect.AnnotatedElement; |
||||
import java.util.ArrayList; |
||||
import java.util.Iterator; |
||||
import java.util.List; |
||||
|
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
|
||||
import net.java.sezpoz.Index; |
||||
import net.java.sezpoz.IndexItem; |
||||
|
||||
/** |
||||
* Using Sezpoz(http://sezpoz.java.net/) for extensions discovery.
|
||||
* |
||||
* @author Decebal Suiu |
||||
*/ |
||||
public class SezpozExtensionFinder implements ExtensionFinder { |
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(SezpozExtensionFinder.class); |
||||
|
||||
private volatile List<IndexItem<Extension, Object>> indices; |
||||
private ClassLoader classLoader; |
||||
|
||||
public SezpozExtensionFinder(ClassLoader classLoader) { |
||||
this.classLoader = classLoader; |
||||
} |
||||
|
||||
@Override |
||||
public <T> List<ExtensionWrapper<T>> find(Class<T> type) { |
||||
log.debug("Find extensions for {}", type); |
||||
List<ExtensionWrapper<T>> result = new ArrayList<ExtensionWrapper<T>>(); |
||||
getIndices(); |
||||
// System.out.println("indices = "+ indices);
|
||||
for (IndexItem<Extension, Object> item : indices) { |
||||
try { |
||||
AnnotatedElement element = item.element(); |
||||
Class<?> extensionType = (Class<?>) element; |
||||
log.debug("Checking extension type {}", extensionType); |
||||
if (type.isAssignableFrom(extensionType)) { |
||||
Object instance = item.instance(); |
||||
if (instance != null) { |
||||
log.debug("Added extension {}", extensionType); |
||||
result.add(new ExtensionWrapper<T>(type.cast(instance), item.annotation().ordinal())); |
||||
} |
||||
} |
||||
} catch (InstantiationException e) { |
||||
log.error(e.getMessage(), e); |
||||
} |
||||
} |
||||
|
||||
return result; |
||||
} |
||||
|
||||
private List<IndexItem<Extension, Object>> getIndices() { |
||||
if (indices == null) { |
||||
indices = new ArrayList<IndexItem<Extension, Object>>(); |
||||
Iterator<IndexItem<Extension, Object>> it = Index.load(Extension.class, Object.class, classLoader).iterator(); |
||||
while (it.hasNext()) { |
||||
indices.add(it.next()); |
||||
} |
||||
} |
||||
|
||||
return indices; |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue