📄 pluginarchiver.java
字号:
if (!result.contains(uid)) {
entry = zipStrm.getNextEntry();
continue;
}
count++;
} else {
int p = name.indexOf('/');
if ((p == -1) || (p == 0)
|| !result.contains(name.substring(0, p))) {
entry = zipStrm.getNextEntry();
continue;
}
}
unpackEntry(zipStrm, entry, destFolder);
entry = zipStrm.getNextEntry();
}
} finally {
zipStrm.close();
}
if (result.size() != count) {
throw new IOException("invalid plug-ins number (" + count //$NON-NLS-1$
+ ") found in the archive, expected number according to " //$NON-NLS-1$
+ "the archive descriptor is " + result.size()); //$NON-NLS-1$
}
return result;
}
/**
* Extracts all plug-ins from the given archive file.
* <br>
* <b>Note:</b>
* <br>
* {@link ObjectFactory#createRegistry() Standard plug-in registry}
* implementation will be used internally to read plug-in manifests.
* @param archiveFile plug-in archive file
* @param destFolder target folder
* @return collection of UID's of all un-packed plug-ins
* @throws IOException if an I/O error has occurred
* @throws ClassNotFoundException if descriptor can't be read
* @throws ManifestProcessingException if manifest can't be registered
* (optional behavior)
*
* @see ObjectFactory#createRegistry()
*/
public static Collection unpack(final URL archiveFile,
final File destFolder) throws ManifestProcessingException,
IOException, ClassNotFoundException {
return unpack(archiveFile, ObjectFactory.newInstance().createRegistry(),
destFolder);
}
/**
* Extracts plug-ins from the given archive file according to given filter.
* <br>
* <b>Note:</b>
* <br>
* {@link ObjectFactory#createRegistry() Standard plug-in registry}
* implementation will be used internally to read plug-in manifests.
* @param archiveFile plug-in archive file
* @param destFolder target folder
* @param filter filter to be used when un-packing plug-ins
* @return collection of UID's of all un-packed plug-ins
* @throws IOException if an I/O error has occurred
* @throws ClassNotFoundException if descriptor can't be read
* @throws ManifestProcessingException if manifest can't be registered
* (optional behavior)
*/
public static Collection unpack(final URL archiveFile,
final File destFolder, final Filter filter)
throws ManifestProcessingException, IOException,
ClassNotFoundException {
return unpack(archiveFile, ObjectFactory.newInstance().createRegistry(),
destFolder, filter);
}
private static void unpackEntry(final ZipInputStream zipStrm,
final ZipEntry entry, final File destFolder) throws IOException {
String name = entry.getName();
if (name.endsWith("/")) { //$NON-NLS-1$
File folder = new File(destFolder.getCanonicalPath() + "/" + name); //$NON-NLS-1$
if (!folder.exists() && !folder.mkdirs()) {
throw new IOException("can't create folder " + folder); //$NON-NLS-1$
}
folder.setLastModified(entry.getTime());
return;
}
File file = new File(destFolder.getCanonicalPath() + "/" + name); //$NON-NLS-1$
File folder = file.getParentFile();
if (!folder.exists() && !folder.mkdirs()) {
throw new IOException("can't create folder " + folder); //$NON-NLS-1$
}
OutputStream strm = new BufferedOutputStream(
new FileOutputStream(file, false));
try {
IoUtil.copyStream(zipStrm, strm, 1024);
} finally {
strm.close();
}
file.setLastModified(entry.getTime());
}
/**
* Reads meta-information from plug-ins archive file and registers found
* plug-in manifest data with given registry for future analysis.
* @param archiveFile plug-in archive file
* @param registry plug-in registry where to register discovered manifests
* for archived plug-ins
* @return collection of UID's of all registered plug-ins
* @throws IOException if an I/O error has occurred
* @throws ClassNotFoundException if descriptor can't be read
* @throws ManifestProcessingException if manifest can't be registered
* (optional behavior)
*
* @see #readDescriptor(URL, PluginRegistry, PluginArchiver.Filter)
*/
public static Collection readDescriptor(final URL archiveFile,
final PluginRegistry registry)
throws IOException, ClassNotFoundException,
ManifestProcessingException {
return readDescriptor(archiveFile, registry, new Filter() {
public boolean accept(final String id, final Version version,
final boolean isFragment) {
return true;
}
});
}
/**
* Reads meta-information from plug-ins archive file and registers found
* plug-in manifest data with given registry for future analysis.
* <br>
* <b>Note:</b>
* <br>
* In the current implementation all plug-in manifests are extracted to
* temporary local storage and deleted immediately after their registration
* with plug-in registry. So manifest URL's are actually point to "fake"
* locations and main purpose of this method is to allow you to analyze
* plug-ins archive without needing to download and unpack it.
* @param archiveFile plug-in archive file
* @param registry plug-in registry where to register discovered manifests
* for archived plug-ins
* @param filter filter to be used when un-packing plug-ins
* @return collection of UID's of all registered plug-ins
* @throws IOException if an I/O error has occurred
* @throws ClassNotFoundException if descriptor can't be read
* @throws ManifestProcessingException if manifest can't be registered
* (optional behavior)
*/
public static Collection readDescriptor(final URL archiveFile,
final PluginRegistry registry, final Filter filter)
throws IOException, ClassNotFoundException,
ManifestProcessingException {
ZipInputStream zipStrm = new ZipInputStream(new BufferedInputStream(
archiveFile.openStream()));
try {
ZipEntry entry = zipStrm.getNextEntry();
//NB: we are expecting that descriptor is in the first ZIP entry
if (entry == null) {
throw new IOException(
"invalid plug-ins archive, no entries found"); //$NON-NLS-1$
}
if (!DESCRIPTOR_ENTRY_NAME.equals(entry.getName())) {
throw new IOException("invalid plug-ins archive " + archiveFile //$NON-NLS-1$
+ ", entry " + DESCRIPTOR_ENTRY_NAME //$NON-NLS-1$
+ " not found as first ZIP entry in the archive file"); //$NON-NLS-1$
}
ObjectInputStream strm = new ObjectInputStream(zipStrm);
return readDescriptor(strm, registry, Util.getTempFolder(), filter);
} finally {
zipStrm.close();
}
}
private static Set writeDescripor(final PluginRegistry registry,
final Filter filter, final ObjectOutputStream strm)
throws IOException {
Map result = new HashMap();
for (Iterator it = registry.getPluginDescriptors().iterator();
it.hasNext();) {
PluginDescriptor descr = (PluginDescriptor) it.next();
if (!filter.accept(descr.getId(), descr.getVersion(), false)) {
continue;
}
result.put(descr.getUniqueId(),
new ArchiveDescriptorEntry(descr.getId(),
descr.getVersion(), false,
Util.readUrlContent(descr.getLocation())));
}
for (Iterator it = registry.getPluginFragments().iterator();
it.hasNext();) {
PluginFragment fragment = (PluginFragment) it.next();
if (!filter.accept(fragment.getId(), fragment.getVersion(), true)) {
continue;
}
result.put(fragment.getUniqueId(),
new ArchiveDescriptorEntry(fragment.getId(),
fragment.getVersion(), true,
Util.readUrlContent(fragment.getLocation())));
}
strm.writeObject(result.values().toArray(
new ArchiveDescriptorEntry[result.size()]));
return result.keySet();
}
private static Set readDescriptor(final ObjectInputStream strm,
final PluginRegistry registry, final File tempFolder,
final Filter filter) throws IOException, ClassNotFoundException,
ManifestProcessingException {
ArchiveDescriptorEntry[] data =
(ArchiveDescriptorEntry[]) strm.readObject();
// For simplicity we'll store manifests to a temporary files rather than
// create special URL's and provide special URL handler for them.
// More powerful approach will be possibly implemented in the future.
Set urls = new HashSet();
Set files = new HashSet();
for (int i = 0; i < data.length; i++) {
if (!filter.accept(data[i].getId(), data[i].getVersion(),
data[i].isFragment())) {
continue;
}
File file = File.createTempFile("manifest.", null, tempFolder); //$NON-NLS-1$
file.deleteOnExit();
OutputStream fileStrm = new BufferedOutputStream(
new FileOutputStream(file, false));
try {
fileStrm.write(data[i].getData());
} finally {
fileStrm.close();
}
files.add(file);
urls.add(IoUtil.file2url(file));
}
Set result = new HashSet();
try {
for (Iterator it = registry.register((URL[]) urls.toArray(
new URL[urls.size()])).values().iterator(); it.hasNext();) {
Object obj = it.next();
if (obj instanceof PluginDescriptor) {
result.add(((PluginDescriptor) obj).getUniqueId());
} else if (obj instanceof PluginFragment) {
result.add(((PluginFragment) obj).getUniqueId());
} else {
//NB: ignore all other elements
}
}
} finally {
for (Iterator it = files.iterator(); it.hasNext();) {
((File) it.next()).delete();
}
}
return result;
}
private PluginArchiver() {
// no-op
}
/**
* Callback interface to filter plug-ins being processed.
* @version $Id: PluginArchiver.java,v 1.1 2006/08/26 15:14:09 ddimon Exp $
*/
public static interface Filter {
/**
* @param id plug-in or plug-in fragment identifier
* @param version plug-in or plug-in fragment version
* @param isFragment <code>true</code> if given identity data
* corresponds to plug-in fragment
* @return <code>true</code> if plug-in or plug-in fragment with given
* identity should be taken into account
*/
boolean accept(String id, Version version, boolean isFragment);
}
private static class ArchiveDescriptorEntry implements Serializable {
private static final long serialVersionUID = 8749937247555974932L;
private final String id;
private final Version version;
private final boolean isFragment;
private final byte[] data;
protected ArchiveDescriptorEntry(final String anId,
final Version aVersion, final boolean fragment,
final byte[] aData) {
id = anId;
version = aVersion;
isFragment = fragment;
data = aData;
}
protected String getId() {
return id;
}
protected Version getVersion() {
return version;
}
protected boolean isFragment() {
return isFragment;
}
protected byte[] getData() {
return data;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -