Class BundleArchive
- java.lang.Object
-
- org.apache.felix.framework.cache.BundleArchive
-
public class BundleArchive extends java.lang.ObjectThis class is a logical abstraction for a bundle archive. This class, combined with BundleCache and concrete BundleRevision subclasses, implement the bundle cache for Felix. The bundle archive abstracts the actual bundle content into revisions and the revisions provide access to the actual bundle content. When a bundle is installed it has one revision associated with its content. Updating a bundle adds another revision for the updated content. Any number of revisions can be associated with a bundle archive. When the bundle (or framework) is refreshed, then all old revisions are purged and only the most recent revision is maintained.
The content associated with a revision can come in many forms, such as a standard JAR file or an exploded bundle directory. The bundle archive is responsible for creating all revision instances during invocations of the revise() method call. Internally, it determines the concrete type of revision type by examining the location string as an URL. Currently, it supports standard JAR files, referenced JAR files, and referenced directories. Examples of each type of URL are, respectively:
- http://www.foo.com/bundle.jar
- reference:file:/foo/bundle.jar
- reference:file:/foo/bundle/
The "reference:" notation signifies that the resource should be used "in place", meaning that they will not be copied. For referenced JAR files, some resources may still be copied, such as embedded JAR files or native libraries, but for referenced exploded bundle directories, nothing will be copied. Currently, reference URLs can only refer to "file:" targets.
- See Also:
BundleCache,org.apache.felix.framework.cache.BundleRevision
-
-
Field Summary
Fields Modifier and Type Field Description private static java.lang.StringACTIVE_STATEprivate static java.lang.StringBUNDLE_ID_FILEprivate static java.lang.StringBUNDLE_INFO_FILEprivate static java.lang.StringBUNDLE_LASTMODIFIED_FILEprivate static java.lang.StringBUNDLE_LOCATION_FILEprivate static java.lang.StringBUNDLE_START_LEVEL_FILEprivate static java.lang.StringBUNDLE_STATE_FILEprivate static java.lang.StringDATA_DIRECTORYstatic java.lang.StringFILE_PROTOCOLstatic java.lang.StringINPUTSTREAM_PROTOCOLprivate static java.lang.StringINSTALLED_STATEprivate java.io.Filem_archiveRootDirprivate java.util.Mapm_configMapprivate longm_idprivate booleanm_isSingleBundleFileprivate longm_lastModifiedprivate Loggerm_loggerprivate java.lang.Stringm_originalLocationprivate intm_persistentStateprivate longm_refreshCountThe refresh count field is used when generating the bundle revision directory name where native libraries are extracted.private java.util.SortedMap<java.lang.Long,BundleArchiveRevision>m_revisionsprivate intm_startLevelprivate WeakZipFileFactorym_zipFactorystatic java.lang.StringREFERENCE_PROTOCOLprivate static java.lang.StringREFRESH_COUNTER_FILEprivate static java.lang.StringREVISION_DIRECTORYprivate static java.lang.StringREVISION_LOCATION_FILEprivate static java.lang.StringSTARTING_STATEprivate static java.lang.StringUNINSTALLED_STATE
-
Constructor Summary
Constructors Constructor Description BundleArchive(Logger logger, java.util.Map configMap, WeakZipFileFactory zipFactory, java.io.File archiveRootDir)This constructor is called when an archive for a bundle is being reconstructed when the framework is restarted.BundleArchive(Logger logger, java.util.Map configMap, WeakZipFileFactory zipFactory, java.io.File archiveRootDir, long id, int startLevel, java.lang.String location, java.io.InputStream is)This constructor is used for creating new archives when a bundle is installed into the framework.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidclose()voidcloseAndDelete()This method closes any revisions and deletes the bundle archive directory.private BundleArchiveRevisioncreateRevisionFromLocation(java.lang.String location, java.io.InputStream is, java.lang.Long revNum)Creates a revision based on the location string and/or input stream.private static java.lang.Stringdecode(java.lang.String s)BundleArchiveRevisiongetCurrentRevision()Returns the current revision object for the archive.java.lang.LonggetCurrentRevisionNumber()Returns the current revision object for the archive.java.io.FilegetDataFile(java.lang.String fileName)Returns a File object corresponding to the data file of the relative path of the specified string.longgetId()Returns the bundle identifier associated with this archive.longgetLastModified()Returns the last modification time of this archive.java.lang.StringgetLocation()Returns the location string associated with this archive.intgetPersistentState()Returns the persistent state of this archive.private longgetRefreshCount()This utility method is used to retrieve the current refresh counter value for the bundle.private java.lang.StringgetRevisionLocation(java.lang.Long revNum)intgetStartLevel()Returns the start level of this archive.private voidinitialize()Initializes the bundle archive object by creating the archive root directory and saving the initial state.booleanisRemovalPending()voidpurge()This method removes all old revisions associated with the archive and keeps only the current revision.private voidreadBundleInfo()private longreadId()private longreadLastModified()private java.lang.StringreadLocation()private intreadPersistentState()private longreadRefreshCount()private intreadStartLevel()voidrevise(java.lang.String location, java.io.InputStream is)This method adds a revision to the archive using the associated location and input stream.private voidreviseInternal(boolean isReload, java.lang.Long revNum, java.lang.String location, java.io.InputStream is)Actually adds a revision to the bundle archive.booleanrollbackRevise()This method undoes the previous revision to the archive; this method will remove the latest revision from the archive.voidsetLastModified(long lastModified)Sets the the last modification time of this archive.voidsetPersistentState(int state)Sets the persistent state of this archive.private voidsetRefreshCount(long count)This utility method is used to retrieve the current refresh counter value for the bundle.private voidsetRevisionLocation(java.lang.String location, java.lang.Long revNum)voidsetStartLevel(int level)Sets the the start level of this archive this archive.private voidwriteBundleInfo()private voidwriteId()private voidwriteLastModified()private voidwriteLocation()private voidwritePersistentState()private voidwriteRefreshCount()private voidwriteStartLevel()
-
-
-
Field Detail
-
FILE_PROTOCOL
public static final transient java.lang.String FILE_PROTOCOL
- See Also:
- Constant Field Values
-
REFERENCE_PROTOCOL
public static final transient java.lang.String REFERENCE_PROTOCOL
- See Also:
- Constant Field Values
-
INPUTSTREAM_PROTOCOL
public static final transient java.lang.String INPUTSTREAM_PROTOCOL
- See Also:
- Constant Field Values
-
BUNDLE_INFO_FILE
private static final transient java.lang.String BUNDLE_INFO_FILE
- See Also:
- Constant Field Values
-
REVISION_LOCATION_FILE
private static final transient java.lang.String REVISION_LOCATION_FILE
- See Also:
- Constant Field Values
-
REVISION_DIRECTORY
private static final transient java.lang.String REVISION_DIRECTORY
- See Also:
- Constant Field Values
-
DATA_DIRECTORY
private static final transient java.lang.String DATA_DIRECTORY
- See Also:
- Constant Field Values
-
m_logger
private final Logger m_logger
-
m_configMap
private final java.util.Map m_configMap
-
m_zipFactory
private final WeakZipFileFactory m_zipFactory
-
m_archiveRootDir
private final java.io.File m_archiveRootDir
-
m_isSingleBundleFile
private final boolean m_isSingleBundleFile
-
m_id
private long m_id
-
m_originalLocation
private java.lang.String m_originalLocation
-
m_persistentState
private int m_persistentState
-
m_startLevel
private int m_startLevel
-
m_lastModified
private long m_lastModified
-
m_refreshCount
private long m_refreshCount
The refresh count field is used when generating the bundle revision directory name where native libraries are extracted. This is necessary because Sun's JVM requires a one-to-one mapping between native libraries and class loaders where the native library is uniquely identified by its absolute path in the file system. This constraint creates a problem when a bundle is refreshed, because it gets a new class loader. Using the refresh counter to generate the name of the bundle revision directory resolves this problem because each time bundle is refresh, the native library will have a unique name. As a result of the unique name, the JVM will then reload the native library without a problem.
-
m_revisions
private final java.util.SortedMap<java.lang.Long,BundleArchiveRevision> m_revisions
-
BUNDLE_ID_FILE
private static final transient java.lang.String BUNDLE_ID_FILE
- See Also:
- Constant Field Values
-
BUNDLE_LOCATION_FILE
private static final transient java.lang.String BUNDLE_LOCATION_FILE
- See Also:
- Constant Field Values
-
BUNDLE_STATE_FILE
private static final transient java.lang.String BUNDLE_STATE_FILE
- See Also:
- Constant Field Values
-
BUNDLE_START_LEVEL_FILE
private static final transient java.lang.String BUNDLE_START_LEVEL_FILE
- See Also:
- Constant Field Values
-
BUNDLE_LASTMODIFIED_FILE
private static final transient java.lang.String BUNDLE_LASTMODIFIED_FILE
- See Also:
- Constant Field Values
-
REFRESH_COUNTER_FILE
private static final transient java.lang.String REFRESH_COUNTER_FILE
- See Also:
- Constant Field Values
-
ACTIVE_STATE
private static final transient java.lang.String ACTIVE_STATE
- See Also:
- Constant Field Values
-
STARTING_STATE
private static final transient java.lang.String STARTING_STATE
- See Also:
- Constant Field Values
-
INSTALLED_STATE
private static final transient java.lang.String INSTALLED_STATE
- See Also:
- Constant Field Values
-
UNINSTALLED_STATE
private static final transient java.lang.String UNINSTALLED_STATE
- See Also:
- Constant Field Values
-
-
Constructor Detail
-
BundleArchive
public BundleArchive(Logger logger, java.util.Map configMap, WeakZipFileFactory zipFactory, java.io.File archiveRootDir, long id, int startLevel, java.lang.String location, java.io.InputStream is) throws java.lang.Exception
This constructor is used for creating new archives when a bundle is installed into the framework. Each archive receives a logger, a root directory, its associated bundle identifier, the associated bundle location string, and an input stream from which to read the bundle content. The root directory is where any required state can be stored. The input stream may be null, in which case the location is used as an URL to the bundle content.
- Parameters:
logger- the logger to be used by the archive.archiveRootDir- the archive root directory for storing state.id- the bundle identifier associated with the archive.location- the bundle location string associated with the archive.is- input stream from which to read the bundle content.- Throws:
java.lang.Exception- if any error occurs.
-
BundleArchive
public BundleArchive(Logger logger, java.util.Map configMap, WeakZipFileFactory zipFactory, java.io.File archiveRootDir) throws java.lang.Exception
This constructor is called when an archive for a bundle is being reconstructed when the framework is restarted. Each archive receives a logger, a root directory, and its associated bundle identifier. The root directory is where any required state can be stored.
- Parameters:
logger- the logger to be used by the archive.archiveRootDir- the archive root directory for storing state.configMap- configMap for BundleArchive- Throws:
java.lang.Exception- if any error occurs.
-
-
Method Detail
-
getId
public long getId() throws java.lang.ExceptionReturns the bundle identifier associated with this archive.
- Returns:
- the bundle identifier associated with this archive.
- Throws:
java.lang.Exception- if any error occurs.
-
getLocation
public java.lang.String getLocation() throws java.lang.ExceptionReturns the location string associated with this archive.
- Returns:
- the location string associated with this archive.
- Throws:
java.lang.Exception- if any error occurs.
-
getPersistentState
public int getPersistentState() throws java.lang.ExceptionReturns the persistent state of this archive. The value returned is one of the following: Bundle.INSTALLED, Bundle.ACTIVE, or Bundle.UNINSTALLED.
- Returns:
- the persistent state of this archive.
- Throws:
java.lang.Exception- if any error occurs.
-
setPersistentState
public void setPersistentState(int state) throws java.lang.ExceptionSets the persistent state of this archive. The value is one of the following: Bundle.INSTALLED, Bundle.ACTIVE, or Bundle.UNINSTALLED.
- Parameters:
state- the persistent state value to set for this archive.- Throws:
java.lang.Exception- if any error occurs.
-
getStartLevel
public int getStartLevel() throws java.lang.ExceptionReturns the start level of this archive.
- Returns:
- the start level of this archive.
- Throws:
java.lang.Exception- if any error occurs.
-
setStartLevel
public void setStartLevel(int level) throws java.lang.ExceptionSets the the start level of this archive this archive.
- Parameters:
level- the start level to set for this archive.- Throws:
java.lang.Exception- if any error occurs.
-
getLastModified
public long getLastModified() throws java.lang.ExceptionReturns the last modification time of this archive.
- Returns:
- the last modification time of this archive.
- Throws:
java.lang.Exception- if any error occurs.
-
setLastModified
public void setLastModified(long lastModified) throws java.lang.ExceptionSets the the last modification time of this archive.
- Parameters:
lastModified- The time of the last modification to set for this archive. According to the OSGi specification this time is set each time a bundle is installed, updated or uninstalled.- Throws:
java.lang.Exception- if any error occurs.
-
getRefreshCount
private long getRefreshCount() throws java.lang.ExceptionThis utility method is used to retrieve the current refresh counter value for the bundle. This value is used when generating the bundle revision directory name where native libraries are extracted. This is necessary because Sun's JVM requires a one-to-one mapping between native libraries and class loaders where the native library is uniquely identified by its absolute path in the file system. This constraint creates a problem when a bundle is refreshed, because it gets a new class loader. Using the refresh counter to generate the name of the bundle revision directory resolves this problem because each time bundle is refresh, the native library will have a unique name. As a result of the unique name, the JVM will then reload the native library without a problem.- Throws:
java.lang.Exception
-
setRefreshCount
private void setRefreshCount(long count) throws java.lang.ExceptionThis utility method is used to retrieve the current refresh counter value for the bundle. This value is used when generating the bundle revision directory name where native libraries are extracted. This is necessary because Sun's JVM requires a one-to-one mapping between native libraries and class loaders where the native library is uniquely identified by its absolute path in the file system. This constraint creates a problem when a bundle is refreshed, because it gets a new class loader. Using the refresh counter to generate the name of the bundle revision directory resolves this problem because each time bundle is refresh, the native library will have a unique name. As a result of the unique name, the JVM will then reload the native library without a problem.- Throws:
java.lang.Exception
-
getDataFile
public java.io.File getDataFile(java.lang.String fileName) throws java.lang.ExceptionReturns a File object corresponding to the data file of the relative path of the specified string.
- Returns:
- a File object corresponding to the specified file name.
- Throws:
java.lang.Exception- if any error occurs.
-
getCurrentRevisionNumber
public java.lang.Long getCurrentRevisionNumber()
Returns the current revision object for the archive.
- Returns:
- the current revision object for the archive.
-
getCurrentRevision
public BundleArchiveRevision getCurrentRevision()
Returns the current revision object for the archive.
- Returns:
- the current revision object for the archive.
-
isRemovalPending
public boolean isRemovalPending()
-
revise
public void revise(java.lang.String location, java.io.InputStream is) throws java.lang.ExceptionThis method adds a revision to the archive using the associated location and input stream. If the input stream is null, then the location is used a URL to obtain an input stream.
- Parameters:
location- the location string associated with the revision.is- the input stream from which to read the revision.- Throws:
java.lang.Exception- if any error occurs.
-
reviseInternal
private void reviseInternal(boolean isReload, java.lang.Long revNum, java.lang.String location, java.io.InputStream is) throws java.lang.ExceptionActually adds a revision to the bundle archive. This method is also used to reload cached bundles too. The revision is given the specified revision number and is read from the input stream if supplied or from the location URL if not.- Parameters:
isReload- if the bundle is being reloaded or not.revNum- the revision number of the revision.location- the location associated with the revision.is- the input stream from which to read the revision.- Throws:
java.lang.Exception- if any error occurs.
-
rollbackRevise
public boolean rollbackRevise() throws java.lang.ExceptionThis method undoes the previous revision to the archive; this method will remove the latest revision from the archive. This method is only called when there are problems during an update after the revision has been created, such as errors in the update bundle's manifest. This method can only be called if there is more than one revision, otherwise there is nothing to undo.
- Returns:
- true if the undo was a success false if there is no previous revision
- Throws:
java.lang.Exception- if any error occurs.
-
getRevisionLocation
private java.lang.String getRevisionLocation(java.lang.Long revNum) throws java.lang.Exception- Throws:
java.lang.Exception
-
setRevisionLocation
private void setRevisionLocation(java.lang.String location, java.lang.Long revNum) throws java.lang.Exception- Throws:
java.lang.Exception
-
close
public void close()
-
closeAndDelete
public void closeAndDelete()
This method closes any revisions and deletes the bundle archive directory.
- Throws:
java.lang.Exception- if any error occurs.
-
purge
public void purge() throws java.lang.ExceptionThis method removes all old revisions associated with the archive and keeps only the current revision.
- Throws:
java.lang.Exception- if any error occurs.
-
initialize
private void initialize() throws java.lang.ExceptionInitializes the bundle archive object by creating the archive root directory and saving the initial state.
- Throws:
java.lang.Exception- if any error occurs.
-
createRevisionFromLocation
private BundleArchiveRevision createRevisionFromLocation(java.lang.String location, java.io.InputStream is, java.lang.Long revNum) throws java.lang.Exception
Creates a revision based on the location string and/or input stream.
- Returns:
- the location string associated with this archive.
- Throws:
java.lang.Exception
-
decode
private static java.lang.String decode(java.lang.String s) throws java.io.UnsupportedEncodingException- Throws:
java.io.UnsupportedEncodingException
-
readBundleInfo
private void readBundleInfo() throws java.lang.Exception- Throws:
java.lang.Exception
-
writeBundleInfo
private void writeBundleInfo() throws java.lang.Exception- Throws:
java.lang.Exception
-
writeId
private void writeId() throws java.lang.Exception- Throws:
java.lang.Exception
-
readId
private long readId() throws java.lang.Exception- Throws:
java.lang.Exception
-
writeLocation
private void writeLocation() throws java.lang.Exception- Throws:
java.lang.Exception
-
readLocation
private java.lang.String readLocation() throws java.lang.Exception- Throws:
java.lang.Exception
-
writePersistentState
private void writePersistentState() throws java.lang.Exception- Throws:
java.lang.Exception
-
readPersistentState
private int readPersistentState() throws java.lang.Exception- Throws:
java.lang.Exception
-
writeStartLevel
private void writeStartLevel() throws java.lang.Exception- Throws:
java.lang.Exception
-
readStartLevel
private int readStartLevel() throws java.lang.Exception- Throws:
java.lang.Exception
-
writeLastModified
private void writeLastModified() throws java.lang.Exception- Throws:
java.lang.Exception
-
readLastModified
private long readLastModified() throws java.lang.Exception- Throws:
java.lang.Exception
-
writeRefreshCount
private void writeRefreshCount() throws java.lang.Exception- Throws:
java.lang.Exception
-
readRefreshCount
private long readRefreshCount() throws java.lang.Exception- Throws:
java.lang.Exception
-
-