You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ma...@apache.org on 2008/01/30 17:46:39 UTC

svn commit: r616813 [1/9] - in /felix/trunk/deploymentadmin: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/felix/ src/main/java/org/apache/felix/deploymentadmin/ src/main/java/org/apache/felix/de...

Author: marrs
Date: Wed Jan 30 08:46:24 2008
New Revision: 616813

URL: http://svn.apache.org/viewvc?rev=616813&view=rev
Log:
Added the initial version of DeploymentAdmin as donated in FELIX-452 (IP clearance posted to dev-felix on january 15th).

Added:
    felix/trunk/deploymentadmin/
    felix/trunk/deploymentadmin/LICENSE
    felix/trunk/deploymentadmin/NOTICE
    felix/trunk/deploymentadmin/pom.xml
    felix/trunk/deploymentadmin/src/
    felix/trunk/deploymentadmin/src/main/
    felix/trunk/deploymentadmin/src/main/java/
    felix/trunk/deploymentadmin/src/main/java/org/
    felix/trunk/deploymentadmin/src/main/java/org/apache/
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/AbstractDeploymentPackage.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/AbstractInfo.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/Activator.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/BundleInfoImpl.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/Constants.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/DeploymentAdminImpl.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/DeploymentPackageManifest.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/ExplodingOutputtingInputStream.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/FileDeploymentPackage.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/OutputtingInputStream.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/ResourceInfoImpl.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/Semaphore.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/StreamDeploymentPackage.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/VersionRange.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/Command.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/CommitResourceCommand.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/DeploymentSessionImpl.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/DropBundleCommand.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/DropResourceCommand.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/GetStorageAreaCommand.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/ProcessResourceCommand.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/SnapshotCommand.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/StartBundleCommand.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/StartCustomizerCommand.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/StopBundleCommand.java
    felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/spi/UpdateCommand.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/application/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/application/ApplicationContext.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/application/ApplicationServiceEvent.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/application/ApplicationServiceListener.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/application/Framework.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/application/package.html
    felix/trunk/deploymentadmin/src/main/java/org/osgi/application/packageinfo
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/application/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/application/ApplicationAdminPermission.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/application/ApplicationDescriptor.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/application/ApplicationException.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/application/ApplicationHandle.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/application/ScheduledApplication.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/application/package.html
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/application/packageinfo
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/cm/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/cm/Configuration.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/cm/ConfigurationEvent.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/cm/ConfigurationException.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/cm/ConfigurationListener.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/cm/ConfigurationPermission.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/cm/ManagedService.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/cm/ManagedServiceFactory.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/cm/package.html
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/cm/packageinfo
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/component/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/component/ComponentConstants.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/component/ComponentContext.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/component/ComponentException.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/component/ComponentFactory.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/component/ComponentInstance.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/component/package.html
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/component/packageinfo
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/deploymentadmin/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/deploymentadmin/BundleInfo.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdmin.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdminPermission.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/deploymentadmin/DeploymentException.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/deploymentadmin/DeploymentPackage.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/deploymentadmin/package.html
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/deploymentadmin/packageinfo
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/deploymentadmin/spi/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentCustomizerPermission.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentSession.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessor.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessorException.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/deploymentadmin/spi/package.html
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/deploymentadmin/spi/packageinfo
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/event/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/event/Event.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/event/EventAdmin.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/event/EventConstants.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/event/EventHandler.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/event/TopicPermission.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/event/package.html
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/event/packageinfo
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/io/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/io/ConnectionFactory.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/io/ConnectorService.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/io/package.html
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/io/packageinfo
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/log/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/log/LogEntry.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/log/LogListener.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/log/LogReaderService.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/log/LogService.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/log/package.html
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/log/packageinfo
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/metatype/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/metatype/AttributeDefinition.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/metatype/MetaTypeInformation.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/metatype/MetaTypeProvider.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/metatype/MetaTypeService.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/metatype/ObjectClassDefinition.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/metatype/package.html
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/metatype/packageinfo
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/monitor/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/monitor/MonitorAdmin.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/monitor/MonitorListener.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/monitor/MonitorPermission.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/monitor/Monitorable.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/monitor/MonitoringJob.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/monitor/StatusVariable.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/monitor/package.html
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/monitor/packageinfo
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/prefs/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/prefs/BackingStoreException.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/prefs/Preferences.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/prefs/PreferencesService.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/prefs/package.html
    felix/trunk/deploymentadmin/src/main/java/org/osgi/service/prefs/packageinfo
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/gsm/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/gsm/IMEICondition.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/gsm/IMSICondition.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/gsm/package.html
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/gsm/packageinfo
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/mobile/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/mobile/UserPromptCondition.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/mobile/package.html
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/mobile/packageinfo
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/tracker/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/tracker/ServiceTracker.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/tracker/package.html
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/tracker/packageinfo
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/xml/
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/xml/XMLParserActivator.java
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/xml/package.html
    felix/trunk/deploymentadmin/src/main/java/org/osgi/util/xml/packageinfo

Added: felix/trunk/deploymentadmin/LICENSE
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/LICENSE?rev=616813&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/LICENSE (added)
+++ felix/trunk/deploymentadmin/LICENSE Wed Jan 30 08:46:24 2008
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License 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.

Added: felix/trunk/deploymentadmin/NOTICE
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/NOTICE?rev=616813&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/NOTICE (added)
+++ felix/trunk/deploymentadmin/NOTICE Wed Jan 30 08:46:24 2008
@@ -0,0 +1,10 @@
+Apache Felix Framework
+Copyright 2006 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+This product includes software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright 2006 The OSGi Alliance.
+Licensed under the Apache License 2.0.

Added: felix/trunk/deploymentadmin/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/pom.xml?rev=616813&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/pom.xml (added)
+++ felix/trunk/deploymentadmin/pom.xml Wed Jan 30 08:46:24 2008
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License 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.
+-->
+<project>
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <relativePath>../pom/pom.xml</relativePath>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>bundle</packaging>
+  <name>Apache Felix Deployment Admin</name>
+  <version>1.0.0-SNAPSHOT</version>
+  <artifactId>org.apache.felix.deploymentadmin</artifactId>
+  <dependencies>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>1.1.0-SNAPSHOT</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <version>0.9.0-SNAPSHOT</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.dependencymanager</artifactId>
+      <version>0.9.0-SNAPSHOT</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>1.1.0-SNAPSHOT</version>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-SymbolicName>org.apache.felix.deploymentadmin</Bundle-SymbolicName>
+            <Bundle-Activator>org.apache.felix.deploymentadmin.Activator</Bundle-Activator>
+	    <Bundle-Name>Apache Felix Deployment Admin</Bundle-Name>
+            <Bundle-Description>A bundle that implements the Deployment Admin.</Bundle-Description>
+            <Bundle-Vendor>Apache Software Foundation</Bundle-Vendor>
+	    <Private-Package>org.apache.felix.deploymentadmin.spi</Private-Package>
+	    <Export-Package>org.apache.felix.deploymentadmin,org.osgi.service.deploymentadmin</Export-Package>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>

Added: felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/AbstractDeploymentPackage.java
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/AbstractDeploymentPackage.java?rev=616813&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/AbstractDeploymentPackage.java (added)
+++ felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/AbstractDeploymentPackage.java Wed Jan 30 08:46:24 2008
@@ -0,0 +1,313 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License 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 org.apache.felix.deploymentadmin;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.jar.Manifest;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.service.deploymentadmin.BundleInfo;
+import org.osgi.service.deploymentadmin.DeploymentException;
+import org.osgi.service.deploymentadmin.DeploymentPackage;
+import org.osgi.service.deploymentadmin.spi.ResourceProcessor;
+
+/**
+ * Base class for various types of deployment packages. Indifferent in regard to how the
+ * deployment package data is obtained, this should be handled by extending classes.
+ */
+public abstract class AbstractDeploymentPackage implements DeploymentPackage {
+
+    private final BundleContext m_bundleContext;
+    private final DeploymentPackageManifest m_manifest;
+    private final Map m_nameToBundleInfo = new HashMap();
+    private final Map m_pathToEntry = new HashMap();
+    private final BundleInfoImpl[] m_bundleInfos;
+    private final ResourceInfoImpl[] m_resourceInfos;
+    private final String[] m_resourcePaths;
+    private final boolean m_isFixPackage;
+    protected static final AbstractDeploymentPackage emptyPackage = new AbstractDeploymentPackage() {
+        public String getHeader(String header) {
+            if (Constants.DEPLOYMENTPACKAGE_SYMBOLICMAME.equals(header)) { return ""; }
+            else if (Constants.DEPLOYMENTPACKAGE_VERSION.equals(header)) { return Version.emptyVersion.toString(); }
+            else { return null; }
+        }
+        public Bundle getBundle(String symbolicName) { return null; }
+        public BundleInfo[] getBundleInfos() { return new BundleInfoImpl[] {}; }
+        public BundleInfoImpl[] getBundleInfoImpls() { return new BundleInfoImpl[] {}; }
+        public String getName() { return ""; }
+        public String getResourceHeader(String resource, String header) { return null; }
+        public ServiceReference getResourceProcessor(String resource) { return null; }
+        public String[] getResources() { return new String[] {}; }
+        public Version getVersion() { return Version.emptyVersion; }
+        public boolean isStale() { return true; }
+        public void uninstall() throws DeploymentException { throw new IllegalStateException("Can not uninstall stale DeploymentPackage"); }
+        public boolean uninstallForced() throws DeploymentException { throw new IllegalStateException("Can not uninstall stale DeploymentPackage"); }
+        public InputStream getBundleStream(String symbolicName) throws IOException { return null; }
+        public BundleInfoImpl[] getOrderedBundleInfos() { return new BundleInfoImpl[] {}; }
+        public ResourceInfoImpl[] getOrderedResourceInfos() { return new ResourceInfoImpl[] {}; }
+        public InputStream getCurrentEntryStream() { throw new UnsupportedOperationException(); }
+        public AbstractInfo getNextEntry() throws IOException { throw new UnsupportedOperationException(); }
+    };
+
+    /* Constructor only for use by the emptyPackage static variable */
+    private AbstractDeploymentPackage() {
+        m_bundleContext = null;
+        m_manifest = null;
+        m_bundleInfos = null;
+        m_resourceInfos = null;
+        m_resourcePaths = null;
+        m_isFixPackage = false;
+    }
+
+    /**
+     * Creates an instance of this class.
+     *
+     * @param manifest The manifest of the deployment package.
+     * @param bundleContext The bundle context.
+     * @throws DeploymentException Thrown if the specified manifest does not describe a valid deployment package.
+     */
+    public AbstractDeploymentPackage(Manifest manifest, BundleContext bundleContext) throws DeploymentException {
+        m_manifest = new DeploymentPackageManifest(manifest);
+        m_isFixPackage = m_manifest.getFixPackage() != null;
+        m_bundleContext = bundleContext;
+        m_bundleInfos = (BundleInfoImpl[]) m_manifest.getBundleInfos().toArray(new BundleInfoImpl[0]);
+        for(int i = 0; i < m_bundleInfos.length; i++) {
+            m_nameToBundleInfo.put(m_bundleInfos[i].getSymbolicName(), m_bundleInfos[i]);
+            m_pathToEntry.put(m_bundleInfos[i].getPath(), m_bundleInfos[i]);
+        }
+        m_resourceInfos =  (ResourceInfoImpl[]) m_manifest.getResourceInfos().toArray(new ResourceInfoImpl[0]);
+        for (int i = 0; i < m_resourceInfos.length; i++) {
+            m_pathToEntry.put(m_resourceInfos[i].getPath(), m_resourceInfos[i]);
+        }
+        m_resourcePaths = (String[]) m_pathToEntry.keySet().toArray(new String[m_pathToEntry.size()]);
+    }
+
+    public Bundle getBundle(String symbolicName) {
+        if (isStale()) {
+            throw new IllegalStateException("Can not get bundle from stale deployment package.");
+        }
+        if (m_nameToBundleInfo.containsKey(symbolicName)) {
+            Bundle[] bundles = m_bundleContext.getBundles();
+            for (int i = 0; i < bundles.length; i++) {
+                if (bundles[i].getSymbolicName().equals(symbolicName)) {
+                    return bundles[i];
+                }
+            }
+        }
+        return null;
+    }
+
+    public BundleInfo[] getBundleInfos() {
+        return (BundleInfo[]) m_bundleInfos.clone();
+    }
+
+    /**
+     * Returns the bundles of this deployment package as an array of <code>BundleInfoImpl</code> objects.
+     *
+     * @return Array containing <code>BundleInfoImpl</code> objects for each bundle this deployment package.
+     */
+    public BundleInfoImpl[] getBundleInfoImpls() {
+        return (BundleInfoImpl[]) m_bundleInfos.clone();
+    }
+
+    /**
+     * Returns the processed resources of this deployment package as an array of <code>ResourceInfoImpl</code> objects.
+     *
+     * @return Array containing <code>ResourceInfoImpl</code> objects for each processed resource of this deployment package.
+     */
+    public ResourceInfoImpl[] getResourceInfos() {
+        return (ResourceInfoImpl[]) m_resourceInfos.clone();
+    }
+
+    /**
+     * Determines whether this deployment package is a fix package.
+     *
+     * @return True if this deployment package is a fix package, false otherwise.
+     */
+    public boolean isFixPackage() {
+        return m_isFixPackage;
+    }
+
+    public String getHeader(String header) {
+        return m_manifest.getHeader(header);
+    }
+
+    public String getName() {
+        return m_manifest.getSymbolicName();
+    }
+
+    public String getResourceHeader(String resource, String header) {
+        AbstractInfo info = (AbstractInfo) m_pathToEntry.get(resource);
+        if (info != null) {
+            return info.getHeader(header);
+        }
+        return null;
+    }
+
+    public ServiceReference getResourceProcessor(String resource) {
+        if (isStale()) {
+            throw new IllegalStateException("Can not get bundle from stale deployment package.");
+        }
+        AbstractInfo info = (AbstractInfo) m_pathToEntry.get(resource);
+        if (info instanceof ResourceInfoImpl) {
+            String processor = ((ResourceInfoImpl) info).getResourceProcessor();
+            if (processor != null) {
+                try {
+                    ServiceReference[] services = m_bundleContext.getServiceReferences(ResourceProcessor.class.getName(), "(" + org.osgi.framework.Constants.SERVICE_PID + "=" + processor + ")");
+                    if (services.length > 0) {
+                        return services[0];
+                    }
+                }
+                catch (InvalidSyntaxException e) {
+                	// TODO: log this
+                    return null;
+                }
+            }
+        }
+        return null;
+    }
+
+    public String[] getResources() {
+        return (String[]) m_resourcePaths.clone();
+    }
+
+    public Version getVersion() {
+        return m_manifest.getVersion();
+    }
+
+    /**
+     * If this deployment package is a fix package this method determines the version range this deployment package can be applied to.
+     *
+     * @return <code>VersionRange</code> the fix package can be applied to or <code>null</code> if it is not a fix package.
+     */
+    public VersionRange getVersionRange() {
+        return m_manifest.getFixPackage();
+    }
+
+    public boolean isStale() {
+        return false;
+    }
+
+    public void uninstall() throws DeploymentException {
+        throw new IllegalStateException("Not implemented");
+    }
+
+    public boolean uninstallForced() throws DeploymentException {
+        throw new IllegalStateException("Not implemented");
+    }
+
+    /**
+     * Determines the bundles of this deployment package in the order in which they were originally received.
+     *
+     * @return Array containing <code>BundleInfoImpl</code> objects of the bundles in this deployment package, ordered in the way they appeared when the deployment package was first received.
+     */
+    public abstract BundleInfoImpl[] getOrderedBundleInfos();
+
+    /**
+     * Determines the resources of this deployment package in the order in which they were originally received.
+     *
+     * @return Array containing <code>ResourceInfoImpl</code> objects of all processed resources in this deployment package, ordered in the way they appeared when the deployment package was first received
+     */
+    public abstract ResourceInfoImpl[] getOrderedResourceInfos();
+
+    /**
+     * Determines the info about a processed resource based on it's path/resource-id.
+     *
+     * @param path String containing a (processed) resource path
+     * @return <code>ResourceInfoImpl</code> for the resource identified by the specified path or null if the path is unknown or does not describe a processed resource
+     */
+    public ResourceInfoImpl getResourceInfoByPath(String path) {
+        AbstractInfo info = (AbstractInfo) m_pathToEntry.get(path);
+        if (info instanceof ResourceInfoImpl) {
+            return (ResourceInfoImpl) info;
+        }
+        return null;
+    }
+
+    /**
+     * Determines the info about either a bundle or processed resource based on it's path/resource-id.
+     *
+     * @param path String containing a resource path (either bundle or processed resource)
+     * @return <code>AbstractInfoImpl</code> for the resource identified by the specified path or null if the path is unknown
+     */
+    protected AbstractInfo getAbstractInfoByPath(String path) {
+        return (AbstractInfo) m_pathToEntry.get(path);
+    }
+
+    /**
+     * Determines the info about a bundle based on it's path/resource-id.
+     *
+     * @param path String containing a bundle path
+     * @return <code>BundleInfoImpl</code> for the bundle resource identified by the specified path or null if the path is unknown or does not describe a bundle resource
+     */
+    public BundleInfoImpl getBundleInfoByPath(String path) {
+        AbstractInfo info = (AbstractInfo) m_pathToEntry.get(path);
+        if (info instanceof BundleInfoImpl) {
+            return (BundleInfoImpl) info;
+        }
+        return null;
+    }
+
+    /**
+     * Determines the info about a bundle resource based on the bundle symbolic name.
+     *
+     * @param symbolicName String containing a bundle symbolic name
+     * @return <code>BundleInfoImpl</code> for the bundle identified by the specified symbolic name or null if the symbolic name is unknown
+     */
+    public BundleInfoImpl getBundleInfoByName(String symbolicName) {
+        return (BundleInfoImpl) m_nameToBundleInfo.get(symbolicName);
+    }
+
+    /**
+     * Determines the data stream of a bundle resource based on the bundle symbolic name
+     *
+     * @param symbolicName Bundle symbolic name
+     * @return Stream to the bundle identified by the specified symbolic name or null if no such bundle exists in this deployment package.
+     * @throws IOException If the bundle can not be properly offered as an inputstream
+     */
+    public abstract InputStream getBundleStream(String symbolicName) throws IOException;
+
+    /**
+     * Determines the next resource entry in this deployment package based on the order in which the resources appeared when the package was originally received.
+     *
+     * @return <code>AbstractInfo</code> describing the next resource entry (as determined by the order in which the deployment package was received originally) or null if there is no next entry
+     * @throws IOException if the next entry can not be properly determined
+     */
+    public abstract AbstractInfo getNextEntry() throws IOException;
+
+    /**
+     * Determines the data stream to the current entry of this deployment package, use this together with the <code>getNextEntry</code> method.
+     *
+     * @return Stream to the current resource in the deployment package (as determined by the order in which the deployment package was received originally) or null if there is no entry
+     */
+    public abstract InputStream getCurrentEntryStream();
+
+	public Bundle getBundle(Object symbolicName) {
+		// TODO Auto-generated method stub
+		return null;
+	}
+}
+

Added: felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/AbstractInfo.java
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/AbstractInfo.java?rev=616813&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/AbstractInfo.java (added)
+++ felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/AbstractInfo.java Wed Jan 30 08:46:24 2008
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License 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 org.apache.felix.deploymentadmin;
+
+import java.util.BitSet;
+import java.util.jar.Attributes;
+
+import org.osgi.service.deploymentadmin.DeploymentException;
+
+/**
+ * Objects of this class represent the meta data for a resource from a deployment package, this
+ * can be either bundle resources or processed resources.
+ */
+public class AbstractInfo {
+
+    private static final BitSet VALID_RESOURCE_PATH_CHARS;
+    static
+    {
+        VALID_RESOURCE_PATH_CHARS = new BitSet();
+        for ( int i = 'a'; i <= 'z'; i++ )
+        {
+            VALID_RESOURCE_PATH_CHARS.set( i );
+        }
+        for ( int i = 'A'; i <= 'Z'; i++ )
+        {
+            VALID_RESOURCE_PATH_CHARS.set( i );
+        }
+        for ( int i = '0'; i <= '9'; i++ )
+        {
+            VALID_RESOURCE_PATH_CHARS.set( i );
+        }
+        VALID_RESOURCE_PATH_CHARS.set( '.' );
+        VALID_RESOURCE_PATH_CHARS.set( '-' );
+        VALID_RESOURCE_PATH_CHARS.set( '_' );
+        VALID_RESOURCE_PATH_CHARS.set( '/' );
+    }
+
+    private final String m_path;
+    private final Attributes m_attributes;
+    private final boolean m_missing;
+
+    /**
+     * Create an instance
+     *
+     * @param path Resource-id aka path of the resource
+     * @param attributes Attributes containing the meta data of the resource
+     * @throws DeploymentException If the specified attributes do not match the correct syntax for a deployment package resource.
+     */
+    public AbstractInfo(String path, Attributes attributes) throws DeploymentException {
+        verifyEntryName(path);
+        m_path = path;
+        m_attributes = attributes;
+        m_missing = parseBooleanHeader(attributes, Constants.DEPLOYMENTPACKAGE_MISSING);
+    }
+
+    /**
+     * @return The path of the resource
+     */
+    public String getPath() {
+        return m_path;
+    }
+
+    /**
+     * Return the value of a header for this resource
+     * @param header Name of the header
+     * @return Value of the header specified by the given header name
+     */
+    public String getHeader(String header) {
+        return m_attributes.getValue(header);
+    }
+
+    private void verifyEntryName(String name) throws DeploymentException {
+        byte[] bytes = name.getBytes();
+        boolean delimiterSeen = false;
+        for(int j = 0; j < bytes.length; j++) {
+            if(!VALID_RESOURCE_PATH_CHARS.get(bytes[j])) {
+                throw new DeploymentException(DeploymentException.CODE_BAD_HEADER, "Resource ID '" + name +"' contains invalid character(s)");
+            }
+            if (bytes[j] == '/') {
+                if (delimiterSeen) {
+                    throw new DeploymentException(DeploymentException.CODE_BAD_HEADER, "Resource ID '" + name +"' contains multiple consequetive path seperators");
+                } else {
+                    delimiterSeen = true;
+                }
+            } else {
+                delimiterSeen = false;
+            }
+        }
+    }
+
+    /**
+     * Determine if a resource is missing or not
+     * @return True if the actual data for this resource is not present, false otherwise
+     */
+    public boolean isMissing() {
+        return m_missing;
+    }
+
+    /**
+     * Parses a header that is allowed to have only boolean values.
+     *
+     * @param attributes Set of attributes containing the header
+     * @param header The header to verify
+     * @return true if the value of the header was "true", false if the value was "false"
+     * @throws DeploymentException if the value was not "true" or "false"
+     */
+    protected boolean parseBooleanHeader(Attributes attributes, String header) throws DeploymentException {
+        String value = attributes.getValue(header);
+        if (value != null) {
+            if ("true".equals(value)) {
+                return true;
+            } else if ("false".equals(value)){
+                return false;
+            } else {
+                throw new DeploymentException(DeploymentException.CODE_BAD_HEADER, "Invalid '" + header + "' header for manifest " +
+                    "entry '" + getPath() + "' header, should be either 'true' or 'false' or not present");
+            }
+        }
+        return false;
+    }
+
+}

Added: felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/Activator.java
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/Activator.java?rev=616813&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/Activator.java (added)
+++ felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/Activator.java Wed Jan 30 08:46:24 2008
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License 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 org.apache.felix.deploymentadmin;
+
+import org.apache.felix.dependencymanager.DependencyActivatorBase;
+import org.apache.felix.dependencymanager.DependencyManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.deploymentadmin.DeploymentAdmin;
+import org.osgi.service.event.EventAdmin;
+import org.osgi.service.log.LogService;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+/**
+ * Bundle activator for the deployment admin bundle
+ *
+ * @author  Christian van Spaandonk
+ * @version $Revision: 8712 $
+ */
+public class Activator extends DependencyActivatorBase {
+
+    public void init(BundleContext context, DependencyManager manager) throws Exception {
+        manager.add(createService()
+            .setInterface(DeploymentAdmin.class.getName(), null)
+            .setImplementation(DeploymentAdminImpl.class)
+            .add(createServiceDependency()
+                .setService(PackageAdmin.class)
+                .setRequired(true))
+            .add(createServiceDependency()
+                .setService(EventAdmin.class)
+                .setRequired(false))
+            .add(createServiceDependency()
+                .setService(LogService.class)
+                .setRequired(false)));
+    }
+
+    public void destroy(BundleContext context, DependencyManager manager) throws Exception {
+        // do nothing
+    }
+}
\ No newline at end of file

Added: felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/BundleInfoImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/BundleInfoImpl.java?rev=616813&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/BundleInfoImpl.java (added)
+++ felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/BundleInfoImpl.java Wed Jan 30 08:46:24 2008
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License 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 org.apache.felix.deploymentadmin;
+
+import java.util.jar.Attributes;
+
+import org.osgi.framework.Version;
+import org.osgi.service.deploymentadmin.BundleInfo;
+import org.osgi.service.deploymentadmin.DeploymentException;
+
+/**
+ * Implementation of the <code>BundleInfo</code> interface as defined by the OSGi mobile specification.
+ */
+public class BundleInfoImpl extends AbstractInfo implements BundleInfo {
+
+    private final Version m_version;
+    private final String m_symbolicName;
+    private final boolean m_customizer;
+
+    /**
+     * Creates an instance of this class.
+     *
+     * @param path The path / resource-id of the bundle resource.
+     * @param attributes Set of attributes describing the bundle resource.
+     * @throws DeploymentException If the specified attributes do not describe a valid bundle.
+     */
+    public BundleInfoImpl(String path, Attributes attributes) throws DeploymentException {
+        super(path, attributes);
+
+        String bundleSymbolicName = attributes.getValue(org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME);
+        if (bundleSymbolicName == null) {
+            throw new DeploymentException(DeploymentException.CODE_MISSING_HEADER, "Missing '" + org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME + "' header for manifest entry '" + getPath() + "'");
+        } else if (bundleSymbolicName.trim().equals("")) {
+            throw new DeploymentException(DeploymentException.CODE_BAD_HEADER, "Invalid '" + org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME + "' header for manifest entry '" + getPath() + "'");
+        } else {
+            m_symbolicName = bundleSymbolicName;
+        }
+
+        String version = attributes.getValue(org.osgi.framework.Constants.BUNDLE_VERSION);
+        try {
+            m_version = Version.parseVersion(version);
+        } catch (IllegalArgumentException e) {
+            throw new DeploymentException(DeploymentException.CODE_BAD_HEADER, "Invalid '" + org.osgi.framework.Constants.BUNDLE_VERSION + "' header for manifest entry '" + getPath() + "'");
+        }
+
+        m_customizer = parseBooleanHeader(attributes, Constants.DEPLOYMENTPACKAGE_CUSTOMISER);
+    }
+
+    public String getSymbolicName() {
+        return m_symbolicName;
+    }
+
+    public Version getVersion() {
+        return m_version;
+    }
+
+    /**
+     * Determine whether this bundle resource is a customizer bundle.
+     *
+     * @return True if the bundle is a customizer bundle, false otherwise.
+     */
+    public boolean isCustomizer() {
+        return m_customizer;
+    }
+
+    /**
+     * Verify if the specified attributes describe a bundle resource.
+     *
+     * @param attributes Attributes describing the resource
+     * @return true if the attributes describe a bundle resource, false otherwise
+     */
+    public static boolean isBundleResource(Attributes attributes) {
+        return (attributes.getValue(org.osgi.framework.Constants.BUNDLE_SYMBOLICNAME) != null);
+    }
+
+}

Added: felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/Constants.java
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/Constants.java?rev=616813&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/Constants.java (added)
+++ felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/Constants.java Wed Jan 30 08:46:24 2008
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License 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 org.apache.felix.deploymentadmin;
+
+public interface Constants extends org.osgi.framework.Constants {
+
+    // manifest main attribute header constants
+    public static final String DEPLOYMENTPACKAGE_SYMBOLICMAME = "DeploymentPackage-SymbolicName";
+    public static final String DEPLOYMENTPACKAGE_VERSION = "DeploymentPackage-Version";
+    public static final String DEPLOYMENTPACKAGE_FIXPACK = "DeploymentPackage-FixPack";
+
+    // manifest 'name' section header constants
+    public static final String RESOURCE_PROCESSOR = "Resource-Processor";
+    public static final String DEPLOYMENTPACKAGE_MISSING = "DeploymentPackage-Missing";
+    public static final String DEPLOYMENTPACKAGE_CUSTOMISER = "DeploymentPackage-Customiser";
+
+    // event topics and properties
+    public static final String EVENTTOPIC_INSTALL = "org/osgi/service/deployment/INSTALL";
+    public static final String EVENTTOPIC_UNINSTALL = "org/osgi/service/deployment/UNINSTALL";
+    public static final String EVENTTOPIC_COMPLETE = "org/osgi/service/deployment/COMPLETE";
+    public static final String EVENTPROPERTY_DEPLOYMENTPACKAGE_NAME = "deploymentpackage.name";
+    public static final String EVENTPROPERTY_SUCCESFULL = "succesfull";
+
+    // miscellaneous constants
+    public static final String BUNDLE_LOCATION_PREFIX = "osgi-dp:";
+}
\ No newline at end of file

Added: felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/DeploymentAdminImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/DeploymentAdminImpl.java?rev=616813&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/DeploymentAdminImpl.java (added)
+++ felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/DeploymentAdminImpl.java Wed Jan 30 08:46:24 2008
@@ -0,0 +1,321 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License 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 org.apache.felix.deploymentadmin;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.jar.JarInputStream;
+
+import org.apache.felix.deploymentadmin.spi.CommitResourceCommand;
+import org.apache.felix.deploymentadmin.spi.DeploymentSessionImpl;
+import org.apache.felix.deploymentadmin.spi.DropBundleCommand;
+import org.apache.felix.deploymentadmin.spi.DropResourceCommand;
+import org.apache.felix.deploymentadmin.spi.GetStorageAreaCommand;
+import org.apache.felix.deploymentadmin.spi.ProcessResourceCommand;
+import org.apache.felix.deploymentadmin.spi.SnapshotCommand;
+import org.apache.felix.deploymentadmin.spi.StartBundleCommand;
+import org.apache.felix.deploymentadmin.spi.StartCustomizerCommand;
+import org.apache.felix.deploymentadmin.spi.StopBundleCommand;
+import org.apache.felix.deploymentadmin.spi.UpdateCommand;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.deploymentadmin.DeploymentAdmin;
+import org.osgi.service.deploymentadmin.DeploymentException;
+import org.osgi.service.deploymentadmin.DeploymentPackage;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+import org.osgi.service.log.LogService;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+public class DeploymentAdminImpl implements DeploymentAdmin {
+
+    public static final String PACKAGE_DIR = "packages";
+    public static final String TEMP_DIR = "temp";
+    public static final String PACKAGECONTENTS_DIR = "contents";
+    public static final String PACKAGEINDEX_FILE = "index.txt";
+    public static final String TEMP_PREFIX = "pkg";
+    public static final String TEMP_POSTFIX = "";
+
+    private static final long TIMEOUT = 10000;
+
+    private BundleContext m_context; /* will be injected by dependencymanager */
+    private PackageAdmin m_packageAdmin;    /* will be injected by dependencymanager */
+    private EventAdmin m_eventAdmin; /* will be injected by dependencymanager */
+    private LogService m_log;        /* will be injected by dependencymanager */
+    private DeploymentSessionImpl m_session = null;
+    private final Map m_packages = new HashMap();
+    private final List m_commandChain = new ArrayList();
+    private final Semaphore m_semaphore = new Semaphore();
+
+    /**
+     * Create new instance of this <code>DeploymentAdmin</code>.
+     */
+    public DeploymentAdminImpl() {
+        GetStorageAreaCommand getStorageAreaCommand = new GetStorageAreaCommand();
+        m_commandChain.add(getStorageAreaCommand);
+        m_commandChain.add(new StopBundleCommand());
+        m_commandChain.add(new SnapshotCommand(getStorageAreaCommand));
+        m_commandChain.add(new UpdateCommand());
+        m_commandChain.add(new StartCustomizerCommand());
+        CommitResourceCommand commitCommand = new CommitResourceCommand();
+        m_commandChain.add(new ProcessResourceCommand(commitCommand));
+        m_commandChain.add(new DropResourceCommand(commitCommand));
+        m_commandChain.add(new DropBundleCommand());
+        m_commandChain.add(commitCommand);
+        m_commandChain.add(new StartBundleCommand());
+    }
+
+    // called automatically once dependencies are satisfied
+    public void start() throws DeploymentException {
+        File packageDir = m_context.getDataFile(PACKAGE_DIR);
+        if (packageDir == null) {
+            throw new DeploymentException(DeploymentException.CODE_OTHER_ERROR, "Could not create directories needed for deployment package persistence");
+        } else {
+            packageDir.mkdirs();
+            File[] packages = packageDir.listFiles();
+            for(int i = 0; i < packages.length; i++) {
+                if (packages[i].isDirectory()) {
+                    try {
+                        File index = new File(packages[i], PACKAGEINDEX_FILE);
+                        File contents = new File(packages[i], PACKAGE_DIR);
+                        FileDeploymentPackage dp = new FileDeploymentPackage(index, contents, m_context);
+                        m_packages.put(dp.getName(), dp);
+                    }
+                    catch (IOException e) {
+                        m_log.log(LogService.LOG_WARNING, "Could not read deployment package from disk, skipping: '" + packages[i].getAbsolutePath() + "'");
+                        continue;
+                    }
+                }
+            }
+        }
+    }
+
+
+    public void stop() {
+    	cancel();
+    }
+
+    public boolean cancel() {
+        if (m_session != null) {
+            m_session.cancel();
+            return true;
+        }
+        return false;
+    }
+
+    public DeploymentPackage getDeploymentPackage(String symbName) {
+        if (symbName == null) {
+            throw new IllegalArgumentException("Symbolic name may not be null");
+        }
+        return (DeploymentPackage) m_packages.get(symbName);
+    }
+
+    public DeploymentPackage getDeploymentPackage(Bundle bundle) {
+        if (bundle == null) {
+            throw new IllegalArgumentException("Bundle can not be null");
+        }
+        for (Iterator i = m_packages.values().iterator(); i.hasNext();) {
+            DeploymentPackage dp = (DeploymentPackage) i.next();
+            if (dp.getBundle(bundle.getSymbolicName()) != null) {
+                return dp;
+            }
+        }
+        return null;
+    }
+
+    public DeploymentPackage installDeploymentPackage(InputStream input) throws DeploymentException {
+        if (input == null) {
+            throw new IllegalArgumentException("Inputstream may not be null");
+        }
+        try {
+            if (!m_semaphore.tryAcquire(TIMEOUT)) {
+                throw new DeploymentException(DeploymentException.CODE_TIMEOUT, "Timeout exceeded while waiting to install deployment package (" + TIMEOUT + "msec)");
+            }
+        }
+        catch (InterruptedException ie) {
+            throw new DeploymentException(DeploymentException.CODE_TIMEOUT, "Thread interrupted");
+        }
+
+        JarInputStream jarInput = null;
+        File tempPackage = null;
+        File tempIndex = null;
+        File tempContents = null;
+
+        try {
+            try {
+                File tempDir = m_context.getDataFile(TEMP_DIR);
+                tempDir.mkdirs();
+                tempPackage = File.createTempFile(TEMP_PREFIX, TEMP_POSTFIX, tempDir);
+                tempPackage.delete();
+                tempPackage.mkdirs();
+                tempIndex = new File(tempPackage, PACKAGEINDEX_FILE);
+                tempContents = new File(tempPackage, PACKAGECONTENTS_DIR);
+                tempContents.mkdirs();
+                input = new ExplodingOutputtingInputStream(input, tempIndex, tempContents);
+            }
+            catch (IOException e) {
+                m_log.log(LogService.LOG_ERROR, "Error writing package to disk", e);
+                throw new DeploymentException(DeploymentException.CODE_OTHER_ERROR, "Error writing package to disk", e);
+            }
+            try {
+                jarInput = new JarInputStream(input);
+            }
+            catch (IOException e) {
+                m_log.log(LogService.LOG_ERROR, "Stream does not contain a valid Jar", e);
+                throw new DeploymentException(DeploymentException.CODE_NOT_A_JAR, "Stream does not contain a valid Jar", e);
+            }
+        }
+        finally {
+            m_semaphore.release();
+        }
+
+        StreamDeploymentPackage source = new StreamDeploymentPackage(jarInput, m_context);
+        sendStartedEvent(source.getName());
+
+        boolean succeeded = false;
+        try {
+            AbstractDeploymentPackage target = (AbstractDeploymentPackage) getDeploymentPackage(source.getName());
+            boolean newPackage = (target == null);
+            if (newPackage) {
+                target = AbstractDeploymentPackage.emptyPackage;
+            }
+            if (source.isFixPackage() && ((newPackage) || (!source.getVersionRange().isInRange(target.getVersion())))) {
+                succeeded = false;
+                m_log.log(LogService.LOG_ERROR, "Target package version '" + target.getVersion() + "' is not in source range '" + source.getVersionRange() + "'");
+                throw new DeploymentException(DeploymentException.CODE_OTHER_ERROR, "Target package version '" + target.getVersion() + "' is not in source range '" + source.getVersionRange() + "'");
+            }
+            try {
+                m_session = new DeploymentSessionImpl(source, target, m_commandChain, this);
+                m_session.call();
+            }
+            catch (DeploymentException de) {
+                succeeded = false;
+                throw de;
+            }
+            try {
+                jarInput.close();
+            }
+            catch (IOException e) {
+                // nothing we can do
+                m_log.log(LogService.LOG_WARNING, "Could not close stream properly", e);
+            }
+
+            File targetContents = m_context.getDataFile(PACKAGE_DIR + File.separator + source.getName() + File.separator + PACKAGECONTENTS_DIR);
+            File targetIndex = m_context.getDataFile(PACKAGE_DIR + File.separator + source.getName() + File.separator + PACKAGEINDEX_FILE);
+            if (source.isFixPackage()) {
+                try {
+                    ExplodingOutputtingInputStream.merge(targetIndex, targetContents, tempIndex, tempContents);
+                }
+                catch (IOException e) {
+                    succeeded = false;
+                    m_log.log(LogService.LOG_ERROR, "Could not merge source fix package with target deployment package", e);
+                    throw new DeploymentException(DeploymentException.CODE_OTHER_ERROR, "Could not merge source fix package with target deployment package", e);
+                }
+            } else {
+                File targetPackage = m_context.getDataFile(PACKAGE_DIR + File.separator + source.getName());
+                targetPackage.mkdirs();
+                ExplodingOutputtingInputStream.replace(targetPackage, tempPackage);
+            }
+            FileDeploymentPackage fileDeploymentPackage = null;
+            try {
+                fileDeploymentPackage = new FileDeploymentPackage(targetIndex, targetContents, m_context);
+                m_packages.put(source.getName(), fileDeploymentPackage);
+            }
+            catch (IOException e) {
+                succeeded = false;
+                m_log.log(LogService.LOG_ERROR, "Could not create installed deployment package from disk", e);
+                throw new DeploymentException(DeploymentException.CODE_OTHER_ERROR, "Could not create installed deployment package from disk", e);
+            }
+            succeeded = true;
+            return fileDeploymentPackage;
+        }
+        finally {
+        	delete(tempPackage);
+            sendCompleteEvent(source.getName(), succeeded);
+            m_semaphore.release();
+        }
+    }
+
+    private void delete(File tempPackage) {
+    	if (tempPackage.isDirectory()) {
+            File[] childs = tempPackage.listFiles();
+            for (int i = 0; i < childs.length; i++) {
+                delete(childs[i]);
+            }
+        }
+    	tempPackage.delete();
+	}
+
+	public DeploymentPackage[] listDeploymentPackages() {
+        Collection packages = m_packages.values();
+        return (DeploymentPackage[]) packages.toArray(new DeploymentPackage[packages.size()]);
+    }
+
+    /**
+     * Returns reference to this bundle's <code>BundleContext</code>
+     *
+     * @return This bundle's <code>BundleContext</code>
+     */
+    public BundleContext getBundleContext() {
+        return m_context;
+    }
+
+    /**
+     * Returns reference to the current logging service defined in the framework.
+     *
+     * @return Currently active <code>LogService</code>.
+     */
+    public LogService getLog() {
+        return m_log;
+    }
+
+    /**
+     * Returns reference to the current package admin defined in the framework.
+     *
+     * @return Currently active <code>PackageAdmin</code>.
+     */
+    public PackageAdmin getPackageAdmin() {
+        return m_packageAdmin;
+    }
+
+    private void sendStartedEvent(String name) {
+        Dictionary props = new Properties();
+        props.put(Constants.EVENTPROPERTY_DEPLOYMENTPACKAGE_NAME, name);
+        Event completeEvent = new Event(Constants.EVENTTOPIC_INSTALL, props);
+        m_eventAdmin.postEvent(completeEvent);
+    }
+
+    private void sendCompleteEvent(String name, boolean success) {
+        Dictionary props = new Properties();
+        props.put(Constants.EVENTPROPERTY_DEPLOYMENTPACKAGE_NAME, name);
+        props.put(Constants.EVENTPROPERTY_SUCCESFULL, String.valueOf(success));
+        Event completeEvent = new Event(Constants.EVENTTOPIC_COMPLETE, props);
+        m_eventAdmin.postEvent(completeEvent);
+    }
+
+}
\ No newline at end of file

Added: felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/DeploymentPackageManifest.java
URL: http://svn.apache.org/viewvc/felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/DeploymentPackageManifest.java?rev=616813&view=auto
==============================================================================
--- felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/DeploymentPackageManifest.java (added)
+++ felix/trunk/deploymentadmin/src/main/java/org/apache/felix/deploymentadmin/DeploymentPackageManifest.java Wed Jan 30 08:46:24 2008
@@ -0,0 +1,164 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License 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 org.apache.felix.deploymentadmin;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import org.osgi.framework.Version;
+import org.osgi.service.deploymentadmin.DeploymentException;
+
+/**
+ * This class represents a manifest file used to describe the contents of a deployment package. It can verify the correctness of a
+ * deployment package manifest and can interpret the various manifest entries and headers the OSGi specification defines.
+ */
+public class DeploymentPackageManifest {
+
+    private final Manifest m_manifest;
+    private final Version m_version;
+
+    private final List m_bundleInfos = new ArrayList();
+    private final List m_resourceInfos = new ArrayList();
+    private final String m_symbolicName;
+    private final VersionRange m_fixPackage;
+
+    /**
+     * Creates an instance of this class.
+     *
+     * @param manifest The manifest file to be used as deployment manifest
+     * @throws DeploymentException If the specified manifest is not a valid deployment package manifest file.
+     */
+    public DeploymentPackageManifest(Manifest manifest) throws DeploymentException {
+        if ((manifest == null) || (manifest.getMainAttributes() == null)) {
+            throw new DeploymentException(DeploymentException.CODE_BAD_HEADER);
+        }
+        m_manifest = manifest;
+
+        Attributes mainAttributes = m_manifest.getMainAttributes();
+
+        // TODO: verify symbolic name for valid format/chars
+        m_symbolicName = getNonNullHeader(mainAttributes.getValue(Constants.DEPLOYMENTPACKAGE_SYMBOLICMAME));
+
+        String version = getNonNullHeader(mainAttributes.getValue(Constants.DEPLOYMENTPACKAGE_VERSION));
+        try {
+            m_version = new Version(version);
+        } catch (IllegalArgumentException e) {
+            throw new DeploymentException(DeploymentException.CODE_BAD_HEADER);
+        }
+
+        String fixPackage = mainAttributes.getValue(Constants.DEPLOYMENTPACKAGE_FIXPACK);
+        if (fixPackage != null) {
+            try {
+                m_fixPackage = VersionRange.parse(fixPackage);
+            }
+            catch (IllegalArgumentException iae) {
+                throw new DeploymentException(DeploymentException.CODE_BAD_HEADER, "Invalid version range for header: " + Constants.DEPLOYMENTPACKAGE_FIXPACK);
+            }
+        } else {
+            m_fixPackage = null;
+        }
+
+        Map entries = m_manifest.getEntries();
+        for(Iterator i = entries.keySet().iterator(); i.hasNext(); ) {
+            String key = (String) i.next();
+            processEntry(key, (Attributes) entries.get(key), (m_fixPackage != null));
+        }
+    }
+
+    /**
+     * Determines the value of a header in the main section of the manifest.
+     *
+     * @param header Name of the header to retrieve.
+     * @return Value of the header or null if the header was not defined.
+     */
+    public String getHeader(String header) {
+        return m_manifest.getMainAttributes().getValue(header);
+    }
+
+    /**
+     * Determines the version range a fix package can be applied to
+     *
+     * @return A VersionRange describing the versions the fixpackage applies to, null if the package is not a fix package.
+     */
+    public VersionRange getFixPackage() {
+        return m_fixPackage;
+    }
+
+    /**
+     * Determines the symbolic name of the deployment package.
+     *
+     * @return String containing the symbolic name of the deployment package.
+     */
+    public String getSymbolicName() {
+        return m_symbolicName;
+    }
+
+    /**
+     * Determines the version of the deployment package.
+     * @return Version of the deployment package.
+     */
+    public Version getVersion() {
+        return m_version;
+    }
+
+    /**
+     * Determines which bundle resources are part of the deployment package, this includes customizer bundles.
+     *
+     * @return A List of <code>BundleInfoImpl</code> objects describing the bundle resources of the deployment package.
+     */
+    public List getBundleInfos() {
+        return m_bundleInfos;
+    }
+
+    /**
+     * Determines which processed resources are part of the deployment package.
+     *
+     * @return A list of <code>ResourceInfoImpl</code> objects describing the processed resources of the deployment package.
+     */
+    public List getResourceInfos() {
+        return m_resourceInfos;
+    }
+
+    private void processEntry(String key, Attributes attributes, boolean isFixPack) throws DeploymentException {
+        if (BundleInfoImpl.isBundleResource(attributes)) {
+            BundleInfoImpl bundleInfo = new BundleInfoImpl(key, attributes);
+            if (bundleInfo.isMissing() && !isFixPack) {
+                throw new DeploymentException(DeploymentException.CODE_BAD_HEADER, "Header '" + Constants.DEPLOYMENTPACKAGE_MISSING + "' for manifest " +
+                    "entry '" + key + "' may only be 'true' if " + Constants.DEPLOYMENTPACKAGE_FIXPACK + " manifest header is 'true'");
+            }
+            m_bundleInfos.add(bundleInfo);
+        } else {
+            m_resourceInfos.add(new ResourceInfoImpl(key, attributes));
+        }
+    }
+
+    private String getNonNullHeader(String header) throws DeploymentException {
+        if (header == null) {
+            throw new DeploymentException(DeploymentException.CODE_MISSING_HEADER);
+        } else if(header.trim().equals("")) {
+            throw new DeploymentException(DeploymentException.CODE_BAD_HEADER);
+        }
+        return header;
+    }
+
+}