📄 bundlearchiveimpl.java
字号:
/* * Copyright (c) 2003-2004, KNOPFLERFISH project * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * - Neither the name of the KNOPFLERFISH project nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */package org.knopflerfish.framework.bundlestorage.file;import org.osgi.framework.*;import org.knopflerfish.framework.*;import java.io.*;import java.lang.reflect.Method;import java.util.Vector;import java.util.Dictionary;import java.util.StringTokenizer;import java.util.List;import java.util.ArrayList;import java.util.Iterator;import java.util.HashMap;import java.util.Map;import java.net.URL;/** * Interface for managing bundle data. * * @author Jan Stein * @author Erik Wistrand * @author Robert Shelley */class BundleArchiveImpl implements BundleArchive{ /** * Bundle status files */ private final static String LOCATION_FILE = "location"; private final static String REV_FILE = "revision"; private final static String STOP_FILE = "stopped"; private final static String STARTLEVEL_FILE = "startlevel"; private final static String PERSISTENT_FILE = "persistent"; /** * Method mapLibraryName if we run in a Java 2 environment. */ private static Method mapLibraryName; private Archive archive; private long id; private String location; private boolean startOnLaunch; private FileTree bundleDir; private BundleStorageImpl storage; private Archive [] archives; private Map nativeLibs; //XXX - start L-3 modification private Map renameLibs; //XXX - end L-3 modification private boolean bFake = false; private int startLevel = -1; private boolean bPersistant = false; static { try { mapLibraryName = System.class.getDeclaredMethod("mapLibraryName", new Class [] { String.class }); } catch (NoSuchMethodException ignore) { mapLibraryName = null; } } /** * Construct new bundle archive. * */ BundleArchiveImpl(BundleStorageImpl bundleStorage, FileTree dir, InputStream is, String bundleLocation, long bundleId) throws Exception { URL source = null; try { source = new URL(bundleLocation); } catch (Exception e) { } bundleDir = dir; archive = new Archive(bundleDir, 0, is, source); storage = bundleStorage; id = bundleId; location = bundleLocation; startOnLaunch = false; nativeLibs = getNativeCode(); bFake = isFake(); setClassPath(); putContent(STOP_FILE, new Boolean(!startOnLaunch).toString()); putContent(LOCATION_FILE, location); // putContent(STARTLEVEL_FILE, Integer.toString(startLevel)); } /** * Construct new bundle archive based on saved data. * */ BundleArchiveImpl(BundleStorageImpl bundleStorage, FileTree dir, long bundleId) throws Exception { bundleDir = dir; location = getContent(LOCATION_FILE); if (location == null || location.length() == 0) { throw new IOException("No bundle location information found"); } int rev = -1; String revS = getContent(REV_FILE); if (revS != null) { try { rev = Integer.parseInt(revS); } catch (NumberFormatException e) { } } String slS = getContent(STARTLEVEL_FILE); if (slS != null) { try { startLevel = Integer.parseInt(slS); } catch (NumberFormatException e) { } } String pS = getContent(PERSISTENT_FILE); if (pS != null) { bPersistant = "true".equals(pS); } archive = new Archive(bundleDir, rev, location); id = bundleId; storage = bundleStorage; startOnLaunch = !(new Boolean(getContent(STOP_FILE))).booleanValue(); nativeLibs = getNativeCode(); bFake = isFake(); setClassPath(); } /** * Construct new bundle archive in an existing bundle archive. * */ BundleArchiveImpl(BundleArchiveImpl old, InputStream is) throws Exception { bundleDir = old.bundleDir; location = old.location; storage = old.storage; id = old.id; startOnLaunch = old.startOnLaunch; int rev = old.archive.getRevision() + 1; archive = new Archive(bundleDir, rev, is); nativeLibs = getNativeCode(); bFake = isFake(); setClassPath(); putContent(REV_FILE, Integer.toString(rev)); } boolean isFake() { // What the f**k is this? Test case seem to require it! // // OK. Some background story might me good here: // // The R3 tests are not compatible with the R3 spec (sic) // // However to be R3, you have to pass the tests. // Thus, KF uses a system property to determine if // it should be compartible with the spec or the tests. // Framework.R3_TESTCOMPLIANT reflects this state. // // One such difference is the "fakeheader" manifest // (another on is the buggy filter test, see LDAPEpr.java) // attribute that the test suite at one stage uses // to read a "bad" manifest, but still pass the // installBundle stage. When this header is present // AND we run in test compliant mode, we skip some // sanity checks on manifests if(Framework.R3_TESTCOMPLIANT) { String fake = getAttribute("fakeheader"); if(fake != null) { return true; } } return false; } /** * Get an attribute from the manifest of a bundle. * * @param key Name of attribute to get. * @return A string with result or null if the entry doesn't exists. */ public String getAttribute(String key) { return archive.getAttribute(key); } /** * Get all attributes from the manifest of a bundle. * * @return All attributes, null if bundle doesn't exists. */ public Dictionary getAttributes() { return new HeaderDictionary(archive.getAttributes()); } /** * Get bundle identifier for this bundle archive. * * @return Bundle identifier. */ public long getBundleId() { return id; } /** * Get bundle location for this bundle archive. * * @return Bundle location. */ public String getBundleLocation() { return location; } public int getStartLevel() { return startLevel; } public void setStartLevel(int level) throws IOException { if (startLevel != level) { startLevel = level; putContent(STARTLEVEL_FILE, Integer.toString(startLevel)); } } public void setPersistent(boolean b) throws IOException { if (bPersistant != b) { bPersistant = b; putContent(PERSISTENT_FILE, b ? "true" : "false"); } } public boolean isPersistent() { return bPersistant; } /** * Get a byte array containg the contents of named file from a bundle * archive. * * @param clazz Class to get. * @return Byte array with contents of file or null if file doesn't exist. * @exception IOException if failed to read jar entry. */ public byte[] getClassBytes(String clazz) throws IOException { String cp = clazz.replace('.', '/') + ".class"; for (int i = 0; i < archives.length; i++) { byte [] res = archives[i].getBytes(cp); if (res != null) { return res; } } return null; } /** * Check if named entry exist in bundles archive. * Leading '/' is stripped. * * @param component Entry to get reference to. * @return Vector or entry numbers, or null if it doesn't exist. */ public Vector componentExists(String component) { Vector v = null; if (component.startsWith("/")) { component = component.substring(1); } for (int i = 0; i < archives.length; i++) { InputStream is = archives[i].getInputStream(component); if (is != null) { if(v == null) { v = new Vector(); } v.addElement(new Integer(i)); try { is.close(); } catch (IOException ignore) { } } } return v; } /** * Same as getInputStream(component, -1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -