[SCM] eclipse - Powerful IDE written in java - Debian package. branch, upstream, updated. 8ce7c8261fdf47a2b043c8c998e5a0bfb6a6dab9
Niels Thykier
nthykier-guest at alioth.debian.org
Sat Mar 13 16:44:32 UTC 2010
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "eclipse - Powerful IDE written in java - Debian package.".
The branch, upstream has been updated
via 8ce7c8261fdf47a2b043c8c998e5a0bfb6a6dab9 (commit)
from 90205164e0ff66ecd39f4c304db76bf99be954ee (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 8ce7c8261fdf47a2b043c8c998e5a0bfb6a6dab9
Author: Niels Thykier <nthykier-guest at alioth.debian.org>
Date: Sat Mar 13 16:42:24 2010 +0000
Unpacked the source for o.e.osgi.services
-----------------------------------------------------------------------
Summary of changes:
.../org/osgi/service/cm/Configuration.class | Bin 532 -> 0 bytes
.../org/osgi/service/cm/ConfigurationAdmin.class | Bin 743 -> 0 bytes
.../org/osgi/service/cm/ConfigurationEvent.class | Bin 1241 -> 0 bytes
.../osgi/service/cm/ConfigurationException.class | Bin 1469 -> 0 bytes
.../osgi/service/cm/ConfigurationListener.class | Bin 218 -> 0 bytes
.../osgi/service/cm/ConfigurationPermission.class | Bin 1620 -> 0 bytes
.../cm/ConfigurationPermissionCollection$1.class | Bin 1064 -> 0 bytes
.../cm/ConfigurationPermissionCollection.class | Bin 1647 -> 0 bytes
.../org/osgi/service/cm/ConfigurationPlugin.class | Bin 366 -> 0 bytes
.../org/osgi/service/cm/ManagedService.class | Bin 246 -> 0 bytes
.../osgi/service/cm/ManagedServiceFactory.class | Bin 361 -> 0 bytes
.../service/component/ComponentConstants.class | Bin 861 -> 0 bytes
.../osgi/service/component/ComponentContext.class | Bin 763 -> 0 bytes
.../service/component/ComponentException.class | Bin 1007 -> 0 bytes
.../osgi/service/component/ComponentFactory.class | Bin 235 -> 0 bytes
.../osgi/service/component/ComponentInstance.class | Bin 211 -> 0 bytes
.../org/osgi/service/device/Constants.class | Bin 303 -> 0 bytes
.../org/osgi/service/device/Device.class | Bin 201 -> 0 bytes
.../org/osgi/service/device/Driver.class | Bin 311 -> 0 bytes
.../org/osgi/service/device/DriverLocator.class | Bin 312 -> 0 bytes
.../org/osgi/service/device/DriverSelector.class | Bin 280 -> 0 bytes
.../org/osgi/service/device/Match.class | Bin 207 -> 0 bytes
.../event/Event$UnmodifiableDictionary.class | Bin 1537 -> 0 bytes
.../org/osgi/service/event/Event.class | Bin 3957 -> 0 bytes
.../org/osgi/service/event/EventAdmin.class | Bin 200 -> 0 bytes
.../org/osgi/service/event/EventConstants.class | Bin 1034 -> 0 bytes
.../org/osgi/service/event/EventHandler.class | Bin 186 -> 0 bytes
.../org/osgi/service/event/TopicPermission.class | Bin 4627 -> 0 bytes
.../service/event/TopicPermissionCollection.class | Bin 2831 -> 0 bytes
.../org/osgi/service/http/HttpContext.class | Bin 689 -> 0 bytes
.../org/osgi/service/http/HttpService.class | Bin 597 -> 0 bytes
.../org/osgi/service/http/NamespaceException.class | Bin 958 -> 0 bytes
.../org/osgi/service/io/ConnectionFactory.class | Bin 349 -> 0 bytes
.../org/osgi/service/io/ConnectorService.class | Bin 857 -> 0 bytes
.../org/osgi/service/log/LogEntry.class | Bin 384 -> 0 bytes
.../org/osgi/service/log/LogListener.class | Bin 209 -> 0 bytes
.../org/osgi/service/log/LogReaderService.class | Bin 272 -> 0 bytes
.../org/osgi/service/log/LogService.class | Bin 529 -> 0 bytes
.../service/metatype/AttributeDefinition.class | Bin 820 -> 0 bytes
.../service/metatype/MetaTypeInformation.class | Bin 314 -> 0 bytes
.../osgi/service/metatype/MetaTypeProvider.class | Bin 309 -> 0 bytes
.../osgi/service/metatype/MetaTypeService.class | Bin 355 -> 0 bytes
.../service/metatype/ObjectClassDefinition.class | Bin 523 -> 0 bytes
.../service/provisioning/ProvisioningService.class | Bin 1292 -> 0 bytes
.../org/osgi/service/upnp/UPnPAction.class | Bin 490 -> 0 bytes
.../org/osgi/service/upnp/UPnPDevice.class | Bin 1605 -> 0 bytes
.../org/osgi/service/upnp/UPnPEventListener.class | Bin 311 -> 0 bytes
.../org/osgi/service/upnp/UPnPException.class | Bin 812 -> 0 bytes
.../org/osgi/service/upnp/UPnPIcon.class | Bin 345 -> 0 bytes
.../osgi/service/upnp/UPnPLocalStateVariable.class | Bin 243 -> 0 bytes
.../org/osgi/service/upnp/UPnPService.class | Bin 632 -> 0 bytes
.../org/osgi/service/upnp/UPnPStateVariable.class | Bin 1456 -> 0 bytes
.../org/osgi/service/useradmin/Authorization.class | Bin 260 -> 0 bytes
.../org/osgi/service/useradmin/Group.class | Bin 356 -> 0 bytes
.../org/osgi/service/useradmin/Role.class | Bin 405 -> 0 bytes
.../org/osgi/service/useradmin/User.class | Bin 273 -> 0 bytes
.../org/osgi/service/useradmin/UserAdmin.class | Bin 668 -> 0 bytes
.../osgi/service/useradmin/UserAdminEvent.class | Bin 1048 -> 0 bytes
.../osgi/service/useradmin/UserAdminListener.class | Bin 213 -> 0 bytes
.../service/useradmin/UserAdminPermission.class | Bin 5628 -> 0 bytes
.../useradmin/UserAdminPermissionCollection.class | Bin 2851 -> 0 bytes
.../org/osgi/service/wireadmin/BasicEnvelope.class | Bin 882 -> 0 bytes
.../org/osgi/service/wireadmin/Consumer.class | Bin 268 -> 0 bytes
.../org/osgi/service/wireadmin/Envelope.class | Bin 236 -> 0 bytes
.../org/osgi/service/wireadmin/Producer.class | Bin 266 -> 0 bytes
.../org/osgi/service/wireadmin/Wire.class | Bin 445 -> 0 bytes
.../org/osgi/service/wireadmin/WireAdmin.class | Bin 531 -> 0 bytes
.../osgi/service/wireadmin/WireAdminEvent.class | Bin 1460 -> 0 bytes
.../osgi/service/wireadmin/WireAdminListener.class | Bin 216 -> 0 bytes
.../org/osgi/service/wireadmin/WireConstants.class | Bin 1522 -> 0 bytes
.../osgi/service/wireadmin/WirePermission.class | Bin 4504 -> 0 bytes
.../wireadmin/WirePermissionCollection.class | Bin 2818 -> 0 bytes
eclipse/plugins/org.eclipse.osgi.services/src.zip | Bin 132671 -> 0 bytes
.../plugins/org.eclipse.osgi.services/src/javax | 1 +
.../src/org/osgi/service/cm/Configuration.java | 225 +++++++
.../org/osgi/service/cm/ConfigurationAdmin.java | 254 ++++++++
.../org/osgi/service/cm/ConfigurationEvent.java | 170 ++++++
.../osgi/service/cm/ConfigurationException.java | 104 ++++
.../org/osgi/service/cm/ConfigurationListener.java | 48 ++
.../osgi/service/cm/ConfigurationPermission.java | 220 +++++++
.../org/osgi/service/cm/ConfigurationPlugin.java | 129 ++++
.../src/org/osgi/service/cm/ManagedService.java | 138 +++++
.../org/osgi/service/cm/ManagedServiceFactory.java | 160 +++++
.../src/org/osgi/service/cm/package.html | 11 +
.../src/org/osgi/service/cm/packageinfo | 1 +
.../osgi/service/component/ComponentConstants.java | 118 ++++
.../osgi/service/component/ComponentContext.java | 191 ++++++
.../osgi/service/component/ComponentException.java | 79 +++
.../osgi/service/component/ComponentFactory.java | 47 ++
.../osgi/service/component/ComponentInstance.java | 46 ++
.../src/org/osgi/service/component/package.html | 11 +
.../src/org/osgi/service/component/packageinfo | 1 +
.../src/org/osgi/service/device/Constants.java | 73 +++
.../src/org/osgi/service/device/Device.java | 62 ++
.../src/org/osgi/service/device/Driver.java | 107 ++++
.../src/org/osgi/service/device/DriverLocator.java | 65 ++
.../org/osgi/service/device/DriverSelector.java | 54 ++
.../src/org/osgi/service/device/Match.java | 43 ++
.../src/org/osgi/service/device/package.html | 10 +
.../src/org/osgi/service/device/packageinfo | 1 +
.../src/org/osgi/service/event/Event.java | 263 ++++++++
.../src/org/osgi/service/event/EventAdmin.java | 52 ++
.../src/org/osgi/service/event/EventConstants.java | 187 ++++++
.../src/org/osgi/service/event/EventHandler.java | 69 +++
.../org/osgi/service/event/TopicPermission.java | 529 ++++++++++++++++
.../src/org/osgi/service/event/package.html | 10 +
.../src/org/osgi/service/event/packageinfo | 1 +
.../src/org/osgi/service/http/HttpContext.java | 166 +++++
.../src/org/osgi/service/http/HttpService.java | 177 ++++++
.../org/osgi/service/http/NamespaceException.java | 88 +++
.../src/org/osgi/service/http/package.html | 10 +
.../src/org/osgi/service/http/packageinfo | 1 +
.../src/org/osgi/service/io/ConnectionFactory.java | 60 ++
.../src/org/osgi/service/io/ConnectorService.java | 165 +++++
.../src/org/osgi/service/io/package.html | 10 +
.../src/org/osgi/service/io/packageinfo | 1 +
.../src/org/osgi/service/log/LogEntry.java | 108 ++++
.../src/org/osgi/service/log/LogListener.java | 50 ++
.../src/org/osgi/service/log/LogReaderService.java | 97 +++
.../src/org/osgi/service/log/LogService.java | 155 +++++
.../src/org/osgi/service/log/package.html | 11 +
.../src/org/osgi/service/log/packageinfo | 1 +
.../osgi/service/metatype/AttributeDefinition.java | 277 +++++++++
.../osgi/service/metatype/MetaTypeInformation.java | 50 ++
.../osgi/service/metatype/MetaTypeProvider.java | 55 ++
.../org/osgi/service/metatype/MetaTypeService.java | 51 ++
.../service/metatype/ObjectClassDefinition.java | 119 ++++
.../src/org/osgi/service/metatype/package.html | 11 +
.../src/org/osgi/service/metatype/packageinfo | 1 +
.../service/provisioning/ProvisioningService.java | 211 +++++++
.../src/org/osgi/service/provisioning/package.html | 10 +
.../src/org/osgi/service/provisioning/packageinfo | 1 +
.../src/org/osgi/service/upnp/UPnPAction.java | 120 ++++
.../src/org/osgi/service/upnp/UPnPDevice.java | 280 +++++++++
.../org/osgi/service/upnp/UPnPEventListener.java | 85 +++
.../src/org/osgi/service/upnp/UPnPException.java | 81 +++
.../src/org/osgi/service/upnp/UPnPIcon.java | 99 +++
.../osgi/service/upnp/UPnPLocalStateVariable.java | 44 ++
.../src/org/osgi/service/upnp/UPnPService.java | 173 ++++++
.../org/osgi/service/upnp/UPnPStateVariable.java | 342 +++++++++++
.../src/org/osgi/service/upnp/package.html | 10 +
.../src/org/osgi/service/upnp/packageinfo | 1 +
.../org/osgi/service/useradmin/Authorization.java | 102 +++
.../src/org/osgi/service/useradmin/Group.java | 158 +++++
.../src/org/osgi/service/useradmin/Role.java | 117 ++++
.../src/org/osgi/service/useradmin/User.java | 94 +++
.../src/org/osgi/service/useradmin/UserAdmin.java | 157 +++++
.../org/osgi/service/useradmin/UserAdminEvent.java | 111 ++++
.../osgi/service/useradmin/UserAdminListener.java | 43 ++
.../service/useradmin/UserAdminPermission.java | 643 ++++++++++++++++++++
.../src/org/osgi/service/useradmin/package.html | 10 +
.../src/org/osgi/service/useradmin/packageinfo | 1 +
.../org/osgi/service/wireadmin/BasicEnvelope.java | 64 ++
.../src/org/osgi/service/wireadmin/Consumer.java | 101 +++
.../src/org/osgi/service/wireadmin/Envelope.java | 79 +++
.../src/org/osgi/service/wireadmin/Producer.java | 123 ++++
.../src/org/osgi/service/wireadmin/Wire.java | 268 ++++++++
.../src/org/osgi/service/wireadmin/WireAdmin.java | 168 +++++
.../org/osgi/service/wireadmin/WireAdminEvent.java | 266 ++++++++
.../osgi/service/wireadmin/WireAdminListener.java | 72 +++
.../org/osgi/service/wireadmin/WireConstants.java | 225 +++++++
.../org/osgi/service/wireadmin/WirePermission.java | 485 +++++++++++++++
.../src/org/osgi/service/wireadmin/package.html | 11 +
.../src/org/osgi/service/wireadmin/packageinfo | 1 +
164 files changed, 9900 insertions(+), 0 deletions(-)
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/Configuration.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/Configuration.class
deleted file mode 100644
index 4dcf2e1..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/Configuration.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationAdmin.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationAdmin.class
deleted file mode 100644
index 77da123..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationAdmin.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationEvent.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationEvent.class
deleted file mode 100644
index e7ac7c0..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationEvent.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationException.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationException.class
deleted file mode 100644
index b59ea82..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationException.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationListener.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationListener.class
deleted file mode 100644
index 13b5e93..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationListener.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationPermission.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationPermission.class
deleted file mode 100644
index d88c04a..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationPermission.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationPermissionCollection$1.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationPermissionCollection$1.class
deleted file mode 100644
index ae1c8cd..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationPermissionCollection$1.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationPermissionCollection.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationPermissionCollection.class
deleted file mode 100644
index a6f831d..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationPermissionCollection.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationPlugin.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationPlugin.class
deleted file mode 100644
index d1c7824..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ConfigurationPlugin.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ManagedService.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ManagedService.class
deleted file mode 100644
index 60094c6..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ManagedService.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ManagedServiceFactory.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ManagedServiceFactory.class
deleted file mode 100644
index 60c4afc..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/cm/ManagedServiceFactory.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/component/ComponentConstants.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/component/ComponentConstants.class
deleted file mode 100644
index 61732d1..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/component/ComponentConstants.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/component/ComponentContext.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/component/ComponentContext.class
deleted file mode 100644
index 31a8381..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/component/ComponentContext.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/component/ComponentException.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/component/ComponentException.class
deleted file mode 100644
index 7e229e2..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/component/ComponentException.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/component/ComponentFactory.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/component/ComponentFactory.class
deleted file mode 100644
index 6a27a81..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/component/ComponentFactory.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/component/ComponentInstance.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/component/ComponentInstance.class
deleted file mode 100644
index 7c615df..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/component/ComponentInstance.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/Constants.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/Constants.class
deleted file mode 100644
index 3aa7d2a..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/Constants.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/Device.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/Device.class
deleted file mode 100644
index c74de60..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/Device.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/Driver.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/Driver.class
deleted file mode 100644
index f19b903..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/Driver.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/DriverLocator.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/DriverLocator.class
deleted file mode 100644
index 211bda8..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/DriverLocator.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/DriverSelector.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/DriverSelector.class
deleted file mode 100644
index d0eb4d5..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/DriverSelector.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/Match.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/Match.class
deleted file mode 100644
index aa75085..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/device/Match.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/Event$UnmodifiableDictionary.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/Event$UnmodifiableDictionary.class
deleted file mode 100644
index f243594..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/Event$UnmodifiableDictionary.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/Event.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/Event.class
deleted file mode 100644
index 5856c5c..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/Event.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/EventAdmin.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/EventAdmin.class
deleted file mode 100644
index ba765dd..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/EventAdmin.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/EventConstants.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/EventConstants.class
deleted file mode 100644
index e84161c..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/EventConstants.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/EventHandler.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/EventHandler.class
deleted file mode 100644
index 6747ad2..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/EventHandler.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/TopicPermission.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/TopicPermission.class
deleted file mode 100644
index b1534be..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/TopicPermission.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/TopicPermissionCollection.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/TopicPermissionCollection.class
deleted file mode 100644
index 15a19b9..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/event/TopicPermissionCollection.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/http/HttpContext.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/http/HttpContext.class
deleted file mode 100644
index 758cf73..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/http/HttpContext.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/http/HttpService.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/http/HttpService.class
deleted file mode 100644
index 09e7e86..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/http/HttpService.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/http/NamespaceException.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/http/NamespaceException.class
deleted file mode 100644
index afa9683..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/http/NamespaceException.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/io/ConnectionFactory.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/io/ConnectionFactory.class
deleted file mode 100644
index fd11291..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/io/ConnectionFactory.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/io/ConnectorService.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/io/ConnectorService.class
deleted file mode 100644
index 795596e..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/io/ConnectorService.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/log/LogEntry.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/log/LogEntry.class
deleted file mode 100644
index 70daca1..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/log/LogEntry.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/log/LogListener.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/log/LogListener.class
deleted file mode 100644
index da9a415..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/log/LogListener.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/log/LogReaderService.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/log/LogReaderService.class
deleted file mode 100644
index 75177cc..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/log/LogReaderService.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/log/LogService.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/log/LogService.class
deleted file mode 100644
index 7b853c5..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/log/LogService.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/metatype/AttributeDefinition.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/metatype/AttributeDefinition.class
deleted file mode 100644
index 1027886..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/metatype/AttributeDefinition.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/metatype/MetaTypeInformation.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/metatype/MetaTypeInformation.class
deleted file mode 100644
index a4f3fdf..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/metatype/MetaTypeInformation.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/metatype/MetaTypeProvider.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/metatype/MetaTypeProvider.class
deleted file mode 100644
index d74b54c..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/metatype/MetaTypeProvider.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/metatype/MetaTypeService.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/metatype/MetaTypeService.class
deleted file mode 100644
index fd62288..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/metatype/MetaTypeService.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/metatype/ObjectClassDefinition.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/metatype/ObjectClassDefinition.class
deleted file mode 100644
index 372f43b..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/metatype/ObjectClassDefinition.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/provisioning/ProvisioningService.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/provisioning/ProvisioningService.class
deleted file mode 100644
index 0855ca2..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/provisioning/ProvisioningService.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPAction.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPAction.class
deleted file mode 100644
index a9e4e2a..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPAction.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPDevice.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPDevice.class
deleted file mode 100644
index b7445d9..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPDevice.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPEventListener.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPEventListener.class
deleted file mode 100644
index 784d1c3..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPEventListener.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPException.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPException.class
deleted file mode 100644
index c2e2ebe..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPException.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPIcon.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPIcon.class
deleted file mode 100644
index 820e4a4..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPIcon.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPLocalStateVariable.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPLocalStateVariable.class
deleted file mode 100644
index 406ff02..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPLocalStateVariable.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPService.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPService.class
deleted file mode 100644
index 140f87d..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPService.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPStateVariable.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPStateVariable.class
deleted file mode 100644
index 133b723..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/upnp/UPnPStateVariable.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/Authorization.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/Authorization.class
deleted file mode 100644
index 07fa739..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/Authorization.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/Group.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/Group.class
deleted file mode 100644
index 77553f7..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/Group.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/Role.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/Role.class
deleted file mode 100644
index 5c74098..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/Role.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/User.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/User.class
deleted file mode 100644
index 2dcd183..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/User.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/UserAdmin.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/UserAdmin.class
deleted file mode 100644
index 4c73226..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/UserAdmin.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/UserAdminEvent.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/UserAdminEvent.class
deleted file mode 100644
index 42e5028..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/UserAdminEvent.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/UserAdminListener.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/UserAdminListener.class
deleted file mode 100644
index 2ace020..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/UserAdminListener.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/UserAdminPermission.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/UserAdminPermission.class
deleted file mode 100644
index 2a3e70b..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/UserAdminPermission.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/UserAdminPermissionCollection.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/UserAdminPermissionCollection.class
deleted file mode 100644
index 71d464c..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/useradmin/UserAdminPermissionCollection.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/BasicEnvelope.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/BasicEnvelope.class
deleted file mode 100644
index 3c0ca38..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/BasicEnvelope.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/Consumer.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/Consumer.class
deleted file mode 100644
index d6065fb..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/Consumer.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/Envelope.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/Envelope.class
deleted file mode 100644
index 2dcdb02..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/Envelope.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/Producer.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/Producer.class
deleted file mode 100644
index d817796..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/Producer.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/Wire.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/Wire.class
deleted file mode 100644
index cd0ef13..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/Wire.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WireAdmin.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WireAdmin.class
deleted file mode 100644
index 09752e7..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WireAdmin.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WireAdminEvent.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WireAdminEvent.class
deleted file mode 100644
index c6297f6..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WireAdminEvent.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WireAdminListener.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WireAdminListener.class
deleted file mode 100644
index a8bbb86..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WireAdminListener.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WireConstants.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WireConstants.class
deleted file mode 100644
index 5b05529..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WireConstants.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WirePermission.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WirePermission.class
deleted file mode 100644
index 45e1483..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WirePermission.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WirePermissionCollection.class b/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WirePermissionCollection.class
deleted file mode 100644
index b11a24f..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/org/osgi/service/wireadmin/WirePermissionCollection.class and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src.zip b/eclipse/plugins/org.eclipse.osgi.services/src.zip
deleted file mode 100644
index fe4cdfa..0000000
Binary files a/eclipse/plugins/org.eclipse.osgi.services/src.zip and /dev/null differ
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/javax b/eclipse/plugins/org.eclipse.osgi.services/src/javax
new file mode 120000
index 0000000..c4f937b
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/javax
@@ -0,0 +1 @@
+../../org.eclipse.equinox.io/src/javax/
\ No newline at end of file
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/Configuration.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/Configuration.java
new file mode 100644
index 0000000..7c17cf1
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/Configuration.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.cm;
+
+import java.io.IOException;
+import java.util.Dictionary;
+
+/**
+ * The configuration information for a <code>ManagedService</code> or
+ * <code>ManagedServiceFactory</code> object.
+ *
+ * The Configuration Admin service uses this interface to represent the
+ * configuration information for a <code>ManagedService</code> or for a
+ * service instance of a <code>ManagedServiceFactory</code>.
+ *
+ * <p>
+ * A <code>Configuration</code> object contains a configuration dictionary and
+ * allows the properties to be updated via this object. Bundles wishing to
+ * receive configuration dictionaries do not need to use this class - they
+ * register a <code>ManagedService</code> or
+ * <code>ManagedServiceFactory</code>. Only administrative bundles, and
+ * bundles wishing to update their own configurations need to use this class.
+ *
+ * <p>
+ * The properties handled in this configuration have case insensitive
+ * <code>String</code> objects as keys. However, case is preserved from the
+ * last set key/value.
+ * <p>
+ * A configuration can be <i>bound </i> to a bundle location (
+ * <code>Bundle.getLocation()</code>). The purpose of binding a
+ * <code>Configuration</code> object to a location is to make it impossible
+ * for another bundle to forge a PID that would match this configuration. When a
+ * configuration is bound to a specific location, and a bundle with a different
+ * location registers a corresponding <code>ManagedService</code> object or
+ * <code>ManagedServiceFactory</code> object, then the configuration is not
+ * passed to the updated method of that object.
+ *
+ * <p>
+ * If a configuration's location is <code>null</code>, it is not yet bound to
+ * a location. It will become bound to the location of the first bundle that
+ * registers a <code>ManagedService</code> or
+ * <code>ManagedServiceFactory</code> object with the corresponding PID.
+ * <p>
+ * The same <code>Configuration</code> object is used for configuring both a
+ * Managed Service Factory and a Managed Service. When it is important to
+ * differentiate between these two the term "factory configuration" is used.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface Configuration {
+ /**
+ * Get the PID for this <code>Configuration</code> object.
+ *
+ * @return the PID for this <code>Configuration</code> object.
+ * @throws IllegalStateException if this configuration has been deleted
+ */
+ public String getPid();
+
+ /**
+ * Return the properties of this <code>Configuration</code> object.
+ *
+ * The <code>Dictionary</code> object returned is a private copy for the
+ * caller and may be changed without influencing the stored configuration.
+ * The keys in the returned dictionary are case insensitive and are always
+ * of type <code>String</code>.
+ *
+ * <p>
+ * If called just after the configuration is created and before update has
+ * been called, this method returns <code>null</code>.
+ *
+ * @return A private copy of the properties for the caller or
+ * <code>null</code>. These properties must not contain the
+ * "service.bundleLocation" property. The value of this property may
+ * be obtained from the <code>getBundleLocation</code> method.
+ * @throws IllegalStateException if this configuration has been deleted
+ */
+ public Dictionary getProperties();
+
+ /**
+ * Update the properties of this <code>Configuration</code> object.
+ *
+ * Stores the properties in persistent storage after adding or overwriting
+ * the following properties:
+ * <ul>
+ * <li>"service.pid" : is set to be the PID of this configuration.</li>
+ * <li>"service.factoryPid" : if this is a factory configuration it is set
+ * to the factory PID else it is not set.</li>
+ * </ul>
+ * These system properties are all of type <code>String</code>.
+ *
+ * <p>
+ * If the corresponding Managed Service/Managed Service Factory is
+ * registered, its updated method must be called asynchronously. Else, this
+ * callback is delayed until aforementioned registration occurs.
+ *
+ * <p>
+ * Also initiates an asynchronous call to all
+ * <code>ConfigurationListener</code>s with a
+ * <code>ConfigurationEvent.CM_UPDATED</code> event.
+ *
+ * @param properties the new set of properties for this configuration
+ * @throws IOException if update cannot be made persistent
+ * @throws IllegalArgumentException if the <code>Dictionary</code> object
+ * contains invalid configuration types or contains case variants of
+ * the same key name.
+ * @throws IllegalStateException if this configuration has been deleted
+ */
+ public void update(Dictionary properties) throws IOException;
+
+ /**
+ * Delete this <code>Configuration</code> object.
+ *
+ * Removes this configuration object from the persistent store. Notify
+ * asynchronously the corresponding Managed Service or Managed Service
+ * Factory. A <code>ManagedService</code> object is notified by a call to
+ * its <code>updated</code> method with a <code>null</code> properties
+ * argument. A <code>ManagedServiceFactory</code> object is notified by a
+ * call to its <code>deleted</code> method.
+ *
+ * <p>
+ * Also initiates an asynchronous call to all
+ * <code>ConfigurationListener</code>s with a
+ * <code>ConfigurationEvent.CM_DELETED</code> event.
+ *
+ * @throws IOException If delete fails
+ * @throws IllegalStateException if this configuration has been deleted
+ */
+ public void delete() throws IOException;
+
+ /**
+ * For a factory configuration return the PID of the corresponding Managed
+ * Service Factory, else return <code>null</code>.
+ *
+ * @return factory PID or <code>null</code>
+ * @throws IllegalStateException if this configuration has been deleted
+ */
+ public String getFactoryPid();
+
+ /**
+ * Update the <code>Configuration</code> object with the current
+ * properties.
+ *
+ * Initiate the <code>updated</code> callback to the Managed Service or
+ * Managed Service Factory with the current properties asynchronously.
+ *
+ * <p>
+ * This is the only way for a bundle that uses a Configuration Plugin
+ * service to initiate a callback. For example, when that bundle detects a
+ * change that requires an update of the Managed Service or Managed Service
+ * Factory via its <code>ConfigurationPlugin</code> object.
+ *
+ * @see ConfigurationPlugin
+ * @throws IOException if update cannot access the properties in persistent
+ * storage
+ * @throws IllegalStateException if this configuration has been deleted
+ */
+ public void update() throws IOException;
+
+ /**
+ * Bind this <code>Configuration</code> object to the specified bundle
+ * location.
+ *
+ * If the bundleLocation parameter is <code>null</code> then the
+ * <code>Configuration</code> object will not be bound to a location. It
+ * will be set to the bundle's location before the first time a Managed
+ * Service/Managed Service Factory receives this <code>Configuration</code>
+ * object via the updated method and before any plugins are called. The
+ * bundle location will be set persistently.
+ *
+ * @param bundleLocation a bundle location or <code>null</code>
+ * @throws IllegalStateException If this configuration has been deleted.
+ * @throws SecurityException If the caller does not have
+ * <code>ConfigurationPermission[*,CONFIGURE]</code>.
+ */
+ public void setBundleLocation(String bundleLocation);
+
+ /**
+ * Get the bundle location.
+ *
+ * Returns the bundle location to which this configuration is bound, or
+ * <code>null</code> if it is not yet bound to a bundle location.
+ *
+ * @return location to which this configuration is bound, or
+ * <code>null</code>.
+ * @throws IllegalStateException If this <code>Configuration</code> object
+ * has been deleted.
+ * @throws SecurityException If the caller does not have
+ * <code>ConfigurationPermission[*,CONFIGURE]</code>.
+ */
+ public String getBundleLocation();
+
+ /**
+ * Equality is defined to have equal PIDs
+ *
+ * Two Configuration objects are equal when their PIDs are equal.
+ *
+ * @param other <code>Configuration</code> object to compare against
+ * @return <code>true</code> if equal, <code>false</code> if not a
+ * <code>Configuration</code> object or one with a different PID.
+ */
+ public boolean equals(Object other);
+
+ /**
+ * Hash code is based on PID.
+ *
+ * The hashcode for two Configuration objects must be the same when the
+ * Configuration PID's are the same.
+ *
+ * @return hash code for this Configuration object
+ */
+ public int hashCode();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationAdmin.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationAdmin.java
new file mode 100644
index 0000000..a8d0a78
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationAdmin.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.cm;
+
+import java.io.IOException;
+import java.util.Dictionary;
+
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * Service for administering configuration data.
+ *
+ * <p>
+ * The main purpose of this interface is to store bundle configuration data
+ * persistently. This information is represented in <code>Configuration</code>
+ * objects. The actual configuration data is a <code>Dictionary</code> of
+ * properties inside a <code>Configuration</code> object.
+ *
+ * <p>
+ * There are two principally different ways to manage configurations. First
+ * there is the concept of a Managed Service, where configuration data is
+ * uniquely associated with an object registered with the service registry.
+ *
+ * <p>
+ * Next, there is the concept of a factory where the Configuration Admin service
+ * will maintain 0 or more <code>Configuration</code> objects for a Managed
+ * Service Factory that is registered with the Framework.
+ *
+ * <p>
+ * The first concept is intended for configuration data about "things/services"
+ * whose existence is defined externally, e.g. a specific printer. Factories are
+ * intended for "things/services" that can be created any number of times, e.g.
+ * a configuration for a DHCP server for different networks.
+ *
+ * <p>
+ * Bundles that require configuration should register a Managed Service or a
+ * Managed Service Factory in the service registry. A registration property
+ * named <code>service.pid</code> (persistent identifier or PID) must be used
+ * to identify this Managed Service or Managed Service Factory to the
+ * Configuration Admin service.
+ *
+ * <p>
+ * When the ConfigurationAdmin detects the registration of a Managed Service, it
+ * checks its persistent storage for a configuration object whose PID matches
+ * the PID registration property (<code>service.pid</code>) of the Managed
+ * Service. If found, it calls {@link ManagedService#updated} method with the
+ * new properties. The implementation of a Configuration Admin service must run
+ * these call-backs asynchronously to allow proper synchronization.
+ *
+ * <p>
+ * When the Configuration Admin service detects a Managed Service Factory
+ * registration, it checks its storage for configuration objects whose
+ * <code>factoryPid</code> matches the PID of the Managed Service Factory. For
+ * each such <code>Configuration</code> objects, it calls the
+ * <code>ManagedServiceFactory.updated</code> method asynchronously with the
+ * new properties. The calls to the <code>updated</code> method of a
+ * <code>ManagedServiceFactory</code> must be executed sequentially and not
+ * overlap in time.
+ *
+ * <p>
+ * In general, bundles having permission to use the Configuration Admin service
+ * can only access and modify their own configuration information. Accessing or
+ * modifying the configuration of another bundle requires
+ * <code>ConfigurationPermission[*,CONFIGURE]</code>.
+ *
+ * <p>
+ * <code>Configuration</code> objects can be <i>bound </i> to a specified
+ * bundle location. In this case, if a matching Managed Service or Managed
+ * Service Factory is registered by a bundle with a different location, then the
+ * Configuration Admin service must not do the normal callback, and it should
+ * log an error. In the case where a <code>Configuration</code> object is not
+ * bound, its location field is <code>null</code>, the Configuration Admin
+ * service will bind it to the location of the bundle that registers the first
+ * Managed Service or Managed Service Factory that has a corresponding PID
+ * property. When a <code>Configuration</code> object is bound to a bundle
+ * location in this manner, the Configuration Admin service must detect if the
+ * bundle corresponding to the location is uninstalled. If this occurs, the
+ * <code>Configuration</code> object is unbound, that is its location field is
+ * set back to <code>null</code>.
+ *
+ * <p>
+ * The method descriptions of this class refer to a concept of "the calling
+ * bundle". This is a loose way of referring to the bundle which obtained the
+ * Configuration Admin service from the service registry. Implementations of
+ * <code>ConfigurationAdmin</code> must use a
+ * {@link org.osgi.framework.ServiceFactory} to support this concept.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface ConfigurationAdmin {
+ /**
+ * Service property naming the Factory PID in the configuration dictionary.
+ * The property's value is of type <code>String</code>.
+ *
+ * @since 1.1
+ */
+ public final static String SERVICE_FACTORYPID = "service.factoryPid";
+ /**
+ * Service property naming the location of the bundle that is associated
+ * with a a <code>Configuration</code> object. This property can be
+ * searched for but must not appear in the configuration dictionary for
+ * security reason. The property's value is of type <code>String</code>.
+ *
+ * @since 1.1
+ */
+ public final static String SERVICE_BUNDLELOCATION = "service.bundleLocation";
+
+ /**
+ * Create a new factory <code>Configuration</code> object with a new PID.
+ *
+ * The properties of the new <code>Configuration</code> object are
+ * <code>null</code> until the first time that its
+ * {@link Configuration#update(Dictionary)} method is called.
+ *
+ * <p>
+ * It is not required that the <code>factoryPid</code> maps to a
+ * registered Managed Service Factory.
+ * <p>
+ * The <code>Configuration</code> object is bound to the location of the
+ * calling bundle.
+ *
+ * @param factoryPid PID of factory (not <code>null</code>).
+ * @return A new <code>Configuration</code> object.
+ * @throws IOException if access to persistent storage fails.
+ * @throws SecurityException if caller does not have <code>ConfigurationPermission[*,CONFIGURE]</code> and <code>factoryPid</code> is bound to another bundle.
+ */
+ public Configuration createFactoryConfiguration(String factoryPid)
+ throws IOException;
+
+ /**
+ * Create a new factory <code>Configuration</code> object with a new PID.
+ *
+ * The properties of the new <code>Configuration</code> object are
+ * <code>null</code> until the first time that its
+ * {@link Configuration#update(Dictionary)} method is called.
+ *
+ * <p>
+ * It is not required that the <code>factoryPid</code> maps to a
+ * registered Managed Service Factory.
+ *
+ * <p>
+ * The <code>Configuration</code> is bound to the location specified. If
+ * this location is <code>null</code> it will be bound to the location of
+ * the first bundle that registers a Managed Service Factory with a
+ * corresponding PID.
+ *
+ * @param factoryPid PID of factory (not <code>null</code>).
+ * @param location A bundle location string, or <code>null</code>.
+ * @return a new <code>Configuration</code> object.
+ * @throws IOException if access to persistent storage fails.
+ * @throws SecurityException if caller does not have <code>ConfigurationPermission[*,CONFIGURE]</code>.
+ */
+ public Configuration createFactoryConfiguration(String factoryPid, String location)
+ throws IOException;
+
+ /**
+ * Get an existing <code>Configuration</code> object from the persistent
+ * store, or create a new <code>Configuration</code> object.
+ *
+ * <p>
+ * If a <code>Configuration</code> with this PID already exists in
+ * Configuration Admin service return it. The location parameter is ignored
+ * in this case.
+ *
+ * <p>
+ * Else, return a new <code>Configuration</code> object. This new object
+ * is bound to the location and the properties are set to <code>null</code>.
+ * If the location parameter is <code>null</code>, it will be set when a
+ * Managed Service with the corresponding PID is registered for the first
+ * time.
+ *
+ * @param pid Persistent identifier.
+ * @param location The bundle location string, or <code>null</code>.
+ * @return An existing or new <code>Configuration</code> object.
+ * @throws IOException if access to persistent storage fails.
+ * @throws SecurityException if the caller does not have <code>ConfigurationPermission[*,CONFIGURE]</code>.
+ */
+ public Configuration getConfiguration(String pid, String location)
+ throws IOException;
+
+ /**
+ * Get an existing or new <code>Configuration</code> object from the
+ * persistent store.
+ *
+ * If the <code>Configuration</code> object for this PID does not exist,
+ * create a new <code>Configuration</code> object for that PID, where
+ * properties are <code>null</code>. Bind its location to the calling
+ * bundle's location.
+ *
+ * <p>
+ * Otherwise, if the location of the existing <code>Configuration</code> object
+ * is <code>null</code>, set it to the calling bundle's location.
+ *
+ * @param pid persistent identifier.
+ * @return an existing or new <code>Configuration</code> matching the PID.
+ * @throws IOException if access to persistent storage fails.
+ * @throws SecurityException if the <code>Configuration</code> object is bound to a location different from that of the calling bundle and it has no <code>ConfigurationPermission[*,CONFIGURE]</code>.
+ */
+ public Configuration getConfiguration(String pid) throws IOException;
+
+ /**
+ * List the current <code>Configuration</code> objects which match the
+ * filter.
+ *
+ * <p>
+ * Only <code>Configuration</code> objects with non- <code>null</code>
+ * properties are considered current. That is,
+ * <code>Configuration.getProperties()</code> is guaranteed not to return
+ * <code>null</code> for each of the returned <code>Configuration</code>
+ * objects.
+ *
+ * <p>
+ * Normally only <code>Configuration</code> objects that are bound to the
+ * location of the calling bundle are returned, or all if the caller has
+ * <code>ConfigurationPermission[*,CONFIGURE]</code>.
+ *
+ * <p>
+ * The syntax of the filter string is as defined in the {@link org.osgi.framework.Filter}
+ * class. The filter can test any configuration parameters including the
+ * following system properties:
+ * <ul>
+ * <li><code>service.pid</code>-<code>String</code>- the PID under
+ * which this is registered</li>
+ * <li><code>service.factoryPid</code>-<code>String</code>- the
+ * factory if applicable</li>
+ * <li><code>service.bundleLocation</code>-<code>String</code>- the
+ * bundle location</li>
+ * </ul>
+ * The filter can also be <code>null</code>, meaning that all
+ * <code>Configuration</code> objects should be returned.
+ *
+ * @param filter A filter string, or <code>null</code> to
+ * retrieve all <code>Configuration</code> objects.
+ * @return All matching <code>Configuration</code> objects, or
+ * <code>null</code> if there aren't any.
+ * @throws IOException if access to persistent storage fails
+ * @throws InvalidSyntaxException if the filter string is invalid
+ */
+ public Configuration[] listConfigurations(String filter) throws IOException,
+ InvalidSyntaxException;
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationEvent.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationEvent.java
new file mode 100644
index 0000000..f17007f
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationEvent.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.cm;
+
+import java.util.Dictionary;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A Configuration Event.
+ *
+ * <p>
+ * <code>ConfigurationEvent</code> objects are delivered to all registered
+ * <code>ConfigurationListener</code> service objects. ConfigurationEvents
+ * must be asynchronously delivered in chronological order with respect to each
+ * listener.
+ *
+ * <p>
+ * A type code is used to identify the type of event. The following event types
+ * are defined:
+ * <ul>
+ * <li>{@link #CM_UPDATED}
+ * <li>{@link #CM_DELETED}
+ * </ul>
+ * Additional event types may be defined in the future.
+ *
+ * <p>
+ * Security Considerations. <code>ConfigurationEvent</code> objects do not
+ * provide <code>Configuration</code> objects, so no sensitive configuration
+ * information is available from the event. If the listener wants to locate the
+ * <code>Configuration</code> object for the specified pid, it must use
+ * <code>ConfigurationAdmin</code>.
+ *
+ * @see ConfigurationListener
+ *
+ * @version $Revision: 6180 $
+ * @since 1.2
+ */
+public class ConfigurationEvent {
+ /**
+ * A <code>Configuration</code> has been updated.
+ *
+ * <p>
+ * This <code>ConfigurationEvent</code> type that indicates that a
+ * <code>Configuration</code> object has been updated with new properties.
+ *
+ * An event is fired when a call to {@link Configuration#update(Dictionary)}
+ * successfully changes a configuration.
+ *
+ * <p>
+ * The value of <code>CM_UPDATED</code> is 1.
+ */
+ public static final int CM_UPDATED = 1;
+ /**
+ * A <code>Configuration</code> has been deleted.
+ *
+ * <p>
+ * This <code>ConfigurationEvent</code> type that indicates that a
+ * <code>Configuration</code> object has been deleted.
+ *
+ * An event is fired when a call to {@link Configuration#delete()}
+ * successfully deletes a configuration.
+ *
+ * <p>
+ * The value of <code>CM_DELETED</code> is 2.
+ */
+ public static final int CM_DELETED = 2;
+ /**
+ * Type of this event.
+ *
+ * @see #getType
+ */
+ private final int type;
+ /**
+ * The factory pid associated with this event.
+ */
+ private final String factoryPid;
+ /**
+ * The pid associated with this event.
+ */
+ private final String pid;
+ /**
+ * The ConfigurationAdmin service which created this event.
+ */
+ private final ServiceReference reference;
+
+ /**
+ * Constructs a <code>ConfigurationEvent</code> object from the given
+ * <code>ServiceReference</code> object, event type, and pids.
+ *
+ * @param reference The <code>ServiceReference</code> object of the
+ * Configuration Admin service that created this event.
+ * @param type The event type. See {@link #getType}.
+ * @param factoryPid The factory pid of the associated configuration if the
+ * target of the configuration is a ManagedServiceFactory. Otherwise
+ * <code>null</code> if the target of the configuration is a
+ * ManagedService.
+ * @param pid The pid of the associated configuration.
+ */
+ public ConfigurationEvent(ServiceReference reference, int type,
+ String factoryPid, String pid) {
+ this.reference = reference;
+ this.type = type;
+ this.factoryPid = factoryPid;
+ this.pid = pid;
+ if ((reference == null) || (pid == null)) {
+ throw new NullPointerException("reference and pid must not be null");
+ }
+ }
+
+ /**
+ * Returns the factory pid of the associated configuration.
+ *
+ * @return Returns the factory pid of the associated configuration if the
+ * target of the configuration is a ManagedServiceFactory. Otherwise
+ * <code>null</code> if the target of the configuration is a
+ * ManagedService.
+ */
+ public String getFactoryPid() {
+ return factoryPid;
+ }
+
+ /**
+ * Returns the pid of the associated configuration.
+ *
+ * @return Returns the pid of the associated configuration.
+ */
+ public String getPid() {
+ return pid;
+ }
+
+ /**
+ * Return the type of this event.
+ * <p>
+ * The type values are:
+ * <ul>
+ * <li>{@link #CM_UPDATED}
+ * <li>{@link #CM_DELETED}
+ * </ul>
+ *
+ * @return The type of this event.
+ */
+ public int getType() {
+ return type;
+ }
+
+ /**
+ * Return the <code>ServiceReference</code> object of the Configuration
+ * Admin service that created this event.
+ *
+ * @return The <code>ServiceReference</code> object for the Configuration
+ * Admin service that created this event.
+ */
+ public ServiceReference getReference() {
+ return reference;
+ }
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationException.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationException.java
new file mode 100644
index 0000000..300f5c8
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationException.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.cm;
+
+/**
+ * An <code>Exception</code> class to inform the Configuration Admin service
+ * of problems with configuration data.
+ *
+ * @version $Revision: 6083 $
+ */
+public class ConfigurationException extends Exception {
+ static final long serialVersionUID = -1690090413441769377L;
+
+ private final String property;
+ private final String reason;
+
+ /**
+ * Create a <code>ConfigurationException</code> object.
+ *
+ * @param property name of the property that caused the problem,
+ * <code>null</code> if no specific property was the cause
+ * @param reason reason for failure
+ */
+ public ConfigurationException(String property, String reason) {
+ super(property + " : " + reason);
+ this.property = property;
+ this.reason = reason;
+ }
+
+ /**
+ * Create a <code>ConfigurationException</code> object.
+ *
+ * @param property name of the property that caused the problem,
+ * <code>null</code> if no specific property was the cause
+ * @param reason reason for failure
+ * @param cause The cause of this exception.
+ * @since 1.2
+ */
+ public ConfigurationException(String property, String reason,
+ Throwable cause) {
+ super(property + " : " + reason, cause);
+ this.property = property;
+ this.reason = reason;
+ }
+
+ /**
+ * Return the property name that caused the failure or null.
+ *
+ * @return name of property or null if no specific property caused the
+ * problem
+ */
+ public String getProperty() {
+ return property;
+ }
+
+ /**
+ * Return the reason for this exception.
+ *
+ * @return reason of the failure
+ */
+ public String getReason() {
+ return reason;
+ }
+
+ /**
+ * Returns the cause of this exception or <code>null</code> if no cause was
+ * set.
+ *
+ * @return The cause of this exception or <code>null</code> if no cause was
+ * set.
+ * @since 1.2
+ */
+ public Throwable getCause() {
+ return super.getCause();
+ }
+
+ /**
+ * Initializes the cause of this exception to the specified value.
+ *
+ * @param cause The cause of this exception.
+ * @return This exception.
+ * @throws IllegalArgumentException If the specified cause is this
+ * exception.
+ * @throws IllegalStateException If the cause of this exception has already
+ * been set.
+ * @since 1.2
+ */
+ public Throwable initCause(Throwable cause) {
+ return super.initCause(cause);
+ }
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationListener.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationListener.java
new file mode 100644
index 0000000..5d7793d
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationListener.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.cm;
+
+/**
+ * Listener for Configuration Events. When a <code>ConfigurationEvent</code>
+ * is fired, it is asynchronously delivered to a
+ * <code>ConfigurationListener</code>.
+ *
+ * <p>
+ * <code>ConfigurationListener</code> objects are registered with the
+ * Framework service registry and are notified with a
+ * <code>ConfigurationEvent</code> object when an event is fired.
+ * <p>
+ * <code>ConfigurationListener</code> objects can inspect the received
+ * <code>ConfigurationEvent</code> object to determine its type, the pid of
+ * the <code>Configuration</code> object with which it is associated, and the
+ * Configuration Admin service that fired the event.
+ *
+ * <p>
+ * Security Considerations. Bundles wishing to monitor configuration events will
+ * require <code>ServicePermission[ConfigurationListener,REGISTER]</code> to
+ * register a <code>ConfigurationListener</code> service.
+ *
+ * @version $Revision: 5673 $
+ * @since 1.2
+ */
+public interface ConfigurationListener {
+ /**
+ * Receives notification of a Configuration that has changed.
+ *
+ * @param event The <code>ConfigurationEvent</code>.
+ */
+ public void configurationEvent(ConfigurationEvent event);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationPermission.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationPermission.java
new file mode 100644
index 0000000..3af9088
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationPermission.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
+ *
+ * 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.
+ */
+
+package org.osgi.service.cm;
+
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.Enumeration;
+import java.util.NoSuchElementException;
+
+/**
+ * Indicates a bundle's authority to configure bundles.
+ *
+ * This permission has only a single action: CONFIGURE.
+ *
+ * @ThreadSafe
+ * @version $Revision: 6381 $
+ * @since 1.2
+ */
+
+public final class ConfigurationPermission extends BasicPermission {
+ static final long serialVersionUID = 5716868734811965383L;
+ /**
+ * The action string <code>configure</code>.
+ */
+ public final static String CONFIGURE = "configure";
+
+ /**
+ * Create a new ConfigurationPermission.
+ *
+ * @param name Name must be "*".
+ * @param actions <code>configure</code> (canonical order).
+ */
+
+ public ConfigurationPermission(String name, String actions) {
+ super(name);
+ if (!name.equals("*")) {
+ throw new IllegalArgumentException("name must be *");
+ }
+ actions = actions.trim();
+ if (actions.equalsIgnoreCase(CONFIGURE)||actions.equals("*"))
+ return;
+
+ throw new IllegalArgumentException("actions must be " + CONFIGURE);
+ }
+
+ /**
+ * Determines if a <code>ConfigurationPermission</code> object "implies"
+ * the specified permission.
+ *
+ * @param p The target permission to check.
+ * @return <code>true</code> if the specified permission is implied by
+ * this object; <code>false</code> otherwise.
+ */
+
+ public boolean implies(Permission p) {
+ return p instanceof ConfigurationPermission;
+ }
+
+ /**
+ * Determines the equality of two <code>ConfigurationPermission</code>
+ * objects.
+ * <p>
+ * Two <code>ConfigurationPermission</code> objects are equal.
+ *
+ * @param obj The object being compared for equality with this object.
+ * @return <code>true</code> if <code>obj</code> is equivalent to this
+ * <code>ConfigurationPermission</code>; <code>false</code>
+ * otherwise.
+ */
+ public boolean equals(Object obj) {
+ return obj instanceof ConfigurationPermission;
+ }
+
+ /**
+ * Returns the hash code value for this object.
+ *
+ * @return Hash code value for this object.
+ */
+
+ public int hashCode() {
+ int h = 31 * 17 + getName().hashCode();
+ h = 31 * h + getActions().hashCode();
+ return h;
+ }
+
+ /**
+ * Returns the canonical string representation of the
+ * <code>ConfigurationPermission</code> actions.
+ *
+ * <p>
+ * Always returns present <code>ConfigurationPermission</code> actions in
+ * the following order: <code>CONFIGURE</code>
+ *
+ * @return Canonical string representation of the
+ * <code>ConfigurationPermission</code> actions.
+ */
+ public String getActions() {
+ return CONFIGURE;
+ }
+
+ /**
+ * Returns a new <code>PermissionCollection</code> object suitable for
+ * storing <code>ConfigurationPermission</code>s.
+ *
+ * @return A new <code>PermissionCollection</code> object.
+ */
+ public PermissionCollection newPermissionCollection() {
+ return new ConfigurationPermissionCollection();
+ }
+}
+
+/**
+ * Stores a set of <code>ConfigurationPermission</code> permissions.
+ *
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+final class ConfigurationPermissionCollection extends PermissionCollection {
+ static final long serialVersionUID = -6917638867081695839L;
+ /**
+ * True if collection is non-empty.
+ *
+ * @serial
+ */
+ private volatile boolean hasElement;
+
+ /**
+ * Creates an empty <tt>ConfigurationPermissionCollection</tt> object.
+ *
+ */
+ public ConfigurationPermissionCollection() {
+ hasElement = false;
+ }
+
+ /**
+ * Adds the specified permission to the
+ * <tt>ConfigurationPermissionCollection</tt>. The key for the hash is
+ * the interface name of the service.
+ *
+ * @param permission The <tt>Permission</tt> object to add.
+ *
+ * @exception IllegalArgumentException If the permission is not an
+ * <tt>ConfigurationPermission</tt>.
+ *
+ * @exception SecurityException If this ConfigurationPermissionCollection
+ * object has been marked read-only.
+ */
+
+ public void add(Permission permission) {
+ if (!(permission instanceof ConfigurationPermission)) {
+ throw new IllegalArgumentException("invalid permission: "
+ + permission);
+ }
+
+ if (isReadOnly())
+ throw new SecurityException("attempt to add a Permission to a "
+ + "readonly PermissionCollection");
+
+ hasElement = true;
+ }
+
+ /**
+ * Determines if the specified set of permissions implies the permissions
+ * expressed in the parameter <tt>permission</tt>.
+ *
+ * @param p The Permission object to compare.
+ *
+ * @return true if permission is a proper subset of a permission in the set;
+ * false otherwise.
+ */
+
+ public boolean implies(Permission p) {
+ return hasElement && (p instanceof ConfigurationPermission);
+ }
+
+ /**
+ * Returns an enumeration of an <tt>ConfigurationPermission</tt> object.
+ *
+ * @return Enumeration of an <tt>ConfigurationPermission</tt> object.
+ */
+
+ public Enumeration elements() {
+ final boolean nonEmpty = hasElement;
+ return new Enumeration() {
+ private boolean more = nonEmpty;
+
+ public boolean hasMoreElements() {
+ return more;
+ }
+
+ public Object nextElement() {
+ if (more) {
+ more = false;
+
+ return new ConfigurationPermission("*",
+ ConfigurationPermission.CONFIGURE);
+ }
+ else {
+ throw new NoSuchElementException();
+ }
+ }
+ };
+ }
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationPlugin.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationPlugin.java
new file mode 100644
index 0000000..574466e
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ConfigurationPlugin.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.cm;
+
+import java.util.Dictionary;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A service interface for processing configuration dictionary before the
+ * update.
+ *
+ * <p>
+ * A bundle registers a <code>ConfigurationPlugin</code> object in order to
+ * process configuration updates before they reach the Managed Service or
+ * Managed Service Factory. The Configuration Admin service will detect
+ * registrations of Configuration Plugin services and must call these services
+ * every time before it calls the <code>ManagedService</code> or
+ * <code>ManagedServiceFactory</code>
+ * <code>updated</code> method. The
+ * Configuration Plugin service thus has the opportunity to view and modify the
+ * properties before they are passed to the Managed Service or Managed Service
+ * Factory.
+ *
+ * <p>
+ * Configuration Plugin (plugin) services have full read/write access to all
+ * configuration information. Therefore, bundles using this facility should be
+ * trusted. Access to this facility should be limited with
+ * <code>ServicePermission[ConfigurationPlugin,REGISTER]</code>.
+ * Implementations of a Configuration Plugin service should assure that they
+ * only act on appropriate configurations.
+ *
+ * <p>
+ * The <code>Integer</code> <code>service.cmRanking</code> registration
+ * property may be specified. Not specifying this registration property, or
+ * setting it to something other than an <code>Integer</code>, is the same as
+ * setting it to the <code>Integer</code> zero. The
+ * <code>service.cmRanking</code> property determines the order in which
+ * plugins are invoked. Lower ranked plugins are called before higher ranked
+ * ones. In the event of more than one plugin having the same value of
+ * <code>service.cmRanking</code>, then the Configuration Admin service
+ * arbitrarily chooses the order in which they are called.
+ *
+ * <p>
+ * By convention, plugins with <code>service.cmRanking< 0</code> or
+ * <code>service.cmRanking > 1000</code> should not make modifications to
+ * the properties.
+ *
+ * <p>
+ * The Configuration Admin service has the right to hide properties from
+ * plugins, or to ignore some or all the changes that they make. This might be
+ * done for security reasons. Any such behavior is entirely implementation
+ * defined.
+ *
+ * <p>
+ * A plugin may optionally specify a <code>cm.target</code> registration
+ * property whose value is the PID of the Managed Service or Managed Service
+ * Factory whose configuration updates the plugin is intended to intercept. The
+ * plugin will then only be called with configuration updates that are targeted
+ * at the Managed Service or Managed Service Factory with the specified PID.
+ * Omitting the <code>cm.target</code> registration property means that the
+ * plugin is called for all configuration updates.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface ConfigurationPlugin {
+ /**
+ * A service property to limit the Managed Service or Managed Service
+ * Factory configuration dictionaries a Configuration Plugin service
+ * receives.
+ *
+ * This property contains a <code>String[]</code> of PIDs. A Configuration
+ * Admin service must call a Configuration Plugin service only when this
+ * property is not set, or the target service's PID is listed in this
+ * property.
+ */
+ public static final String CM_TARGET = "cm.target";
+ /**
+ * A service property to specify the order in which plugins are invoked.
+ *
+ * This property contains an <code>Integer</code> ranking of the plugin.
+ * Not specifying this registration property, or setting it to something
+ * other than an <code>Integer</code>, is the same as setting it to the
+ * <code>Integer</code> zero. This property determines the order in which
+ * plugins are invoked. Lower ranked plugins are called before higher ranked
+ * ones.
+ *
+ * @since 1.2
+ */
+ public static final String CM_RANKING = "service.cmRanking";
+
+ /**
+ * View and possibly modify the a set of configuration properties before
+ * they are sent to the Managed Service or the Managed Service Factory. The
+ * Configuration Plugin services are called in increasing order of their
+ * <code>service.cmRanking</code> property. If this property is undefined
+ * or is a non- <code>Integer</code> type, 0 is used.
+ *
+ * <p>
+ * This method should not modify the properties unless the
+ * <code>service.cmRanking</code> of this plugin is in the range
+ * <code>0 <= service.cmRanking <= 1000</code>.
+ * <p>
+ * If this method throws any <code>Exception</code>, the Configuration
+ * Admin service must catch it and should log it.
+ *
+ * @param reference reference to the Managed Service or Managed Service
+ * Factory
+ * @param properties The configuration properties. This argument must not
+ * contain the "service.bundleLocation" property. The value of this
+ * property may be obtained from the
+ * <code>Configuration.getBundleLocation</code> method.
+ */
+ public void modifyConfiguration(ServiceReference reference,
+ Dictionary properties);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ManagedService.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ManagedService.java
new file mode 100644
index 0000000..6812434
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ManagedService.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.cm;
+
+import java.util.Dictionary;
+
+/**
+ * A service that can receive configuration data from a Configuration Admin
+ * service.
+ *
+ * <p>
+ * A Managed Service is a service that needs configuration data. Such an object
+ * should be registered with the Framework registry with the
+ * <code>service.pid</code> property set to some unique identifier called a
+ * PID.
+ *
+ * <p>
+ * If the Configuration Admin service has a <code>Configuration</code> object
+ * corresponding to this PID, it will callback the <code>updated()</code>
+ * method of the <code>ManagedService</code> object, passing the properties of
+ * that <code>Configuration</code> object.
+ *
+ * <p>
+ * If it has no such <code>Configuration</code> object, then it calls back
+ * with a <code>null</code> properties argument. Registering a Managed Service
+ * will always result in a callback to the <code>updated()</code> method
+ * provided the Configuration Admin service is, or becomes active. This callback
+ * must always be done asynchronously.
+ *
+ * <p>
+ * Else, every time that either of the <code>updated()</code> methods is
+ * called on that <code>Configuration</code> object, the
+ * <code>ManagedService.updated()</code> method with the new properties is
+ * called. If the <code>delete()</code> method is called on that
+ * <code>Configuration</code> object, <code>ManagedService.updated()</code>
+ * is called with a <code>null</code> for the properties parameter. All these
+ * callbacks must be done asynchronously.
+ *
+ * <p>
+ * The following example shows the code of a serial port that will create a port
+ * depending on configuration information.
+ *
+ * <pre>
+ *
+ * class SerialPort implements ManagedService {
+ *
+ * ServiceRegistration registration;
+ * Hashtable configuration;
+ * CommPortIdentifier id;
+ *
+ * synchronized void open(CommPortIdentifier id,
+ * BundleContext context) {
+ * this.id = id;
+ * registration = context.registerService(
+ * ManagedService.class.getName(),
+ * this,
+ * getDefaults()
+ * );
+ * }
+ *
+ * Hashtable getDefaults() {
+ * Hashtable defaults = new Hashtable();
+ * defaults.put( "port", id.getName() );
+ * defaults.put( "product", "unknown" );
+ * defaults.put( "baud", "9600" );
+ * defaults.put( Constants.SERVICE_PID,
+ * "com.acme.serialport." + id.getName() );
+ * return defaults;
+ * }
+ *
+ * public synchronized void updated(
+ * Dictionary configuration ) {
+ * if ( configuration ==
+ * <code>
+ * null
+ * </code>
+ * )
+ * registration.setProperties( getDefaults() );
+ * else {
+ * setSpeed( configuration.get("baud") );
+ * registration.setProperties( configuration );
+ * }
+ * }
+ * ...
+ * }
+ *
+ * </pre>
+ *
+ * <p>
+ * As a convention, it is recommended that when a Managed Service is updated, it
+ * should copy all the properties it does not recognize into the service
+ * registration properties. This will allow the Configuration Admin service to
+ * set properties on services which can then be used by other applications.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface ManagedService {
+ /**
+ * Update the configuration for a Managed Service.
+ *
+ * <p>
+ * When the implementation of <code>updated(Dictionary)</code> detects any
+ * kind of error in the configuration properties, it should create a new
+ * <code>ConfigurationException</code> which describes the problem. This
+ * can allow a management system to provide useful information to a human
+ * administrator.
+ *
+ * <p>
+ * If this method throws any other <code>Exception</code>, the
+ * Configuration Admin service must catch it and should log it.
+ * <p>
+ * The Configuration Admin service must call this method asynchronously
+ * which initiated the callback. This implies that implementors of Managed
+ * Service can be assured that the callback will not take place during
+ * registration when they execute the registration in a synchronized method.
+ *
+ * @param properties A copy of the Configuration properties, or
+ * <code>null</code>. This argument must not contain the
+ * "service.bundleLocation" property. The value of this property may
+ * be obtained from the <code>Configuration.getBundleLocation</code>
+ * method.
+ * @throws ConfigurationException when the update fails
+ */
+ public void updated(Dictionary properties) throws ConfigurationException;
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ManagedServiceFactory.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ManagedServiceFactory.java
new file mode 100644
index 0000000..8c334c0
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/ManagedServiceFactory.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.cm;
+
+import java.util.Dictionary;
+
+/**
+ * Manage multiple service instances.
+ *
+ * Bundles registering this interface are giving the Configuration Admin service
+ * the ability to create and configure a number of instances of a service that
+ * the implementing bundle can provide. For example, a bundle implementing a
+ * DHCP server could be instantiated multiple times for different interfaces
+ * using a factory.
+ *
+ * <p>
+ * Each of these <i>service instances </i> is represented, in the persistent
+ * storage of the Configuration Admin service, by a factory
+ * <code>Configuration</code> object that has a PID. When such a
+ * <code>Configuration</code> is updated, the Configuration Admin service
+ * calls the <code>ManagedServiceFactory</code> updated method with the new
+ * properties. When <code>updated</code> is called with a new PID, the Managed
+ * Service Factory should create a new factory instance based on these
+ * configuration properties. When called with a PID that it has seen before, it
+ * should update that existing service instance with the new configuration
+ * information.
+ *
+ * <p>
+ * In general it is expected that the implementation of this interface will
+ * maintain a data structure that maps PIDs to the factory instances that it has
+ * created. The semantics of a factory instance are defined by the Managed
+ * Service Factory. However, if the factory instance is registered as a service
+ * object with the service registry, its PID should match the PID of the
+ * corresponding <code>Configuration</code> object (but it should <b>not </b>
+ * be registered as a Managed Service!).
+ *
+ * <p>
+ * An example that demonstrates the use of a factory. It will create serial
+ * ports under command of the Configuration Admin service.
+ *
+ * <pre>
+ *
+ * class SerialPortFactory
+ * implements ManagedServiceFactory {
+ * ServiceRegistration registration;
+ * Hashtable ports;
+ * void start(BundleContext context) {
+ * Hashtable properties = new Hashtable();
+ * properties.put( Constants.SERVICE_PID,
+ * "com.acme.serialportfactory" );
+ * registration = context.registerService(
+ * ManagedServiceFactory.class.getName(),
+ * this,
+ * properties
+ * );
+ * }
+ * public void updated( String pid,
+ * Dictionary properties ) {
+ * String portName = (String) properties.get("port");
+ * SerialPortService port =
+ * (SerialPort) ports.get( pid );
+ * if ( port == null ) {
+ * port = new SerialPortService();
+ * ports.put( pid, port );
+ * port.open();
+ * }
+ * if ( port.getPortName().equals(portName) )
+ * return;
+ * port.setPortName( portName );
+ * }
+ * public void deleted( String pid ) {
+ * SerialPortService port =
+ * (SerialPort) ports.get( pid );
+ * port.close();
+ * ports.remove( pid );
+ * }
+ * ...
+ * }
+ *
+ * </pre>
+ *
+ * @version $Revision: 5673 $
+ */
+public interface ManagedServiceFactory {
+ /**
+ * Return a descriptive name of this factory.
+ *
+ * @return the name for the factory, which might be localized
+ */
+ public String getName();
+
+ /**
+ * Create a new instance, or update the configuration of an existing
+ * instance.
+ *
+ * If the PID of the <code>Configuration</code> object is new for the
+ * Managed Service Factory, then create a new factory instance, using the
+ * configuration <code>properties</code> provided. Else, update the
+ * service instance with the provided <code>properties</code>.
+ *
+ * <p>
+ * If the factory instance is registered with the Framework, then the
+ * configuration <code>properties</code> should be copied to its registry
+ * properties. This is not mandatory and security sensitive properties
+ * should obviously not be copied.
+ *
+ * <p>
+ * If this method throws any <code>Exception</code>, the Configuration
+ * Admin service must catch it and should log it.
+ *
+ * <p>
+ * When the implementation of updated detects any kind of error in the
+ * configuration properties, it should create a new
+ * {@link ConfigurationException} which describes the problem.
+ *
+ * <p>
+ * The Configuration Admin service must call this method asynchronously.
+ * This implies that implementors of the <code>ManagedServiceFactory</code>
+ * class can be assured that the callback will not take place during
+ * registration when they execute the registration in a synchronized method.
+ *
+ * @param pid The PID for this configuration.
+ * @param properties A copy of the configuration properties. This argument
+ * must not contain the service.bundleLocation" property. The value
+ * of this property may be obtained from the
+ * <code>Configuration.getBundleLocation</code> method.
+ * @throws ConfigurationException when the configuration properties are
+ * invalid.
+ */
+ public void updated(String pid, Dictionary properties)
+ throws ConfigurationException;
+
+ /**
+ * Remove a factory instance.
+ *
+ * Remove the factory instance associated with the PID. If the instance was
+ * registered with the service registry, it should be unregistered.
+ * <p>
+ * If this method throws any <code>Exception</code>, the Configuration
+ * Admin service must catch it and should log it.
+ * <p>
+ * The Configuration Admin service must call this method asynchronously.
+ *
+ * @param pid the PID of the service to be removed
+ */
+ public void deleted(String pid);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/package.html b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/package.html
new file mode 100644
index 0000000..443d9c1
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Configuration Admin Package Version 1.2.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.cm; version="[1.2,2.0)"
+</pre>
+</BODY>
+
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/packageinfo b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/packageinfo
new file mode 100644
index 0000000..6ebb891
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/cm/packageinfo
@@ -0,0 +1 @@
+version 1.2.1
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/ComponentConstants.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/ComponentConstants.java
new file mode 100644
index 0000000..2f9d089
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/ComponentConstants.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
+ *
+ * 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.
+ */
+
+package org.osgi.service.component;
+
+/**
+ * Defines standard names for Service Component constants.
+ *
+ * @version $Revision: 6454 $
+ */
+public interface ComponentConstants {
+ /**
+ * Manifest header specifying the XML documents within a bundle that contain
+ * the bundle's Service Component descriptions.
+ * <p>
+ * The attribute value may be retrieved from the <code>Dictionary</code>
+ * object returned by the <code>Bundle.getHeaders</code> method.
+ */
+ public static final String SERVICE_COMPONENT = "Service-Component";
+
+ /**
+ * A component property for a component configuration that contains the name
+ * of the component as specified in the <code>name</code> attribute of the
+ * <code>component</code> element. The value of this property must be of
+ * type <code>String</code>.
+ */
+ public final static String COMPONENT_NAME = "component.name";
+
+ /**
+ * A component property that contains the generated id for a component
+ * configuration. The value of this property must be of type
+ * <code>Long</code>.
+ *
+ * <p>
+ * The value of this property is assigned by the Service Component Runtime
+ * when a component configuration is created. The Service Component Runtime
+ * assigns a unique value that is larger than all previously assigned values
+ * since the Service Component Runtime was started. These values are NOT
+ * persistent across restarts of the Service Component Runtime.
+ */
+ public final static String COMPONENT_ID = "component.id";
+
+ /**
+ * A service registration property for a Component Factory that contains the
+ * value of the <code>factory</code> attribute. The value of this property
+ * must be of type <code>String</code>.
+ */
+ public final static String COMPONENT_FACTORY = "component.factory";
+
+ /**
+ * The suffix for reference target properties. These properties contain the
+ * filter to select the target services for a reference. The value of this
+ * property must be of type <code>String</code>.
+ */
+ public final static String REFERENCE_TARGET_SUFFIX = ".target";
+
+ /**
+ * The reason the component configuration was deactivated is unspecified.
+ *
+ * @since 1.1
+ */
+ public static final int DEACTIVATION_REASON_UNSPECIFIED = 0;
+
+ /**
+ * The component configuration was deactivated because the component was disabled.
+ *
+ * @since 1.1
+ */
+ public static final int DEACTIVATION_REASON_DISABLED = 1;
+
+ /**
+ * The component configuration was deactivated because a reference became unsatisfied.
+ *
+ * @since 1.1
+ */
+ public static final int DEACTIVATION_REASON_REFERENCE = 2;
+
+ /**
+ * The component configuration was deactivated because its configuration was changed.
+ *
+ * @since 1.1
+ */
+ public static final int DEACTIVATION_REASON_CONFIGURATION_MODIFIED = 3;
+
+ /**
+ * The component configuration was deactivated because its configuration was deleted.
+ *
+ * @since 1.1
+ */
+ public static final int DEACTIVATION_REASON_CONFIGURATION_DELETED = 4;
+
+ /**
+ * The component configuration was deactivated because the component was disposed.
+ *
+ * @since 1.1
+ */
+ public static final int DEACTIVATION_REASON_DISPOSED = 5;
+
+ /**
+ * The component configuration was deactivated because the bundle was stopped.
+ *
+ * @since 1.1
+ */
+ public static final int DEACTIVATION_REASON_BUNDLE_STOPPED = 6;
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/ComponentContext.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/ComponentContext.java
new file mode 100644
index 0000000..aad348c
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/ComponentContext.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
+ *
+ * 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.
+ */
+
+package org.osgi.service.component;
+
+import java.util.Dictionary;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A Component Context object is used by a component instance to interact with
+ * its execution context including locating services by reference name. Each
+ * component instance has a unique Component Context.
+ *
+ * <p>
+ * A component instance may have an activate method. If a component instance has
+ * a suitable and accessible activate method, this method will be called when a
+ * component configuration is activated. If the activate method takes a
+ * <code>ComponentContext</code> argument, it will be passed the component
+ * instance's Component Context object. If the activate method takes a
+ * <code>BundleContext</code> argument, it will be passed the component
+ * instance's Bundle Context object. If the activate method takes a
+ * <code>Map</code> argument, it will be passed an unmodifiable Map containing
+ * the component properties.
+ *
+ * <p>
+ * A component instance may have a deactivate method. If a component instance
+ * has a suitable and accessible deactivate method, this method will be called
+ * when the component configuration is deactivated. If the deactivate method
+ * takes a <code>ComponentContext</code> argument, it will be passed the
+ * component instance's Component Context object. If the deactivate method takes
+ * a <code>BundleContext</code> argument, it will be passed the component
+ * instance's Bundle Context object. If the deactivate method takes a
+ * <code>Map</code> argument, it will be passed an unmodifiable Map containing
+ * the component properties. If the deactivate method takes an <code>int</code>
+ * or <code>Integer</code> argument, it will be passed the reason code for the
+ * component instance's deactivation.
+ *
+ * @ThreadSafe
+ * @version $Revision: 6462 $
+ */
+public interface ComponentContext {
+ /**
+ * Returns the component properties for this Component Context.
+ *
+ * @return The properties for this Component Context. The Dictionary is read
+ * only and cannot be modified.
+ */
+ public Dictionary getProperties();
+
+ /**
+ * Returns the service object for the specified reference name.
+ *
+ * <p>
+ * If the cardinality of the reference is <code>0..n</code> or
+ * <code>1..n</code> and multiple services are bound to the reference, the
+ * service with the highest ranking (as specified in its
+ * <code>Constants.SERVICE_RANKING</code> property) is returned. If there is
+ * a tie in ranking, the service with the lowest service ID (as specified in
+ * its <code>Constants.SERVICE_ID</code> property); that is, the service
+ * that was registered first is returned.
+ *
+ * @param name The name of a reference as specified in a
+ * <code>reference</code> element in this component's description.
+ * @return A service object for the referenced service or <code>null</code>
+ * if the reference cardinality is <code>0..1</code> or
+ * <code>0..n</code> and no bound service is available.
+ * @throws ComponentException If the Service Component Runtime catches an
+ * exception while activating the bound service.
+ */
+ public Object locateService(String name);
+
+ /**
+ * Returns the service object for the specified reference name and
+ * <code>ServiceReference</code>.
+ *
+ * @param name The name of a reference as specified in a
+ * <code>reference</code> element in this component's description.
+ * @param reference The <code>ServiceReference</code> to a bound service.
+ * This must be a <code>ServiceReference</code> provided to the
+ * component via the bind or unbind method for the specified
+ * reference name.
+ * @return A service object for the referenced service or <code>null</code>
+ * if the specified <code>ServiceReference</code> is not a bound
+ * service for the specified reference name.
+ * @throws ComponentException If the Service Component Runtime catches an
+ * exception while activating the bound service.
+ */
+ public Object locateService(String name, ServiceReference reference);
+
+ /**
+ * Returns the service objects for the specified reference name.
+ *
+ * @param name The name of a reference as specified in a
+ * <code>reference</code> element in this component's description.
+ * @return An array of service objects for the referenced service or
+ * <code>null</code> if the reference cardinality is
+ * <code>0..1</code> or <code>0..n</code> and no bound service is
+ * available. If the reference cardinality is <code>0..1</code> or
+ * <code>1..1</code> and a bound service is available, the array
+ * will have exactly one element.
+ * @throws ComponentException If the Service Component Runtime catches an
+ * exception while activating a bound service.
+ */
+ public Object[] locateServices(String name);
+
+ /**
+ * Returns the <code>BundleContext</code> of the bundle which contains this
+ * component.
+ *
+ * @return The <code>BundleContext</code> of the bundle containing this
+ * component.
+ */
+ public BundleContext getBundleContext();
+
+ /**
+ * If the component instance is registered as a service using the
+ * <code>servicefactory="true"</code> attribute, then this method
+ * returns the bundle using the service provided by the component instance.
+ * <p>
+ * This method will return <code>null</code> if:
+ * <ul>
+ * <li>The component instance is not a service, then no bundle can be using
+ * it as a service.
+ * <li>The component instance is a service but did not specify the
+ * <code>servicefactory="true"</code> attribute, then all bundles
+ * using the service provided by the component instance will share the same
+ * component instance.
+ * <li>The service provided by the component instance is not currently being
+ * used by any bundle.
+ * </ul>
+ *
+ * @return The bundle using the component instance as a service or
+ * <code>null</code>.
+ */
+ public Bundle getUsingBundle();
+
+ /**
+ * Returns the Component Instance object for the component instance
+ * associated with this Component Context.
+ *
+ * @return The Component Instance object for the component instance.
+ */
+ public ComponentInstance getComponentInstance();
+
+ /**
+ * Enables the specified component name. The specified component name must
+ * be in the same bundle as this component.
+ *
+ * @param name The name of a component or <code>null</code> to indicate all
+ * components in the bundle.
+ */
+ public void enableComponent(String name);
+
+ /**
+ * Disables the specified component name. The specified component name must
+ * be in the same bundle as this component.
+ *
+ * @param name The name of a component.
+ */
+ public void disableComponent(String name);
+
+ /**
+ * If the component instance is registered as a service using the
+ * <code>service</code> element, then this method returns the service
+ * reference of the service provided by this component instance.
+ * <p>
+ * This method will return <code>null</code> if the component instance is
+ * not registered as a service.
+ *
+ * @return The <code>ServiceReference</code> object for the component
+ * instance or <code>null</code> if the component instance is not
+ * registered as a service.
+ */
+ public ServiceReference getServiceReference();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/ComponentException.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/ComponentException.java
new file mode 100644
index 0000000..0aee948
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/ComponentException.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+
+package org.osgi.service.component;
+
+/**
+ * Unchecked exception which may be thrown by the Service Component Runtime.
+ *
+ * @version $Revision: 6083 $
+ */
+public class ComponentException extends RuntimeException {
+ static final long serialVersionUID = -7438212656298726924L;
+
+ /**
+ * Construct a new ComponentException with the specified message and cause.
+ *
+ * @param message The message for the exception.
+ * @param cause The cause of the exception. May be <code>null</code>.
+ */
+ public ComponentException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Construct a new ComponentException with the specified message.
+ *
+ * @param message The message for the exception.
+ */
+ public ComponentException(String message) {
+ super(message);
+ }
+
+ /**
+ * Construct a new ComponentException with the specified cause.
+ *
+ * @param cause The cause of the exception. May be <code>null</code>.
+ */
+ public ComponentException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Returns the cause of this exception or <code>null</code> if no cause was
+ * set.
+ *
+ * @return The cause of this exception or <code>null</code> if no cause was
+ * set.
+ */
+ public Throwable getCause() {
+ return super.getCause();
+ }
+
+ /**
+ * Initializes the cause of this exception to the specified value.
+ *
+ * @param cause The cause of this exception.
+ * @return This exception.
+ * @throws IllegalArgumentException If the specified cause is this
+ * exception.
+ * @throws IllegalStateException If the cause of this exception has already
+ * been set.
+ */
+ public Throwable initCause(Throwable cause) {
+ return super.initCause(cause);
+ }
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/ComponentFactory.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/ComponentFactory.java
new file mode 100644
index 0000000..1c77177
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/ComponentFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+
+package org.osgi.service.component;
+
+import java.util.Dictionary;
+
+/**
+ * When a component is declared with the <code>factory</code> attribute on its
+ * <code>component</code> element, the Service Component Runtime will register
+ * a Component Factory service to allow new component configurations to be
+ * created and activated rather than automatically creating and activating
+ * component configuration as necessary.
+ *
+ * @ThreadSafe
+ * @version $Revision: 5654 $
+ */
+public interface ComponentFactory {
+ /**
+ * Create and activate a new component configuration. Additional properties
+ * may be provided for the component configuration.
+ *
+ * @param properties Additional properties for the component configuration
+ * or <code>null</code> if there are no additional properties.
+ * @return A <code>ComponentInstance</code> object encapsulating the
+ * component instance of the component configuration. The component
+ * configuration has been activated and, if the component specifies
+ * a <code>service</code> element, the component instance has been
+ * registered as a service.
+ * @throws ComponentException If the Service Component Runtime is unable to
+ * activate the component configuration.
+ */
+ public ComponentInstance newInstance(Dictionary properties);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/ComponentInstance.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/ComponentInstance.java
new file mode 100644
index 0000000..f2bd2cb
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/ComponentInstance.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+
+package org.osgi.service.component;
+
+/**
+ * A ComponentInstance encapsulates a component instance of an activated
+ * component configuration. ComponentInstances are created whenever a component
+ * configuration is activated.
+ *
+ * <p>
+ * ComponentInstances are never reused. A new ComponentInstance object will be
+ * created when the component configuration is activated again.
+ *
+ * @ThreadSafe
+ * @version $Revision: 5654 $
+ */
+public interface ComponentInstance {
+ /**
+ * Dispose of the component configuration for this component instance. The
+ * component configuration will be deactivated. If the component
+ * configuration has already been deactivated, this method does nothing.
+ */
+ public void dispose();
+
+ /**
+ * Returns the component instance of the activated component configuration.
+ *
+ * @return The component instance or <code>null</code> if the component
+ * configuration has been deactivated.
+ */
+ public Object getInstance();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/package.html b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/package.html
new file mode 100644
index 0000000..2e7717e
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Service Component Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.component; version="[1.1,2.0)"
+</pre>
+</BODY>
+
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/packageinfo b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/component/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/Constants.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/Constants.java
new file mode 100644
index 0000000..8787256
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/Constants.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.device;
+
+/**
+ * This interface defines standard names for property keys associated with
+ * {@link Device} and {@link Driver} services.
+ *
+ * <p>
+ * The values associated with these keys are of type <code>java.lang.String</code>,
+ * unless otherwise stated.
+ *
+ * @version $Revision: 5673 $
+ * @since 1.1
+ * @see Device
+ * @see Driver
+ */
+public interface Constants {
+ /**
+ * Property (named "DRIVER_ID") identifying a driver.
+ *
+ * <p>
+ * A <code>DRIVER_ID</code> should start with the reversed domain name of the
+ * company that implemented the driver (e.g., <code>com.acme</code>), and
+ * must meet the following requirements:
+ *
+ * <ul>
+ * <li>It must be independent of the location from where it is obtained.
+ * <li>It must be independent of the {@link DriverLocator} service that
+ * downloaded it.
+ * <li>It must be unique.
+ * <li>It must be different for different revisions of the same driver.
+ * </ul>
+ *
+ * <p>
+ * This property is mandatory, i.e., every <code>Driver</code> service must be
+ * registered with it.
+ */
+ public static final String DRIVER_ID = "DRIVER_ID";
+ /**
+ * Property (named "DEVICE_CATEGORY") containing a human readable
+ * description of the device categories implemented by a device. This
+ * property is of type <code>String[]</code>
+ *
+ * <p>
+ * Services registered with this property will be treated as devices and
+ * discovered by the device manager
+ */
+ public static final String DEVICE_CATEGORY = "DEVICE_CATEGORY";
+ /**
+ * Property (named "DEVICE_SERIAL") specifying a device's serial
+ * number.
+ */
+ public static final String DEVICE_SERIAL = "DEVICE_SERIAL";
+ /**
+ * Property (named "DEVICE_DESCRIPTION") containing a human
+ * readable string describing the actual hardware device.
+ */
+ public static final String DEVICE_DESCRIPTION = "DEVICE_DESCRIPTION";
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/Device.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/Device.java
new file mode 100644
index 0000000..2af0330
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/Device.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.device;
+
+/**
+ * <p>
+ * Interface for identifying device services.
+ *
+ * <p>
+ * A service must implement this interface or use the
+ * {@link Constants#DEVICE_CATEGORY} registration property to indicate that it
+ * is a device. Any services implementing this interface or registered with the
+ * <code>DEVICE_CATEGORY</code> property will be discovered by the device
+ * manager.
+ *
+ * <p>
+ * Device services implementing this interface give the device manager the
+ * opportunity to indicate to the device that no drivers were found that could
+ * (further) refine it. In this case, the device manager calls the
+ * {@link #noDriverFound} method on the <code>Device</code> object.
+ *
+ * <p>
+ * Specialized device implementations will extend this interface by adding
+ * methods appropriate to their device category to it.
+ *
+ * @version $Revision: 5654 $
+ * @see Driver
+ * @ThreadSafe
+ */
+public interface Device {
+ /**
+ * Return value from {@link Driver#match} indicating that the driver cannot
+ * refine the device presented to it by the device manager.
+ *
+ * The value is zero.
+ */
+ public static final int MATCH_NONE = 0;
+
+ /**
+ * Indicates to this <code>Device</code> object that the device manager has
+ * failed to attach any drivers to it.
+ *
+ * <p>
+ * If this <code>Device</code> object can be configured differently, the
+ * driver that registered this <code>Device</code> object may unregister it
+ * and register a different Device service instead.
+ */
+ public void noDriverFound();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/Driver.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/Driver.java
new file mode 100644
index 0000000..98e3617
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/Driver.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.device;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A <code>Driver</code> service object must be registered by each Driver bundle
+ * wishing to attach to Device services provided by other drivers. For each
+ * newly discovered {@link Device} object, the device manager enters a bidding
+ * phase. The <code>Driver</code> object whose {@link #match} method bids the
+ * highest for a particular <code>Device</code> object will be instructed by the
+ * device manager to attach to the <code>Device</code> object.
+ *
+ * @version $Revision: 5654 $
+ * @see Device
+ * @see DriverLocator
+ * @ThreadSafe
+ */
+public interface Driver {
+ /**
+ * Checks whether this Driver service can be attached to the Device service.
+ *
+ * The Device service is represented by the given {@link ServiceReference}
+ * and returns a value indicating how well this driver can support the given
+ * Device service, or {@link Device#MATCH_NONE} if it cannot support the
+ * given Device service at all.
+ *
+ * <p>
+ * The return value must be one of the possible match values defined in the
+ * device category definition for the given Device service, or
+ * <code>Device.MATCH_NONE</code> if the category of the Device service is
+ * not recognized.
+ *
+ * <p>
+ * In order to make its decision, this Driver service may examine the
+ * properties associated with the given Device service, or may get the
+ * referenced service object (representing the actual physical device) to
+ * talk to it, as long as it ungets the service and returns the physical
+ * device to a normal state before this method returns.
+ *
+ * <p>
+ * A Driver service must always return the same match code whenever it is
+ * presented with the same Device service.
+ *
+ * <p>
+ * The match function is called by the device manager during the matching
+ * process.
+ *
+ * @param reference the <code>ServiceReference</code> object of the device
+ * to match
+ *
+ * @return value indicating how well this driver can support the given
+ * Device service, or <code>Device.MATCH_NONE</code> if it cannot
+ * support the Device service at all
+ *
+ * @throws java.lang.Exception if this Driver service cannot examine the
+ * Device service
+ */
+ public int match(ServiceReference reference) throws Exception;
+
+ /**
+ * Attaches this Driver service to the Device service represented by the
+ * given <code>ServiceReference</code> object.
+ *
+ * <p>
+ * A return value of <code>null</code> indicates that this Driver service
+ * has successfully attached to the given Device service. If this Driver
+ * service is unable to attach to the given Device service, but knows of a
+ * more suitable Driver service, it must return the <code>DRIVER_ID</code>
+ * of that Driver service. This allows for the implementation of referring
+ * drivers whose only purpose is to refer to other drivers capable of
+ * handling a given Device service.
+ *
+ * <p>
+ * After having attached to the Device service, this driver may register the
+ * underlying device as a new service exposing driver-specific
+ * functionality.
+ *
+ * <p>
+ * This method is called by the device manager.
+ *
+ * @param reference the <code>ServiceReference</code> object of the device
+ * to attach to
+ *
+ * @return <code>null</code> if this Driver service has successfully
+ * attached to the given Device service, or the
+ * <code>DRIVER_ID</code> of a more suitable driver
+ *
+ * @throws java.lang.Exception if the driver cannot attach to the given
+ * device and does not know of a more suitable driver
+ */
+ public String attach(ServiceReference reference) throws Exception;
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/DriverLocator.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/DriverLocator.java
new file mode 100644
index 0000000..2726b99
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/DriverLocator.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.device;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Dictionary;
+
+/**
+ * A Driver Locator service can find and load device driver bundles given a
+ * property set. Each driver is represented by a unique <code>DRIVER_ID</code>.
+ * <p>
+ * Driver Locator services provide the mechanism for dynamically downloading new
+ * device driver bundles into an OSGi environment. They are supplied by
+ * providers and encapsulate all provider-specific details related to the
+ * location and acquisition of driver bundles.
+ *
+ * @version $Revision: 5654 $
+ * @see Driver
+ * @ThreadSafe
+ */
+public interface DriverLocator {
+ /**
+ * Returns an array of <code>DRIVER_ID</code> strings of drivers capable of
+ * attaching to a device with the given properties.
+ *
+ * <p>
+ * The property keys in the specified <code>Dictionary</code> objects are
+ * case-insensitive.
+ *
+ * @param props the properties of the device for which a driver is sought
+ * @return array of driver <code>DRIVER_ID</code> strings of drivers capable
+ * of attaching to a Device service with the given properties, or
+ * <code>null</code> if this Driver Locator service does not know of
+ * any such drivers
+ */
+ public String[] findDrivers(Dictionary props);
+
+ /**
+ * Get an <code>InputStream</code> from which the driver bundle providing a
+ * driver with the giving <code>DRIVER_ID</code> can be installed.
+ *
+ * @param id the <code>DRIVER_ID</code> of the driver that needs to be
+ * installed.
+ * @return An <code>InputStream</code> object from which the driver bundle
+ * can be installed or <code>null</code> if the driver with the
+ * given ID cannot be located
+ * @throws java.io.IOException the input stream for the bundle cannot be
+ * created
+ */
+ public InputStream loadDriver(String id) throws IOException;
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/DriverSelector.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/DriverSelector.java
new file mode 100644
index 0000000..59fd0b9
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/DriverSelector.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.device;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * When the device manager detects a new Device service, it calls all registered
+ * Driver services to determine if anyone matches the Device service. If at
+ * least one Driver service matches, the device manager must choose one. If
+ * there is a Driver Selector service registered with the Framework, the device
+ * manager will ask it to make the selection. If there is no Driver Selector
+ * service, or if it returns an invalid result, or throws an
+ * <code>Exception</code>, the device manager uses the default selection
+ * strategy.
+ *
+ * @version $Revision: 5654 $
+ * @since 1.1
+ * @ThreadSafe
+ */
+public interface DriverSelector {
+ /**
+ * Return value from <code>DriverSelector.select</code>, if no Driver
+ * service should be attached to the Device service. The value is -1.
+ */
+ public static final int SELECT_NONE = -1;
+
+ /**
+ * Select one of the matching Driver services. The device manager calls this
+ * method if there is at least one driver bidding for a device. Only Driver
+ * services that have responded with nonzero (not {@link Device#MATCH_NONE})
+ * <code></code> match values will be included in the list.
+ *
+ * @param reference the <code>ServiceReference</code> object of the Device
+ * service.
+ * @param matches the array of all non-zero matches.
+ * @return index into the array of <code>Match</code> objects, or
+ * <code>SELECT_NONE</code> if no Driver service should be attached
+ */
+ public int select(ServiceReference reference, Match[] matches);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/Match.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/Match.java
new file mode 100644
index 0000000..6410659
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/Match.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.device;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Instances of <code>Match</code> are used in the {@link DriverSelector#select}
+ * method to identify Driver services matching a Device service.
+ *
+ * @version $Revision: 5654 $
+ * @since 1.1
+ * @see DriverSelector
+ * @ThreadSafe
+ */
+public interface Match {
+ /**
+ * Return the reference to a Driver service.
+ *
+ * @return <code>ServiceReference</code> object to a Driver service.
+ */
+ public ServiceReference getDriver();
+
+ /**
+ * Return the match value of this object.
+ *
+ * @return the match value returned by this Driver service.
+ */
+ public int getMatchValue();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/package.html b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/package.html
new file mode 100644
index 0000000..7647c20
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Device Access Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.device; version="[1.1,2.0)"
+</pre>
+</BODY>
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/packageinfo b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/device/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/Event.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/Event.java
new file mode 100644
index 0000000..42cdb1b
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/Event.java
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) OSGi Alliance (2005, 2009). All Rights Reserved.
+ *
+ * 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.
+ */
+
+package org.osgi.service.event;
+
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.osgi.framework.Filter;
+
+/**
+ * An event.
+ *
+ * <code>Event</code> objects are delivered to <code>EventHandler</code>
+ * services which subscribe to the topic of the event.
+ *
+ * @Immutable
+ * @version $Revision: 7003 $
+ */
+public class Event {
+ /**
+ * The topic of this event.
+ */
+ private final String topic;
+ /**
+ * The properties carried by this event. Keys are strings and values are
+ * objects
+ */
+ private final Map /* <String,Object> */properties;
+
+ /**
+ * Constructs an event.
+ *
+ * @param topic The topic of the event.
+ * @param properties The event's properties (may be <code>null</code>). A
+ * property whose key is not of type <code>String</code> will be
+ * ignored.
+ * @throws IllegalArgumentException If topic is not a valid topic name.
+ * @since 1.2
+ */
+ public Event(String topic, Map/* <String,Object> */properties) {
+ validateTopicName(topic);
+ this.topic = topic;
+ int size = (properties == null) ? 1 : (properties.size() + 1);
+ Map p = new HashMap(size);
+ if (properties != null) {
+ for (Iterator iter = properties.keySet().iterator(); iter.hasNext();) {
+ Object key = iter.next();
+ if (key instanceof String) {
+ Object value = properties.get(key);
+ p.put(key, value);
+ }
+ }
+ }
+ p.put(EventConstants.EVENT_TOPIC, topic);
+ this.properties = p; // safely publish the map
+ }
+
+ /**
+ * Constructs an event.
+ *
+ * @param topic The topic of the event.
+ * @param properties The event's properties (may be <code>null</code>). A
+ * property whose key is not of type <code>String</code> will be
+ * ignored.
+ * @throws IllegalArgumentException If topic is not a valid topic name.
+ */
+ public Event(String topic, Dictionary/* <String,Object> */properties) {
+ validateTopicName(topic);
+ this.topic = topic;
+ int size = (properties == null) ? 1 : (properties.size() + 1);
+ Map p = new HashMap(size);
+ if (properties != null) {
+ for (Enumeration e = properties.keys(); e.hasMoreElements();) {
+ Object key = e.nextElement();
+ if (key instanceof String) {
+ Object value = properties.get(key);
+ p.put(key, value);
+ }
+ }
+ }
+ p.put(EventConstants.EVENT_TOPIC, topic);
+ this.properties = p; // safely publish the map
+ }
+
+ /**
+ * Retrieves a property.
+ *
+ * @param name the name of the property to retrieve
+ * @return The value of the property, or <code>null</code> if not found.
+ */
+ public final Object getProperty(String name) {
+ return properties.get(name);
+ }
+
+ /**
+ * Returns a list of this event's property names.
+ *
+ * @return A non-empty array with one element per property.
+ */
+ public final String[] getPropertyNames() {
+ return (String[]) properties.keySet().toArray(
+ new String[properties.size()]);
+ }
+
+ /**
+ * Returns the topic of this event.
+ *
+ * @return The topic of this event.
+ */
+ public final String getTopic() {
+ return topic;
+ }
+
+ /**
+ * Tests this event's properties against the given filter using a case
+ * sensitive match.
+ *
+ * @param filter The filter to test.
+ * @return true If this event's properties match the filter, false
+ * otherwise.
+ */
+ public final boolean matches(Filter filter) {
+ return filter.matchCase(new UnmodifiableDictionary(properties));
+ }
+
+ /**
+ * Compares this <code>Event</code> object to another object.
+ *
+ * <p>
+ * An event is considered to be <b>equal to</b> another event if the topic
+ * is equal and the properties are equal.
+ *
+ * @param object The <code>Event</code> object to be compared.
+ * @return <code>true</code> if <code>object</code> is a <code>Event</code>
+ * and is equal to this object; <code>false</code> otherwise.
+ */
+ public boolean equals(Object object) {
+ if (object == this) { // quick test
+ return true;
+ }
+
+ if (!(object instanceof Event)) {
+ return false;
+ }
+
+ Event event = (Event) object;
+ return topic.equals(event.topic) && properties.equals(event.properties);
+ }
+
+ /**
+ * Returns a hash code value for the object.
+ *
+ * @return An integer which is a hash code value for this object.
+ */
+ public int hashCode() {
+ int h = 31 * 17 + topic.hashCode();
+ h = 31 * h + properties.hashCode();
+ return h;
+ }
+
+ /**
+ * Returns the string representation of this event.
+ *
+ * @return The string representation of this event.
+ */
+ public String toString() {
+ return getClass().getName() + " [topic=" + topic + "]";
+ }
+
+ /**
+ * Called by the constructor to validate the topic name.
+ *
+ * @param topic The topic name to validate.
+ * @throws IllegalArgumentException If the topic name is invalid.
+ */
+ private static void validateTopicName(String topic) {
+ char[] chars = topic.toCharArray();
+ int length = chars.length;
+ if (length == 0) {
+ throw new IllegalArgumentException("empty topic");
+ }
+ for (int i = 0; i < length; i++) {
+ char ch = chars[i];
+ if (ch == '/') {
+ // Can't start or end with a '/' but anywhere else is okay
+ if (i == 0 || (i == length - 1)) {
+ throw new IllegalArgumentException(
+ "invalid topic: "
+ + topic);
+ }
+ // Can't have "//" as that implies empty token
+ if (chars[i-1] == '/') {
+ throw new IllegalArgumentException(
+ "invalid topic: "
+ + topic);
+ }
+ continue;
+ }
+ if (('A' <= ch) && (ch <= 'Z')) {
+ continue;
+ }
+ if (('a' <= ch) && (ch <= 'z')) {
+ continue;
+ }
+ if (('0' <= ch) && (ch <= '9')) {
+ continue;
+ }
+ if ((ch == '_') || (ch == '-')) {
+ continue;
+ }
+ throw new IllegalArgumentException("invalid topic: " + topic);
+ }
+ }
+
+ /**
+ * Unmodifiable wrapper for Dictionary.
+ */
+ private static class UnmodifiableDictionary extends Dictionary {
+ private final Map wrapped;
+ UnmodifiableDictionary(Map wrapped) {
+ this.wrapped = wrapped;
+ }
+ public Enumeration elements() {
+ return Collections.enumeration(wrapped.values());
+ }
+ public Object get(Object key) {
+ return wrapped.get(key);
+ }
+ public boolean isEmpty() {
+ return wrapped.isEmpty();
+ }
+ public Enumeration keys() {
+ return Collections.enumeration(wrapped.keySet());
+ }
+ public Object put(Object key, Object value) {
+ throw new UnsupportedOperationException();
+ }
+ public Object remove(Object key) {
+ throw new UnsupportedOperationException();
+ }
+ public int size() {
+ return wrapped.size();
+ }
+ }
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/EventAdmin.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/EventAdmin.java
new file mode 100644
index 0000000..f48a10f
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/EventAdmin.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+
+package org.osgi.service.event;
+
+/**
+ * The Event Admin service. Bundles wishing to publish events must obtain the
+ * Event Admin service and call one of the event delivery methods.
+ *
+ * @ThreadSafe
+ * @version $Revision: 5673 $
+ */
+public interface EventAdmin {
+ /**
+ * Initiate asynchronous delivery of an event. This method returns to the
+ * caller before delivery of the event is completed.
+ *
+ * @param event The event to send to all listeners which subscribe to the
+ * topic of the event.
+ *
+ * @throws SecurityException If the caller does not have
+ * <code>TopicPermission[topic,PUBLISH]</code> for the topic
+ * specified in the event.
+ */
+ void postEvent(Event event);
+
+ /**
+ * Initiate synchronous delivery of an event. This method does not return to
+ * the caller until delivery of the event is completed.
+ *
+ * @param event The event to send to all listeners which subscribe to the
+ * topic of the event.
+ *
+ * @throws SecurityException If the caller does not have
+ * <code>TopicPermission[topic,PUBLISH]</code> for the topic
+ * specified in the event.
+ */
+ void sendEvent(Event event);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/EventConstants.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/EventConstants.java
new file mode 100644
index 0000000..ac6b484
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/EventConstants.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+
+package org.osgi.service.event;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+
+/**
+ * Defines standard names for <code>EventHandler</code> properties.
+ *
+ * @version $Revision: 6080 $
+ */
+public interface EventConstants {
+
+ /**
+ * Service registration property (named <code>event.topics</code>)
+ * specifying the <code>Event</code> topics of interest to a Event Handler
+ * service.
+ * <p>
+ * Event handlers SHOULD be registered with this property. The value of the
+ * property is a string or an array of strings that describe the topics in
+ * which the handler is interested. An asterisk ('*') may be used as a
+ * trailing wildcard. Event Handlers which do not have a value for this
+ * property must not receive events. More precisely, the value of each
+ * string must conform to the following grammar:
+ *
+ * <pre>
+ * topic-description := '*' | topic ( '/*' )?
+ * topic := token ( '/' token )*
+ * </pre>
+ *
+ * @see Event
+ */
+ public static final String EVENT_TOPIC = "event.topics";
+
+ /**
+ * Service Registration property (named <code>event.filter</code>)
+ * specifying a filter to further select <code>Event</code> s of interest to
+ * a Event Handler service.
+ * <p>
+ * Event handlers MAY be registered with this property. The value of this
+ * property is a string containing an LDAP-style filter specification. Any
+ * of the event's properties may be used in the filter expression. Each
+ * event handler is notified for any event which belongs to the topics in
+ * which the handler has expressed an interest. If the event handler is also
+ * registered with this service property, then the properties of the event
+ * must also match the filter for the event to be delivered to the event
+ * handler.
+ * <p>
+ * If the filter syntax is invalid, then the Event Handler must be ignored
+ * and a warning should be logged.
+ *
+ * @see Event
+ * @see Filter
+ */
+ public static final String EVENT_FILTER = "event.filter";
+
+ /**
+ * The Distinguished Names of the signers of the bundle relevant to the
+ * event. The type of the value for this event property is
+ * <code>String</code> if there is a single signer or <code>String[]</code>
+ * if there are multiple signers.
+ */
+ public static final String BUNDLE_SIGNER = "bundle.signer";
+
+ /**
+ * The Bundle Symbolic Name of the bundle relevant to the event. The type of
+ * the value for this event property is <code>String</code>.
+ */
+ public static final String BUNDLE_SYMBOLICNAME = "bundle.symbolicName";
+
+ /**
+ * The Bundle id of the bundle relevant to the event. The type of the value
+ * for this event property is <code>Long</code>.
+ *
+ * @since 1.1
+ */
+ public static final String BUNDLE_ID = "bundle.id";
+
+ /**
+ * The Bundle object of the bundle relevant to the event. The type of the
+ * value for this event property is {@link Bundle}.
+ *
+ * @since 1.1
+ */
+ public static final String BUNDLE = "bundle";
+
+ /**
+ * The version of the bundle relevant to the event. The type of the value
+ * for this event property is {@link Version}.
+ *
+ * @since 1.2
+ */
+ public static final String BUNDLE_VERSION = "bundle.version";
+
+ /**
+ * The forwarded event object. Used when rebroadcasting an event that was
+ * sent via some other event mechanism. The type of the value for this event
+ * property is <code>Object</code>.
+ */
+ public static final String EVENT = "event";
+
+ /**
+ * An exception or error. The type of the value for this event property is
+ * <code>Throwable</code>.
+ */
+ public static final String EXCEPTION = "exception";
+
+ /**
+ * The name of the exception type. Must be equal to the name of the class of
+ * the exception in the event property {@link #EXCEPTION}. The type of the
+ * value for this event property is <code>String</code>.
+ *
+ * @since 1.1
+ */
+ public static final String EXCEPTION_CLASS = "exception.class";
+
+ /**
+ * The exception message. Must be equal to the result of calling
+ * <code>getMessage()</code> on the exception in the event property
+ * {@link #EXCEPTION}. The type of the value for this event property is
+ * <code>String</code>.
+ */
+ public static final String EXCEPTION_MESSAGE = "exception.message";
+
+ /**
+ * A human-readable message that is usually not localized. The type of the
+ * value for this event property is <code>String</code>.
+ */
+ public static final String MESSAGE = "message";
+
+ /**
+ * A service reference. The type of the value for this event property is
+ * {@link ServiceReference}.
+ */
+ public static final String SERVICE = "service";
+
+ /**
+ * A service's id. The type of the value for this event property is
+ * <code>Long</code>.
+ */
+ public static final String SERVICE_ID = Constants.SERVICE_ID;
+
+ /**
+ * A service's objectClass. The type of the value for this event property is
+ * <code>String[]</code>.
+ */
+ public static final String SERVICE_OBJECTCLASS = "service.objectClass";
+
+ /**
+ * A service's persistent identity. The type of the value for this event
+ * property is <code>String</code>.
+ */
+ public static final String SERVICE_PID = Constants.SERVICE_PID;
+
+ /**
+ * The time when the event occurred, as reported by
+ * <code>System.currentTimeMillis()</code>. The type of the value for this
+ * event property is <code>Long</code>.
+ */
+ public static final String TIMESTAMP = "timestamp";
+
+ /**
+ * This constant was released with an incorrectly spelled name. It has been
+ * replaced by {@link #EXCEPTION_CLASS}
+ *
+ * @deprecated As of 1.1, replaced by EXCEPTION_CLASS
+ */
+ public static final String EXECPTION_CLASS = "exception.class";
+}
\ No newline at end of file
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/EventHandler.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/EventHandler.java
new file mode 100644
index 0000000..d25782f
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/EventHandler.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+
+package org.osgi.service.event;
+
+/**
+ * Listener for Events.
+ *
+ * <p>
+ * <code>EventHandler</code> objects are registered with the Framework service
+ * registry and are notified with an <code>Event</code> object when an event
+ * is sent or posted.
+ * <p>
+ * <code>EventHandler</code> objects can inspect the received
+ * <code>Event</code> object to determine its topic and properties.
+ *
+ * <p>
+ * <code>EventHandler</code> objects must be registered with a service
+ * property {@link EventConstants#EVENT_TOPIC} whose value is the list of topics
+ * in which the event handler is interested.
+ * <p>
+ * For example:
+ *
+ * <pre>
+ * String[] topics = new String[] {"com/isv/*"};
+ * Hashtable ht = new Hashtable();
+ * ht.put(EventConstants.EVENT_TOPIC, topics);
+ * context.registerService(EventHandler.class.getName(), this, ht);
+ * </pre>
+ *
+ * Event Handler services can also be registered with an
+ * {@link EventConstants#EVENT_FILTER} service property to further filter the
+ * events. If the syntax of this filter is invalid, then the Event Handler must
+ * be ignored by the Event Admin service. The Event Admin service should log a
+ * warning.
+ * <p>
+ * Security Considerations. Bundles wishing to monitor <code>Event</code>
+ * objects will require <code>ServicePermission[EventHandler,REGISTER]</code>
+ * to register an <code>EventHandler</code> service. The bundle must also have
+ * <code>TopicPermission[topic,SUBSCRIBE]</code> for the topic specified in
+ * the event in order to receive the event.
+ *
+ * @see Event
+ *
+ * @ThreadSafe
+ * @version $Revision: 5673 $
+ */
+public interface EventHandler {
+ /**
+ * Called by the {@link EventAdmin} service to notify the listener of an
+ * event.
+ *
+ * @param event The event that occurred.
+ */
+ void handleEvent(Event event);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/TopicPermission.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/TopicPermission.java
new file mode 100644
index 0000000..ae0d190
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/TopicPermission.java
@@ -0,0 +1,529 @@
+/*
+ * Copyright (c) OSGi Alliance (2005, 2009). All Rights Reserved.
+ *
+ * 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.
+ */
+
+package org.osgi.service.event;
+
+import java.io.IOException;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * A bundle's authority to publish or subscribe to event on a topic.
+ *
+ * <p>
+ * A topic is a slash-separated string that defines a topic.
+ * <p>
+ * For example:
+ *
+ * <pre>
+ * org / osgi / service / foo / FooEvent / ACTION
+ * </pre>
+ *
+ * <p>
+ * <code>TopicPermission</code> has two actions: <code>publish</code> and
+ * <code>subscribe</code>.
+ *
+ * @ThreadSafe
+ * @version $Revision: 6381 $
+ */
+public final class TopicPermission extends Permission {
+ static final long serialVersionUID = -5855563886961618300L;
+ /**
+ * The action string <code>publish</code>.
+ */
+ public final static String PUBLISH = "publish";
+ /**
+ * The action string <code>subscribe</code>.
+ */
+ public final static String SUBSCRIBE = "subscribe";
+ private final static int ACTION_PUBLISH = 0x00000001;
+ private final static int ACTION_SUBSCRIBE = 0x00000002;
+ private final static int ACTION_ALL = ACTION_PUBLISH
+ | ACTION_SUBSCRIBE;
+ private final static int ACTION_NONE = 0;
+ /**
+ * The actions mask.
+ */
+ private transient int action_mask;
+
+ /**
+ * prefix if the name is wildcarded.
+ */
+ private transient volatile String prefix;
+
+ /**
+ * The actions in canonical form.
+ *
+ * @serial
+ */
+ private volatile String actions = null;
+
+ /**
+ * Defines the authority to publich and/or subscribe to a topic within the
+ * EventAdmin service.
+ * <p>
+ * The name is specified as a slash-separated string. Wildcards may be used.
+ * For example:
+ *
+ * <pre>
+ * org/osgi/service/fooFooEvent/ACTION
+ * com/isv/*
+ * *
+ * </pre>
+ *
+ * <p>
+ * A bundle that needs to publish events on a topic must have the
+ * appropriate <code>TopicPermission</code> for that topic; similarly, a
+ * bundle that needs to subscribe to events on a topic must have the
+ * appropriate <code>TopicPermssion</code> for that topic.
+ * <p>
+ *
+ * @param name Topic name.
+ * @param actions <code>publish</code>,<code>subscribe</code> (canonical
+ * order).
+ */
+ public TopicPermission(String name, String actions) {
+ this(name, parseActions(actions));
+ }
+
+ /**
+ * Package private constructor used by TopicPermissionCollection.
+ *
+ * @param name class name
+ * @param mask action mask
+ */
+ TopicPermission(String name, int mask) {
+ super(name);
+ setTransients(mask);
+ }
+
+ /**
+ * Called by constructors and when deserialized.
+ *
+ * @param name topic name
+ * @param mask action mask
+ */
+ private synchronized void setTransients(final int mask) {
+ final String name = getName();
+ if ((name == null) || name.length() == 0) {
+ throw new IllegalArgumentException("invalid name");
+ }
+
+ if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+ throw new IllegalArgumentException("invalid action string");
+ }
+ action_mask = mask;
+
+ if (name.equals("*")) {
+ prefix = "";
+ }
+ else {
+ if (name.endsWith("/*")) {
+ prefix = name.substring(0, name.length() - 1);
+ }
+ else {
+ prefix = null;
+ }
+ }
+ }
+
+ /**
+ * Returns the current action mask.
+ * <p>
+ * Used by the TopicPermissionCollection class.
+ *
+ * @return Current action mask.
+ */
+ synchronized int getActionsMask() {
+ return action_mask;
+ }
+
+ /**
+ * Parse action string into action mask.
+ *
+ * @param actions Action string.
+ * @return action mask.
+ */
+ private static int parseActions(final String actions) {
+ boolean seencomma = false;
+ int mask = ACTION_NONE;
+ if (actions == null) {
+ return mask;
+ }
+ char[] a = actions.toCharArray();
+ int i = a.length - 1;
+ if (i < 0)
+ return mask;
+ while (i != -1) {
+ char c;
+ // skip whitespace
+ while ((i != -1)
+ && ((c = a[i]) == ' ' || c == '\r' || c == '\n'
+ || c == '\f' || c == '\t'))
+ i--;
+ // check for the known strings
+ int matchlen;
+ if (i >= 8 && (a[i - 8] == 's' || a[i - 8] == 'S')
+ && (a[i - 7] == 'u' || a[i - 7] == 'U')
+ && (a[i - 6] == 'b' || a[i - 6] == 'B')
+ && (a[i - 5] == 's' || a[i - 5] == 'S')
+ && (a[i - 4] == 'c' || a[i - 4] == 'C')
+ && (a[i - 3] == 'r' || a[i - 3] == 'R')
+ && (a[i - 2] == 'i' || a[i - 2] == 'I')
+ && (a[i - 1] == 'b' || a[i - 1] == 'B')
+ && (a[i] == 'e' || a[i] == 'E')) {
+ matchlen = 9;
+ mask |= ACTION_SUBSCRIBE;
+ }
+ else
+ if (i >= 6 && (a[i - 6] == 'p' || a[i - 6] == 'P')
+ && (a[i - 5] == 'u' || a[i - 5] == 'U')
+ && (a[i - 4] == 'b' || a[i - 4] == 'B')
+ && (a[i - 3] == 'l' || a[i - 3] == 'L')
+ && (a[i - 2] == 'i' || a[i - 2] == 'I')
+ && (a[i - 1] == 's' || a[i - 1] == 'S')
+ && (a[i] == 'h' || a[i] == 'H')) {
+ matchlen = 7;
+ mask |= ACTION_PUBLISH;
+ }
+ else {
+ // parse error
+ throw new IllegalArgumentException("invalid permission: "
+ + actions);
+ }
+ // make sure we didn't just match the tail of a word
+ // like "ackbarfpublish". Also, skip to the comma.
+ seencomma = false;
+ while (i >= matchlen && !seencomma) {
+ switch (a[i - matchlen]) {
+ case ',' :
+ seencomma = true;
+ /* FALLTHROUGH */
+ case ' ' :
+ case '\r' :
+ case '\n' :
+ case '\f' :
+ case '\t' :
+ break;
+ default :
+ throw new IllegalArgumentException(
+ "invalid permission: " + actions);
+ }
+ i--;
+ }
+ // point i at the location of the comma minus one (or -1).
+ i -= matchlen;
+ }
+ if (seencomma) {
+ throw new IllegalArgumentException("invalid permission: " + actions);
+ }
+ return mask;
+ }
+
+ /**
+ * Determines if the specified permission is implied by this object.
+ *
+ * <p>
+ * This method checks that the topic name of the target is implied by the
+ * topic name of this object. The list of <code>TopicPermission</code>
+ * actions must either match or allow for the list of the target object to
+ * imply the target <code>TopicPermission</code> action.
+ *
+ * <pre>
+ * x/y/*,"publish" -> x/y/z,"publish" is true
+ * *,"subscribe" -> x/y,"subscribe" is true
+ * *,"publish" -> x/y,"subscribe" is false
+ * x/y,"publish" -> x/y/z,"publish" is false
+ * </pre>
+ *
+ * @param p The target permission to interrogate.
+ * @return <code>true</code> if the specified <code>TopicPermission</code>
+ * action is implied by this object; <code>false</code> otherwise.
+ */
+ public boolean implies(Permission p) {
+ if (p instanceof TopicPermission) {
+ TopicPermission requested = (TopicPermission) p;
+ int requestedMask = requested.getActionsMask();
+ if ((getActionsMask() & requestedMask) == requestedMask) {
+ String requestedName = requested.getName();
+ String pre = prefix;
+ if (pre != null) {
+ return requestedName.startsWith(pre);
+ }
+
+ return requestedName.equals(getName());
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns the canonical string representation of the
+ * <code>TopicPermission</code> actions.
+ *
+ * <p>
+ * Always returns present <code>TopicPermission</code> actions in the
+ * following order: <code>publish</code>,<code>subscribe</code>.
+ *
+ * @return Canonical string representation of the
+ * <code>TopicPermission</code> actions.
+ */
+ public String getActions() {
+ String result = actions;
+ if (result == null) {
+ StringBuffer sb = new StringBuffer();
+ boolean comma = false;
+ int mask = getActionsMask();
+ if ((mask & ACTION_PUBLISH) == ACTION_PUBLISH) {
+ sb.append(PUBLISH);
+ comma = true;
+ }
+ if ((mask & ACTION_SUBSCRIBE) == ACTION_SUBSCRIBE) {
+ if (comma)
+ sb.append(',');
+ sb.append(SUBSCRIBE);
+ }
+ actions = result = sb.toString();
+ }
+ return result;
+ }
+
+ /**
+ * Returns a new <code>PermissionCollection</code> object suitable for
+ * storing <code>TopicPermission</code> objects.
+ *
+ * @return A new <code>PermissionCollection</code> object.
+ */
+ public PermissionCollection newPermissionCollection() {
+ return new TopicPermissionCollection();
+ }
+
+ /**
+ * Determines the equality of two <code>TopicPermission</code> objects.
+ *
+ * This method checks that specified <code>TopicPermission</code> has the
+ * same topic name and actions as this <code>TopicPermission</code> object.
+ *
+ * @param obj The object to test for equality with this
+ * <code>TopicPermission</code> object.
+ * @return <code>true</code> if <code>obj</code> is a
+ * <code>TopicPermission</code>, and has the same topic name and
+ * actions as this <code>TopicPermission</code> object;
+ * <code>false</code> otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof TopicPermission)) {
+ return false;
+ }
+ TopicPermission tp = (TopicPermission) obj;
+ return (getActionsMask() == tp.getActionsMask())
+ && getName().equals(tp.getName());
+ }
+
+ /**
+ * Returns the hash code value for this object.
+ *
+ * @return A hash code value for this object.
+ */
+ public int hashCode() {
+ int h = 31 * 17 + getName().hashCode();
+ h = 31 * h + getActions().hashCode();
+ return h;
+ }
+
+ /**
+ * WriteObject is called to save the state of this permission object to a
+ * stream. The actions are serialized, and the superclass takes care of the
+ * name.
+ */
+ private synchronized void writeObject(java.io.ObjectOutputStream s)
+ throws IOException {
+ // Write out the actions. The superclass takes care of the name
+ // call getActions to make sure actions field is initialized
+ if (actions == null)
+ getActions();
+ s.defaultWriteObject();
+ }
+
+ /**
+ * readObject is called to restore the state of this permission from a
+ * stream.
+ */
+ private synchronized void readObject(java.io.ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ // Read in the action, then initialize the rest
+ s.defaultReadObject();
+ setTransients(parseActions(actions));
+ }
+}
+
+/**
+ * Stores a set of <code>TopicPermission</code> permissions.
+ *
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+final class TopicPermissionCollection extends PermissionCollection {
+ static final long serialVersionUID = -614647783533924048L;
+ /**
+ * Table of permissions.
+ *
+ * @serial
+ * @GuardedBy this
+ */
+ private final Hashtable permissions;
+ /**
+ * Boolean saying if "*" is in the collection.
+ *
+ * @serial
+ * @GuardedBy this
+ */
+ private boolean all_allowed;
+
+ /**
+ * Create an empty TopicPermissions object.
+ *
+ */
+ public TopicPermissionCollection() {
+ permissions = new Hashtable();
+ all_allowed = false;
+ }
+
+ /**
+ * Adds a permission to the <code>TopicPermission</code> objects. The key
+ * for the hash is the name.
+ *
+ * @param permission The <code>TopicPermission</code> object to add.
+ *
+ * @throws IllegalArgumentException If the permission is not a
+ * <code>TopicPermission</code> instance.
+ *
+ * @throws SecurityException If this <code>TopicPermissionCollection</code>
+ * object has been marked read-only.
+ */
+ public void add(final Permission permission) {
+ if (!(permission instanceof TopicPermission)) {
+ throw new IllegalArgumentException("invalid permission: "
+ + permission);
+ }
+ if (isReadOnly()) {
+ throw new SecurityException("attempt to add a Permission to a "
+ + "readonly PermissionCollection");
+ }
+ final TopicPermission tp = (TopicPermission) permission;
+ final String name = tp.getName();
+ final int newMask = tp.getActionsMask();
+
+ synchronized (this) {
+ final TopicPermission existing = (TopicPermission) permissions
+ .get(name);
+ if (existing != null) {
+ final int oldMask = existing.getActionsMask();
+ if (oldMask != newMask) {
+ permissions.put(name, new TopicPermission(name, oldMask
+ | newMask));
+ }
+ }
+ else {
+ permissions.put(name, tp);
+ }
+ if (!all_allowed) {
+ if (name.equals("*"))
+ all_allowed = true;
+ }
+ }
+ }
+
+ /**
+ * Determines if the specified permissions implies the permissions expressed
+ * in <code>permission</code>.
+ *
+ * @param permission The Permission object to compare with this
+ * <code>TopicPermission</code> object.
+ *
+ * @return <code>true</code> if <code>permission</code> is a proper subset
+ * of a permission in the set; <code>false</code> otherwise.
+ */
+ public boolean implies(final Permission permission) {
+ if (!(permission instanceof TopicPermission)) {
+ return false;
+ }
+ final TopicPermission requested = (TopicPermission) permission;
+ String name = requested.getName();
+ final int desired = requested.getActionsMask();
+ int effective = 0;
+
+ TopicPermission x;
+ // short circuit if the "*" Permission was added
+ synchronized (this) {
+ if (all_allowed) {
+ x = (TopicPermission) permissions.get("*");
+ if (x != null) {
+ effective |= x.getActionsMask();
+ if ((effective & desired) == desired) {
+ return true;
+ }
+ }
+ }
+ x = (TopicPermission) permissions.get(name);
+ }
+ // strategy:
+ // Check for full match first. Then work our way up the
+ // name looking for matches on a/b/*
+ if (x != null) {
+ // we have a direct hit!
+ effective |= x.getActionsMask();
+ if ((effective & desired) == desired) {
+ return true;
+ }
+ }
+ // work our way up the tree...
+ int last;
+ int offset = name.length() - 1;
+ while ((last = name.lastIndexOf("/", offset)) != -1) {
+ name = name.substring(0, last + 1) + "*";
+ synchronized (this) {
+ x = (TopicPermission) permissions.get(name);
+ }
+ if (x != null) {
+ effective |= x.getActionsMask();
+ if ((effective & desired) == desired) {
+ return true;
+ }
+ }
+ offset = last - 1;
+ }
+ // we don't have to check for "*" as it was already checked
+ // at the top (all_allowed), so we just return false
+ return false;
+ }
+
+ /**
+ * Returns an enumeration of all <code>TopicPermission</code> objects in the
+ * container.
+ *
+ * @return Enumeration of all <code>TopicPermission</code> objects.
+ */
+ public Enumeration elements() {
+ return permissions.elements();
+ }
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/package.html b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/package.html
new file mode 100644
index 0000000..0d9d0bf
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Event Admin Package Version 1.2.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.event; version="[1.2,2.0)"
+</pre>
+</BODY>
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/packageinfo b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/packageinfo
new file mode 100644
index 0000000..ef7df68
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/event/packageinfo
@@ -0,0 +1 @@
+version 1.2
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/http/HttpContext.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/http/HttpContext.java
new file mode 100644
index 0000000..e39cd17
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/http/HttpContext.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.http;
+
+import java.io.IOException;
+import java.net.URL;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * This interface defines methods that the Http Service may call to get
+ * information about a registration.
+ *
+ * <p>
+ * Servlets and resources may be registered with an <code>HttpContext</code>
+ * object; if no <code>HttpContext</code> object is specified, a default
+ * <code>HttpContext</code> object is used. Servlets that are registered using the
+ * same <code>HttpContext</code> object will share the same
+ * <code>ServletContext</code> object.
+ *
+ * <p>
+ * This interface is implemented by users of the <code>HttpService</code>.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface HttpContext {
+ /**
+ * <code>HttpServletRequest</code> attribute specifying the name of the
+ * authenticated user. The value of the attribute can be retrieved by
+ * <code>HttpServletRequest.getRemoteUser</code>. This attribute name is
+ * <code>org.osgi.service.http.authentication.remote.user</code>.
+ *
+ * @since 1.1
+ */
+ public static final String REMOTE_USER = "org.osgi.service.http.authentication.remote.user";
+ /**
+ * <code>HttpServletRequest</code> attribute specifying the scheme used in
+ * authentication. The value of the attribute can be retrieved by
+ * <code>HttpServletRequest.getAuthType</code>. This attribute name is
+ * <code>org.osgi.service.http.authentication.type</code>.
+ *
+ * @since 1.1
+ */
+ public static final String AUTHENTICATION_TYPE = "org.osgi.service.http.authentication.type";
+ /**
+ * <code>HttpServletRequest</code> attribute specifying the
+ * <code>Authorization</code> object obtained from the
+ * <code>org.osgi.service.useradmin.UserAdmin</code> service. The value of the
+ * attribute can be retrieved by
+ * <code>HttpServletRequest.getAttribute(HttpContext.AUTHORIZATION)</code>.
+ * This attribute name is <code>org.osgi.service.useradmin.authorization</code>.
+ *
+ * @since 1.1
+ */
+ public static final String AUTHORIZATION = "org.osgi.service.useradmin.authorization";
+
+ /**
+ * Handles security for the specified request.
+ *
+ * <p>
+ * The Http Service calls this method prior to servicing the specified
+ * request. This method controls whether the request is processed in the
+ * normal manner or an error is returned.
+ *
+ * <p>
+ * If the request requires authentication and the Authorization header in
+ * the request is missing or not acceptable, then this method should set the
+ * WWW-Authenticate header in the response object, set the status in the
+ * response object to Unauthorized(401) and return <code>false</code>. See
+ * also RFC 2617: <i>HTTP Authentication: Basic and Digest Access
+ * Authentication </i> (available at http://www.ietf.org/rfc/rfc2617.txt).
+ *
+ * <p>
+ * If the request requires a secure connection and the <code>getScheme</code>
+ * method in the request does not return 'https' or some other acceptable
+ * secure protocol, then this method should set the status in the response
+ * object to Forbidden(403) and return <code>false</code>.
+ *
+ * <p>
+ * When this method returns <code>false</code>, the Http Service will send
+ * the response back to the client, thereby completing the request. When
+ * this method returns <code>true</code>, the Http Service will proceed with
+ * servicing the request.
+ *
+ * <p>
+ * If the specified request has been authenticated, this method must set the
+ * {@link #AUTHENTICATION_TYPE} request attribute to the type of
+ * authentication used, and the {@link #REMOTE_USER} request attribute to
+ * the remote user (request attributes are set using the
+ * <code>setAttribute</code> method on the request). If this method does not
+ * perform any authentication, it must not set these attributes.
+ *
+ * <p>
+ * If the authenticated user is also authorized to access certain resources,
+ * this method must set the {@link #AUTHORIZATION} request attribute to the
+ * <code>Authorization</code> object obtained from the
+ * <code>org.osgi.service.useradmin.UserAdmin</code> service.
+ *
+ * <p>
+ * The servlet responsible for servicing the specified request determines
+ * the authentication type and remote user by calling the
+ * <code>getAuthType</code> and <code>getRemoteUser</code> methods,
+ * respectively, on the request.
+ *
+ * @param request the HTTP request
+ * @param response the HTTP response
+ * @return <code>true</code> if the request should be serviced, <code>false</code>
+ * if the request should not be serviced and Http Service will send
+ * the response back to the client.
+ * @throws java.io.IOException may be thrown by this method. If this
+ * occurs, the Http Service will terminate the request and close
+ * the socket.
+ */
+ public boolean handleSecurity(HttpServletRequest request,
+ HttpServletResponse response) throws IOException;
+
+ /**
+ * Maps a resource name to a URL.
+ *
+ * <p>
+ * Called by the Http Service to map a resource name to a URL. For servlet
+ * registrations, Http Service will call this method to support the
+ * <code>ServletContext</code> methods <code>getResource</code> and
+ * <code>getResourceAsStream</code>. For resource registrations, Http Service
+ * will call this method to locate the named resource. The context can
+ * control from where resources come. For example, the resource can be
+ * mapped to a file in the bundle's persistent storage area via
+ * <code>bundleContext.getDataFile(name).toURL()</code> or to a resource in
+ * the context's bundle via <code>getClass().getResource(name)</code>
+ *
+ * @param name the name of the requested resource
+ * @return URL that Http Service can use to read the resource or
+ * <code>null</code> if the resource does not exist.
+ */
+ public URL getResource(String name);
+
+ /**
+ * Maps a name to a MIME type.
+ *
+ * Called by the Http Service to determine the MIME type for the name. For
+ * servlet registrations, the Http Service will call this method to support
+ * the <code>ServletContext</code> method <code>getMimeType</code>. For
+ * resource registrations, the Http Service will call this method to
+ * determine the MIME type for the Content-Type header in the response.
+ *
+ * @param name determine the MIME type for this name.
+ * @return MIME type (e.g. text/html) of the name or <code>null</code> to
+ * indicate that the Http Service should determine the MIME type
+ * itself.
+ */
+ public String getMimeType(String name);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/http/HttpService.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/http/HttpService.java
new file mode 100644
index 0000000..c578a93
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/http/HttpService.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.http;
+
+import java.util.Dictionary;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+
+/**
+ * The Http Service allows other bundles in the OSGi environment to dynamically
+ * register resources and servlets into the URI namespace of Http Service. A
+ * bundle may later unregister its resources or servlets.
+ *
+ * @version $Revision: 5673 $
+ * @see HttpContext
+ */
+public interface HttpService {
+ /**
+ * Registers a servlet into the URI namespace.
+ *
+ * <p>
+ * The alias is the name in the URI namespace of the Http Service at which
+ * the registration will be mapped.
+ *
+ * <p>
+ * An alias must begin with slash ('/') and must not end with slash ('/'),
+ * with the exception that an alias of the form "/" is used to
+ * denote the root alias. See the specification text for details on how HTTP
+ * requests are mapped to servlet and resource registrations.
+ *
+ * <p>
+ * The Http Service will call the servlet's <code>init</code> method before
+ * returning.
+ *
+ * <pre>
+ * httpService.registerServlet("/myservlet", servlet, initparams, context);
+ * </pre>
+ *
+ * <p>
+ * Servlets registered with the same <code>HttpContext</code> object will
+ * share the same <code>ServletContext</code>. The Http Service will call the
+ * <code>context</code> argument to support the <code>ServletContext</code>
+ * methods <code>getResource</code>,<code>getResourceAsStream</code> and
+ * <code>getMimeType</code>, and to handle security for requests. If the
+ * <code>context</code> argument is <code>null</code>, a default
+ * <code>HttpContext</code> object is used (see
+ * {@link #createDefaultHttpContext}).
+ *
+ * @param alias name in the URI namespace at which the servlet is registered
+ * @param servlet the servlet object to register
+ * @param initparams initialization arguments for the servlet or
+ * <code>null</code> if there are none. This argument is used by the
+ * servlet's <code>ServletConfig</code> object.
+ * @param context the <code>HttpContext</code> object for the registered
+ * servlet, or <code>null</code> if a default <code>HttpContext</code> is
+ * to be created and used.
+ * @throws NamespaceException if the registration fails because the alias
+ * is already in use.
+ * @throws javax.servlet.ServletException if the servlet's <code>init</code>
+ * method throws an exception, or the given servlet object has
+ * already been registered at a different alias.
+ * @throws java.lang.IllegalArgumentException if any of the arguments are
+ * invalid
+ */
+ public void registerServlet(String alias, Servlet servlet,
+ Dictionary initparams, HttpContext context)
+ throws ServletException, NamespaceException;
+
+ /**
+ * Registers resources into the URI namespace.
+ *
+ * <p>
+ * The alias is the name in the URI namespace of the Http Service at which
+ * the registration will be mapped. An alias must begin with slash ('/') and
+ * must not end with slash ('/'), with the exception that an alias of the
+ * form "/" is used to denote the root alias. The name parameter
+ * must also not end with slash ('/') with the exception that a name of the
+ * form "/" is used to denote the root of the bundle. See the
+ * specification text for details on how HTTP requests are mapped to servlet
+ * and resource registrations.
+ * <p>
+ * For example, suppose the resource name /tmp is registered to the alias
+ * /files. A request for /files/foo.txt will map to the resource name
+ * /tmp/foo.txt.
+ *
+ * <pre>
+ * httpservice.registerResources("/files", "/tmp", context);
+ * </pre>
+ *
+ * The Http Service will call the <code>HttpContext</code> argument to map
+ * resource names to URLs and MIME types and to handle security for
+ * requests. If the <code>HttpContext</code> argument is <code>null</code>,
+ * a default <code>HttpContext</code> is used (see
+ * {@link #createDefaultHttpContext}).
+ *
+ * @param alias name in the URI namespace at which the resources are
+ * registered
+ * @param name the base name of the resources that will be registered
+ * @param context the <code>HttpContext</code> object for the registered
+ * resources, or <code>null</code> if a default
+ * <code>HttpContext</code> is to be created and used.
+ * @throws NamespaceException if the registration fails because the alias is
+ * already in use.
+ * @throws java.lang.IllegalArgumentException if any of the parameters are
+ * invalid
+ */
+ public void registerResources(String alias, String name,
+ HttpContext context) throws NamespaceException;
+
+ /**
+ * Unregisters a previous registration done by <code>registerServlet</code> or
+ * <code>registerResources</code> methods.
+ *
+ * <p>
+ * After this call, the registered alias in the URI name-space will no
+ * longer be available. If the registration was for a servlet, the Http
+ * Service must call the <code>destroy</code> method of the servlet before
+ * returning.
+ * <p>
+ * If the bundle which performed the registration is stopped or otherwise
+ * "unget"s the Http Service without calling {@link #unregister} then Http
+ * Service must automatically unregister the registration. However, if the
+ * registration was for a servlet, the <code>destroy</code> method of the
+ * servlet will not be called in this case since the bundle may be stopped.
+ * {@link #unregister} must be explicitly called to cause the
+ * <code>destroy</code> method of the servlet to be called. This can be done
+ * in the <code>BundleActivator.stop</code> method of the
+ * bundle registering the servlet.
+ *
+ * @param alias name in the URI name-space of the registration to unregister
+ * @throws java.lang.IllegalArgumentException if there is no registration
+ * for the alias or the calling bundle was not the bundle which
+ * registered the alias.
+ */
+ public void unregister(String alias);
+
+ /**
+ * Creates a default <code>HttpContext</code> for registering servlets or
+ * resources with the HttpService, a new <code>HttpContext</code> object is
+ * created each time this method is called.
+ *
+ * <p>
+ * The behavior of the methods on the default <code>HttpContext</code> is
+ * defined as follows:
+ * <ul>
+ * <li><code>getMimeType</code>- Does not define any customized MIME types
+ * for the Content-Type header in the response, and always returns
+ * <code>null</code>.
+ * <li><code>handleSecurity</code>- Performs implementation-defined
+ * authentication on the request.
+ * <li><code>getResource</code>- Assumes the named resource is in the
+ * context bundle; this method calls the context bundle's
+ * <code>Bundle.getResource</code> method, and returns the appropriate URL to
+ * access the resource. On a Java runtime environment that supports
+ * permissions, the Http Service needs to be granted
+ * <code>org.osgi.framework.AdminPermission[*,RESOURCE]</code>.
+ * </ul>
+ *
+ * @return a default <code>HttpContext</code> object.
+ * @since 1.1
+ */
+ public HttpContext createDefaultHttpContext();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/http/NamespaceException.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/http/NamespaceException.java
new file mode 100644
index 0000000..dce2ba8
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/http/NamespaceException.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.http;
+
+/**
+ * A NamespaceException is thrown to indicate an error with the caller's request
+ * to register a servlet or resources into the URI namespace of the Http
+ * Service. This exception indicates that the requested alias already is in use.
+ *
+ * @version $Revision: 6083 $
+ */
+public class NamespaceException extends Exception {
+ static final long serialVersionUID = 7235606031147877747L;
+
+ /**
+ * Construct a <code>NamespaceException</code> object with a detail message.
+ *
+ * @param message the detail message
+ */
+ public NamespaceException(String message) {
+ super(message);
+ }
+
+ /**
+ * Construct a <code>NamespaceException</code> object with a detail message
+ * and a nested exception.
+ *
+ * @param message The detail message.
+ * @param cause The nested exception.
+ */
+ public NamespaceException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Returns the nested exception.
+ *
+ * <p>
+ * This method predates the general purpose exception chaining mechanism.
+ * The <code>getCause()</code> method is now the preferred means of
+ * obtaining this information.
+ *
+ * @return The result of calling <code>getCause()</code>.
+ */
+ public Throwable getException() {
+ return getCause();
+ }
+
+ /**
+ * Returns the cause of this exception or <code>null</code> if no cause was
+ * set.
+ *
+ * @return The cause of this exception or <code>null</code> if no cause was
+ * set.
+ * @since 1.2
+ */
+ public Throwable getCause() {
+ return super.getCause();
+ }
+
+ /**
+ * Initializes the cause of this exception to the specified value.
+ *
+ * @param cause The cause of this exception.
+ * @return This exception.
+ * @throws IllegalArgumentException If the specified cause is this
+ * exception.
+ * @throws IllegalStateException If the cause of this exception has already
+ * been set.
+ * @since 1.2
+ */
+ public Throwable initCause(Throwable cause) {
+ return super.initCause(cause);
+ }
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/http/package.html b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/http/package.html
new file mode 100644
index 0000000..21f5fed
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/http/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Http Service Package Version 1.2.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.http; version="[1.2,2.0)"
+</pre>
+</BODY>
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/http/packageinfo b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/http/packageinfo
new file mode 100644
index 0000000..6ebb891
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/http/packageinfo
@@ -0,0 +1 @@
+version 1.2.1
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/io/ConnectionFactory.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/io/ConnectionFactory.java
new file mode 100644
index 0000000..71a0af8
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/io/ConnectionFactory.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.io;
+
+import java.io.IOException;
+
+import javax.microedition.io.Connection;
+
+/**
+ * A Connection Factory service is called by the implementation of the Connector
+ * Service to create <code>javax.microedition.io.Connection</code> objects which
+ * implement the scheme named by <code>IO_SCHEME</code>.
+ *
+ * When a <code>ConnectorService.open</code> method is called, the implementation
+ * of the Connector Service will examine the specified name for a scheme. The
+ * Connector Service will then look for a Connection Factory service which is
+ * registered with the service property <code>IO_SCHEME</code> which matches the
+ * scheme. The {@link #createConnection} method of the selected Connection
+ * Factory will then be called to create the actual <code>Connection</code>
+ * object.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface ConnectionFactory {
+ /**
+ * Service property containing the scheme(s) for which this Connection
+ * Factory can create <code>Connection</code> objects. This property is of
+ * type <code>String</code> or <code>String[]</code>.
+ */
+ public static final String IO_SCHEME = "io.scheme";
+
+ /**
+ * Create a new <code>Connection</code> object for the specified URI.
+ *
+ * @param name The full URI passed to the <code>ConnectorService.open</code>
+ * method
+ * @param mode The mode parameter passed to the
+ * <code>ConnectorService.open</code> method
+ * @param timeouts The timeouts parameter passed to the
+ * <code>ConnectorService.open</code> method
+ * @return A new <code>javax.microedition.io.Connection</code> object.
+ * @throws IOException If a <code>javax.microedition.io.Connection</code>
+ * object can not not be created.
+ */
+ public Connection createConnection(String name, int mode, boolean timeouts)
+ throws IOException;
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/io/ConnectorService.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/io/ConnectorService.java
new file mode 100644
index 0000000..dbfc04a
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/io/ConnectorService.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.io;
+
+import java.io.*;
+
+import javax.microedition.io.Connection;
+import javax.microedition.io.Connector;
+
+/**
+ * The Connector Service should be called to create and open
+ * <code>javax.microedition.io.Connection</code> objects.
+ *
+ * When an <code>open*</code> method is called, the implementation of the
+ * Connector Service will examine the specified name for a scheme. The Connector
+ * Service will then look for a Connection Factory service which is registered
+ * with the service property <code>IO_SCHEME</code> which matches the scheme. The
+ * <code>createConnection</code> method of the selected Connection Factory will
+ * then be called to create the actual <code>Connection</code> object.
+ *
+ * <p>
+ * If more than one Connection Factory service is registered for a particular
+ * scheme, the service with the highest ranking (as specified in its
+ * <code>service.ranking</code> property) is called. If there is a tie in ranking,
+ * the service with the lowest service ID (as specified in its
+ * <code>service.id</code> property), that is the service that was registered
+ * first, is called. This is the same algorithm used by
+ * <code>BundleContext.getServiceReference</code>.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface ConnectorService {
+ /**
+ * Read access mode.
+ *
+ * @see "javax.microedition.io.Connector.READ"
+ */
+ public static final int READ = Connector.READ;
+ /**
+ * Write access mode.
+ *
+ * @see "javax.microedition.io.Connector.WRITE"
+ */
+ public static final int WRITE = Connector.WRITE;
+ /**
+ * Read/Write access mode.
+ *
+ * @see "javax.microedition.io.Connector.READ_WRITE"
+ */
+ public static final int READ_WRITE = Connector.READ_WRITE;
+
+ /**
+ * Create and open a <code>Connection</code> object for the specified name.
+ *
+ * @param name The URI for the connection.
+ * @return A new <code>javax.microedition.io.Connection</code> object.
+ * @throws IllegalArgumentException If a parameter is invalid.
+ * @throws javax.microedition.io.ConnectionNotFoundException If the
+ * connection cannot be found.
+ * @throws IOException If some other kind of I/O error occurs.
+ * @see "javax.microedition.io.Connector.open(String name)"
+ */
+ public Connection open(String name) throws IOException;
+
+ /**
+ * Create and open a <code>Connection</code> object for the specified name and
+ * access mode.
+ *
+ * @param name The URI for the connection.
+ * @param mode The access mode.
+ * @return A new <code>javax.microedition.io.Connection</code> object.
+ * @throws IllegalArgumentException If a parameter is invalid.
+ * @throws javax.microedition.io.ConnectionNotFoundException If the
+ * connection cannot be found.
+ * @throws IOException If some other kind of I/O error occurs.
+ * @see "javax.microedition.io.Connector.open(String name, int mode)"
+ */
+ public Connection open(String name, int mode) throws IOException;
+
+ /**
+ * Create and open a <code>Connection</code> object for the specified name,
+ * access mode and timeouts.
+ *
+ * @param name The URI for the connection.
+ * @param mode The access mode.
+ * @param timeouts A flag to indicate that the caller wants timeout
+ * exceptions.
+ * @return A new <code>javax.microedition.io.Connection</code> object.
+ * @throws IllegalArgumentException If a parameter is invalid.
+ * @throws javax.microedition.io.ConnectionNotFoundException If the
+ * connection cannot be found.
+ * @throws IOException If some other kind of I/O error occurs.
+ * @see "<code>javax.microedition.io.Connector.open</code>"
+ */
+ public Connection open(String name, int mode, boolean timeouts)
+ throws IOException;
+
+ /**
+ * Create and open an <code>InputStream</code> object for the specified name.
+ *
+ * @param name The URI for the connection.
+ * @return An <code>InputStream</code> object.
+ * @throws IllegalArgumentException If a parameter is invalid.
+ * @throws javax.microedition.io.ConnectionNotFoundException If the
+ * connection cannot be found.
+ * @throws IOException If some other kind of I/O error occurs.
+ * @see "javax.microedition.io.Connector.openInputStream(String name)"
+ */
+ public InputStream openInputStream(String name) throws IOException;
+
+ /**
+ * Create and open a <code>DataInputStream</code> object for the specified
+ * name.
+ *
+ * @param name The URI for the connection.
+ * @return A <code>DataInputStream</code> object.
+ * @throws IllegalArgumentException If a parameter is invalid.
+ * @throws javax.microedition.io.ConnectionNotFoundException If the
+ * connection cannot be found.
+ * @throws IOException If some other kind of I/O error occurs.
+ * @see "javax.microedition.io.Connector.openDataInputStream(String name)"
+ */
+ public DataInputStream openDataInputStream(String name) throws IOException;
+
+ /**
+ * Create and open an <code>OutputStream</code> object for the specified name.
+ *
+ * @param name The URI for the connection.
+ * @return An <code>OutputStream</code> object.
+ * @throws IllegalArgumentException If a parameter is invalid.
+ * @throws javax.microedition.io.ConnectionNotFoundException If the
+ * connection cannot be found.
+ * @throws IOException If some other kind of I/O error occurs.
+ * @see "javax.microedition.io.Connector.openOutputStream(String name)"
+ */
+ public OutputStream openOutputStream(String name) throws IOException;
+
+ /**
+ * Create and open a <code>DataOutputStream</code> object for the specified
+ * name.
+ *
+ * @param name The URI for the connection.
+ * @return A <code>DataOutputStream</code> object.
+ * @throws IllegalArgumentException If a parameter is invalid.
+ * @throws javax.microedition.io.ConnectionNotFoundException If the
+ * connection cannot be found.
+ * @throws IOException If some other kind of I/O error occurs.
+ * @see "javax.microedition.io.Connector.openDataOutputStream(String name)"
+ */
+ public DataOutputStream openDataOutputStream(String name)
+ throws IOException;
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/io/package.html b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/io/package.html
new file mode 100644
index 0000000..cecc3c3
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/io/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>IO Connector Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.io; version="[1.0,2.0)", javax.microedition.io
+</pre>
+</BODY>
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/io/packageinfo b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/io/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/io/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/LogEntry.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/LogEntry.java
new file mode 100644
index 0000000..8130cf8
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/LogEntry.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.log;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Provides methods to access the information contained in an individual Log
+ * Service log entry.
+ *
+ * <p>
+ * A <code>LogEntry</code> object may be acquired from the
+ * <code>LogReaderService.getLog</code> method or by registering a
+ * <code>LogListener</code> object.
+ *
+ * @ThreadSafe
+ * @version $Revision: 5654 $
+ * @see LogReaderService#getLog
+ * @see LogListener
+ */
+public interface LogEntry {
+ /**
+ * Returns the bundle that created this <code>LogEntry</code> object.
+ *
+ * @return The bundle that created this <code>LogEntry</code> object;
+ * <code>null</code> if no bundle is associated with this
+ * <code>LogEntry</code> object.
+ */
+ public Bundle getBundle();
+
+ /**
+ * Returns the <code>ServiceReference</code> object for the service associated
+ * with this <code>LogEntry</code> object.
+ *
+ * @return <code>ServiceReference</code> object for the service associated
+ * with this <code>LogEntry</code> object; <code>null</code> if no
+ * <code>ServiceReference</code> object was provided.
+ */
+ public ServiceReference getServiceReference();
+
+ /**
+ * Returns the severity level of this <code>LogEntry</code> object.
+ *
+ * <p>
+ * This is one of the severity levels defined by the <code>LogService</code>
+ * interface.
+ *
+ * @return Severity level of this <code>LogEntry</code> object.
+ *
+ * @see LogService#LOG_ERROR
+ * @see LogService#LOG_WARNING
+ * @see LogService#LOG_INFO
+ * @see LogService#LOG_DEBUG
+ */
+ public int getLevel();
+
+ /**
+ * Returns the human readable message associated with this <code>LogEntry</code>
+ * object.
+ *
+ * @return <code>String</code> containing the message associated with this
+ * <code>LogEntry</code> object.
+ */
+ public String getMessage();
+
+ /**
+ * Returns the exception object associated with this <code>LogEntry</code>
+ * object.
+ *
+ * <p>
+ * In some implementations, the returned exception may not be the original
+ * exception. To avoid references to a bundle defined exception class, thus
+ * preventing an uninstalled bundle from being garbage collected, the Log
+ * Service may return an exception object of an implementation defined
+ * Throwable subclass. The returned object will attempt to provide as much
+ * information as possible from the original exception object such as the
+ * message and stack trace.
+ *
+ * @return <code>Throwable</code> object of the exception associated with this
+ * <code>LogEntry</code>;<code>null</code> if no exception is
+ * associated with this <code>LogEntry</code> object.
+ */
+ public Throwable getException();
+
+ /**
+ * Returns the value of <code>currentTimeMillis()</code> at the time this
+ * <code>LogEntry</code> object was created.
+ *
+ * @return The system time in milliseconds when this <code>LogEntry</code>
+ * object was created.
+ * @see "System.currentTimeMillis()"
+ */
+ public long getTime();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/LogListener.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/LogListener.java
new file mode 100644
index 0000000..de29a56
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/LogListener.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.log;
+
+import java.util.EventListener;
+
+/**
+ * Subscribes to <code>LogEntry</code> objects from the <code>LogReaderService</code>.
+ *
+ * <p>
+ * A <code>LogListener</code> object may be registered with the Log Reader Service
+ * using the <code>LogReaderService.addLogListener</code> method. After the
+ * listener is registered, the <code>logged</code> method will be called for each
+ * <code>LogEntry</code> object created. The <code>LogListener</code> object may be
+ * unregistered by calling the <code>LogReaderService.removeLogListener</code>
+ * method.
+ *
+ * @ThreadSafe
+ * @version $Revision: 5654 $
+ * @see LogReaderService
+ * @see LogEntry
+ * @see LogReaderService#addLogListener(LogListener)
+ * @see LogReaderService#removeLogListener(LogListener)
+ */
+public interface LogListener extends EventListener {
+ /**
+ * Listener method called for each LogEntry object created.
+ *
+ * <p>
+ * As with all event listeners, this method should return to its caller as
+ * soon as possible.
+ *
+ * @param entry A <code>LogEntry</code> object containing log information.
+ * @see LogEntry
+ */
+ public void logged(LogEntry entry);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/LogReaderService.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/LogReaderService.java
new file mode 100644
index 0000000..b3753e4
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/LogReaderService.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.log;
+
+import java.util.Enumeration;
+
+/**
+ * Provides methods to retrieve <code>LogEntry</code> objects from the log.
+ * <p>
+ * There are two ways to retrieve <code>LogEntry</code> objects:
+ * <ul>
+ * <li>The primary way to retrieve <code>LogEntry</code> objects is to register a
+ * <code>LogListener</code> object whose <code>LogListener.logged</code> method will
+ * be called for each entry added to the log.
+ * <li>To retrieve past <code>LogEntry</code> objects, the <code>getLog</code>
+ * method can be called which will return an <code>Enumeration</code> of all
+ * <code>LogEntry</code> objects in the log.
+ *
+ * @ThreadSafe
+ * @version $Revision: 5654 $
+ * @see LogEntry
+ * @see LogListener
+ * @see LogListener#logged(LogEntry)
+ */
+public interface LogReaderService {
+ /**
+ * Subscribes to <code>LogEntry</code> objects.
+ *
+ * <p>
+ * This method registers a <code>LogListener</code> object with the Log Reader
+ * Service. The <code>LogListener.logged(LogEntry)</code> method will be
+ * called for each <code>LogEntry</code> object placed into the log.
+ *
+ * <p>
+ * When a bundle which registers a <code>LogListener</code> object is stopped
+ * or otherwise releases the Log Reader Service, the Log Reader Service must
+ * remove all of the bundle's listeners.
+ *
+ * <p>
+ * If this Log Reader Service's list of listeners already contains a
+ * listener <code>l</code> such that <code>(l==listener)</code>, this method
+ * does nothing.
+ *
+ * @param listener A <code>LogListener</code> object to register; the
+ * <code>LogListener</code> object is used to receive <code>LogEntry</code>
+ * objects.
+ * @see LogListener
+ * @see LogEntry
+ * @see LogListener#logged(LogEntry)
+ */
+ public void addLogListener(LogListener listener);
+
+ /**
+ * Unsubscribes to <code>LogEntry</code> objects.
+ *
+ * <p>
+ * This method unregisters a <code>LogListener</code> object from the Log
+ * Reader Service.
+ *
+ * <p>
+ * If <code>listener</code> is not contained in this Log Reader Service's list
+ * of listeners, this method does nothing.
+ *
+ * @param listener A <code>LogListener</code> object to unregister.
+ * @see LogListener
+ */
+ public void removeLogListener(LogListener listener);
+
+ /**
+ * Returns an <code>Enumeration</code> of all <code>LogEntry</code> objects in
+ * the log.
+ *
+ * <p>
+ * Each element of the enumeration is a <code>LogEntry</code> object, ordered
+ * with the most recent entry first. Whether the enumeration is of all
+ * <code>LogEntry</code> objects since the Log Service was started or some
+ * recent past is implementation-specific. Also implementation-specific is
+ * whether informational and debug <code>LogEntry</code> objects are included
+ * in the enumeration.
+ * @return An <code>Enumeration</code> of all <code>LogEntry</code> objects in
+ * the log.
+ */
+ public Enumeration getLog();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/LogService.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/LogService.java
new file mode 100644
index 0000000..1889355
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/LogService.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.log;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Provides methods for bundles to write messages to the log.
+ *
+ * <p>
+ * <code>LogService</code> methods are provided to log messages; optionally with a
+ * <code>ServiceReference</code> object or an exception.
+ *
+ * <p>
+ * Bundles must log messages in the OSGi environment with a severity level
+ * according to the following hierarchy:
+ * <ol>
+ * <li>{@link #LOG_ERROR}
+ * <li>{@link #LOG_WARNING}
+ * <li>{@link #LOG_INFO}
+ * <li>{@link #LOG_DEBUG}
+ * </ol>
+ *
+ * @ThreadSafe
+ * @version $Revision: 5654 $
+ */
+public interface LogService {
+ /**
+ * An error message (Value 1).
+ *
+ * <p>
+ * This log entry indicates the bundle or service may not be functional.
+ */
+ public static final int LOG_ERROR = 1;
+ /**
+ * A warning message (Value 2).
+ *
+ * <p>
+ * This log entry indicates a bundle or service is still functioning but may
+ * experience problems in the future because of the warning condition.
+ */
+ public static final int LOG_WARNING = 2;
+ /**
+ * An informational message (Value 3).
+ *
+ * <p>
+ * This log entry may be the result of any change in the bundle or service
+ * and does not indicate a problem.
+ */
+ public static final int LOG_INFO = 3;
+ /**
+ * A debugging message (Value 4).
+ *
+ * <p>
+ * This log entry is used for problem determination and may be irrelevant to
+ * anyone but the bundle developer.
+ */
+ public static final int LOG_DEBUG = 4;
+
+ /**
+ * Logs a message.
+ *
+ * <p>
+ * The <code>ServiceReference</code> field and the <code>Throwable</code> field
+ * of the <code>LogEntry</code> object will be set to <code>null</code>.
+ *
+ * @param level The severity of the message. This should be one of the
+ * defined log levels but may be any integer that is interpreted in a
+ * user defined way.
+ * @param message Human readable string describing the condition or
+ * <code>null</code>.
+ * @see #LOG_ERROR
+ * @see #LOG_WARNING
+ * @see #LOG_INFO
+ * @see #LOG_DEBUG
+ */
+ public void log(int level, String message);
+
+ /**
+ * Logs a message with an exception.
+ *
+ * <p>
+ * The <code>ServiceReference</code> field of the <code>LogEntry</code> object
+ * will be set to <code>null</code>.
+ *
+ * @param level The severity of the message. This should be one of the
+ * defined log levels but may be any integer that is interpreted in a
+ * user defined way.
+ * @param message The human readable string describing the condition or
+ * <code>null</code>.
+ * @param exception The exception that reflects the condition or
+ * <code>null</code>.
+ * @see #LOG_ERROR
+ * @see #LOG_WARNING
+ * @see #LOG_INFO
+ * @see #LOG_DEBUG
+ */
+ public void log(int level, String message, Throwable exception);
+
+ /**
+ * Logs a message associated with a specific <code>ServiceReference</code>
+ * object.
+ *
+ * <p>
+ * The <code>Throwable</code> field of the <code>LogEntry</code> will be set to
+ * <code>null</code>.
+ *
+ * @param sr The <code>ServiceReference</code> object of the service that this
+ * message is associated with or <code>null</code>.
+ * @param level The severity of the message. This should be one of the
+ * defined log levels but may be any integer that is interpreted in a
+ * user defined way.
+ * @param message Human readable string describing the condition or
+ * <code>null</code>.
+ * @see #LOG_ERROR
+ * @see #LOG_WARNING
+ * @see #LOG_INFO
+ * @see #LOG_DEBUG
+ */
+ public void log(ServiceReference sr, int level, String message);
+
+ /**
+ * Logs a message with an exception associated and a
+ * <code>ServiceReference</code> object.
+ *
+ * @param sr The <code>ServiceReference</code> object of the service that this
+ * message is associated with.
+ * @param level The severity of the message. This should be one of the
+ * defined log levels but may be any integer that is interpreted in a
+ * user defined way.
+ * @param message Human readable string describing the condition or
+ * <code>null</code>.
+ * @param exception The exception that reflects the condition or
+ * <code>null</code>.
+ * @see #LOG_ERROR
+ * @see #LOG_WARNING
+ * @see #LOG_INFO
+ * @see #LOG_DEBUG
+ */
+ public void log(ServiceReference sr, int level, String message,
+ Throwable exception);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/package.html b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/package.html
new file mode 100644
index 0000000..02312bb
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Log Service Package Version 1.3.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.log; version="[1.3,2.0)"
+</pre>
+</BODY>
+
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/packageinfo b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/packageinfo
new file mode 100644
index 0000000..0117a56
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/log/packageinfo
@@ -0,0 +1 @@
+version 1.3
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/AttributeDefinition.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/AttributeDefinition.java
new file mode 100644
index 0000000..d427163
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/AttributeDefinition.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.metatype;
+
+/**
+ * An interface to describe an attribute.
+ *
+ * <p>
+ * An <code>AttributeDefinition</code> object defines a description of the data
+ * type of a property/attribute.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface AttributeDefinition {
+ /**
+ * The <code>STRING</code> (1) type.
+ *
+ * <p>
+ * Attributes of this type should be stored as <code>String</code>,
+ * <code>Vector</code> with <code>String</code> or <code>String[]</code> objects,
+ * depending on the <code>getCardinality()</code> value.
+ */
+ public static final int STRING = 1;
+ /**
+ * The <code>LONG</code> (2) type.
+ *
+ * Attributes of this type should be stored as <code>Long</code>,
+ * <code>Vector</code> with <code>Long</code> or <code>long[]</code> objects,
+ * depending on the <code>getCardinality()</code> value.
+ */
+ public static final int LONG = 2;
+ /**
+ * The <code>INTEGER</code> (3) type.
+ *
+ * Attributes of this type should be stored as <code>Integer</code>,
+ * <code>Vector</code> with <code>Integer</code> or <code>int[]</code> objects,
+ * depending on the <code>getCardinality()</code> value.
+ */
+ public static final int INTEGER = 3;
+ /**
+ * The <code>SHORT</code> (4) type.
+ *
+ * Attributes of this type should be stored as <code>Short</code>,
+ * <code>Vector</code> with <code>Short</code> or <code>short[]</code> objects,
+ * depending on the <code>getCardinality()</code> value.
+ */
+ public static final int SHORT = 4;
+ /**
+ * The <code>CHARACTER</code> (5) type.
+ *
+ * Attributes of this type should be stored as <code>Character</code>,
+ * <code>Vector</code> with <code>Character</code> or <code>char[]</code> objects,
+ * depending on the <code>getCardinality()</code> value.
+ */
+ public static final int CHARACTER = 5;
+ /**
+ * The <code>BYTE</code> (6) type.
+ *
+ * Attributes of this type should be stored as <code>Byte</code>,
+ * <code>Vector</code> with <code>Byte</code> or <code>byte[]</code> objects,
+ * depending on the <code>getCardinality()</code> value.
+ */
+ public static final int BYTE = 6;
+ /**
+ * The <code>DOUBLE</code> (7) type.
+ *
+ * Attributes of this type should be stored as <code>Double</code>,
+ * <code>Vector</code> with <code>Double</code> or <code>double[]</code> objects,
+ * depending on the <code>getCardinality()</code> value.
+ */
+ public static final int DOUBLE = 7;
+ /**
+ * The <code>FLOAT</code> (8) type.
+ *
+ * Attributes of this type should be stored as <code>Float</code>,
+ * <code>Vector</code> with <code>Float</code> or <code>float[]</code> objects,
+ * depending on the <code>getCardinality()</code> value.
+ */
+ public static final int FLOAT = 8;
+ /**
+ * The <code>BIGINTEGER</code> (9) type.
+ *
+ * Attributes of this type should be stored as <code>BigInteger</code>,
+ * <code>Vector</code> with <code>BigInteger</code> or <code>BigInteger[]</code>
+ * objects, depending on the <code>getCardinality()</code> value.
+ *
+ * @deprecated As of 1.1.
+ */
+ public static final int BIGINTEGER = 9;
+ /**
+ * The <code>BIGDECIMAL</code> (10) type.
+ *
+ * Attributes of this type should be stored as <code>BigDecimal</code>,
+ * <code>Vector</code> with <code>BigDecimal</code> or <code>BigDecimal[]</code>
+ * objects depending on <code>getCardinality()</code>.
+ *
+ * @deprecated As of 1.1.
+ */
+ public static final int BIGDECIMAL = 10;
+ /**
+ * The <code>BOOLEAN</code> (11) type.
+ *
+ * Attributes of this type should be stored as <code>Boolean</code>,
+ * <code>Vector</code> with <code>Boolean</code> or <code>boolean[]</code> objects
+ * depending on <code>getCardinality()</code>.
+ */
+ public static final int BOOLEAN = 11;
+
+ /**
+ * Get the name of the attribute. This name may be localized.
+ *
+ * @return The localized name of the definition.
+ */
+ public String getName();
+
+ /**
+ * Unique identity for this attribute.
+ *
+ * Attributes share a global namespace in the registry. E.g. an attribute
+ * <code>cn</code> or <code>commonName</code> must always be a <code>String</code>
+ * and the semantics are always a name of some object. They share this
+ * aspect with LDAP/X.500 attributes. In these standards the OSI Object
+ * Identifier (OID) is used to uniquely identify an attribute. If such an
+ * OID exists, (which can be requested at several standard organisations and
+ * many companies already have a node in the tree) it can be returned here.
+ * Otherwise, a unique id should be returned which can be a Java class name
+ * (reverse domain name) or generated with a GUID algorithm. Note that all
+ * LDAP defined attributes already have an OID. It is strongly advised to
+ * define the attributes from existing LDAP schemes which will give the OID.
+ * Many such schemes exist ranging from postal addresses to DHCP parameters.
+ *
+ * @return The id or oid
+ */
+ public String getID();
+
+ /**
+ * Return a description of this attribute.
+ *
+ * The description may be localized and must describe the semantics of this
+ * type and any constraints.
+ *
+ * @return The localized description of the definition.
+ */
+ public String getDescription();
+
+ /**
+ * Return the cardinality of this attribute.
+ *
+ * The OSGi environment handles multi valued attributes in arrays ([]) or in
+ * <code>Vector</code> objects. The return value is defined as follows:
+ *
+ * <pre>
+ *
+ * x = Integer.MIN_VALUE no limit, but use Vector
+ * x < 0 -x = max occurrences, store in Vector
+ * x > 0 x = max occurrences, store in array []
+ * x = Integer.MAX_VALUE no limit, but use array []
+ * x = 0 1 occurrence required
+ *
+ * </pre>
+ *
+ * @return The cardinality of this attribute.
+ */
+ public int getCardinality();
+
+ /**
+ * Return the type for this attribute.
+ *
+ * <p>
+ * Defined in the following constants which map to the appropriate Java
+ * type. <code>STRING</code>,<code>LONG</code>,<code>INTEGER</code>,
+ * <code>CHAR</code>,<code>BYTE</code>,<code>DOUBLE</code>,<code>FLOAT</code>,
+ * <code>BOOLEAN</code>.
+ *
+ * @return The type for this attribute.
+ */
+ public int getType();
+
+ /**
+ * Return a list of option values that this attribute can take.
+ *
+ * <p>
+ * If the function returns <code>null</code>, there are no option values
+ * available.
+ *
+ * <p>
+ * Each value must be acceptable to validate() (return "") and must be a
+ * <code>String</code> object that can be converted to the data type defined
+ * by getType() for this attribute.
+ *
+ * <p>
+ * This list must be in the same sequence as <code>getOptionLabels()</code>.
+ * I.e. for each index i in <code>getOptionValues</code>, i in
+ * <code>getOptionLabels()</code> should be the label.
+ *
+ * <p>
+ * For example, if an attribute can have the value male, female, unknown,
+ * this list can return
+ * <code>new String[] { "male", "female", "unknown" }</code>.
+ *
+ * @return A list values
+ */
+ public String[] getOptionValues();
+
+ /**
+ * Return a list of labels of option values.
+ *
+ * <p>
+ * The purpose of this method is to allow menus with localized labels. It is
+ * associated with <code>getOptionValues</code>. The labels returned here are
+ * ordered in the same way as the values in that method.
+ *
+ * <p>
+ * If the function returns <code>null</code>, there are no option labels
+ * available.
+ * <p>
+ * This list must be in the same sequence as the <code>getOptionValues()</code>
+ * method. I.e. for each index i in <code>getOptionLabels</code>, i in
+ * <code>getOptionValues()</code> should be the associated value.
+ *
+ * <p>
+ * For example, if an attribute can have the value male, female, unknown,
+ * this list can return (for dutch)
+ * <code>new String[] { "Man", "Vrouw", "Onbekend" }</code>.
+ *
+ * @return A list values
+ */
+ public String[] getOptionLabels();
+
+ /**
+ * Validate an attribute in <code>String</code> form.
+ *
+ * An attribute might be further constrained in value. This method will
+ * attempt to validate the attribute according to these constraints. It can
+ * return three different values:
+ *
+ * <pre>
+ * null No validation present
+ * "" No problems detected
+ * "..." A localized description of why the value is wrong
+ * </pre>
+ *
+ * @param value The value before turning it into the basic data type
+ * @return <code>null</code>, "", or another string
+ */
+ public String validate(String value);
+
+ /**
+ * Return a default for this attribute.
+ *
+ * The object must be of the appropriate type as defined by the cardinality
+ * and <code>getType()</code>. The return type is a list of <code>String</code>
+ * objects that can be converted to the appropriate type. The cardinality of
+ * the return array must follow the absolute cardinality of this type. E.g.
+ * if the cardinality = 0, the array must contain 1 element. If the
+ * cardinality is 1, it must contain 0 or 1 elements. If it is -5, it must
+ * contain from 0 to max 5 elements. Note that the special case of a 0
+ * cardinality, meaning a single value, does not allow arrays or vectors of
+ * 0 elements.
+ *
+ * @return Return a default value or <code>null</code> if no default exists.
+ */
+ public String[] getDefaultValue();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/MetaTypeInformation.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/MetaTypeInformation.java
new file mode 100644
index 0000000..8b336dc
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/MetaTypeInformation.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.metatype;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * A MetaType Information object is created by the MetaTypeService to return
+ * meta type information for a specific bundle.
+ *
+ * @version $Revision: 5673 $
+ * @since 1.1
+ */
+public interface MetaTypeInformation extends MetaTypeProvider {
+ /**
+ * Return the PIDs (for ManagedServices) for which ObjectClassDefinition
+ * information is available.
+ *
+ * @return Array of PIDs.
+ */
+ public String[] getPids();
+
+ /**
+ * Return the Factory PIDs (for ManagedServiceFactories) for which
+ * ObjectClassDefinition information is available.
+ *
+ * @return Array of Factory PIDs.
+ */
+ public String[] getFactoryPids();
+
+ /**
+ * Return the bundle for which this object provides meta type information.
+ *
+ * @return Bundle for which this object provides meta type information.
+ */
+ public Bundle getBundle();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/MetaTypeProvider.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/MetaTypeProvider.java
new file mode 100644
index 0000000..b2385b2
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/MetaTypeProvider.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.metatype;
+
+/**
+ * Provides access to metatypes.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface MetaTypeProvider {
+ /**
+ * Returns an object class definition for the specified id localized to the
+ * specified locale.
+ *
+ * <p>
+ * The locale parameter must be a name that consists of <code>language</code>[
+ * "_" <code>country</code>[ "_" <code>variation</code>] ] as is customary in
+ * the <code>Locale</code> class. This <code>Locale</code> class is not used
+ * because certain profiles do not contain it.
+ *
+ * @param id The ID of the requested object class. This can be a pid or
+ * factory pid returned by getPids or getFactoryPids.
+ * @param locale The locale of the definition or <code>null</code> for default
+ * locale.
+ * @return A <code>ObjectClassDefinition</code> object.
+ * @throws IllegalArgumentException If the id or locale arguments are not
+ * valid
+ */
+ public ObjectClassDefinition getObjectClassDefinition(String id, String locale);
+
+ /**
+ * Return a list of available locales.
+ *
+ * The results must be names that consists of language [ _ country [ _
+ * variation ]] as is customary in the <code>Locale</code> class.
+ *
+ * @return An array of locale strings or <code>null</code> if there is no
+ * locale specific localization can be found.
+ *
+ */
+ public String[] getLocales();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/MetaTypeService.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/MetaTypeService.java
new file mode 100644
index 0000000..d8f77a3
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/MetaTypeService.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.metatype;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * The MetaType Service can be used to obtain meta type information for a
+ * bundle. The MetaType Service will examine the specified bundle for meta type
+ * documents to create the returned <code>MetaTypeInformation</code> object.
+ *
+ * <p>
+ * If the specified bundle does not contain any meta type documents, then a
+ * <code>MetaTypeInformation</code> object will be returned that wrappers any
+ * <code>ManagedService</code> or <code>ManagedServiceFactory</code>
+ * services registered by the specified bundle that implement
+ * <code>MetaTypeProvider</code>. Thus the MetaType Service can be used to
+ * retrieve meta type information for bundles which contain a meta type
+ * documents or which provide their own <code>MetaTypeProvider</code> objects.
+ *
+ * @version $Revision: 5673 $
+ * @since 1.1
+ */
+public interface MetaTypeService {
+ /**
+ * Return the MetaType information for the specified bundle.
+ *
+ * @param bundle The bundle for which meta type information is requested.
+ * @return A MetaTypeInformation object for the specified bundle.
+ */
+ public MetaTypeInformation getMetaTypeInformation(Bundle bundle);
+
+ /**
+ * Location of meta type documents. The MetaType Service will process each
+ * entry in the meta type documents directory.
+ */
+ public final static String METATYPE_DOCUMENTS_LOCATION = "OSGI-INF/metatype";
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/ObjectClassDefinition.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/ObjectClassDefinition.java
new file mode 100644
index 0000000..5c6687e
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/ObjectClassDefinition.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.metatype;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Description for the data type information of an objectclass.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface ObjectClassDefinition {
+ /**
+ * Argument for <code>getAttributeDefinitions(int)</code>.
+ * <p>
+ * <code>REQUIRED</code> indicates that only the required definitions are
+ * returned. The value is 1.
+ */
+ public static final int REQUIRED = 1;
+ /**
+ * Argument for <code>getAttributeDefinitions(int)</code>.
+ * <p>
+ * <code>OPTIONAL</code> indicates that only the optional definitions are
+ * returned. The value is 2.
+ */
+ public static final int OPTIONAL = 2;
+ /**
+ * Argument for <code>getAttributeDefinitions(int)</code>.
+ * <p>
+ * <code>ALL</code> indicates that all the definitions are returned. The value
+ * is -1.
+ */
+ public static final int ALL = 0xFFFFFFFF;
+
+ /**
+ * Return the name of this object class.
+ *
+ * The name may be localized.
+ *
+ * @return The name of this object class.
+ */
+ public String getName();
+
+ /**
+ * Return the id of this object class.
+ *
+ * <p>
+ * <code>ObjectDefintion</code> objects share a global namespace in the
+ * registry. They share this aspect with LDAP/X.500 attributes. In these
+ * standards the OSI Object Identifier (OID) is used to uniquely identify
+ * object classes. If such an OID exists, (which can be requested at several
+ * standard organisations and many companies already have a node in the
+ * tree) it can be returned here. Otherwise, a unique id should be returned
+ * which can be a java class name (reverse domain name) or generated with a
+ * GUID algorithm. Note that all LDAP defined object classes already have an
+ * OID associated. It is strongly advised to define the object classes from
+ * existing LDAP schemes which will give the OID for free. Many such schemes
+ * exist ranging from postal addresses to DHCP parameters.
+ *
+ * @return The id of this object class.
+ */
+ public String getID();
+
+ /**
+ * Return a description of this object class.
+ *
+ * The description may be localized.
+ *
+ * @return The description of this object class.
+ */
+ public String getDescription();
+
+ /**
+ * Return the attribute definitions for this object class.
+ *
+ * <p>
+ * Return a set of attributes. The filter parameter can distinguish between
+ * <code>ALL</code>,<code>REQUIRED</code> or the <code>OPTIONAL</code>
+ * attributes.
+ *
+ * @param filter <code>ALL</code>,<code>REQUIRED</code>,<code>OPTIONAL</code>
+ * @return An array of attribute definitions or <code>null</code> if no
+ * attributes are selected
+ */
+ public AttributeDefinition[] getAttributeDefinitions(int filter);
+
+ /**
+ * Return an <code>InputStream</code> object that can be used to create an
+ * icon from.
+ *
+ * <p>
+ * Indicate the size and return an <code>InputStream</code> object containing
+ * an icon. The returned icon maybe larger or smaller than the indicated
+ * size.
+ *
+ * <p>
+ * The icon may depend on the localization.
+ *
+ * @param size Requested size of an icon, e.g. a 16x16 pixels icon then size =
+ * 16
+ * @return An InputStream representing an icon or <code>null</code>
+ * @throws IOException If the <code>InputStream</code> cannot be returned.
+ */
+ public InputStream getIcon(int size) throws IOException;
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/package.html b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/package.html
new file mode 100644
index 0000000..0b2b533
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Metatype Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.metatype; version="[1.1,2.0)"
+</pre>
+</BODY>
+
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/packageinfo b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/metatype/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/provisioning/ProvisioningService.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/provisioning/ProvisioningService.java
new file mode 100644
index 0000000..0b29053
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/provisioning/ProvisioningService.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.provisioning;
+
+import java.io.IOException;
+import java.util.Dictionary;
+import java.util.zip.ZipInputStream;
+
+/**
+ * Service for managing the initial provisioning information.
+ * <p>
+ * Initial provisioning of an OSGi device is a multi step process that
+ * culminates with the installation and execution of the initial management
+ * agent. At each step of the process, information is collected for the next
+ * step. Multiple bundles may be involved and this service provides a means for
+ * these bundles to exchange information. It also provides a means for the
+ * initial Management Bundle to get its initial configuration information.
+ * <p>
+ * The provisioning information is collected in a <code>Dictionary</code>
+ * object, called the Provisioning Dictionary. Any bundle that can access the
+ * service can get a reference to this object and read and update provisioning
+ * information. The key of the dictionary is a <code>String</code> object and
+ * the value is a <code>String</code> or <code>byte[]</code> object. The
+ * single exception is the PROVISIONING_UPDATE_COUNT value which is an Integer.
+ * The <code>provisioning</code> prefix is reserved for keys defined by OSGi,
+ * other key names may be used for implementation dependent provisioning
+ * systems.
+ * <p>
+ * Any changes to the provisioning information will be reflected immediately in
+ * all the dictionary objects obtained from the Provisioning Service.
+ * <p>
+ * Because of the specific application of the Provisioning Service, there should
+ * be only one Provisioning Service registered. This restriction will not be
+ * enforced by the Framework. Gateway operators or manufactures should ensure
+ * that a Provisioning Service bundle is not installed on a device that already
+ * has a bundle providing the Provisioning Service.
+ * <p>
+ * The provisioning information has the potential to contain sensitive
+ * information. Also, the ability to modify provisioning information can have
+ * drastic consequences. Thus, only trusted bundles should be allowed to
+ * register and get the Provisioning Service. The <code>ServicePermission</code>
+ * is used to limit the bundles that can gain access to the Provisioning
+ * Service. There is no check of <code>Permission</code> objects to read or
+ * modify the provisioning information, so care must be taken not to leak the
+ * Provisioning Dictionary received from <code>getInformation</code> method.
+ *
+ * @version $Revision: 5654 $
+ */
+public interface ProvisioningService {
+ /**
+ * The key to the provisioning information that uniquely identifies the
+ * Service Platform. The value must be of type <code>String</code>.
+ */
+ public final static String PROVISIONING_SPID = "provisioning.spid";
+
+ /**
+ * The key to the provisioning information that contains the location of the
+ * provision data provider. The value must be of type <code>String</code>.
+ */
+ public final static String PROVISIONING_REFERENCE = "provisioning.reference";
+
+ /**
+ * The key to the provisioning information that contains the initial
+ * configuration information of the initial Management Agent. The value will
+ * be of type <code>byte[]</code>.
+ */
+ public final static String PROVISIONING_AGENT_CONFIG = "provisioning.agent.config";
+
+ /**
+ * The key to the provisioning information that contains the update count of
+ * the info data. Each set of changes to the provisioning information must
+ * end with this value being incremented. The value must be of type
+ * <code>Integer</code>. This key/value pair is also reflected in the
+ * properties of the ProvisioningService in the service registry.
+ */
+ public final static String PROVISIONING_UPDATE_COUNT = "provisioning.update.count";
+
+ /**
+ * The key to the provisioning information that contains the location of the
+ * bundle to start with <code>AllPermission</code>. The bundle must have
+ * be previously installed for this entry to have any effect.
+ */
+ public final static String PROVISIONING_START_BUNDLE = "provisioning.start.bundle";
+
+ /**
+ * The key to the provisioning information that contains the root X509
+ * certificate used to establish trust with operator when using HTTPS.
+ */
+ public final static String PROVISIONING_ROOTX509 = "provisioning.rootx509";
+
+ /**
+ * The key to the provisioning information that contains the shared secret
+ * used in conjunction with the RSH protocol.
+ */
+ public final static String PROVISIONING_RSH_SECRET = "provisioning.rsh.secret";
+
+ /**
+ * MIME type to be used in the InitialProvisioning-Entries header or stored
+ * in the extra field of a <code>ZipEntry</code> object for String data.
+ */
+ public final static String MIME_STRING = "text/plain;charset=utf-8";
+
+ /**
+ * MIME type to be used in the InitialProvisioning-Entries header or stored
+ * stored in the extra field of a <code>ZipEntry</code> object for
+ * <code>byte[]</code> data.
+ */
+ public final static String MIME_BYTE_ARRAY = "application/octet-stream";
+
+ /**
+ * MIME type to be used in the InitialProvisioning-Entries header or stored
+ * stored in the extra field of a <code>ZipEntry</code> object for an
+ * installable bundle file. Zip entries of this type will be installed in
+ * the framework, but not started. The entry will also not be put into the
+ * information dictionary.
+ */
+ public final static String MIME_BUNDLE = "application/vnd.osgi.bundle";
+
+ /**
+ * Alternative MIME type to be used in the InitialProvisioning-Entries header or stored
+ * stored in the extra field of a <code>ZipEntry</code> object for an
+ * installable bundle file. Zip entries of this type will be installed in
+ * the framework, but not started. The entry will also not be put into the
+ * information dictionary. This alternative entry is only for backward compatibility,
+ * new applications are recommended to use <code>MIME_BUNDLE</code>, which is an official
+ * IANA MIME type.
+ */
+ public final static String MIME_BUNDLE_ALT = "application/x-osgi-bundle";
+
+ /**
+ * MIME type to be stored in the extra field of a ZipEntry for a String that
+ * represents a URL for a bundle. Zip entries of this type will be used to
+ * install (but not start) a bundle from the URL. The entry will not be put
+ * into the information dictionary.
+ */
+ public final static String MIME_BUNDLE_URL = "text/x-osgi-bundle-url";
+
+ /**
+ * Name of the header that specifies the (MIME) type information for the ZIP file
+ * entries.
+ */
+ public final static String INITIALPROVISIONING_ENTRIES = "InitialProvisioning-Entries";
+
+ /**
+ * Returns a reference to the Provisioning Dictionary. Any change operations
+ * (put and remove) to the dictionary will cause an
+ * <code>UnsupportedOperationException</code> to be thrown. Changes must
+ * be done using the <code>setInformation</code> and
+ * <code>addInformation</code> methods of this service.
+ *
+ * @return A reference to the Provisioning Dictionary.
+ */
+ public Dictionary getInformation();
+
+ /**
+ * Replaces the Provisioning Information dictionary with the key/value pairs
+ * contained in <code>info</code>. Any key/value pairs not in
+ * <code>info</code> will be removed from the Provisioning Information
+ * dictionary. This method causes the <code>PROVISIONING_UPDATE_COUNT</code>
+ * to be incremented.
+ *
+ * @param info the new set of Provisioning Information key/value pairs. Any
+ * keys are values that are of an invalid type will be silently
+ * ignored.
+ */
+ public void setInformation(Dictionary info);
+
+ /**
+ * Adds the key/value pairs contained in <code>info</code> to the
+ * Provisioning Information dictionary. This method causes the
+ * <code>PROVISIONING_UPDATE_COUNT</code> to be incremented.
+ *
+ * @param info the set of Provisioning Information key/value pairs to add to
+ * the Provisioning Information dictionary. Any keys are values that
+ * are of an invalid type will be silently ignored.
+ */
+ public void addInformation(Dictionary info);
+
+ /**
+ * Processes the <code>ZipInputStream</code> and extracts information to
+ * add to the Provisioning Information dictionary, as well as,
+ * install/update and start bundles. This method causes the
+ * <code>PROVISIONING_UPDATE_COUNT</code> to be incremented.
+ *
+ * @param zis the <code>ZipInputStream</code> that will be used to add
+ * key/value pairs to the Provisioning Information dictionary and
+ * install and start bundles. If a <code>ZipEntry</code> does not
+ * have an <code>Extra</code> field that corresponds to one of the
+ * four defined MIME types (<code>MIME_STRING</code>,
+ * <code>MIME_BYTE_ARRAY</code>,<code>MIME_BUNDLE</code>, and
+ * <code>MIME_BUNDLE_URL</code>) in will be silently ignored.
+ * @throws IOException if an error occurs while processing the
+ * ZipInputStream. No additions will be made to the Provisioning
+ * Information dictionary and no bundles must be started or
+ * installed.
+ */
+ public void addInformation(ZipInputStream zis) throws IOException;
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/provisioning/package.html b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/provisioning/package.html
new file mode 100644
index 0000000..8c28950
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/provisioning/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Provisioning Package Version 1.2.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.provisioning; version="[1.2,2.0)"
+</pre>
+</BODY>
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/provisioning/packageinfo b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/provisioning/packageinfo
new file mode 100644
index 0000000..ef7df68
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/provisioning/packageinfo
@@ -0,0 +1 @@
+version 1.2
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPAction.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPAction.java
new file mode 100644
index 0000000..742673f
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPAction.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.upnp;
+
+import java.util.Dictionary;
+
+/**
+ * A UPnP action.
+ *
+ * Each UPnP service contains zero or more actions. Each action may have zero or
+ * more UPnP state variables as arguments.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface UPnPAction {
+ /**
+ * Returns the action name.
+ *
+ * The action name corresponds to the <code>name</code> field in the
+ * <code>actionList</code> of the service description.
+ * <ul>
+ * <li>For standard actions defined by a UPnP Forum working committee,
+ * action names must not begin with <code>X_ </code> nor <code> A_</code>.</li>
+ * <li>For non-standard actions specified by a UPnP vendor and added to a
+ * standard service, action names must begin with <code>X_</code>.</li>
+ * </ul>
+ *
+ * @return Name of action, must not contain a hyphen character or a hash
+ * character
+ */
+ String getName();
+
+ /**
+ * Returns the name of the designated return argument.
+ * <p>
+ * One of the output arguments can be flagged as a designated return
+ * argument.
+ *
+ * @return The name of the designated return argument or <code>null</code> if
+ * none is marked.
+ */
+ String getReturnArgumentName();
+
+ /**
+ * Lists all input arguments for this action.
+ * <p>
+ * Each action may have zero or more input arguments.
+ *
+ * @return Array of input argument names or <code>null</code> if no input
+ * arguments.
+ *
+ * @see UPnPStateVariable
+ */
+ String[] getInputArgumentNames();
+
+ /**
+ * List all output arguments for this action.
+ *
+ * @return Array of output argument names or <code>null</code> if there are no
+ * output arguments.
+ *
+ * @see UPnPStateVariable
+ */
+ String[] getOutputArgumentNames();
+
+ /**
+ * Finds the state variable associated with an argument name.
+ *
+ * Helps to resolve the association of state variables with argument names
+ * in UPnP actions.
+ *
+ * @param argumentName The name of the UPnP action argument.
+ * @return State variable associated with the named argument or
+ * <code>null</code> if there is no such argument.
+ *
+ * @see UPnPStateVariable
+ */
+ UPnPStateVariable getStateVariable(String argumentName);
+
+ /**
+ * Invokes the action.
+ *
+ * The input and output arguments are both passed as <code>Dictionary</code>
+ * objects. Each entry in the <code>Dictionary</code> object has a
+ * <code>String</code> object as key representing the argument name and the
+ * value is the argument itself. The class of an argument value must be
+ * assignable from the class of the associated UPnP state variable.
+ *
+ * The input argument <code>Dictionary</code> object must contain exactly
+ * those arguments listed by <code>getInputArguments</code> method. The output
+ * argument <code>Dictionary</code> object will contain exactly those
+ * arguments listed by <code>getOutputArguments</code> method.
+ *
+ * @param args A <code>Dictionary</code> of arguments. Must contain the correct set and
+ * type of arguments for this action. May be <code>null</code> if no
+ * input arguments exist.
+ *
+ * @return A <code>Dictionary</code> with the output arguments.
+ * <code>null</code> if the action has no output arguments.
+ *
+ * @throws UPnPException A UPnP error has occured.
+ * @throws Exception The execution fails for some reason.
+ *
+ * @see UPnPStateVariable
+ */
+ Dictionary invoke(Dictionary args) throws Exception;
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPDevice.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPDevice.java
new file mode 100644
index 0000000..24ce178
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPDevice.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.upnp;
+
+import java.util.Dictionary;
+
+/**
+ * Represents a UPnP device.
+ *
+ * For each UPnP root and embedded device, an object is registered with the
+ * framework under the <code>UPnPDevice</code> interface.
+ * <p>
+ * The relationship between a root device and its embedded devices can be
+ * deduced using the <code>UPnPDevice.CHILDREN_UDN</code> and
+ * <code>UPnPDevice.PARENT_UDN</code> service registration properties.
+ * <p>
+ * The values of the UPnP property names are defined by the UPnP Forum.
+ * <p>
+ * All values of the UPnP properties are obtained from the device using the
+ * device's default locale.
+ * <p>
+ * If an application wants to query for a set of localized property values, it
+ * has to use the method <code>UPnPDevice.getDescriptions(String locale)</code>.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface UPnPDevice {
+ /*
+ * Constants for the UPnP device match scale.
+ */
+ /**
+ * Constant for the UPnP device match scale, indicating a generic match for
+ * the device. Value is 1.
+ */
+ int MATCH_GENERIC = 1;
+ /**
+ * Constant for the UPnP device match scale, indicating a match with the
+ * device type. Value is 3.
+ */
+ int MATCH_TYPE = 3;
+ /**
+ * Constant for the UPnP device match scale, indicating a match with the
+ * device model. Value is 7.
+ */
+ int MATCH_MANUFACTURER_MODEL = 7;
+ /**
+ * Constant for the UPnP device match scale, indicating a match with the
+ * device revision. Value is 15.
+ */
+ int MATCH_MANUFACTURER_MODEL_REVISION = 15;
+ /**
+ * Constant for the UPnP device match scale, indicating a match with the
+ * device revision and the serial number. Value is 31.
+ */
+ int MATCH_MANUFACTURER_MODEL_REVISION_SERIAL = 31;
+ /**
+ * Constant for the value of the service property <code>DEVICE_CATEGORY</code>
+ * used for all UPnP devices. Value is "UPnP".
+ *
+ * @see "<code>org.osgi.service.device.Constants.DEVICE_CATEGORY</code>"
+ */
+ String DEVICE_CATEGORY = "UPnP";
+ /**
+ * The <code>UPnP.export</code> service property is a hint that marks a device
+ * to be picked up and exported by the UPnP Service. Imported devices do not
+ * have this property set. The registered property requires no value.
+ * <p>
+ * The UPNP_EXPORT string is "UPnP.export".
+ */
+ String UPNP_EXPORT = "UPnP.export";
+ /**
+ * Property key for the Unique Device Name (UDN) property. It is the unique
+ * identifier of an instance of a <code>UPnPDevice</code>. The value of the
+ * property is a <code>String</code> object of the Device UDN. Value of the
+ * key is "UPnP.device.UDN". This property must be set.
+ */
+ String UDN = "UPnP.device.UDN";
+ /**
+ * Property key for the Unique Device ID property. This property is an alias
+ * to <code>UPnPDevice.UDN</code>. It is merely provided for reasons of
+ * symmetry with the <code>UPnPService.ID</code> property. The value of the
+ * property is a <code>String</code> object of the Device UDN. The value of
+ * the key is "UPnP.device.UDN".
+ */
+ String ID = UDN;
+ /**
+ * Property key for the UPnP Device Type property. Some standard property
+ * values are defined by the Universal Plug and Play Forum. The type string
+ * also includes a version number as defined in the UPnP specification. This
+ * property must be set.
+ * <p>
+ * For standard devices defined by a UPnP Forum working committee, this must
+ * consist of the following components in the given order separated by
+ * colons:
+ * <ul>
+ * <li><code>urn</code></li>
+ * <li>schemas-upnp-org</li>
+ * <li><code>device</code></li>
+ * <li>a device type suffix</li>
+ * <li>an integer device version</li>
+ * </ul>
+ * For non-standard devices specified by UPnP vendors following components
+ * must be specified in the given order separated by colons:
+ * <ul>
+ * <li><code>urn</code></li>
+ * <li>an ICANN domain name owned by the vendor</li>
+ * <li><code>device</code></li>
+ * <li>a device type suffix</li>
+ * <li>an integer device version</li>
+ * </ul>
+ * <p>
+ * To allow for backward compatibility the UPnP driver must automatically
+ * generate additional Device Type property entries for smaller versions
+ * than the current one. If for example a device announces its type as
+ * version 3, then properties for versions 2 and 1 must be automatically
+ * generated.
+ * <p>
+ * In the case of exporting a UPnPDevice, the highest available version must
+ * be announced on the network.
+ * <p>
+ * Syntax Example: <code>urn:schemas-upnp-org:device:deviceType:v</code>
+ * <p>
+ * The value is "UPnP.device.type".
+ */
+ String TYPE = "UPnP.device.type";
+ /**
+ * Mandatory property key for the device manufacturer's property. The
+ * property value holds a String representation of the device manufacturer's
+ * name. Value is "UPnP.device.manufacturer".
+ */
+ String MANUFACTURER = "UPnP.device.manufacturer";
+ /**
+ * Mandatory property key for the device model name. The property value
+ * holds a <code>String</code> object giving more information about the device
+ * model. Value is "UPnP.device.modelName".
+ */
+ String MODEL_NAME = "UPnP.device.modelName";
+ /**
+ * Mandatory property key for a short user friendly version of the device
+ * name. The property value holds a <code>String</code> object with the user
+ * friendly name of the device. Value is "UPnP.device.friendlyName".
+ */
+ String FRIENDLY_NAME = "UPnP.device.friendlyName";
+ /**
+ * Optional property key for a URL to the device manufacturers Web site. The
+ * value of the property is a <code>String</code> object representing the URL.
+ * Value is "UPnP.device.manufacturerURL".
+ */
+ String MANUFACTURER_URL = "UPnP.device.manufacturerURL";
+ /**
+ * Optional (but recommended) property key for a <code>String</code> object
+ * with a long description of the device for the end user. The value is
+ * "UPnP.device.modelDescription".
+ */
+ String MODEL_DESCRIPTION = "UPnP.device.modelDescription";
+ /**
+ * Optional (but recommended) property key for a <code>String</code> class
+ * typed property holding the model number of the device. Value is
+ * "UPnP.device.modelNumber".
+ */
+ String MODEL_NUMBER = "UPnP.device.modelNumber";
+ /**
+ * Optional property key for a <code>String</code> typed property holding a
+ * string representing the URL to the Web site for this model. Value is
+ * "UPnP.device.modelURL".
+ */
+ String MODEL_URL = "UPnP.device.modelURL";
+ /**
+ * Optional (but recommended) property key for a <code>String</code> typed
+ * property holding the serial number of the device. Value is
+ * "UPnP.device.serialNumber".
+ */
+ String SERIAL_NUMBER = "UPnP.device.serialNumber";
+ /**
+ * Optional property key for a <code>String</code> typed property holding the
+ * Universal Product Code (UPC) of the device. Value is "UPnP.device.UPC".
+ */
+ String UPC = "UPnP.device.UPC";
+ /**
+ * Optional (but recommended) property key for a <code>String</code> typed
+ * property holding a string representing the URL to a device representation
+ * Web page. Value is "UPnP.presentationURL".
+ */
+ String PRESENTATION_URL = "UPnP.presentationURL";
+ /**
+ * The property key that must be set for all embedded devices. It contains
+ * the UDN of the parent device. The property is not set for root devices.
+ * The value is "UPnP.device.parentUDN".
+ */
+ String PARENT_UDN = "UPnP.device.parentUDN";
+ /**
+ * The property key that must be set for all devices containing other
+ * embedded devices.
+ * <p>
+ * The value is an array of UDNs for each of the device's children (
+ * <code>String[]</code>). The array contains UDNs for the immediate
+ * descendants only.
+ * </p>
+ * <p>
+ * If an embedded device in turn contains embedded devices, the latter are
+ * not included in the array.
+ * </p>
+ * The UPnP Specification does not encourage more than two levels of
+ * nesting.
+ * <p>
+ * The property is not set if the device does not contain embedded devices.
+ * <p>
+ * The property is of type <code>String[]</code>. Value is
+ * "UPnP.device.childrenUDN"
+ */
+ String CHILDREN_UDN = "UPnP.device.childrenUDN";
+
+ /**
+ * Locates a specific service by its service id.
+ *
+ * @param serviceId The service id
+ * @return The requested service or null if not found.
+ */
+ UPnPService getService(String serviceId);
+
+ /**
+ * Lists all services provided by this device.
+ *
+ * @return Array of services or <code>null</code> if no services are
+ * available.
+ */
+ UPnPService[] getServices();
+
+ /**
+ * Lists all icons for this device in a given locale.
+ *
+ * The UPnP specification allows a device to present different icons based
+ * on the client's locale.
+ *
+ * @param locale A language tag as defined by RFC 1766 and maintained by ISO
+ * 639. Examples include "<code>de</code>", "<code>en</code>" or "
+ * <code>en-US</code>". The default locale of the device is specified
+ * by passing a <code>null</code> argument.
+ *
+ * @return Array of icons or null if no icons are available.
+ */
+ UPnPIcon[] getIcons(String locale);
+
+ /**
+ * Get a set of localized UPnP properties.
+ *
+ * The UPnP specification allows a device to present different device
+ * properties based on the client's locale. The properties used to register
+ * the UPnPDevice service in the OSGi registry are based on the device's
+ * default locale. To obtain a localized set of the properties, an
+ * application can use this method.
+ * <p>
+ * Not all properties might be available in all locales. This method does
+ * <b>not </b> substitute missing properties with their default locale
+ * versions.
+ * <p>
+ *
+ * @param locale A language tag as defined by RFC 1766 and maintained by ISO
+ * 639. Examples include "<code>de</code>", "<code>en</code>" or "
+ * <code>en-US</code>". The default locale of the device is specified
+ * by passing a <code>null</code> argument.
+ * @return Dictionary mapping property name Strings to property value
+ * Strings
+ *
+ */
+ Dictionary getDescriptions(String locale);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPEventListener.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPEventListener.java
new file mode 100644
index 0000000..80d4455
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPEventListener.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.upnp;
+
+import java.util.Dictionary;
+
+/**
+ * UPnP Events are mapped and delivered to applications according to the OSGi
+ * whiteboard model. An application that wishes to be notified of events
+ * generated by a particular UPnP Device registers a service extending this
+ * interface.
+ * <p>
+ * The notification call from the UPnP Service to any
+ * <code>UPnPEventListener</code> object must be done asynchronous with respect
+ * to the originator (in a separate thread).
+ * <p>
+ * Upon registration of the UPnP Event Listener service with the Framework, the
+ * service is notified for each variable which it listens for with an initial
+ * event containing the current value of the variable. Subsequent notifications
+ * only happen on changes of the value of the variable.
+ * <p>
+ * A UPnP Event Listener service filter the events it receives. This event set
+ * is limited using a standard framework filter expression which is specified
+ * when the listener service is registered.
+ * <p>
+ * The filter is specified in a property named "upnp.filter" and has as a value
+ * an object of type <code>org.osgi.framework.Filter</code>.
+ * <p>
+ * When the Filter is evaluated, the folowing keywords are recognized as defined
+ * as literal constants in the <code>UPnPDevice</code> class.
+ * <p>
+ * The valid subset of properties for the registration of UPnP Event Listener
+ * services are:
+ * <ul>
+ * <li><code>UPnPDevice.TYPE</code>-- Which type of device to listen for events.
+ * </li>
+ * <li><code>UPnPDevice.ID</code>-- The ID of a specific device to listen for
+ * events.</li>
+ * <li><code>UPnPService.TYPE</code>-- The type of a specific service to listen
+ * for events.</li>
+ * <li><code>UPnPService.ID</code>-- The ID of a specific service to listen for
+ * events.</li>
+ * </ul>
+ *
+ * @version $Revision: 5673 $
+ */
+public interface UPnPEventListener {
+ /**
+ * Key for a service property having a value that is an object of type
+ * <code>org.osgi.framework.Filter</code> and that is used to limit received
+ * events.
+ */
+ static final String UPNP_FILTER = "upnp.filter";
+
+ /**
+ * Callback method that is invoked for received events.
+ *
+ * The events are collected in a <code>Dictionary</code> object. Each entry
+ * has a <code>String</code> key representing the event name (= state variable
+ * name) and the new value of the state variable. The class of the value
+ * object must match the class specified by the UPnP State Variable
+ * associated with the event. This method must be called asynchronously
+ *
+ * @param deviceId ID of the device sending the events
+ * @param serviceId ID of the service sending the events
+ * @param events <code>Dictionary</code> object containing the new values for
+ * the state variables that have changed.
+ *
+ *
+ */
+ void notifyUPnPEvent(String deviceId, String serviceId, Dictionary events);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPException.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPException.java
new file mode 100644
index 0000000..172c995
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPException.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.upnp;
+
+/**
+ * There are several defined error situations describing UPnP problems while a
+ * control point invokes actions to UPnPDevices.
+ *
+ * @since 1.1
+ * @version $Revision: 5673 $
+ */
+public class UPnPException extends Exception {
+ static final long serialVersionUID = -262013318122195146L;
+
+ /**
+ * No Action found by that name at this service.
+ */
+ public final static int INVALID_ACTION = 401;
+
+ /**
+ * Not enough arguments, too many arguments with a specific name, or one of
+ * more of the arguments are of the wrong type.
+ */
+ public final static int INVALID_ARGS = 402;
+
+ /**
+ * The different end-points are no longer in synchronization.
+ */
+ public final static int INVALID_SEQUENCE_NUMBER = 403;
+
+ /**
+ * Refers to a non existing variable.
+ */
+ public final static int INVALID_VARIABLE = 404;
+
+ /**
+ * The invoked action failed during execution.
+ */
+ public final static int DEVICE_INTERNAL_ERROR = 501;
+
+ /**
+ * Key for an error information that is an int type variable and that is
+ * used to identify occured errors.
+ */
+ private final int errorCode;
+
+ /**
+ * This constructor creates a UPnPException on the specified error code and
+ * error description.
+ *
+ * @param errorCode errorCode which defined UPnP Device Architecture V1.0.
+ * @param errordesc errorDescription which explain the type of propblem.
+ */
+ public UPnPException(int errorCode, String errordesc) {
+ super(errordesc);
+ this.errorCode = errorCode;
+ }
+
+ /**
+ * Returns the UPnPError Code occured by UPnPDevices during invocation.
+ *
+ * @return The UPnPErrorCode defined by a UPnP Forum working committee or
+ * specified by a UPnP vendor.
+ */
+ public int getUPnPError_Code() {
+ return errorCode;
+ }
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPIcon.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPIcon.java
new file mode 100644
index 0000000..8b99be9
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPIcon.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.upnp;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * A UPnP icon representation.
+ *
+ * Each UPnP device can contain zero or more icons.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface UPnPIcon {
+ /**
+ * Returns the MIME type of the icon.
+ *
+ * This method returns the format in which the icon graphics, read from the
+ * <code>InputStream</code> object obtained by the <code>getInputStream()</code>
+ * method, is encoded.
+ * <p>
+ * The format of the returned string is in accordance to RFC2046. A list of
+ * valid MIME types is maintained by the <a
+ * href="http://www.iana.org/assignments/media-types/">IANA</a>.
+ * <p>
+ * Typical values returned include: "image/jpeg" or "image/gif"
+ *
+ * @return The MIME type of the encoded icon.
+ */
+ String getMimeType();
+
+ /**
+ * Returns the width of the icon in pixels.
+ *
+ * If the actual width of the icon is unknown, -1 is returned.
+ *
+ * @return The width in pixels, or -1 if unknown.
+ */
+ int getWidth();
+
+ /**
+ * Returns the height of the icon in pixels.
+ *
+ * If the actual height of the icon is unknown, -1 is returned.
+ *
+ * @return The height in pixels, or -1 if unknown.
+ */
+ int getHeight();
+
+ /**
+ * Returns the size of the icon in bytes.
+ *
+ * This method returns the number of bytes of the icon available to read
+ * from the <code>InputStream</code> object obtained by the
+ * <code>getInputStream()</code> method. If the actual size can not be
+ * determined, -1 is returned.
+ *
+ * @return The icon size in bytes, or -1 if the size is unknown.
+ */
+ int getSize();
+
+ /**
+ * Returns the color depth of the icon in bits.
+ *
+ * @return The color depth in bits. If the actual color depth of the icon is
+ * unknown, -1 is returned.
+ */
+ int getDepth();
+
+ /**
+ * Returns an <code>InputStream</code> object for the icon data.
+ *
+ * The <code>InputStream</code> object provides a way for a client to read the
+ * actual icon graphics data. The number of bytes available from this
+ * <code>InputStream</code> object can be determined via the
+ * <code>getSize()</code> method. The format of the data encoded can be
+ * determined by the MIME type availble via the <code>getMimeType()</code>
+ * method.
+ *
+ * @return An InputStream to read the icon graphics data from.
+ * @throws IOException If the <code>InputStream</code> cannot be returned.
+ * @see UPnPIcon#getMimeType()
+ */
+ InputStream getInputStream() throws IOException;
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPLocalStateVariable.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPLocalStateVariable.java
new file mode 100644
index 0000000..241fb8a
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPLocalStateVariable.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+/**
+ * To keep the current values getting from subscribed UPnPDevices.
+ *
+ * The actual values of the UPnPStateVaraible are passed as Java object type.
+ *
+ * @since 1.1
+ **/
+package org.osgi.service.upnp;
+
+/**
+ * A local UPnP state variable which allows the value of the state variable to
+ * be queried.
+ *
+ * @since 1.1
+ *
+ * @version $Revision: 5673 $
+ */
+public interface UPnPLocalStateVariable extends UPnPStateVariable {
+ /**
+ * This method will keep the current values of UPnPStateVariables of a
+ * UPnPDevice whenever UPnPStateVariable's value is changed , this method
+ * must be called.
+ *
+ * @return <code>Object</code> current value of UPnPStateVariable. if the
+ * current value is initialized with the default value defined UPnP
+ * service description.
+ */
+ public Object getCurrentValue();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPService.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPService.java
new file mode 100644
index 0000000..64b5894
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPService.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.upnp;
+
+/**
+ * A representation of a UPnP Service.
+ *
+ * Each UPnP device contains zero or more services. The UPnP description for a
+ * service defines actions, their arguments, and event characteristics.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface UPnPService {
+ /**
+ * Property key for the optional service type uri.
+ *
+ * The service type property is used when registering UPnP Device services
+ * and UPnP Event Listener services. The property contains a <code>String</code>
+ * array (<code>String[]</code>) of service types. A UPnP Device service can
+ * thus announce what types of services it contains. A UPnP Event Listener
+ * service can announce for what type of UPnP services it wants
+ * notifications. The service version is encoded in the type string as
+ * specified in the UPnP specification. A <code>null</code> value is a
+ * wildcard, matching <b>all </b> service types. Value is
+ * "UPnP.service.type".
+ *
+ * @see UPnPService#getType()
+ */
+ String TYPE = "UPnP.service.type";
+ /**
+ * Property key for the optional service id.
+ *
+ * The service id property is used when registering UPnP Device services or
+ * UPnP Event Listener services. The value of the property contains a
+ * <code>String</code> array (<code>String[]</code>) of service ids. A UPnP
+ * Device service can thus announce what service ids it contains. A UPnP
+ * Event Listener service can announce for what UPnP service ids it wants
+ * notifications. A service id does <b>not </b> have to be universally
+ * unique. It must be unique only within a device. A <code>null</code> value
+ * is a wildcard, matching <b>all </b> services. The value is
+ * "UPnP.service.id".
+ */
+ String ID = "UPnP.service.id";
+
+ /**
+ * Returns the <code>serviceId</code> field in the UPnP service description.
+ *
+ *
+ * <p>
+ * For standard services defined by a UPnP Forum working committee, the
+ * serviceId must contain the following components in the indicated order:
+ * <ul>
+ * <li><code>urn:upnp-org:serviceId:</code></li>
+ * <li>service ID suffix</li>
+ * </ul>
+ * Example: <code>urn:upnp-org:serviceId:serviceID</code>.
+ *
+ * <p>
+ * Note that <code>upnp-org</code> is used instead of
+ * <code>schemas-upnp-org</code> in this example because an XML schema is not
+ * defined for each serviceId.
+ * </p>
+ *
+ * <p>
+ * For non-standard services specified by UPnP vendors, the serviceId must
+ * contain the following components in the indicated order:
+ * <ul>
+ * <li><code>urn:</code></li>
+ * <li>ICANN domain name owned by the vendor</li>
+ * <li><code>:serviceId:</code></li>
+ * <li>service ID suffix</li>
+ * </ul>
+ * Example: <code>urn:domain-name:serviceId:serviceID</code>.
+ *
+ * @return The service ID suffix defined by a UPnP Forum working committee
+ * or specified by a UPnP vendor. Must be <= 64 characters.
+ * Single URI.
+ */
+ String getId();
+
+ /**
+ * Returns the <code>serviceType</code> field in the UPnP service description.
+ *
+ * <p>
+ * For standard services defined by a UPnP Forum working committee, the
+ * serviceType must contain the following components in the indicated order:
+ * <ul>
+ * <li><code>urn:schemas-upnp-org:service:</code></li>
+ * <li>service type suffix:</li>
+ * <li>integer service version</li>
+ * </ul>
+ * Example: <code>urn:schemas-upnp-org:service:serviceType:v</code>.
+ *
+ * <p>
+ * For non-standard services specified by UPnP vendors, the
+ * <code>serviceType</code> must contain the following components in the
+ * indicated order:
+ * <ul>
+ * <li><code>urn:</code></li>
+ * <li>ICANN domain name owned by the vendor</li>
+ * <li><code>:service:</code></li>
+ * <li>service type suffix:</li>
+ * <li>integer service version</li>
+ * </ul>
+ * Example: <code>urn:domain-name:service:serviceType:v</code>.
+ *
+ * @return The service type suffix defined by a UPnP Forum working committee
+ * or specified by a UPnP vendor. Must be <= 64 characters, not
+ * including the version suffix and separating colon. Single URI.
+ */
+ String getType();
+
+ /**
+ * Returns the version suffix encoded in the <code>serviceType</code> field in
+ * the UPnP service description.
+ *
+ * @return The integer service version defined by a UPnP Forum working
+ * committee or specified by a UPnP vendor.
+ */
+ String getVersion();
+
+ /**
+ * Locates a specific action by name.
+ *
+ * Looks up an action by its name.
+ *
+ * @param name Name of action. Must not contain hyphen or hash characters.
+ * Should be < 32 characters.
+ *
+ * @return The requested action or <code>null</code> if no action is found.
+ */
+ UPnPAction getAction(String name);
+
+ /**
+ * Lists all actions provided by this service.
+ *
+ * @return Array of actions (<code>UPnPAction[]</code> )or <code>null</code> if
+ * no actions are defined for this service.
+ */
+ UPnPAction[] getActions();
+
+ /**
+ * Lists all <code>UPnPStateVariable</code> objects provided by this service.
+ *
+ * @return Array of state variables or <code>null</code> if none are defined
+ * for this service.
+ */
+ UPnPStateVariable[] getStateVariables();
+
+ /**
+ * Gets a <code>UPnPStateVariable</code> objects provided by this service by
+ * name
+ *
+ * @param name Name of the State Variable
+ *
+ * @return State variable or <code>null</code> if no such state variable
+ * exists for this service.
+ */
+ UPnPStateVariable getStateVariable(String name);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPStateVariable.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPStateVariable.java
new file mode 100644
index 0000000..27b7241
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/UPnPStateVariable.java
@@ -0,0 +1,342 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.upnp;
+
+/**
+ * The meta-information of a UPnP state variable as declared in the device's
+ * service state table (SST).
+ * <p>
+ * Method calls to interact with a device (e.g.
+ * <code>UPnPAction.invoke(...);</code>) use this class to encapsulate meta
+ * information about the input and output arguments.
+ * <p>
+ * The actual values of the arguments are passed as Java objects. The mapping of
+ * types from UPnP data types to Java data types is described with the field
+ * definitions.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface UPnPStateVariable {
+ /**
+ * Unsigned 1 <code>Byte</code> int.
+ * <p>
+ * Mapped to an <code>Integer</code> object.
+ */
+ static final String TYPE_UI1 = "ui1";
+ /**
+ * Unsigned 2 Byte int.
+ * <p>
+ * Mapped to <code>Integer</code> object.
+ */
+ static final String TYPE_UI2 = "ui2";
+ /**
+ * Unsigned 4 Byte int.
+ * <p>
+ * Mapped to <code>Long</code> object.
+ */
+ static final String TYPE_UI4 = "ui4";
+ /**
+ * 1 Byte int.
+ * <p>
+ * Mapped to <code>Integer</code> object.
+ */
+ static final String TYPE_I1 = "i1";
+ /**
+ * 2 Byte int.
+ * <p>
+ * Mapped to <code>Integer</code> object.
+ */
+ static final String TYPE_I2 = "i2";
+ /**
+ * 4 Byte int.
+ * <p>
+ * Must be between -2147483648 and 2147483647
+ * <p>
+ * Mapped to <code>Integer</code> object.
+ */
+ static final String TYPE_I4 = "i4";
+ /**
+ * Integer number.
+ * <p>
+ * Mapped to <code>Integer</code> object.
+ */
+ static final String TYPE_INT = "int";
+ /**
+ * 4 Byte float.
+ * <p>
+ * Same format as float. Must be between 3.40282347E+38 to 1.17549435E-38.
+ * <p>
+ * Mapped to <code>Float</code> object.
+ */
+ static final String TYPE_R4 = "r4";
+ /**
+ * 8 Byte float.
+ * <p>
+ * Same format as float. Must be between -1.79769313486232E308 and
+ * -4.94065645841247E-324 for negative values, and between
+ * 4.94065645841247E-324 and 1.79769313486232E308 for positive values, i.e.,
+ * IEEE 64-bit (8-Byte) double.
+ * <p>
+ * Mapped to <code>Double</code> object.
+ */
+ static final String TYPE_R8 = "r8";
+ /**
+ * Same as r8.
+ * <p>
+ * Mapped to <code>Double</code> object.
+ */
+ static final String TYPE_NUMBER = "number";
+ /**
+ * Same as r8 but no more than 14 digits to the left of the decimal point
+ * and no more than 4 to the right.
+ * <p>
+ * Mapped to <code>Double</code> object.
+ */
+ static final String TYPE_FIXED_14_4 = "fixed.14.4";
+ /**
+ * Floating-point number.
+ * <p>
+ * Mantissa (left of the decimal) and/or exponent may have a leading sign.
+ * Mantissa and/or exponent may have leading zeros. Decimal character in
+ * mantissa is a period, i.e., whole digits in mantissa separated from
+ * fractional digits by period. Mantissa separated from exponent by E. (No
+ * currency symbol.) (No grouping of digits in the mantissa, e.g., no
+ * commas.)
+ * <p>
+ * Mapped to <code>Float</code> object.
+ */
+ static final String TYPE_FLOAT = "float";
+ /**
+ * Unicode string.
+ * <p>
+ * One character long.
+ * <p>
+ * Mapped to <code>Character</code> object.
+ */
+ static final String TYPE_CHAR = "char";
+ /**
+ * Unicode string.
+ * <p>
+ * No limit on length.
+ * <p>
+ * Mapped to <code>String</code> object.
+ */
+ static final String TYPE_STRING = "string";
+ /**
+ * A calendar date.
+ * <p>
+ * Date in a subset of ISO 8601 format without time data.
+ * <p>
+ * See <a
+ * href="http://www.w3.org/TR/xmlschema-2/#date">http://www.w3.org/TR/xmlschema-2/#date
+ * </a>.
+ * <p>
+ * Mapped to <code>java.util.Date</code> object. Always 00:00 hours.
+ */
+ static final String TYPE_DATE = "date";
+ /**
+ * A specific instant of time.
+ * <p>
+ * Date in ISO 8601 format with optional time but no time zone.
+ * <p>
+ * See <a
+ * href="http://www.w3.org/TR/xmlschema-2/#dateTime">http://www.w3.org/TR/xmlschema-2/#dateTime
+ * </a>.
+ * <p>
+ * Mapped to <code>java.util.Date</code> object using default time zone.
+ */
+ static final String TYPE_DATETIME = "dateTime";
+ /**
+ * A specific instant of time.
+ * <p>
+ * Date in ISO 8601 format with optional time and optional time zone.
+ * <p>
+ * See <a
+ * href="http://www.w3.org/TR/xmlschema-2/#dateTime">http://www.w3.org/TR/xmlschema-2/#dateTime
+ * </a>.
+ * <p>
+ * Mapped to <code>java.util.Date</code> object adjusted to default time zone.
+ */
+ static final String TYPE_DATETIME_TZ = "dateTime.tz";
+ /**
+ * An instant of time that recurs every day.
+ * <p>
+ * Time in a subset of ISO 8601 format with no date and no time zone.
+ * <p>
+ * See <a
+ * href="http://www.w3.org/TR/xmlschema-2/#dateTime">http://www.w3.org/TR/xmlschema-2/#time
+ * </a>.
+ * <p>
+ * Mapped to <code>Long</code>. Converted to milliseconds since midnight.
+ */
+ static final String TYPE_TIME = "time";
+ /**
+ * An instant of time that recurs every day.
+ * <p>
+ * Time in a subset of ISO 8601 format with optional time zone but no date.
+ * <p>
+ * See <a
+ * href="http://www.w3.org/TR/xmlschema-2/#dateTime">http://www.w3.org/TR/xmlschema-2/#time
+ * </a>.
+ * <p>
+ * Mapped to <code>Long</code> object. Converted to milliseconds since
+ * midnight and adjusted to default time zone, wrapping at 0 and
+ * 24*60*60*1000.
+ */
+ static final String TYPE_TIME_TZ = "time.tz";
+ /**
+ * True or false.
+ * <p>
+ * Mapped to <code>Boolean</code> object.
+ */
+ static final String TYPE_BOOLEAN = "boolean";
+ /**
+ * MIME-style Base64 encoded binary BLOB.
+ * <p>
+ * Takes 3 Bytes, splits them into 4 parts, and maps each 6 bit piece to an
+ * octet. (3 octets are encoded as 4.) No limit on size.
+ * <p>
+ * Mapped to <code>byte[]</code> object. The Java byte array will hold the
+ * decoded content of the BLOB.
+ */
+ static final String TYPE_BIN_BASE64 = "bin.base64";
+ /**
+ * Hexadecimal digits representing octets.
+ * <p>
+ * Treats each nibble as a hex digit and encodes as a separate Byte. (1
+ * octet is encoded as 2.) No limit on size.
+ * <p>
+ * Mapped to <code>byte[]</code> object. The Java byte array will hold the
+ * decoded content of the BLOB.
+ */
+ static final String TYPE_BIN_HEX = "bin.hex";
+ /**
+ * Universal Resource Identifier.
+ * <p>
+ * Mapped to <code>String</code> object.
+ */
+ static final String TYPE_URI = "uri";
+ /**
+ * Universally Unique ID.
+ * <p>
+ * Hexadecimal digits representing octets. Optional embedded hyphens are
+ * ignored.
+ * <p>
+ * Mapped to <code>String</code> object.
+ */
+ static final String TYPE_UUID = "uuid";
+
+ /**
+ * Returns the variable name.
+ *
+ * <ul>
+ * <li>All standard variables defined by a UPnP Forum working committee
+ * must not begin with <code>X_</code> nor <code>A_</code>.</li>
+ * <li>All non-standard variables specified by a UPnP vendor and added to a
+ * standard service must begin with <code>X_</code>.</li>
+ * </ul>
+ *
+ * @return Name of state variable. Must not contain a hyphen character nor a
+ * hash character. Should be < 32 characters.
+ */
+ String getName();
+
+ /**
+ * Returns the Java class associated with the UPnP data type of this state
+ * variable.
+ * <P>
+ * Mapping between the UPnP data types and Java classes is performed
+ * according to the schema mentioned above.
+ *
+ * <pre>
+ *
+ * Integer ui1, ui2, i1, i2, i4, int
+ * Long ui4, time, time.tz
+ * Float r4, float
+ * Double r8, number, fixed.14.4
+ * Character char
+ * String string, uri, uuid
+ * Date date, dateTime, dateTime.tz
+ * Boolean boolean
+ * byte[] bin.base64, bin.hex
+ *
+ * </pre>
+ *
+ * @return A class object corresponding to the Java type of this argument.
+ */
+ Class getJavaDataType();
+
+ /**
+ * Returns the UPnP type of this state variable. Valid types are defined as
+ * constants.
+ *
+ * @return The UPnP data type of this state variable, as defined in above
+ * constants.
+ */
+ String getUPnPDataType();
+
+ /**
+ * Returns the default value, if defined.
+ *
+ * @return The default value or <code>null</code> if not defined. The type of
+ * the returned object can be determined by <code>getJavaDataType</code>.
+ */
+ Object getDefaultValue();
+
+ /**
+ * Returns the allowed values, if defined. Allowed values can be defined
+ * only for String types.
+ *
+ * @return The allowed values or <code>null</code> if not defined. Should be
+ * less than 32 characters.
+ */
+ String[] getAllowedValues();
+
+ /**
+ * Returns the minimum value, if defined. Minimum values can only be defined
+ * for numeric types.
+ *
+ * @return The minimum value or <code>null</code> if not defined.
+ */
+ Number getMinimum();
+
+ /**
+ * Returns the maximum value, if defined. Maximum values can only be defined
+ * for numeric types.
+ *
+ * @return The maximum value or <code>null</code> if not defined.
+ */
+ Number getMaximum();
+
+ /**
+ * Returns the size of an increment operation, if defined. Step sizes can be
+ * defined only for numeric types.
+ *
+ * @return The increment size or null if not defined.
+ */
+ Number getStep();
+
+ /**
+ * Tells if this StateVariable can be used as an event source.
+ *
+ * If the StateVariable is eventable, an event listener service can be
+ * registered to be notified when changes to the variable appear.
+ *
+ * @return <code>true</code> if the <code>StateVariable</code> generates events,
+ * <code>false</code> otherwise.
+ */
+ boolean sendsEvents();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/package.html b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/package.html
new file mode 100644
index 0000000..5422e04
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>UPnP Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.upnp; version="[1.1,2.0)"
+</pre>
+</BODY>
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/packageinfo b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/upnp/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/Authorization.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/Authorization.java
new file mode 100644
index 0000000..94289f7
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/Authorization.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.useradmin;
+
+/**
+ * The <code>Authorization</code> interface encapsulates an authorization context
+ * on which bundles can base authorization decisions, where appropriate.
+ * <p>
+ * Bundles associate the privilege to access restricted resources or operations
+ * with roles. Before granting access to a restricted resource or operation, a
+ * bundle will check if the <code>Authorization</code> object passed to it possess
+ * the required role, by calling its <code>hasRole</code> method.
+ * <p>
+ * Authorization contexts are instantiated by calling the
+ * {@link UserAdmin#getAuthorization} method.
+ *
+ * <p>
+ * <i>Trusting Authorization objects </i>
+ * <p>
+ * There are no restrictions regarding the creation of <code>Authorization</code>
+ * objects. Hence, a service must only accept <code>Authorization</code> objects
+ * from bundles that has been authorized to use the service using code based (or
+ * Java 2) permissions.
+ *
+ * <p>
+ * In some cases it is useful to use <code>ServicePermission</code> to do the code
+ * based access control. A service basing user access control on
+ * <code>Authorization</code> objects passed to it, will then require that a
+ * calling bundle has the <code>ServicePermission</code> to get the service in
+ * question. This is the most convenient way. The OSGi environment will do the
+ * code based permission check when the calling bundle attempts to get the
+ * service from the service registry.
+ * <p>
+ * Example: A servlet using a service on a user's behalf. The bundle with the
+ * servlet must be given the <code>ServicePermission</code> to get the Http
+ * Service.
+ * <p>
+ * However, in some cases the code based permission checks need to be more
+ * fine-grained. A service might allow all bundles to get it, but require
+ * certain code based permissions for some of its methods.
+ * <p>
+ * Example: A servlet using a service on a user's behalf, where some service
+ * functionality is open to anyone, and some is restricted by code based
+ * permissions. When a restricted method is called (e.g., one handing over an
+ * <code>Authorization</code> object), the service explicitly checks that the
+ * calling bundle has permission to make the call.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface Authorization {
+ /**
+ * Gets the name of the {@link User} that this <code>Authorization</code>
+ * context was created for.
+ *
+ * @return The name of the {@link User} object that this
+ * <code>Authorization</code> context was created for, or
+ * <code>null</code> if no user was specified when this
+ * <code>Authorization</code> context was created.
+ */
+ public String getName();
+
+ /**
+ * Checks if the role with the specified name is implied by this
+ * <code>Authorization</code> context.
+ * <p>
+ *
+ * Bundles must define globally unique role names that are associated with
+ * the privilege of accessing restricted resources or operations. Operators
+ * will grant users access to these resources, by creating a {@link Group}
+ * object for each role and adding {@link User} objects to it.
+ *
+ * @param name The name of the role to check for.
+ *
+ * @return <code>true</code> if this <code>Authorization</code> context implies
+ * the specified role, otherwise <code>false</code>.
+ */
+ public boolean hasRole(String name);
+
+ /**
+ * Gets the names of all roles implied by this <code>Authorization</code>
+ * context.
+ *
+ * @return The names of all roles implied by this
+ * <code>Authorization</code> context, or <code>null</code> if no roles
+ * are in the context. The predefined role <code>user.anyone</code>
+ * will not be included in this list.
+ */
+ public String[] getRoles();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/Group.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/Group.java
new file mode 100644
index 0000000..4016a43
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/Group.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.useradmin;
+
+/**
+ * A named grouping of roles (<code>Role</code> objects).
+ * <p>
+ * Whether or not a given <code>Authorization</code> context implies a
+ * <code>Group</code> object depends on the members of that <code>Group</code>
+ * object.
+ * <p>
+ * A <code>Group</code> object can have two kinds of members: <i>basic </i> and
+ * <i>required </i>. A <code>Group</code> object is implied by an
+ * <code>Authorization</code> context if all of its required members are implied
+ * and at least one of its basic members is implied.
+ * <p>
+ * A <code>Group</code> object must contain at least one basic member in order to
+ * be implied. In other words, a <code>Group</code> object without any basic
+ * member roles is never implied by any <code>Authorization</code> context.
+ * <p>
+ * A <code>User</code> object always implies itself.
+ * <p>
+ * No loop detection is performed when adding members to <code>Group</code>
+ * objects, which means that it is possible to create circular implications.
+ * Loop detection is instead done when roles are checked. The semantics is that
+ * if a role depends on itself (i.e., there is an implication loop), the role is
+ * not implied.
+ * <p>
+ * The rule that a <code>Group</code> object must have at least one basic member
+ * to be implied is motivated by the following example:
+ *
+ * <pre>
+ *
+ * group foo
+ * required members: marketing
+ * basic members: alice, bob
+ *
+ * </pre>
+ *
+ * Privileged operations that require membership in "foo" can be performed only
+ * by "alice" and "bob", who are in marketing.
+ * <p>
+ * If "alice" and "bob" ever transfer to a different department, anybody in
+ * marketing will be able to assume the "foo" role, which certainly must be
+ * prevented. Requiring that "foo" (or any <code>Group</code> object for that
+ * matter) must have at least one basic member accomplishes that.
+ * <p>
+ * However, this would make it impossible for a <code>Group</code> object to be
+ * implied by just its required members. An example where this implication might
+ * be useful is the following declaration: "Any citizen who is an adult is
+ * allowed to vote." An intuitive configuration of "voter" would be:
+ *
+ * <pre>
+ *
+ * group voter
+ * required members: citizen, adult
+ * basic members:
+ *
+ * </pre>
+ *
+ * However, according to the above rule, the "voter" role could never be assumed
+ * by anybody, since it lacks any basic members. In order to address this issue
+ * a predefined role named "user.anyone" can be specified, which is always
+ * implied. The desired implication of the "voter" group can then be achieved by
+ * specifying "user.anyone" as its basic member, as follows:
+ *
+ * <pre>
+ *
+ * group voter
+ * required members: citizen, adult
+ * basic members: user.anyone
+ *
+ * </pre>
+ *
+ * @version $Revision: 5673 $
+ */
+public interface Group extends User {
+ /**
+ * Adds the specified <code>Role</code> object as a basic member to this
+ * <code>Group</code> object.
+ *
+ * @param role The role to add as a basic member.
+ *
+ * @return <code>true</code> if the given role could be added as a basic
+ * member, and <code>false</code> if this <code>Group</code> object
+ * already contains a <code>Role</code> object whose name matches that
+ * of the specified role.
+ *
+ * @throws SecurityException If a security manager exists and the caller
+ * does not have the <code>UserAdminPermission</code> with name
+ * <code>admin</code>.
+ */
+ public boolean addMember(Role role);
+
+ /**
+ * Adds the specified <code>Role</code> object as a required member to this
+ * <code>Group</code> object.
+ *
+ * @param role The <code>Role</code> object to add as a required member.
+ *
+ * @return <code>true</code> if the given <code>Role</code> object could be
+ * added as a required member, and <code>false</code> if this
+ * <code>Group</code> object already contains a <code>Role</code> object
+ * whose name matches that of the specified role.
+ *
+ * @throws SecurityException If a security manager exists and the caller
+ * does not have the <code>UserAdminPermission</code> with name
+ * <code>admin</code>.
+ */
+ public boolean addRequiredMember(Role role);
+
+ /**
+ * Removes the specified <code>Role</code> object from this <code>Group</code>
+ * object.
+ *
+ * @param role The <code>Role</code> object to remove from this <code>Group</code>
+ * object.
+ *
+ * @return <code>true</code> if the <code>Role</code> object could be removed,
+ * otherwise <code>false</code>.
+ *
+ * @throws SecurityException If a security manager exists and the caller
+ * does not have the <code>UserAdminPermission</code> with name
+ * <code>admin</code>.
+ */
+ public boolean removeMember(Role role);
+
+ /**
+ * Gets the basic members of this <code>Group</code> object.
+ *
+ * @return The basic members of this <code>Group</code> object, or
+ * <code>null</code> if this <code>Group</code> object does not contain
+ * any basic members.
+ */
+ public Role[] getMembers();
+
+ /**
+ * Gets the required members of this <code>Group</code> object.
+ *
+ * @return The required members of this <code>Group</code> object, or
+ * <code>null</code> if this <code>Group</code> object does not contain
+ * any required members.
+ */
+ public Role[] getRequiredMembers();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/Role.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/Role.java
new file mode 100644
index 0000000..e33d559
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/Role.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.useradmin;
+
+import java.util.Dictionary;
+
+/**
+ * The base interface for <code>Role</code> objects managed by the User Admin
+ * service.
+ *
+ * <p>
+ * This interface exposes the characteristics shared by all <code>Role</code>
+ * classes: a name, a type, and a set of properties.
+ * <p>
+ * Properties represent public information about the <code>Role</code> object that
+ * can be read by anyone. Specific {@link UserAdminPermission} objects are
+ * required to change a <code>Role</code> object's properties.
+ * <p>
+ * <code>Role</code> object properties are <code>Dictionary</code> objects. Changes
+ * to these objects are propagated to the User Admin service and made
+ * persistent.
+ * <p>
+ * Every User Admin service contains a set of predefined <code>Role</code> objects
+ * that are always present and cannot be removed. All predefined <code>Role</code>
+ * objects are of type <code>ROLE</code>. This version of the
+ * <code>org.osgi.service.useradmin</code> package defines a single predefined
+ * role named "user.anyone", which is inherited by any other role.
+ * Other predefined roles may be added in the future. Since
+ * "user.anyone" is a <code>Role</code> object that has properties
+ * associated with it that can be read and modified. Access to these properties
+ * and their use is application specific and is controlled using
+ * <code>UserAdminPermission</code> in the same way that properties for other
+ * <code>Role</code> objects are.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface Role {
+ /**
+ * The name of the predefined role, user.anyone, that all users and groups
+ * belong to.
+ * @since 1.1
+ */
+ public static final String USER_ANYONE = "user.anyone";
+ /**
+ * The type of a predefined role.
+ *
+ * <p>
+ * The value of <code>ROLE</code> is 0.
+ */
+ public static final int ROLE = 0;
+ /**
+ * The type of a {@link User} role.
+ *
+ * <p>
+ * The value of <code>USER</code> is 1.
+ */
+ public static final int USER = 1;
+ /**
+ * The type of a {@link Group} role.
+ *
+ * <p>
+ * The value of <code>GROUP</code> is 2.
+ */
+ public static final int GROUP = 2;
+
+ /**
+ * Returns the name of this role.
+ *
+ * @return The role's name.
+ */
+ public String getName();
+
+ /**
+ * Returns the type of this role.
+ *
+ * @return The role's type.
+ */
+ public int getType();
+
+ /**
+ * Returns a <code>Dictionary</code> of the (public) properties of this
+ * <code>Role</code> object. Any changes to the returned <code>Dictionary</code>
+ * will change the properties of this <code>Role</code> object. This will
+ * cause a <code>UserAdminEvent</code> object of type
+ * {@link UserAdminEvent#ROLE_CHANGED} to be broadcast to any
+ * <code>UserAdminListener</code> objects.
+ *
+ * <p>
+ * Only objects of type <code>String</code> may be used as property keys, and
+ * only objects of type <code>String</code> or <code>byte[]</code> may be used
+ * as property values. Any other types will cause an exception of type
+ * <code>IllegalArgumentException</code> to be raised.
+ *
+ * <p>
+ * In order to add, change, or remove a property in the returned
+ * <code>Dictionary</code>, a {@link UserAdminPermission} named after the
+ * property name (or a prefix of it) with action <code>changeProperty</code>
+ * is required.
+ *
+ * @return <code>Dictionary</code> containing the properties of this
+ * <code>Role</code> object.
+ */
+ public Dictionary getProperties();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/User.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/User.java
new file mode 100644
index 0000000..b9103fd
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/User.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.useradmin;
+
+import java.util.Dictionary;
+
+/**
+ * A <code>User</code> role managed by a User Admin service.
+ *
+ * <p>
+ * In this context, the term "user" is not limited to just human
+ * beings. Instead, it refers to any entity that may have any number of
+ * credentials associated with it that it may use to authenticate itself.
+ * <p>
+ * In general, <code>User</code> objects are associated with a specific User Admin
+ * service (namely the one that created them), and cannot be used with other
+ * User Admin services.
+ * <p>
+ * A <code>User</code> object may have credentials (and properties, inherited from
+ * the {@link Role} class) associated with it. Specific
+ * {@link UserAdminPermission} objects are required to read or change a
+ * <code>User</code> object's credentials.
+ * <p>
+ * Credentials are <code>Dictionary</code> objects and have semantics that are
+ * similar to the properties in the <code>Role</code> class.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface User extends Role {
+ /**
+ * Returns a <code>Dictionary</code> of the credentials of this <code>User</code>
+ * object. Any changes to the returned <code>Dictionary</code> object will
+ * change the credentials of this <code>User</code> object. This will cause a
+ * <code>UserAdminEvent</code> object of type
+ * {@link UserAdminEvent#ROLE_CHANGED} to be broadcast to any
+ * <code>UserAdminListeners</code> objects.
+ *
+ * <p>
+ * Only objects of type <code>String</code> may be used as credential keys,
+ * and only objects of type <code>String</code> or of type <code>byte[]</code>
+ * may be used as credential values. Any other types will cause an exception
+ * of type <code>IllegalArgumentException</code> to be raised.
+ *
+ * <p>
+ * In order to retrieve a credential from the returned <code>Dictionary</code>
+ * object, a {@link UserAdminPermission} named after the credential name (or
+ * a prefix of it) with action <code>getCredential</code> is required.
+ * <p>
+ * In order to add or remove a credential from the returned
+ * <code>Dictionary</code> object, a {@link UserAdminPermission} named after
+ * the credential name (or a prefix of it) with action
+ * <code>changeCredential</code> is required.
+ *
+ * @return <code>Dictionary</code> object containing the credentials of this
+ * <code>User</code> object.
+ */
+ public Dictionary getCredentials();
+
+ /**
+ * Checks to see if this <code>User</code> object has a credential with the
+ * specified <code>key</code> set to the specified <code>value</code>.
+ *
+ * <p>
+ * If the specified credential <code>value</code> is not of type
+ * <code>String</code> or <code>byte[]</code>, it is ignored, that is,
+ * <code>false</code> is returned (as opposed to an
+ * <code>IllegalArgumentException</code> being raised).
+ *
+ * @param key The credential <code>key</code>.
+ * @param value The credential <code>value</code>.
+ *
+ * @return <code>true</code> if this user has the specified credential;
+ * <code>false</code> otherwise.
+ *
+ * @throws SecurityException If a security manager exists and the caller
+ * does not have the <code>UserAdminPermission</code> named after the
+ * credential key (or a prefix of it) with action
+ * <code>getCredential</code>.
+ */
+ public boolean hasCredential(String key, Object value);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/UserAdmin.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/UserAdmin.java
new file mode 100644
index 0000000..2e4b096
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/UserAdmin.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.useradmin;
+
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * This interface is used to manage a database of named <code>Role</code> objects,
+ * which can be used for authentication and authorization purposes.
+ *
+ * <p>
+ * This version of the User Admin service defines two types of <code>Role</code>
+ * objects: "User" and "Group". Each type of role is represented by an
+ * <code>int</code> constant and an interface. The range of positive integers is
+ * reserved for new types of roles that may be added in the future. When
+ * defining proprietary role types, negative constant values must be used.
+ *
+ * <p>
+ * Every role has a name and a type.
+ *
+ * <p>
+ * A {@link User} object can be configured with credentials (e.g., a password)
+ * and properties (e.g., a street address, phone number, etc.).
+ * <p>
+ * A {@link Group} object represents an aggregation of {@link User} and
+ * {@link Group} objects. In other words, the members of a <code>Group</code>
+ * object are roles themselves.
+ * <p>
+ * Every User Admin service manages and maintains its own namespace of
+ * <code>Role</code> objects, in which each <code>Role</code> object has a unique
+ * name.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface UserAdmin {
+ /**
+ * Creates a <code>Role</code> object with the given name and of the given
+ * type.
+ *
+ * <p>
+ * If a <code>Role</code> object was created, a <code>UserAdminEvent</code>
+ * object of type {@link UserAdminEvent#ROLE_CREATED} is broadcast to any
+ * <code>UserAdminListener</code> object.
+ *
+ * @param name The <code>name</code> of the <code>Role</code> object to create.
+ * @param type The type of the <code>Role</code> object to create. Must be
+ * either a {@link Role#USER} type or {@link Role#GROUP} type.
+ *
+ * @return The newly created <code>Role</code> object, or <code>null</code> if a
+ * role with the given name already exists.
+ *
+ * @throws IllegalArgumentException if <code>type</code> is invalid.
+ *
+ * @throws SecurityException If a security manager exists and the caller
+ * does not have the <code>UserAdminPermission</code> with name
+ * <code>admin</code>.
+ */
+ public Role createRole(String name, int type);
+
+ /**
+ * Removes the <code>Role</code> object with the given name from this User
+ * Admin service and all groups it is a member of.
+ *
+ * <p>
+ * If the <code>Role</code> object was removed, a <code>UserAdminEvent</code>
+ * object of type {@link UserAdminEvent#ROLE_REMOVED} is broadcast to any
+ * <code>UserAdminListener</code> object.
+ *
+ * @param name The name of the <code>Role</code> object to remove.
+ *
+ * @return <code>true</code> If a <code>Role</code> object with the given name
+ * is present in this User Admin service and could be removed,
+ * otherwise <code>false</code>.
+ *
+ * @throws SecurityException If a security manager exists and the caller
+ * does not have the <code>UserAdminPermission</code> with name
+ * <code>admin</code>.
+ */
+ public boolean removeRole(String name);
+
+ /**
+ * Gets the <code>Role</code> object with the given <code>name</code> from this
+ * User Admin service.
+ *
+ * @param name The name of the <code>Role</code> object to get.
+ *
+ * @return The requested <code>Role</code> object, or <code>null</code> if this
+ * User Admin service does not have a <code>Role</code> object with
+ * the given <code>name</code>.
+ */
+ public Role getRole(String name);
+
+ /**
+ * Gets the <code>Role</code> objects managed by this User Admin service that
+ * have properties matching the specified LDAP filter criteria. See
+ * <code>org.osgi.framework.Filter</code> for a description of the filter
+ * syntax. If a <code>null</code> filter is specified, all Role objects
+ * managed by this User Admin service are returned.
+ *
+ * @param filter The filter criteria to match.
+ *
+ * @return The <code>Role</code> objects managed by this User Admin service
+ * whose properties match the specified filter criteria, or all
+ * <code>Role</code> objects if a <code>null</code> filter is specified.
+ * If no roles match the filter, <code>null</code> will be returned.
+ * @throws InvalidSyntaxException If the filter is not well formed.
+ *
+ */
+ public Role[] getRoles(String filter) throws InvalidSyntaxException;
+
+ /**
+ * Gets the user with the given property <code>key</code>-<code>value</code>
+ * pair from the User Admin service database. This is a convenience method
+ * for retrieving a <code>User</code> object based on a property for which
+ * every <code>User</code> object is supposed to have a unique value (within
+ * the scope of this User Admin service), such as for example a X.500
+ * distinguished name.
+ *
+ * @param key The property key to look for.
+ * @param value The property value to compare with.
+ *
+ * @return A matching user, if <em>exactly</em> one is found. If zero or
+ * more than one matching users are found, <code>null</code> is
+ * returned.
+ */
+ public User getUser(String key, String value);
+
+ /**
+ * Creates an <code>Authorization</code> object that encapsulates the
+ * specified <code>User</code> object and the <code>Role</code> objects it
+ * possesses. The <code>null</code> user is interpreted as the anonymous user.
+ * The anonymous user represents a user that has not been authenticated. An
+ * <code>Authorization</code> object for an anonymous user will be unnamed,
+ * and will only imply groups that user.anyone implies.
+ *
+ * @param user The <code>User</code> object to create an
+ * <code>Authorization</code> object for, or <code>null</code> for the
+ * anonymous user.
+ *
+ * @return the <code>Authorization</code> object for the specified
+ * <code>User</code> object.
+ */
+ public Authorization getAuthorization(User user);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/UserAdminEvent.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/UserAdminEvent.java
new file mode 100644
index 0000000..88ef8fb
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/UserAdminEvent.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.useradmin;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * <code>Role</code> change event.
+ * <p>
+ * <code>UserAdminEvent</code> objects are delivered asynchronously to any
+ * <code>UserAdminListener</code> objects when a change occurs in any of the
+ * <code>Role</code> objects managed by a User Admin service.
+ *
+ * <p>
+ * A type code is used to identify the event. The following event types are
+ * defined: {@link #ROLE_CREATED} type, {@link #ROLE_CHANGED} type, and
+ * {@link #ROLE_REMOVED} type. Additional event types may be defined in the
+ * future.
+ *
+ * @see UserAdmin
+ * @see UserAdminListener
+ *
+ * @version $Revision: 5673 $
+ */
+public class UserAdminEvent {
+ private ServiceReference ref;
+ private int type;
+ private Role role;
+ /**
+ * A <code>Role</code> object has been created.
+ *
+ * <p>
+ * The value of <code>ROLE_CREATED</code> is 0x00000001.
+ */
+ public static final int ROLE_CREATED = 0x00000001;
+ /**
+ * A <code>Role</code> object has been modified.
+ *
+ * <p>
+ * The value of <code>ROLE_CHANGED</code> is 0x00000002.
+ */
+ public static final int ROLE_CHANGED = 0x00000002;
+ /**
+ * A <code>Role</code> object has been removed.
+ *
+ * <p>
+ * The value of <code>ROLE_REMOVED</code> is 0x00000004.
+ */
+ public static final int ROLE_REMOVED = 0x00000004;
+
+ /**
+ * Constructs a <code>UserAdminEvent</code> object from the given
+ * <code>ServiceReference</code> object, event type, and <code>Role</code>
+ * object.
+ *
+ * @param ref The <code>ServiceReference</code> object of the User Admin
+ * service that generated this event.
+ * @param type The event type.
+ * @param role The <code>Role</code> object on which this event occurred.
+ */
+ public UserAdminEvent(ServiceReference ref, int type, Role role) {
+ this.ref = ref;
+ this.type = type;
+ this.role = role;
+ }
+
+ /**
+ * Gets the <code>ServiceReference</code> object of the User Admin service
+ * that generated this event.
+ *
+ * @return The User Admin service's <code>ServiceReference</code> object.
+ */
+ public ServiceReference getServiceReference() {
+ return ref;
+ }
+
+ /**
+ * Returns the type of this event.
+ *
+ * <p>
+ * The type values are {@link #ROLE_CREATED} type, {@link #ROLE_CHANGED}
+ * type, and {@link #ROLE_REMOVED} type.
+ *
+ * @return The event type.
+ */
+ public int getType() {
+ return type;
+ }
+
+ /**
+ * Gets the <code>Role</code> object this event was generated for.
+ *
+ * @return The <code>Role</code> object this event was generated for.
+ */
+ public Role getRole() {
+ return role;
+ }
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/UserAdminListener.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/UserAdminListener.java
new file mode 100644
index 0000000..a301b92
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/UserAdminListener.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.useradmin;
+
+/**
+ * Listener for UserAdminEvents.
+ *
+ * <p>
+ * <code>UserAdminListener</code> objects are registered with the Framework
+ * service registry and notified with a <code>UserAdminEvent</code> object when a
+ * <code>Role</code> object has been created, removed, or modified.
+ * <p>
+ * <code>UserAdminListener</code> objects can further inspect the received
+ * <code>UserAdminEvent</code> object to determine its type, the <code>Role</code>
+ * object it occurred on, and the User Admin service that generated it.
+ *
+ * @see UserAdmin
+ * @see UserAdminEvent
+ *
+ * @version $Revision: 5673 $
+ */
+public interface UserAdminListener {
+ /**
+ * Receives notification that a <code>Role</code> object has been created,
+ * removed, or modified.
+ *
+ * @param event The <code>UserAdminEvent</code> object.
+ */
+ public void roleChanged(UserAdminEvent event);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/UserAdminPermission.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/UserAdminPermission.java
new file mode 100644
index 0000000..52be194
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/UserAdminPermission.java
@@ -0,0 +1,643 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2009). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.useradmin;
+
+import java.io.IOException;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * Permission to configure and access the {@link Role} objects managed by a User
+ * Admin service.
+ *
+ * <p>
+ * This class represents access to the <code>Role</code> objects managed by a
+ * User Admin service and their properties and credentials (in the case of
+ * {@link User} objects).
+ * <p>
+ * The permission name is the name (or name prefix) of a property or credential.
+ * The naming convention follows the hierarchical property naming convention.
+ * Also, an asterisk may appear at the end of the name, following a
+ * ".", or by itself, to signify a wildcard match. For example:
+ * "org.osgi.security.protocol.*" or "*" is valid, but
+ * "*protocol" or "a*b" are not valid.
+ *
+ * <p>
+ * The <code>UserAdminPermission</code> with the reserved name "admin"
+ * represents the permission required for creating and removing
+ * <code>Role</code> objects in the User Admin service, as well as adding and
+ * removing members in a <code>Group</code> object. This
+ * <code>UserAdminPermission</code> does not have any actions associated with
+ * it.
+ *
+ * <p>
+ * The actions to be granted are passed to the constructor in a string
+ * containing a list of one or more comma-separated keywords. The possible
+ * keywords are: <code>changeProperty</code>,<code>changeCredential</code>, and
+ * <code>getCredential</code>. Their meaning is defined as follows:
+ *
+ * <pre>
+ *
+ * action
+ * changeProperty Permission to change (i.e., add and remove)
+ * Role object properties whose names start with
+ * the name argument specified in the constructor.
+ * changeCredential Permission to change (i.e., add and remove)
+ * User object credentials whose names start
+ * with the name argument specified in the constructor.
+ * getCredential Permission to retrieve and check for the
+ * existence of User object credentials whose names
+ * start with the name argument specified in the
+ * constructor.
+ *
+ * </pre>
+ *
+ * The action string is converted to lowercase before processing.
+ *
+ * <p>
+ * Following is a PermissionInfo style policy entry which grants a user
+ * administration bundle a number of <code>UserAdminPermission</code> object:
+ *
+ * <pre>
+ *
+ * (org.osgi.service.useradmin.UserAdminPermission "admin")
+ * (org.osgi.service.useradmin.UserAdminPermission "com.foo.*" "changeProperty,getCredential,changeCredential")
+ * (org.osgi.service.useradmin.UserAdminPermission "user.*", "changeProperty,changeCredential")
+ *
+ * </pre>
+ *
+ * The first permission statement grants the bundle the permission to perform
+ * any User Admin service operations of type "admin", that is, create and remove
+ * roles and configure <code>Group</code> objects.
+ *
+ * <p>
+ * The second permission statement grants the bundle the permission to change
+ * any properties as well as get and change any credentials whose names start
+ * with <code>com.foo.</code>.
+ *
+ * <p>
+ * The third permission statement grants the bundle the permission to change any
+ * properties and credentials whose names start with <code>user.</code>. This
+ * means that the bundle is allowed to change, but not retrieve any credentials
+ * with the given prefix.
+ *
+ * <p>
+ * The following policy entry empowers the Http Service bundle to perform user
+ * authentication:
+ *
+ * <pre>
+ *
+ * grant codeBase "${jars}http.jar" {
+ * permission org.osgi.service.useradmin.UserAdminPermission
+ * "user.password", "getCredential";
+ * };
+ *
+ * </pre>
+ *
+ * <p>
+ * The permission statement grants the Http Service bundle the permission to
+ * validate any password credentials (for authentication purposes), but the
+ * bundle is not allowed to change any properties or credentials.
+ *
+ * @ThreadSafe
+ * @version $Revision: 6381 $
+ */
+public final class UserAdminPermission extends BasicPermission {
+ static final long serialVersionUID = -1179971692401603789L;
+ /**
+ * The permission name "admin".
+ */
+ public static final String ADMIN = "admin";
+ /**
+ * The action string "changeProperty".
+ */
+ public static final String CHANGE_PROPERTY = "changeProperty";
+ private static final int ACTION_CHANGE_PROPERTY = 0x1;
+ /**
+ * The action string "changeCredential".
+ */
+ public static final String CHANGE_CREDENTIAL = "changeCredential";
+ private static final int ACTION_CHANGE_CREDENTIAL = 0x2;
+ /**
+ * The action string "getCredential".
+ */
+ public static final String GET_CREDENTIAL = "getCredential";
+ private static final int ACTION_GET_CREDENTIAL = 0x4;
+ /**
+ * All actions
+ */
+ private static final int ACTION_ALL = ACTION_CHANGE_PROPERTY
+ | ACTION_CHANGE_CREDENTIAL
+ | ACTION_GET_CREDENTIAL;
+ /**
+ * No actions.
+ */
+ static final int ACTION_NONE = 0;
+ /**
+ * The actions in canonical form.
+ *
+ * @serial
+ */
+ private volatile String actions = null;
+ /**
+ * The actions mask.
+ */
+ private transient int action_mask;
+
+ /**
+ * Creates a new <code>UserAdminPermission</code> with the specified name
+ * and actions. <code>name</code> is either the reserved string
+ * "admin" or the name of a credential or property, and
+ * <code>actions</code> contains a comma-separated list of the actions
+ * granted on the specified name. Valid actions are
+ * <code>changeProperty</code>,<code>changeCredential</code>, and
+ * getCredential.
+ *
+ * @param name the name of this <code>UserAdminPermission</code>
+ * @param actions the action string.
+ *
+ * @throws IllegalArgumentException If <code>name</code> equals
+ * "admin" and <code>actions</code> are specified.
+ */
+ public UserAdminPermission(String name, String actions) {
+ this(name, parseActions(actions));
+ }
+
+ /**
+ * Package private constructor used by
+ * <code>UserAdminPermissionCollection</code>.
+ *
+ * @param name class name
+ * @param mask action mask
+ */
+ UserAdminPermission(String name, int mask) {
+ super(name);
+ setTransients(mask);
+ }
+
+ /**
+ * Called by constructors and when deserialized.
+ *
+ * @param mask action mask
+ */
+ private synchronized void setTransients(int mask) {
+ if (getName().equals(ADMIN)) {
+ if (mask != ACTION_NONE) {
+ throw new IllegalArgumentException("Actions specified for "
+ + "no-action " + "UserAdminPermission");
+ }
+ }
+ else {
+ if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+ throw new IllegalArgumentException("Invalid action string");
+ }
+ }
+ action_mask = mask;
+ }
+
+ /**
+ * Returns the current action mask.
+ * <p>
+ * Used by the UserAdminPermissionCollection class.
+ *
+ * @return Current action mask.
+ */
+ synchronized int getActionsMask() {
+ return action_mask;
+ }
+
+ /**
+ * Parse action string into action mask.
+ *
+ * @param actions Action string.
+ * @return action mask.
+ */
+ private static int parseActions(String actions) {
+ boolean seencomma = false;
+ int mask = ACTION_NONE;
+ if (actions == null) {
+ return mask;
+ }
+ char[] a = actions.toCharArray();
+ int i = a.length - 1;
+ if (i < 0)
+ return mask;
+ while (i != -1) {
+ char c;
+ // skip whitespace
+ while ((i != -1)
+ && ((c = a[i]) == ' ' || c == '\r' || c == '\n'
+ || c == '\f' || c == '\t'))
+ i--;
+ // check for the known strings
+ int matchlen;
+ if (i >= 12 && match_get(a, i - 10) && match_credential(a, i)) {
+ matchlen = 13;
+ mask |= ACTION_GET_CREDENTIAL;
+ }
+ else
+ if (i >= 13 && match_change(a, i - 8) && match_property(a, i)) {
+ matchlen = 14;
+ mask |= ACTION_CHANGE_PROPERTY;
+ }
+ else
+ if (i >= 15 && match_change(a, i - 10)
+ && match_credential(a, i)) {
+ matchlen = 16;
+ mask |= ACTION_CHANGE_CREDENTIAL;
+ }
+ else {
+ // parse error
+ throw new IllegalArgumentException(
+ "invalid permission: " + actions);
+ }
+ // make sure we didn't just match the tail of a word
+ // like "ackbarfimport". Also, skip to the comma.
+ seencomma = false;
+ while (i >= matchlen && !seencomma) {
+ switch (a[i - matchlen]) {
+ case ',' :
+ seencomma = true;
+ /* FALLTHROUGH */
+ case ' ' :
+ case '\r' :
+ case '\n' :
+ case '\f' :
+ case '\t' :
+ break;
+ default :
+ throw new IllegalArgumentException(
+ "invalid permission: " + actions);
+ }
+ i--;
+ }
+ // point i at the location of the comma minus one (or -1).
+ i -= matchlen;
+ }
+ if (seencomma) {
+ throw new IllegalArgumentException("invalid permission: " + actions);
+ }
+ return mask;
+ }
+
+ private static boolean match_change(char[] a, int i) {
+ return ((a[i - 5] == 'c' || a[i - 5] == 'C')
+ && (a[i - 4] == 'h' || a[i - 4] == 'H')
+ && (a[i - 3] == 'a' || a[i - 3] == 'A')
+ && (a[i - 2] == 'n' || a[i - 2] == 'N')
+ && (a[i - 1] == 'g' || a[i - 1] == 'G') && (a[i - 0] == 'e' || a[i - 0] == 'E'));
+ }
+
+ private static boolean match_get(char[] a, int i) {
+ return ((a[i - 2] == 'g' || a[i - 2] == 'G')
+ && (a[i - 1] == 'e' || a[i - 1] == 'E') && (a[i - 0] == 't' || a[i - 0] == 'T'));
+ }
+
+ private static boolean match_property(char[] a, int i) {
+ return ((a[i - 7] == 'p' || a[i - 7] == 'P')
+ && (a[i - 6] == 'r' || a[i - 6] == 'R')
+ && (a[i - 5] == 'o' || a[i - 5] == 'O')
+ && (a[i - 4] == 'p' || a[i - 4] == 'P')
+ && (a[i - 3] == 'e' || a[i - 3] == 'E')
+ && (a[i - 2] == 'r' || a[i - 2] == 'R')
+ && (a[i - 1] == 't' || a[i - 1] == 'T') && (a[i - 0] == 'y' || a[i - 0] == 'Y'));
+ }
+
+ private static boolean match_credential(char[] a, int i) {
+ return ((a[i - 9] == 'c' || a[i - 9] == 'C')
+ && (a[i - 8] == 'r' || a[i - 8] == 'R')
+ && (a[i - 7] == 'e' || a[i - 7] == 'E')
+ && (a[i - 6] == 'd' || a[i - 6] == 'D')
+ && (a[i - 5] == 'e' || a[i - 5] == 'E')
+ && (a[i - 4] == 'n' || a[i - 4] == 'N')
+ && (a[i - 3] == 't' || a[i - 3] == 'T')
+ && (a[i - 2] == 'i' || a[i - 2] == 'I')
+ && (a[i - 1] == 'a' || a[i - 1] == 'A') && (a[i - 0] == 'l' || a[i - 0] == 'L'));
+ }
+
+ /**
+ * Checks if this <code>UserAdminPermission</code> object
+ * "implies" the specified permission.
+ * <P>
+ * More specifically, this method returns <code>true</code> if:
+ * <p>
+ * <ul>
+ * <li><i>p </i> is an instanceof <code>UserAdminPermission</code>,
+ * <li><i>p </i>'s actions are a proper subset of this object's actions, and
+ * <li><i>p </i>'s name is implied by this object's name. For example,
+ * "java.*" implies "java.home".
+ * </ul>
+ *
+ * @param p the permission to check against.
+ *
+ * @return <code>true</code> if the specified permission is implied by this
+ * object; <code>false</code> otherwise.
+ */
+ public boolean implies(Permission p) {
+ if (p instanceof UserAdminPermission) {
+ UserAdminPermission requested = (UserAdminPermission) p;
+ int mask = getActionsMask();
+ int targetMask = requested.getActionsMask();
+ return // Check that the we have the requested action
+ ((targetMask & mask) == targetMask) &&
+ // If the target action mask is ACTION_NONE, it must be an
+ // admin permission, and then we must be that too
+ (targetMask != ACTION_NONE || mask == ACTION_NONE) &&
+ // Check that name name matches
+ super.implies(p);
+ }
+ return false;
+ }
+
+ /**
+ * Returns the canonical string representation of the actions, separated by
+ * comma.
+ *
+ * @return the canonical string representation of the actions.
+ */
+ public String getActions() {
+ String result = actions;
+ if (result == null) {
+ StringBuffer sb = new StringBuffer();
+ boolean comma = false;
+ int mask = getActionsMask();
+ if ((mask & ACTION_CHANGE_CREDENTIAL) == ACTION_CHANGE_CREDENTIAL) {
+ sb.append(CHANGE_CREDENTIAL);
+ comma = true;
+ }
+ if ((mask & ACTION_CHANGE_PROPERTY) == ACTION_CHANGE_PROPERTY) {
+ if (comma)
+ sb.append(',');
+ sb.append(CHANGE_PROPERTY);
+ comma = true;
+ }
+ if ((mask & ACTION_GET_CREDENTIAL) == ACTION_GET_CREDENTIAL) {
+ if (comma)
+ sb.append(',');
+ sb.append(GET_CREDENTIAL);
+ }
+ actions = result = sb.toString();
+ }
+ return result;
+ }
+
+ /**
+ * Returns a new <code>PermissionCollection</code> object for storing
+ * <code>UserAdminPermission</code> objects.
+ *
+ * @return a new <code>PermissionCollection</code> object suitable for
+ * storing <code>UserAdminPermission</code> objects.
+ */
+ public PermissionCollection newPermissionCollection() {
+ return new UserAdminPermissionCollection();
+ }
+
+ /**
+ * Checks two <code>UserAdminPermission</code> objects for equality. Checks
+ * that <code>obj</code> is a <code>UserAdminPermission</code>, and has the
+ * same name and actions as this object.
+ *
+ * @param obj the object to be compared for equality with this object.
+ *
+ * @return <code>true</code> if <code>obj</code> is a
+ * <code>UserAdminPermission</code> object, and has the same name
+ * and actions as this <code>UserAdminPermission</code> object.
+ */
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof UserAdminPermission)) {
+ return false;
+ }
+
+ UserAdminPermission uap = (UserAdminPermission) obj;
+
+ return (getActionsMask() == uap.getActionsMask())
+ && getName().equals(uap.getName());
+ }
+
+ /**
+ * Returns the hash code value for this object.
+ *
+ * @return A hash code value for this object.
+ */
+ public int hashCode() {
+ int h = 31 * 17 + getName().hashCode();
+ h = 31 * h + getActions().hashCode();
+ return h;
+ }
+
+ /**
+ * writeObject is called to save the state of this object to a stream. The
+ * actions are serialized, and the superclass takes care of the name.
+ */
+ private synchronized void writeObject(java.io.ObjectOutputStream s)
+ throws IOException {
+ // Write out the actions. The superclass takes care of the name
+ // call getActions to make sure actions field is initialized
+ if (actions == null)
+ getActions();
+ s.defaultWriteObject();
+ }
+
+ /*
+ * Restores this object from a stream (i.e., deserializes it).
+ */
+ private synchronized void readObject(java.io.ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ // Read in the action, then initialize the rest
+ s.defaultReadObject();
+ setTransients(parseActions(actions));
+ }
+
+ /**
+ * Returns a string describing this <code>UserAdminPermission</code> object.
+ * This string must be in <code>PermissionInfo</code> encoded format.
+ *
+ * @return The <code>PermissionInfo</code> encoded string for this
+ * <code>UserAdminPermission</code> object.
+ * @see "<code>org.osgi.service.permissionadmin.PermissionInfo.getEncoded</code>"
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append('(');
+ sb.append(getClass().getName());
+ sb.append(" \"");
+ sb.append(getName());
+ String a = getActions();
+ if (a.length() > 0) {
+ sb.append("\" \"");
+ sb.append(a);
+ }
+ sb.append("\")");
+ return sb.toString();
+ }
+}
+
+/**
+ * A <code>UserAdminPermissionCollection</code> stores a set of
+ * <code>UserAdminPermission</code> permissions.
+ */
+
+final class UserAdminPermissionCollection extends PermissionCollection {
+ static final long serialVersionUID = -7222111885230120581L;
+ /**
+ * Table of permissions.
+ *
+ * @serial
+ * @GuardedBy this
+ */
+ private final Hashtable permissions;
+ /**
+ * Boolean saying if "*" is in the collection.
+ *
+ * @serial
+ * @GuardedBy this
+ */
+ private boolean all_allowed;
+
+ /**
+ * Creates an empty <code>UserAdminPermissionCollection</code> object.
+ */
+ public UserAdminPermissionCollection() {
+ permissions = new Hashtable();
+ all_allowed = false;
+ }
+
+ /**
+ * Adds the given permission to this
+ * <code>UserAdminPermissionCollection</code>. The key for the hash is the
+ * name.
+ *
+ * @param permission the <code>Permission</code> object to add.
+ *
+ * @throws IllegalArgumentException If the given permission is not a
+ * <code>UserAdminPermission</code>
+ * @throws SecurityException If this
+ * <code>UserAdminPermissionCollection</code> object has been marked
+ * readonly
+ */
+ public void add(Permission permission) {
+ if (!(permission instanceof UserAdminPermission))
+ throw new IllegalArgumentException("Invalid permission: "
+ + permission);
+ if (isReadOnly()) {
+ throw new SecurityException("Attempt to add a Permission to a "
+ + "readonly PermissionCollection");
+ }
+ final UserAdminPermission uap = (UserAdminPermission) permission;
+ final String name = uap.getName();
+ synchronized (this) {
+ final UserAdminPermission existing = (UserAdminPermission) permissions
+ .get(name);
+ if (existing != null) {
+ int oldMask = existing.getActionsMask();
+ int newMask = uap.getActionsMask();
+ if (oldMask != newMask) {
+ permissions.put(name, new UserAdminPermission(name, oldMask
+ | newMask));
+ }
+ }
+ else {
+ permissions.put(name, uap);
+ }
+ if (!all_allowed) {
+ if (name.equals("*")) {
+ all_allowed = true;
+ }
+ }
+ }
+ }
+
+ /**
+ * Checks to see if this <code>PermissionCollection</code> implies the given
+ * permission.
+ *
+ * @param permission the <code>Permission</code> object to check against
+ *
+ * @return true if the given permission is implied by this
+ * <code>PermissionCollection</code>, false otherwise.
+ */
+ public boolean implies(Permission permission) {
+ if (!(permission instanceof UserAdminPermission)) {
+ return false;
+ }
+ final UserAdminPermission requested = (UserAdminPermission) permission;
+ String name = requested.getName();
+ final int desired = requested.getActionsMask();
+ UserAdminPermission x;
+ int effective = 0;
+ synchronized (this) {
+ // Short circuit if the "*" Permission was added.
+ // desired can only be ACTION_NONE when name is "admin".
+ if (all_allowed && (desired != UserAdminPermission.ACTION_NONE)) {
+ x = (UserAdminPermission) permissions.get("*");
+ if (x != null) {
+ effective |= x.getActionsMask();
+ if ((effective & desired) == desired) {
+ return true;
+ }
+ }
+ }
+ // strategy:
+ // Check for full match first. Then work our way up the
+ // name looking for matches on a.b.*
+
+ x = (UserAdminPermission) permissions.get(name);
+ }
+ if (x != null) {
+ // we have a direct hit!
+ effective |= x.getActionsMask();
+ if ((effective & desired) == desired) {
+ return true;
+ }
+ }
+ // work our way up the tree...
+ int last;
+ int offset = name.length() - 1;
+ while ((last = name.lastIndexOf(".", offset)) != -1) {
+ name = name.substring(0, last + 1) + "*";
+ synchronized (this) {
+ x = (UserAdminPermission) permissions.get(name);
+ }
+ if (x != null) {
+ effective |= x.getActionsMask();
+ if ((effective & desired) == desired) {
+ return true;
+ }
+ }
+ offset = last - 1;
+ }
+ // we don't have to check for "*" as it was already checked
+ // at the top (all_allowed), so we just return false
+ return false;
+ }
+
+ /**
+ * Returns an enumeration of all the <code>UserAdminPermission</code>
+ * objects in the container.
+ *
+ * @return an enumeration of all the <code>UserAdminPermission</code>
+ * objects.
+ */
+ public Enumeration elements() {
+ return permissions.elements();
+ }
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/package.html b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/package.html
new file mode 100644
index 0000000..c8c223d
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>User Admin Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.useradmin; version="[1.1,2.0)"
+</pre>
+</BODY>
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/packageinfo b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/useradmin/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/BasicEnvelope.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/BasicEnvelope.java
new file mode 100644
index 0000000..49df68a
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/BasicEnvelope.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.wireadmin;
+
+/**
+ * <code>BasicEnvelope</code> is an implementation of the {@link Envelope}
+ * interface
+ *
+ * @version $Revision: 5673 $
+ */
+public class BasicEnvelope implements Envelope {
+ Object value;
+ Object identification;
+ String scope;
+
+ /**
+ * Constructor.
+ *
+ * @param value Content of this envelope, may be <code>null</code>.
+ * @param identification Identifying object for this <code>Envelope</code>
+ * object, must not be <code>null</code>
+ * @param scope Scope name for this object, must not be <code>null</code>
+ * @see Envelope
+ */
+ public BasicEnvelope(Object value, Object identification, String scope) {
+ this.value = value;
+ this.identification = identification;
+ this.scope = scope;
+ }
+
+ /**
+ * @see org.osgi.service.wireadmin.Envelope#getValue()
+ */
+ public Object getValue() {
+ return value;
+ }
+
+ /**
+ * @see org.osgi.service.wireadmin.Envelope#getIdentification()
+ */
+ public Object getIdentification() {
+ return identification;
+ }
+
+ /**
+ * @see org.osgi.service.wireadmin.Envelope#getScope()
+ */
+ public String getScope() {
+ return scope;
+ }
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/Consumer.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/Consumer.java
new file mode 100644
index 0000000..cef1c1c
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/Consumer.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.wireadmin;
+
+/**
+ * Data Consumer, a service that can receive udpated values from
+ * {@link Producer} services.
+ *
+ * <p>
+ * Service objects registered under the <code>Consumer</code> interface are
+ * expected to consume values from a Producer service via a <code>Wire</code>
+ * object. A Consumer service may poll the Producer service by calling the
+ * {@link Wire#poll} method. The Consumer service will also receive an updated
+ * value when called at it's {@link #updated} method. The Producer service
+ * should have coerced the value to be an instance of one of the types specified
+ * by the {@link Wire#getFlavors} method, or one of their subclasses.
+ *
+ * <p>
+ * Consumer service objects must register with a <code>service.pid</code> and a
+ * {@link WireConstants#WIREADMIN_CONSUMER_FLAVORS} property. It is recommended
+ * that Consumer service objects also register with a
+ * <code>service.description</code> property.
+ *
+ * <p>
+ * If an <code>Exception</code> is thrown by any of the <code>Consumer</code>
+ * methods, a <code>WireAdminEvent</code> of type
+ * {@link WireAdminEvent#CONSUMER_EXCEPTION} is broadcast by the Wire Admin
+ * service.
+ *
+ * <p>
+ * Security Considerations - Data consuming bundles will require
+ * <code>ServicePermission[Consumer,REGISTER]</code>. In general, only the Wire
+ * Admin service bundle should have this permission. Thus only the Wire Admin
+ * service may directly call a Consumer service. Care must be taken in the
+ * sharing of <code>Wire</code> objects with other bundles.
+ * <p>
+ * Consumer services must be registered with their scope when they can receive
+ * different types of objects from the Producer service. The Consumer service
+ * should have <code>WirePermission</code> for each of these scope names.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface Consumer {
+ /**
+ * Update the value. This Consumer service is called by the <code>Wire</code>
+ * object with an updated value from the Producer service.
+ *
+ * <p>
+ * Note: This method may be called by a <code>Wire</code> object prior to this
+ * object being notified that it is connected to that <code>Wire</code> object
+ * (via the {@link #producersConnected} method).
+ * <p>
+ * When the Consumer service can receive <code>Envelope</code> objects, it
+ * must have registered all scope names together with the service object,
+ * and each of those names must be permitted by the bundle's
+ * <code>WirePermission</code>. If an <code>Envelope</code> object is delivered
+ * with the <code>updated</code> method, then the Consumer service should
+ * assume that the security check has been performed.
+ *
+ * @param wire The <code>Wire</code> object which is delivering the updated
+ * value.
+ * @param value The updated value. The value should be an instance of one of
+ * the types specified by the {@link Wire#getFlavors} method.
+ */
+ public void updated(Wire wire, Object value);
+
+ /**
+ * Update the list of <code>Wire</code> objects to which this Consumer service
+ * is connected.
+ *
+ * <p>
+ * This method is called when the Consumer service is first registered and
+ * subsequently whenever a <code>Wire</code> associated with this Consumer
+ * service becomes connected, is modified or becomes disconnected.
+ *
+ * <p>
+ * The Wire Admin service must call this method asynchronously. This implies
+ * that implementors of Consumer can be assured that the callback will not
+ * take place during registration when they execute the registration in a
+ * synchronized method.
+ *
+ * @param wires An array of the current and complete list of <code>Wire</code>
+ * objects to which this Consumer service is connected. May be
+ * <code>null</code> if the Consumer service is not currently connected
+ * to any <code>Wire</code> objects.
+ */
+ public void producersConnected(Wire[] wires);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/Envelope.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/Envelope.java
new file mode 100644
index 0000000..5f57638
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/Envelope.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.wireadmin;
+
+/**
+ * Identifies a contained value.
+ *
+ * An <code>Envelope</code> object combines a status value, an identification
+ * object and a scope name. The <code>Envelope</code> object allows the use of
+ * standard Java types when a Producer service can produce more than one kind of
+ * object. The <code>Envelope</code> object allows the Consumer service to
+ * recognize the kind of object that is received. For example, a door lock could
+ * be represented by a <code>Boolean</code> object. If the <code>Producer</code>
+ * service would send such a <code>Boolean</code> object, then the Consumer
+ * service would not know what door the <code>Boolean</code> object represented.
+ * The <code>Envelope</code> object contains an identification object so the
+ * Consumer service can discriminate between different kinds of values. The
+ * identification object may be a simple <code>String</code> object, but it can
+ * also be a domain specific object that is mutually agreed by the Producer and
+ * the Consumer service. This object can then contain relevant information that
+ * makes the identification easier.
+ * <p>
+ * The scope name of the envelope is used for security. The Wire object must
+ * verify that any <code>Envelope</code> object send through the <code>update</code>
+ * method or coming from the <code>poll</code> method has a scope name that
+ * matches the permissions of both the Producer service and the Consumer service
+ * involved. The wireadmin package also contains a class <code>BasicEnvelope</code>
+ * that implements the methods of this interface.
+ *
+ * @see WirePermission
+ * @see BasicEnvelope
+ *
+ * @version $Revision: 5673 $
+ */
+public interface Envelope {
+ /**
+ * Return the value associated with this <code>Envelope</code> object.
+ *
+ * @return the value of the status item, or <code>null</code> when no item is
+ * associated with this object.
+ */
+ public Object getValue();
+
+ /**
+ * Return the identification of this <code>Envelope</code> object.
+ *
+ * An identification may be of any Java type. The type must be mutually
+ * agreed between the Consumer and Producer services.
+ *
+ * @return an object which identifies the status item in the address space
+ * of the composite producer, must not be null.
+ */
+ public Object getIdentification();
+
+ /**
+ * Return the scope name of this <code>Envelope</code> object.
+ *
+ * Scope names are used to restrict the communication between the Producer
+ * and Consumer services. Only <code>Envelopes</code> objects with a scope
+ * name that is permitted for the Producer and the Consumer services must be
+ * passed through a <code>Wire</code> object.
+ *
+ * @return the security scope for the status item, must not be null.
+ */
+ public String getScope();
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/Producer.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/Producer.java
new file mode 100644
index 0000000..faf6dfd
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/Producer.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.wireadmin;
+
+/**
+ * Data Producer, a service that can generate values to be used by
+ * {@link Consumer} services.
+ *
+ * <p>
+ * Service objects registered under the Producer interface are expected to
+ * produce values (internally generated or from external sensors). The value can
+ * be of different types. When delivering a value to a <code>Wire</code> object,
+ * the Producer service should coerce the value to be an instance of one of the
+ * types specified by {@link Wire#getFlavors}. The classes are specified in
+ * order of preference.
+ *
+ * <p>
+ * When the data represented by the Producer object changes, this object should
+ * send the updated value by calling the <code>update</code> method on each of
+ * <code>Wire</code> objects passed in the most recent call to this object's
+ * {@link #consumersConnected} method. These <code>Wire</code> objects will pass
+ * the value on to the associated <code>Consumer</code> service object.
+ *
+ * <p>
+ * The Producer service may use the information in the <code>Wire</code> object's
+ * properties to schedule the delivery of values to the <code>Wire</code> object.
+ *
+ * <p>
+ * Producer service objects must register with a <code>service.pid</code> and a
+ * {@link WireConstants#WIREADMIN_PRODUCER_FLAVORS} property. It is recommended
+ * that a Producer service object also registers with a
+ * <code>service.description</code> property. Producer service objects must
+ * register with a {@link WireConstants#WIREADMIN_PRODUCER_FILTERS} property if
+ * the Producer service will be performing filtering instead of the
+ * <code>Wire</code> object.
+ *
+ * <p>
+ * If an exception is thrown by a Producer object method, a
+ * <code>WireAdminEvent</code> of type {@link WireAdminEvent#PRODUCER_EXCEPTION}
+ * is broadcast by the Wire Admin service.
+ *
+ * <p>
+ * Security Considerations. Data producing bundles will require
+ * <code>ServicePermission[Producer,REGISTER]</code> to register a Producer
+ * service. In general, only the Wire Admin service should have
+ * <code>ServicePermission[Producer,GET]</code>. Thus only the Wire Admin service
+ * may directly call a Producer service. Care must be taken in the sharing of
+ * <code>Wire</code> objects with other bundles.
+ * <p>
+ * Producer services must be registered with scope names when they can send
+ * different types of objects (composite) to the Consumer service. The Producer
+ * service should have <code>WirePermission</code> for each of these scope names.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface Producer {
+ /**
+ * Return the current value of this <code>Producer</code> object.
+ *
+ * <p>
+ * This method is called by a <code>Wire</code> object in response to the
+ * Consumer service calling the <code>Wire</code> object's <code>poll</code>
+ * method. The Producer should coerce the value to be an instance of one of
+ * the types specified by {@link Wire#getFlavors}. The types are specified
+ * in order of of preference. The returned value should be as new or newer
+ * than the last value furnished by this object.
+ *
+ * <p>
+ * Note: This method may be called by a <code>Wire</code> object prior to this
+ * object being notified that it is connected to that <code>Wire</code> object
+ * (via the {@link #consumersConnected} method).
+ * <p>
+ * If the Producer service returns an <code>Envelope</code> object that has an
+ * unpermitted scope name, then the Wire object must ignore (or remove) the
+ * transfer.
+ * <p>
+ * If the <code>Wire</code> object has a scope set, the return value must be
+ * an array of <code>Envelope</code> objects (<code>Envelope[]</code>). The
+ * <code>Wire</code> object must have removed any <code>Envelope</code> objects
+ * that have a scope name that is not in the Wire object's scope.
+ *
+ * @param wire The <code>Wire</code> object which is polling this service.
+ * @return The current value of the Producer service or <code>null</code> if
+ * the value cannot be coerced into a compatible type. Or an array
+ * of <code>Envelope</code> objects.
+ */
+ public Object polled(Wire wire);
+
+ /**
+ * Update the list of <code>Wire</code> objects to which this
+ * <code>Producer</code> object is connected.
+ *
+ * <p>
+ * This method is called when the Producer service is first registered and
+ * subsequently whenever a <code>Wire</code> associated with this Producer
+ * becomes connected, is modified or becomes disconnected.
+ *
+ * <p>
+ * The Wire Admin service must call this method asynchronously. This implies
+ * that implementors of a Producer service can be assured that the callback
+ * will not take place during registration when they execute the
+ * registration in a synchronized method.
+ *
+ * @param wires An array of the current and complete list of <code>Wire</code>
+ * objects to which this Producer service is connected. May be
+ * <code>null</code> if the Producer is not currently connected to any
+ * <code>Wire</code> objects.
+ */
+ public void consumersConnected(Wire[] wires);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/Wire.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/Wire.java
new file mode 100644
index 0000000..9e0c1a9
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/Wire.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.wireadmin;
+
+import java.util.Dictionary;
+
+/**
+ * A connection between a Producer service and a Consumer service.
+ *
+ * <p>
+ * A <code>Wire</code> object connects a Producer service to a Consumer service.
+ * Both the Producer and Consumer services are identified by their unique
+ * <code>service.pid</code> values. The Producer and Consumer services may
+ * communicate with each other via <code>Wire</code> objects that connect them.
+ * The Producer service may send updated values to the Consumer service by
+ * calling the {@link #update} method. The Consumer service may request an
+ * updated value from the Producer service by calling the {@link #poll} method.
+ *
+ * <p>
+ * A Producer service and a Consumer service may be connected through multiple
+ * <code>Wire</code> objects.
+ *
+ * <p>
+ * Security Considerations. <code>Wire</code> objects are available to Producer
+ * and Consumer services connected to a given <code>Wire</code> object and to
+ * bundles which can access the <code>WireAdmin</code> service. A bundle must have
+ * <code>ServicePermission[WireAdmin,GET]</code> to get the <code>WireAdmin</code>
+ * service to access all <code>Wire</code> objects. A bundle registering a
+ * Producer service or a Consumer service must have the appropriate
+ * <code>ServicePermission[Consumer|Producer,REGISTER]</code> to register the
+ * service and will be passed <code>Wire</code> objects when the service object's
+ * <code>consumersConnected</code> or <code>producersConnected</code> method is
+ * called.
+ *
+ * <p>
+ * Scope. Each Wire object can have a scope set with the <code>setScope</code>
+ * method. This method should be called by a Consumer service when it assumes a
+ * Producer service that is composite (supports multiple information items). The
+ * names in the scope must be verified by the <code>Wire</code> object before it
+ * is used in communication. The semantics of the names depend on the Producer
+ * service and must not be interpreted by the Wire Admin service.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface Wire {
+ /**
+ * Return the state of this <code>Wire</code> object.
+ *
+ * <p>
+ * A connected <code>Wire</code> must always be disconnected before becoming
+ * invalid.
+ *
+ * @return <code>false</code> if this <code>Wire</code> object is invalid
+ * because it has been deleted via {@link WireAdmin#deleteWire};
+ * <code>true</code> otherwise.
+ */
+ public boolean isValid();
+
+ /**
+ * Return the connection state of this <code>Wire</code> object.
+ *
+ * <p>
+ * A <code>Wire</code> is connected after the Wire Admin service receives
+ * notification that the Producer service and the Consumer service for this
+ * <code>Wire</code> object are both registered. This method will return
+ * <code>true</code> prior to notifying the Producer and Consumer services via
+ * calls to their respective <code>consumersConnected</code> and
+ * <code>producersConnected</code> methods.
+ * <p>
+ * A <code>WireAdminEvent</code> of type {@link WireAdminEvent#WIRE_CONNECTED}
+ * must be broadcast by the Wire Admin service when the <code>Wire</code>
+ * becomes connected.
+ *
+ * <p>
+ * A <code>Wire</code> object is disconnected when either the Consumer or
+ * Producer service is unregistered or the <code>Wire</code> object is
+ * deleted.
+ * <p>
+ * A <code>WireAdminEvent</code> of type
+ * {@link WireAdminEvent#WIRE_DISCONNECTED} must be broadcast by the Wire
+ * Admin service when the <code>Wire</code> becomes disconnected.
+ *
+ * @return <code>true</code> if both the Producer and Consumer for this
+ * <code>Wire</code> object are connected to the <code>Wire</code>
+ * object; <code>false</code> otherwise.
+ */
+ public boolean isConnected();
+
+ /**
+ * Return the list of data types understood by the Consumer service
+ * connected to this <code>Wire</code> object. Note that subclasses of the
+ * classes in this list are acceptable data types as well.
+ *
+ * <p>
+ * The list is the value of the
+ * {@link WireConstants#WIREADMIN_CONSUMER_FLAVORS} service property of the
+ * Consumer service object connected to this object. If no such property was
+ * registered or the type of the property value is not <code>Class[]</code>,
+ * this method must return <code>null</code>.
+ *
+ * @return An array containing the list of classes understood by the
+ * Consumer service or <code>null</code> if the <code>Wire</code> is not
+ * connected, or the consumer did not register a
+ * {@link WireConstants#WIREADMIN_CONSUMER_FLAVORS} property or the
+ * value of the property is not of type <code>Class[]</code>.
+ */
+ public Class[] getFlavors();
+
+ /**
+ * Update the value.
+ *
+ * <p>
+ * This methods is called by the Producer service to notify the Consumer
+ * service connected to this <code>Wire</code> object of an updated value.
+ * <p>
+ * If the properties of this <code>Wire</code> object contain a
+ * {@link WireConstants#WIREADMIN_FILTER} property, then filtering is
+ * performed. If the Producer service connected to this <code>Wire</code>
+ * object was registered with the service property
+ * {@link WireConstants#WIREADMIN_PRODUCER_FILTERS}, the Producer service
+ * will perform the filtering according to the rules specified for the
+ * filter. Otherwise, this <code>Wire</code> object will perform the filtering
+ * of the value.
+ * <p>
+ * If no filtering is done, or the filter indicates the updated value should
+ * be delivered to the Consumer service, then this <code>Wire</code> object
+ * must call the {@link Consumer#updated} method with the updated value. If
+ * this <code>Wire</code> object is not connected, then the Consumer service
+ * must not be called and the value is ignored.
+ * <p>
+ * If the value is an <code>Envelope</code> object, and the scope name is not
+ * permitted, then the <code>Wire</code> object must ignore this call and not
+ * transfer the object to the Consumer service.
+ *
+ * <p>
+ * A <code>WireAdminEvent</code> of type {@link WireAdminEvent#WIRE_TRACE}
+ * must be broadcast by the Wire Admin service after the Consumer service
+ * has been successfully called.
+ *
+ * @param value The updated value. The value should be an instance of one of
+ * the types returned by {@link #getFlavors}.
+ * @see WireConstants#WIREADMIN_FILTER
+ */
+ public void update(Object value);
+
+ /**
+ * Poll for an updated value.
+ *
+ * <p>
+ * This methods is normally called by the Consumer service to request an
+ * updated value from the Producer service connected to this <code>Wire</code>
+ * object. This <code>Wire</code> object will call the {@link Producer#polled}
+ * method to obtain an updated value. If this <code>Wire</code> object is not
+ * connected, then the Producer service must not be called.
+ * <p>
+ *
+ * If this <code>Wire</code> object has a scope, then this method must return
+ * an array of <code>Envelope</code> objects. The objects returned must match
+ * the scope of this object. The <code>Wire</code> object must remove all
+ * <code>Envelope</code> objects with a scope name that is not in the
+ * <code>Wire</code> object's scope. Thus, the list of objects returned must
+ * only contain <code>Envelope</code> objects with a permitted scope name. If
+ * the array becomes empty, <code>null</code> must be returned.
+ *
+ * <p>
+ * A <code>WireAdminEvent</code> of type {@link WireAdminEvent#WIRE_TRACE}
+ * must be broadcast by the Wire Admin service after the Producer service
+ * has been successfully called.
+ *
+ * @return A value whose type should be one of the types returned by
+ * {@link #getFlavors},<code>Envelope[]</code>, or <code>null</code>
+ * if the <code>Wire</code> object is not connected, the Producer
+ * service threw an exception, or the Producer service returned a
+ * value which is not an instance of one of the types returned by
+ * {@link #getFlavors}.
+ */
+ public Object poll();
+
+ /**
+ * Return the last value sent through this <code>Wire</code> object.
+ *
+ * <p>
+ * The returned value is the most recent, valid value passed to the
+ * {@link #update} method or returned by the {@link #poll} method of this
+ * object. If filtering is performed by this <code>Wire</code> object, this
+ * methods returns the last value provided by the Producer service. This
+ * value may be an <code>Envelope[]</code> when the Producer service uses
+ * scoping. If the return value is an Envelope object (or array), it must be
+ * verified that the Consumer service has the proper WirePermission to see
+ * it.
+ *
+ * @return The last value passed though this <code>Wire</code> object or
+ * <code>null</code> if no valid values have been passed or the
+ * Consumer service has no permission.
+ */
+ public Object getLastValue();
+
+ /**
+ * Return the wire properties for this <code>Wire</code> object.
+ *
+ * @return The properties for this <code>Wire</code> object. The returned
+ * <code>Dictionary</code> must be read only.
+ */
+ public Dictionary getProperties();
+
+ /**
+ * Return the calculated scope of this <code>Wire</code> object.
+ *
+ * The purpose of the <code>Wire</code> object's scope is to allow a Producer
+ * and/or Consumer service to produce/consume different types over a single
+ * <code>Wire</code> object (this was deemed necessary for efficiency
+ * reasons). Both the Consumer service and the Producer service must set an
+ * array of scope names (their scope) with the service registration property
+ * <code>WIREADMIN_PRODUCER_SCOPE</code>, or
+ * <code>WIREADMIN_CONSUMER_SCOPE</code> when they can produce multiple types.
+ * If a Producer service can produce different types, it should set this
+ * property to the array of scope names it can produce, the Consumer service
+ * must set the array of scope names it can consume. The scope of a
+ * <code>Wire</code> object is defined as the intersection of permitted scope
+ * names of the Producer service and Consumer service.
+ * <p>
+ * If neither the Consumer, or the Producer service registers scope names
+ * with its service registration, then the <code>Wire</code> object's scope
+ * must be <code>null</code>.
+ * <p>
+ * The <code>Wire</code> object's scope must not change when a Producer or
+ * Consumer services modifies its scope.
+ * <p>
+ * A scope name is permitted for a Producer service when the registering
+ * bundle has <code>WirePermission[name,PRODUCE]</code>, and for a Consumer
+ * service when the registering bundle has <code>WirePermission[name,CONSUME]</code>.
+ * <p>
+ * If either Consumer service or Producer service has not set a
+ * <code>WIREADMIN_*_SCOPE</code> property, then the returned value must be
+ * <code>null</code>.
+ * <p>
+ * If the scope is set, the <code>Wire</code> object must enforce the scope
+ * names when <code>Envelope</code> objects are used as a parameter to update
+ * or returned from the <code>poll</code> method. The <code>Wire</code> object
+ * must then remove all <code>Envelope</code> objects with a scope name that
+ * is not permitted.
+ *
+ * @return A list of permitted scope names or null if the Produce or
+ * Consumer service has set no scope names.
+ */
+ public String[] getScope();
+
+ /**
+ * Return true if the given name is in this <code>Wire</code> object's scope.
+ *
+ * @param name The scope name
+ * @return true if the name is listed in the permitted scope names
+ */
+ public boolean hasScope(String name);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/WireAdmin.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/WireAdmin.java
new file mode 100644
index 0000000..578ef4f
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/WireAdmin.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.wireadmin;
+
+import java.util.Dictionary;
+
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * Wire Administration service.
+ *
+ * <p>
+ * This service can be used to create <code>Wire</code> objects connecting a
+ * Producer service and a Consumer service. <code>Wire</code> objects also have
+ * wire properties that may be specified when a <code>Wire</code> object is
+ * created. The Producer and Consumer services may use the <code>Wire</code>
+ * object's properties to manage or control their interaction. The use of
+ * <code>Wire</code> object's properties by a Producer or Consumer services is
+ * optional.
+ *
+ * <p>
+ * Security Considerations. A bundle must have
+ * <code>ServicePermission[WireAdmin,GET]</code> to get the Wire Admin service to
+ * create, modify, find, and delete <code>Wire</code> objects.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface WireAdmin {
+ /**
+ * Create a new <code>Wire</code> object that connects a Producer service to a
+ * Consumer service.
+ *
+ * The Producer service and Consumer service do not have to be registered
+ * when the <code>Wire</code> object is created.
+ *
+ * <p>
+ * The <code>Wire</code> configuration data must be persistently stored. All
+ * <code>Wire</code> connections are reestablished when the <code>WireAdmin</code>
+ * service is registered. A <code>Wire</code> can be permanently removed by
+ * using the {@link #deleteWire} method.
+ *
+ * <p>
+ * The <code>Wire</code> object's properties must have case insensitive
+ * <code>String</code> objects as keys (like the Framework). However, the case
+ * of the key must be preserved.
+ *
+ * <p>
+ * The <code>WireAdmin</code> service must automatically add the following
+ * <code>Wire</code> properties:
+ * <ul>
+ * <li>{@link WireConstants#WIREADMIN_PID} set to the value of the
+ * <code>Wire</code> object's persistent identity (PID). This value is
+ * generated by the Wire Admin service when a <code>Wire</code> object is
+ * created.</li>
+ * <li>{@link WireConstants#WIREADMIN_PRODUCER_PID} set to the value of
+ * Producer service's PID.</li>
+ * <li>{@link WireConstants#WIREADMIN_CONSUMER_PID} set to the value of
+ * Consumer service's PID.</li>
+ * </ul>
+ * If the <code>properties</code> argument already contains any of these keys,
+ * then the supplied values are replaced with the values assigned by the
+ * Wire Admin service.
+ *
+ * <p>
+ * The Wire Admin service must broadcast a <code>WireAdminEvent</code> of type
+ * {@link WireAdminEvent#WIRE_CREATED} after the new <code>Wire</code> object
+ * becomes available from {@link #getWires}.
+ *
+ * @param producerPID The <code>service.pid</code> of the Producer service to
+ * be connected to the <code>Wire</code> object.
+ * @param consumerPID The <code>service.pid</code> of the Consumer service to
+ * be connected to the <code>Wire</code> object.
+ * @param properties The <code>Wire</code> object's properties. This argument
+ * may be <code>null</code> if the caller does not wish to define any
+ * <code>Wire</code> object's properties.
+ * @return The <code>Wire</code> object for this connection.
+ *
+ * @throws java.lang.IllegalArgumentException If <code>properties</code>
+ * contains invalid wire types or case variants of the same key
+ * name.
+ */
+ public Wire createWire(String producerPID, String consumerPID,
+ Dictionary properties);
+
+ /**
+ * Delete a <code>Wire</code> object.
+ *
+ * <p>
+ * The <code>Wire</code> object representing a connection between a Producer
+ * service and a Consumer service must be removed. The persistently stored
+ * configuration data for the <code>Wire</code> object must destroyed. The
+ * <code>Wire</code> object's method {@link Wire#isValid} will return
+ * <code>false</code> after it is deleted.
+ *
+ * <p>
+ * The Wire Admin service must broadcast a <code>WireAdminEvent</code> of type
+ * {@link WireAdminEvent#WIRE_DELETED} after the <code>Wire</code> object
+ * becomes invalid.
+ *
+ * @param wire The <code>Wire</code> object which is to be deleted.
+ */
+ public void deleteWire(Wire wire);
+
+ /**
+ * Update the properties of a <code>Wire</code> object.
+ *
+ * The persistently stored configuration data for the <code>Wire</code> object
+ * is updated with the new properties and then the Consumer and Producer
+ * services will be called at the respective
+ * {@link Consumer#producersConnected} and
+ * {@link Producer#consumersConnected} methods.
+ *
+ * <p>
+ * The Wire Admin service must broadcast a <code>WireAdminEvent</code> of type
+ * {@link WireAdminEvent#WIRE_UPDATED} after the updated properties are
+ * available from the <code>Wire</code> object.
+ *
+ * @param wire The <code>Wire</code> object which is to be updated.
+ * @param properties The new <code>Wire</code> object's properties or
+ * <code>null</code> if no properties are required.
+ *
+ * @throws java.lang.IllegalArgumentException If <code>properties</code>
+ * contains invalid wire types or case variants of the same key
+ * name.
+ */
+ public void updateWire(Wire wire, Dictionary properties);
+
+ /**
+ * Return the <code>Wire</code> objects that match the given <code>filter</code>.
+ *
+ * <p>
+ * The list of available <code>Wire</code> objects is matched against the
+ * specified <code>filter</code>.<code>Wire</code> objects which match the
+ * <code>filter</code> must be returned. These <code>Wire</code> objects are not
+ * necessarily connected. The Wire Admin service should not return invalid
+ * <code>Wire</code> objects, but it is possible that a <code>Wire</code> object
+ * is deleted after it was placed in the list.
+ *
+ * <p>
+ * The filter matches against the <code>Wire</code> object's properties
+ * including {@link WireConstants#WIREADMIN_PRODUCER_PID},
+ * {@link WireConstants#WIREADMIN_CONSUMER_PID} and
+ * {@link WireConstants#WIREADMIN_PID}.
+ *
+ * @param filter Filter string to select <code>Wire</code> objects or
+ * <code>null</code> to select all <code>Wire</code> objects.
+ * @return An array of <code>Wire</code> objects which match the
+ * <code>filter</code> or <code>null</code> if no <code>Wire</code>
+ * objects match the <code>filter</code>.
+ * @throws org.osgi.framework.InvalidSyntaxException If the specified
+ * <code>filter</code> has an invalid syntax.
+ * @see org.osgi.framework.Filter
+ */
+ public Wire[] getWires(String filter) throws InvalidSyntaxException;
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/WireAdminEvent.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/WireAdminEvent.java
new file mode 100644
index 0000000..bba84ef
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/WireAdminEvent.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.wireadmin;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A Wire Admin Event.
+ *
+ * <p>
+ * <code>WireAdminEvent</code> objects are delivered to all registered
+ * <code>WireAdminListener</code> service objects which specify an interest in the
+ * <code>WireAdminEvent</code> type. Events must be delivered in chronological
+ * order with respect to each listener. For example, a <code>WireAdminEvent</code>
+ * of type {@link #WIRE_CONNECTED} must be delivered before a
+ * <code>WireAdminEvent</code> of type {@link #WIRE_DISCONNECTED} for a particular
+ * <code>Wire</code> object.
+ *
+ * <p>
+ * A type code is used to identify the type of event. The following event types
+ * are defined:
+ * <ul>
+ * <li>{@link #WIRE_CREATED}
+ * <li>{@link #WIRE_CONNECTED}
+ * <li>{@link #WIRE_UPDATED}
+ * <li>{@link #WIRE_TRACE}
+ * <li>{@link #WIRE_DISCONNECTED}
+ * <li>{@link #WIRE_DELETED}
+ * <li>{@link #PRODUCER_EXCEPTION}
+ * <li>{@link #CONSUMER_EXCEPTION}
+ * </ul>
+ * Additional event types may be defined in the future.
+ *
+ * <p>
+ * Event type values must be unique and disjoint bit values. Event types must be
+ * defined as a bit in a 32 bit integer and can thus be bitwise OR'ed together.
+ * <p>
+ * Security Considerations. <code>WireAdminEvent</code> objects contain
+ * <code>Wire</code> objects. Care must be taken in the sharing of <code>Wire</code>
+ * objects with other bundles.
+ *
+ * @see WireAdminListener
+ *
+ * @version $Revision: 5673 $
+ */
+public class WireAdminEvent {
+ /**
+ * The WireAdmin service which created this event.
+ */
+ private ServiceReference reference;
+ /**
+ * The <code>Wire</code> object associated with this event.
+ */
+ private Wire wire;
+ /**
+ * Type of this event.
+ *
+ * @see #getType
+ */
+ private int type;
+ /**
+ * Exception associates with this the event.
+ */
+ private Throwable throwable;
+ /**
+ * A Producer service method has thrown an exception.
+ *
+ * <p>
+ * This <code>WireAdminEvent</code> type indicates that a Producer service
+ * method has thrown an exception. The {@link WireAdminEvent#getThrowable}
+ * method will return the exception that the Producer service method raised.
+ *
+ * <p>
+ * The value of <code>PRODUCER_EXCEPTION</code> is 0x00000001.
+ */
+ public final static int PRODUCER_EXCEPTION = 0x00000001;
+ /**
+ * A Consumer service method has thrown an exception.
+ *
+ * <p>
+ * This <code>WireAdminEvent</code> type indicates that a Consumer service
+ * method has thrown an exception. The {@link WireAdminEvent#getThrowable}
+ * method will return the exception that the Consumer service method raised.
+ *
+ * <p>
+ * The value of <code>CONSUMER_EXCEPTION</code> is 0x00000002.
+ */
+ public final static int CONSUMER_EXCEPTION = 0x00000002;
+ /**
+ * A <code>Wire</code> has been created.
+ *
+ * <p>
+ * This <code>WireAdminEvent</code> type that indicates that a new
+ * <code>Wire</code> object has been created.
+ *
+ * An event is broadcast when {@link WireAdmin#createWire} is called. The
+ * {@link WireAdminEvent#getWire} method will return the <code>Wire</code>
+ * object that has just been created.
+ *
+ * <p>
+ * The value of <code>WIRE_CREATED</code> is 0x00000004.
+ */
+ public final static int WIRE_CREATED = 0x00000004;
+ /**
+ * A <code>Wire</code> has been updated.
+ *
+ * <p>
+ * This <code>WireAdminEvent</code> type that indicates that an existing
+ * <code>Wire</code> object has been updated with new properties.
+ *
+ * An event is broadcast when {@link WireAdmin#updateWire} is called with a
+ * valid wire. The {@link WireAdminEvent#getWire} method will return the
+ * <code>Wire</code> object that has just been updated.
+ *
+ * <p>
+ * The value of <code>WIRE_UPDATED</code> is 0x00000008.
+ */
+ public final static int WIRE_UPDATED = 0x00000008;
+ /**
+ * A <code>Wire</code> has been deleted.
+ *
+ * <p>
+ * This <code>WireAdminEvent</code> type that indicates that an existing wire
+ * has been deleted.
+ *
+ * An event is broadcast when {@link WireAdmin#deleteWire} is called with a
+ * valid wire. {@link WireAdminEvent#getWire} will return the <code>Wire</code>
+ * object that has just been deleted.
+ *
+ * <p>
+ * The value of <code>WIRE_DELETED</code> is 0x00000010.
+ */
+ public final static int WIRE_DELETED = 0x00000010;
+ /**
+ * The <code>WireAdminEvent</code> type that indicates that an existing
+ * <code>Wire</code> object has become connected.
+ *
+ * The Consumer object and the Producer object that are associated with the
+ * <code>Wire</code> object have both been registered and the <code>Wire</code>
+ * object is connected. See {@link Wire#isConnected} for a description of
+ * the connected state. This event may come before the
+ * <code>producersConnected</code> and <code>consumersConnected</code> method
+ * have returned or called to allow synchronous delivery of the events. Both
+ * methods can cause other <code>WireAdminEvent</code> s to take place and
+ * requiring this event to be send before these methods are returned would
+ * mandate asynchronous delivery.
+ *
+ * <p>
+ * The value of <code>WIRE_CONNECTED</code> is 0x00000020.
+ */
+ public final static int WIRE_CONNECTED = 0x00000020;
+ /**
+ * The <code>WireAdminEvent</code> type that indicates that an existing
+ * <code>Wire</code> object has become disconnected.
+ *
+ * The Consumer object or/and Producer object is/are unregistered breaking
+ * the connection between the two. See {@link Wire#isConnected} for a
+ * description of the connected state.
+ *
+ * <p>
+ * The value of <code>WIRE_DISCONNECTED</code> is 0x00000040.
+ */
+ public final static int WIRE_DISCONNECTED = 0x00000040;
+ /**
+ * The <code>WireAdminEvent</code> type that indicates that a new value is
+ * transferred over the <code>Wire</code> object.
+ *
+ * This event is sent after the Consumer service has been notified by
+ * calling the {@link Consumer#updated} method or the Consumer service
+ * requested a new value with the {@link Wire#poll} method. This is an
+ * advisory event meaning that when this event is received, another update
+ * may already have occurred and this the {@link Wire#getLastValue} method
+ * returns a newer value then the value that was communicated for this
+ * event.
+ *
+ * <p>
+ * The value of <code>WIRE_TRACE</code> is 0x00000080.
+ */
+ public final static int WIRE_TRACE = 0x00000080;
+
+ /**
+ * Constructs a <code>WireAdminEvent</code> object from the given
+ * <code>ServiceReference</code> object, event type, <code>Wire</code> object
+ * and exception.
+ *
+ * @param reference The <code>ServiceReference</code> object of the Wire Admin
+ * service that created this event.
+ * @param type The event type. See {@link #getType}.
+ * @param wire The <code>Wire</code> object associated with this event.
+ * @param exception An exception associated with this event. This may be
+ * <code>null</code> if no exception is associated with this event.
+ */
+ public WireAdminEvent(ServiceReference reference, int type, Wire wire,
+ Throwable exception) {
+ this.reference = reference;
+ this.wire = wire;
+ this.type = type;
+ this.throwable = exception;
+ }
+
+ /**
+ * Return the <code>ServiceReference</code> object of the Wire Admin service
+ * that created this event.
+ *
+ * @return The <code>ServiceReference</code> object for the Wire Admin service
+ * that created this event.
+ */
+ public ServiceReference getServiceReference() {
+ return reference;
+ }
+
+ /**
+ * Return the <code>Wire</code> object associated with this event.
+ *
+ * @return The <code>Wire</code> object associated with this event or
+ * <code>null</code> when no <code>Wire</code> object is associated with
+ * the event.
+ */
+ public Wire getWire() {
+ return wire;
+ }
+
+ /**
+ * Return the type of this event.
+ * <p>
+ * The type values are:
+ * <ul>
+ * <li>{@link #WIRE_CREATED}
+ * <li>{@link #WIRE_CONNECTED}
+ * <li>{@link #WIRE_UPDATED}
+ * <li>{@link #WIRE_TRACE}
+ * <li>{@link #WIRE_DISCONNECTED}
+ * <li>{@link #WIRE_DELETED}
+ * <li>{@link #PRODUCER_EXCEPTION}
+ * <li>{@link #CONSUMER_EXCEPTION}
+ * </ul>
+ *
+ * @return The type of this event.
+ */
+ public int getType() {
+ return type;
+ }
+
+ /**
+ * Returns the exception associated with the event, if any.
+ *
+ * @return An exception or <code>null</code> if no exception is associated
+ * with this event.
+ */
+ public Throwable getThrowable() {
+ return throwable;
+ }
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/WireAdminListener.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/WireAdminListener.java
new file mode 100644
index 0000000..e741dd9
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/WireAdminListener.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.wireadmin;
+
+/**
+ * Listener for Wire Admin Events.
+ *
+ * <p>
+ * <code>WireAdminListener</code> objects are registered with the Framework
+ * service registry and are notified with a <code>WireAdminEvent</code> object
+ * when an event is broadcast.
+ * <p>
+ * <code>WireAdminListener</code> objects can inspect the received
+ * <code>WireAdminEvent</code> object to determine its type, the <code>Wire</code>
+ * object with which it is associated, and the Wire Admin service that
+ * broadcasts the event.
+ *
+ * <p>
+ * <code>WireAdminListener</code> objects must be registered with a service
+ * property {@link WireConstants#WIREADMIN_EVENTS} whose value is a bitwise OR
+ * of all the event types the listener is interested in receiving.
+ * <p>
+ * For example:
+ *
+ * <pre>
+ * Integer mask = new Integer(WIRE_TRACE | WIRE_CONNECTED | WIRE_DISCONNECTED);
+ * Hashtable ht = new Hashtable();
+ * ht.put(WIREADMIN_EVENTS, mask);
+ * context.registerService(WireAdminListener.class.getName(), this, ht);
+ * </pre>
+ *
+ * If a <code>WireAdminListener</code> object is registered without a service
+ * property {@link WireConstants#WIREADMIN_EVENTS}, then the
+ * <code>WireAdminListener</code> will receive no events.
+ *
+ * <p>
+ * Security Considerations. Bundles wishing to monitor <code>WireAdminEvent</code>
+ * objects will require <code>ServicePermission[WireAdminListener,REGISTER]</code>
+ * to register a <code>WireAdminListener</code> service. Since
+ * <code>WireAdminEvent</code> objects contain <code>Wire</code> objects, care must
+ * be taken in assigning permission to register a <code>WireAdminListener</code>
+ * service.
+ *
+ * @see WireAdminEvent
+ *
+ * @version $Revision: 5673 $
+ */
+public interface WireAdminListener {
+ /**
+ * Receives notification of a broadcast <code>WireAdminEvent</code> object.
+ *
+ * The event object will be of an event type specified in this
+ * <code>WireAdminListener</code> service's
+ * {@link WireConstants#WIREADMIN_EVENTS} service property.
+ *
+ * @param event The <code>WireAdminEvent</code> object.
+ */
+ void wireAdminEvent(WireAdminEvent event);
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/WireConstants.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/WireConstants.java
new file mode 100644
index 0000000..b616a4f
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/WireConstants.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.wireadmin;
+
+/**
+ * Defines standard names for <code>Wire</code> properties, wire filter
+ * attributes, Consumer and Producer service properties.
+ *
+ * @version $Revision: 5673 $
+ */
+public interface WireConstants {
+ /**
+ * <code>Wire</code> property key (named <code>wireadmin.pid</code>) specifying
+ * the persistent identity (PID) of this <code>Wire</code> object.
+ *
+ * <p>
+ * Each <code>Wire</code> object has a PID to allow unique and persistent
+ * identification of a specific <code>Wire</code> object. The PID must be
+ * generated by the {@link WireAdmin} service when the <code>Wire</code>
+ * object is created.
+ *
+ * <p>
+ * This wire property is automatically set by the Wire Admin service. The
+ * value of the property must be of type <code>String</code>.
+ */
+ public final static String WIREADMIN_PID = "wireadmin.pid";
+ /**
+ * A service registration property for a Producer service that is composite.
+ * It contains the names of the composite Consumer services it can
+ * inter-operate with. Inter-operability exists when any name in this array
+ * matches any name in the array set by the Consumer service. The type of
+ * this property must be <code>String[]</code>.
+ */
+ public final static String WIREADMIN_PRODUCER_COMPOSITE = "wireadmin.producer.composite";
+ /**
+ * A service registration property for a Consumer service that is composite.
+ * It contains the names of the composite Producer services it can cooperate
+ * with. Inter-operability exists when any name in this array matches any
+ * name in the array set by the Producer service. The type of this property
+ * must be <code>String[]</code>.
+ */
+ public final static String WIREADMIN_CONSUMER_COMPOSITE = "wireadmin.consumer.composite";
+ /**
+ * Service registration property key (named
+ * <code>wireadmin.producer.scope</code>) specifying a list of names that may
+ * be used to define the scope of this <code>Wire</code> object. A Producer
+ * service should set this service property when it can produce more than
+ * one kind of value. This property is only used during registration,
+ * modifying the property must not have any effect of the <code>Wire</code>
+ * object's scope. Each name in the given list mist have
+ * <code>WirePermission[name,PRODUCE]</code> or else is ignored. The type of
+ * this service registration property must be <code>String[]</code>.
+ *
+ * @see Wire#getScope
+ * @see #WIREADMIN_CONSUMER_SCOPE
+ */
+ public final static String WIREADMIN_PRODUCER_SCOPE = "wireadmin.producer.scope";
+ /**
+ * Service registration property key (named
+ * <code>wireadmin.consumer.scope</code>) specifying a list of names that may
+ * be used to define the scope of this <code>Wire</code> object. A
+ * <code>Consumer</code> service should set this service property when it can
+ * produce more than one kind of value. This property is only used during
+ * registration, modifying the property must not have any effect of the
+ * <code>Wire</code> object's scope. Each name in the given list mist have
+ * <code>WirePermission[name,CONSUME]</code> or else is ignored. The type of this
+ * service registration property must be <code>String[]</code>.
+ *
+ * @see Wire#getScope
+ * @see #WIREADMIN_PRODUCER_SCOPE
+ */
+ public final static String WIREADMIN_CONSUMER_SCOPE = "wireadmin.consumer.scope";
+ /**
+ * Matches all scope names.
+ */
+ public final static String WIREADMIN_SCOPE_ALL[] = {"*"};
+ /**
+ * <code>Wire</code> property key (named <code>wireadmin.producer.pid</code>)
+ * specifying the <code>service.pid</code> of the associated Producer service.
+ *
+ * <p>
+ * This wire property is automatically set by the WireAdmin service. The
+ * value of the property must be of type <code>String</code>.
+ */
+ public final static String WIREADMIN_PRODUCER_PID = "wireadmin.producer.pid";
+ /**
+ * <code>Wire</code> property key (named <code>wireadmin.consumer.pid</code>)
+ * specifying the <code>service.pid</code> of the associated Consumer service.
+ *
+ * <p>
+ * This wire property is automatically set by the Wire Admin service. The
+ * value of the property must be of type <code>String</code>.
+ */
+ public final static String WIREADMIN_CONSUMER_PID = "wireadmin.consumer.pid";
+ /**
+ * <code>Wire</code> property key (named <code>wireadmin.filter</code>)
+ * specifying a filter used to control the delivery rate of data between the
+ * Producer and the Consumer service.
+ *
+ * <p>
+ * This property should contain a filter as described in the <code>Filter</code>
+ * class. The filter can be used to specify when an updated value from the
+ * Producer service should be delivered to the Consumer service. In many
+ * cases the Consumer service does not need to receive the data with the
+ * same rate that the Producer service can generate data. This property can
+ * be used to control the delivery rate.
+ * <p>
+ * The filter can use a number of pre-defined attributes that can be used to
+ * control the delivery of new data values. If the filter produces a match
+ * upon the wire filter attributes, the Consumer service should be notifed
+ * of the updated data value.
+ * <p>
+ * If the Producer service was registered with the
+ * {@link #WIREADMIN_PRODUCER_FILTERS} service property indicating that the
+ * Producer service will perform the data filtering then the <code>Wire</code>
+ * object will not perform data filtering. Otherwise, the <code>Wire</code>
+ * object must perform basic filtering. Basic filtering includes supporting
+ * the following standard wire filter attributes:
+ * <ul>
+ * <li>{@link #WIREVALUE_CURRENT}- Current value
+ * <li>{@link #WIREVALUE_PREVIOUS}- Previous value
+ * <li>{@link #WIREVALUE_DELTA_ABSOLUTE}- Absolute delta
+ * <li>{@link #WIREVALUE_DELTA_RELATIVE}- Relative delta
+ * <li>{@link #WIREVALUE_ELAPSED}- Elapsed time
+ * </ul>
+ *
+ * @see org.osgi.framework.Filter
+ */
+ public final static String WIREADMIN_FILTER = "wireadmin.filter";
+ /* Wire filter attribute names. */
+ /**
+ * <code>Wire</code> object's filter attribute (named
+ * <code>wirevalue.current</code>) representing the current value.
+ */
+ public final static String WIREVALUE_CURRENT = "wirevalue.current";
+ /**
+ * <code>Wire</code> object's filter attribute (named
+ * <code>wirevalue.previous</code>) representing the previous value.
+ */
+ public final static String WIREVALUE_PREVIOUS = "wirevalue.previous";
+ /**
+ * <code>Wire</code> object's filter attribute (named
+ * <code>wirevalue.delta.absolute</code>) representing the absolute delta.
+ * The absolute (always positive) difference between the last update and the
+ * current value (only when numeric). This attribute must not be used when
+ * the values are not numeric.
+ */
+ public final static String WIREVALUE_DELTA_ABSOLUTE = "wirevalue.delta.absolute";
+ /**
+ * <code>Wire</code> object's filter attribute (named
+ * <code>wirevalue.delta.relative</code>) representing the relative delta.
+ * The relative difference is |<code>previous</code>-<code>current</code> |/|
+ * <code>current</code>| (only when numeric). This attribute must not be used
+ * when the values are not numeric.
+ */
+ public final static String WIREVALUE_DELTA_RELATIVE = "wirevalue.delta.relative";
+ /**
+ * <code>Wire</code> object's filter attribute (named
+ * <code>wirevalue.elapsed</code>) representing the elapsed time, in ms,
+ * between this filter evaluation and the last update of the
+ * <code>Consumer</code> service.
+ */
+ public final static String WIREVALUE_ELAPSED = "wirevalue.elapsed";
+ /* Service registration property key names. */
+ /**
+ * Service Registration property (named <code>wireadmin.producer.filters</code>).
+ * A <code>Producer</code> service registered with this property indicates to
+ * the Wire Admin service that the Producer service implements at least the
+ * filtering as described for the {@link #WIREADMIN_FILTER} property. If the
+ * Producer service is not registered with this property, the <code>Wire</code>
+ * object must perform the basic filtering as described in
+ * {@link #WIREADMIN_FILTER}.
+ *
+ * <p>
+ * The type of the property value is not relevant. Only its presence is
+ * relevant.
+ */
+ public final static String WIREADMIN_PRODUCER_FILTERS = "wireadmin.producer.filters";
+ /**
+ * Service Registration property (named <code>wireadmin.consumer.flavors</code>)
+ * specifying the list of data types understood by this Consumer service.
+ *
+ * <p>
+ * The Consumer service object must be registered with this service
+ * property. The list must be in the order of preference with the first type
+ * being the most preferred. The value of the property must be of type
+ * <code>Class[]</code>.
+ */
+ public final static String WIREADMIN_CONSUMER_FLAVORS = "wireadmin.consumer.flavors";
+ /**
+ * Service Registration property (named <code>wireadmin.producer.flavors</code>)
+ * specifying the list of data types available from this Producer service.
+ *
+ * <p>
+ * The Producer service object should be registered with this service
+ * property.
+ *
+ * <p>
+ * The value of the property must be of type <code>Class[]</code>.
+ */
+ public final static String WIREADMIN_PRODUCER_FLAVORS = "wireadmin.producer.flavors";
+ /**
+ * Service Registration property (named <code>wireadmin.events</code>)
+ * specifying the <code>WireAdminEvent</code> type of interest to a Wire Admin
+ * Listener service. The value of the property is a bitwise OR of all the
+ * <code>WireAdminEvent</code> types the Wire Admin Listener service wishes to
+ * receive and must be of type <code>Integer</code>.
+ *
+ * @see WireAdminEvent
+ */
+ public final static String WIREADMIN_EVENTS = "wireadmin.events";
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/WirePermission.java b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/WirePermission.java
new file mode 100644
index 0000000..6073466
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/WirePermission.java
@@ -0,0 +1,485 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2009). All Rights Reserved.
+ *
+ * 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.
+ */
+package org.osgi.service.wireadmin;
+
+import java.io.IOException;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+/**
+ * Permission for the scope of a <code>Wire</code> object. When a
+ * <code>Envelope</code> object is used for communication with the
+ * <code>poll</code> or <code>update</code> method, and the scope is set, then
+ * the <code>Wire</code> object must verify that the Consumer service has
+ * <code>WirePermission[name,CONSUME]</code> and the Producer service has
+ * <code>WirePermission[name,PRODUCE]</code> for all names in the scope.
+ * <p>
+ * The names are compared with the normal rules for permission names. This means
+ * that they may end with a "*" to indicate wildcards. E.g. Door.* indicates all
+ * scope names starting with the string "Door". The last period is required due
+ * to the implementations of the <code>BasicPermission</code> class.
+ *
+ * @ThreadSafe
+ * @version $Revision: 6381 $
+ */
+final public class WirePermission extends BasicPermission {
+ static final long serialVersionUID = -5583709391516569321L;
+ /**
+ * The action string for the <code>produce</code> action.
+ */
+ public static final String PRODUCE = "produce";
+ /**
+ * The action string for the <code>consume</code> action.
+ */
+ public static final String CONSUME = "consume";
+ private final static int ACTION_PRODUCE = 0x00000001;
+ private final static int ACTION_CONSUME = 0x00000002;
+ private final static int ACTION_ALL = ACTION_PRODUCE
+ | ACTION_CONSUME;
+ private final static int ACTION_NONE = 0;
+ /**
+ * The actions mask.
+ */
+ private transient int action_mask;
+ /**
+ * The actions in canonical form.
+ *
+ * @serial
+ */
+ private volatile String actions = null;
+
+ /**
+ * Create a new WirePermission with the given name (may be wildcard) and
+ * actions.
+ *
+ * @param name Wire name.
+ * @param actions <code>produce</code>, <code>consume</code> (canonical
+ * order).
+ */
+ public WirePermission(String name, String actions) {
+ this(name, parseActions(actions));
+ }
+
+ /**
+ * Package private constructor used by WirePermissionCollection.
+ *
+ * @param name class name
+ * @param mask action mask
+ */
+ WirePermission(String name, int mask) {
+ super(name);
+ setTransients(mask);
+ }
+
+ /**
+ * Called by constructors and when deserialized.
+ *
+ * @param mask action mask
+ */
+ private synchronized void setTransients(int mask) {
+ if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+ throw new IllegalArgumentException("invalid action string");
+ }
+ action_mask = mask;
+ }
+
+ /**
+ * Returns the current action mask. Used by the WirePermissionCollection
+ * object.
+ *
+ * @return The actions mask.
+ */
+ synchronized int getActionsMask() {
+ return action_mask;
+ }
+
+ /**
+ * Parse action string into action mask.
+ *
+ * @param actions Action string.
+ * @return action mask.
+ */
+ private static int parseActions(String actions) {
+ boolean seencomma = false;
+ int mask = ACTION_NONE;
+ if (actions == null) {
+ return mask;
+ }
+ char[] a = actions.toCharArray();
+ int i = a.length - 1;
+ if (i < 0)
+ return mask;
+ while (i != -1) {
+ char c;
+ // skip whitespace
+ while ((i != -1)
+ && ((c = a[i]) == ' ' || c == '\r' || c == '\n'
+ || c == '\f' || c == '\t'))
+ i--;
+ // check for the known strings
+ int matchlen;
+ if (i >= 6 && (a[i - 6] == 'p' || a[i - 6] == 'P')
+ && (a[i - 5] == 'r' || a[i - 5] == 'R')
+ && (a[i - 4] == 'o' || a[i - 4] == 'O')
+ && (a[i - 3] == 'd' || a[i - 3] == 'D')
+ && (a[i - 2] == 'u' || a[i - 2] == 'U')
+ && (a[i - 1] == 'c' || a[i - 1] == 'C')
+ && (a[i] == 'e' || a[i] == 'E')) {
+ matchlen = 7;
+ mask |= ACTION_PRODUCE;
+ }
+ else
+ if (i >= 6 && (a[i - 6] == 'c' || a[i - 6] == 'C')
+ && (a[i - 5] == 'o' || a[i - 5] == 'O')
+ && (a[i - 4] == 'n' || a[i - 4] == 'N')
+ && (a[i - 3] == 's' || a[i - 3] == 'S')
+ && (a[i - 2] == 'u' || a[i - 2] == 'U')
+ && (a[i - 1] == 'm' || a[i - 1] == 'M')
+ && (a[i] == 'e' || a[i] == 'E')) {
+ matchlen = 7;
+ mask |= ACTION_CONSUME;
+ }
+ else {
+ // parse error
+ throw new IllegalArgumentException("invalid permission: "
+ + actions);
+ }
+ // make sure we didn't just match the tail of a word
+ // like "ackbarfregister". Also, skip to the comma.
+ seencomma = false;
+ while (i >= matchlen && !seencomma) {
+ switch (a[i - matchlen]) {
+ case ',' :
+ seencomma = true;
+ /* FALLTHROUGH */
+ case ' ' :
+ case '\r' :
+ case '\n' :
+ case '\f' :
+ case '\t' :
+ break;
+ default :
+ throw new IllegalArgumentException(
+ "invalid permission: " + actions);
+ }
+ i--;
+ }
+ // point i at the location of the comma minus one (or -1).
+ i -= matchlen;
+ }
+ if (seencomma) {
+ throw new IllegalArgumentException("invalid permission: " + actions);
+ }
+ return mask;
+ }
+
+ /**
+ * Checks if this <code>WirePermission</code> object <code>implies</code>
+ * the specified permission.
+ * <P>
+ * More specifically, this method returns <code>true</code> if:
+ * <p>
+ * <ul>
+ * <li><i>p </i> is an instanceof the <code>WirePermission</code> class,
+ * <li><i>p </i>'s actions are a proper subset of this object's actions, and
+ * <li><i>p </i>'s name is implied by this object's name. For example,
+ * <code>java.*</code> implies <code>java.home</code>.
+ * </ul>
+ *
+ * @param p The permission to check against.
+ *
+ * @return <code>true</code> if the specified permission is implied by this
+ * object; <code>false</code> otherwise.
+ */
+ public boolean implies(Permission p) {
+ if (p instanceof WirePermission) {
+ WirePermission requested = (WirePermission) p;
+ int requestedMask = requested.getActionsMask();
+ return ((getActionsMask() & requestedMask) == requestedMask)
+ && super.implies(p);
+ }
+ return false;
+ }
+
+ /**
+ * Returns the canonical string representation of the actions. Always
+ * returns present actions in the following order: <code>produce</code>,
+ * <code>consume</code>.
+ *
+ * @return The canonical string representation of the actions.
+ */
+ public String getActions() {
+ String result = actions;
+ if (result == null) {
+ StringBuffer sb = new StringBuffer();
+ boolean comma = false;
+ int mask = getActionsMask();
+ if ((mask & ACTION_PRODUCE) == ACTION_PRODUCE) {
+ sb.append(PRODUCE);
+ comma = true;
+ }
+ if ((mask & ACTION_CONSUME) == ACTION_CONSUME) {
+ if (comma)
+ sb.append(',');
+ sb.append(CONSUME);
+ }
+ actions = result = sb.toString();
+ }
+ return result;
+ }
+
+ /**
+ * Returns a new <code>PermissionCollection</code> object for storing
+ * <code>WirePermission</code> objects.
+ *
+ * @return A new <code>PermissionCollection</code> object suitable for
+ * storing <code>WirePermission</code> objects.
+ */
+ public PermissionCollection newPermissionCollection() {
+ return new WirePermissionCollection();
+ }
+
+ /**
+ * Determines the equalty of two <code>WirePermission</code> objects.
+ *
+ * Checks that specified object has the same name and actions as this
+ * <code>WirePermission</code> object.
+ *
+ * @param obj The object to test for equality.
+ * @return true if <code>obj</code> is a <code>WirePermission</code>, and
+ * has the same name and actions as this <code>WirePermission</code>
+ * object; <code>false</code> otherwise.
+ */
+ public boolean equals(Object obj) {
+ if (obj == this) {
+ return true;
+ }
+ if (!(obj instanceof WirePermission)) {
+ return false;
+ }
+ WirePermission wp = (WirePermission) obj;
+ return (getActionsMask() == wp.getActionsMask())
+ && getName().equals(wp.getName());
+ }
+
+ /**
+ * Returns the hash code value for this object.
+ *
+ * @return Hash code value for this object.
+ */
+ public int hashCode() {
+ int h = 31 * 17 + getName().hashCode();
+ h = 31 * h + getActions().hashCode();
+ return h;
+ }
+
+ /**
+ * Returns a string describing this <code>WirePermission</code>. The
+ * convention is to specify the class name, the permission name, and the
+ * actions in the following format:
+ * '(org.osgi.service.wireadmin.WirePermission "name"
+ * "actions")'.
+ *
+ * @return information about this <code>Permission</code> object.
+ */
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.append('(');
+ sb.append(getClass().getName());
+ sb.append(" \"");
+ sb.append(getName());
+ String a = getActions();
+ if (a.length() > 0) {
+ sb.append("\" \"");
+ sb.append(a);
+ }
+ sb.append("\")");
+ return sb.toString();
+ }
+
+ /**
+ * WriteObject is called to save the state of the ServicePermission to a
+ * stream. The actions are serialized, and the superclass takes care of the
+ * name.
+ */
+ private synchronized void writeObject(java.io.ObjectOutputStream s)
+ throws IOException {
+ // Write out the actions. The superclass takes care of the name
+ // call getActions to make sure actions field is initialized
+ if (actions == null)
+ getActions();
+ s.defaultWriteObject();
+ }
+
+ /**
+ * readObject is called to restore the state of the ServicePermission from a
+ * stream.
+ */
+ private synchronized void readObject(java.io.ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ // Read in the action, then initialize the rest
+ s.defaultReadObject();
+ setTransients(parseActions(actions));
+ }
+}
+
+/**
+ * A <code>WirePermissionCollection</code> stores a set of
+ * <code>WirePermission</code> permissions.
+ */
+
+final class WirePermissionCollection extends PermissionCollection {
+ static final long serialVersionUID = 2617521094909826016L;
+ /**
+ * Table of permissions.
+ *
+ * @GuardedBy this
+ * @serial
+ */
+ private final Hashtable permissions;
+ /**
+ * Boolean saying if "*" is in the collection.
+ *
+ * @GuardedBy this
+ * @serial
+ */
+ private boolean all_allowed;
+
+ /**
+ * Creates an empty WirePermissionCollection object.
+ *
+ */
+ public WirePermissionCollection() {
+ permissions = new Hashtable();
+ all_allowed = false;
+ }
+
+ /**
+ * Adds a permission to this PermissionCollection.
+ *
+ * @param permission The Permission object to add.
+ *
+ * @throws IllegalArgumentException If the permission is not a
+ * WirePermission object.
+ *
+ * @throws SecurityException If this PermissionCollection has been marked
+ * read-only.
+ */
+ public void add(Permission permission) {
+ if (!(permission instanceof WirePermission)) {
+ throw new IllegalArgumentException("invalid permission: "
+ + permission);
+ }
+ if (isReadOnly()) {
+ throw new SecurityException("attempt to add a Permission to a "
+ + "readonly PermissionCollection");
+ }
+ WirePermission wp = (WirePermission) permission;
+ String name = wp.getName();
+ synchronized (this) {
+ WirePermission existing = (WirePermission) permissions.get(name);
+ if (existing != null) {
+ int oldMask = existing.getActionsMask();
+ int newMask = wp.getActionsMask();
+ if (oldMask != newMask) {
+ permissions.put(name, new WirePermission(name, oldMask
+ | newMask));
+ }
+ }
+ else {
+ permissions.put(name, wp);
+ }
+ if (!all_allowed) {
+ if (name.equals("*")) {
+ all_allowed = true;
+ }
+ }
+ }
+ }
+
+ /**
+ * Determines if a set of permissions implies the permissions expressed in
+ * <code>permission</code>.
+ *
+ * @param permission The Permission object to compare.
+ *
+ * @return <code>true</code> if <code>permission</code> is a proper subset
+ * of a permission in the set; <code>false</code> otherwise.
+ */
+ public boolean implies(Permission permission) {
+ if (!(permission instanceof WirePermission)) {
+ return false;
+ }
+ WirePermission requested = (WirePermission) permission;
+ WirePermission x;
+ int desired = requested.getActionsMask();
+ int effective = 0;
+ String name = requested.getName();
+ synchronized (this) {
+ // short circuit if the "*" Permission was added
+ if (all_allowed) {
+ x = (WirePermission) permissions.get("*");
+ if (x != null) {
+ effective |= x.getActionsMask();
+ if ((effective & desired) == desired)
+ return true;
+ }
+ }
+ // strategy:
+ // Check for full match first. Then work our way up the
+ // name looking for matches on a.b.*
+ x = (WirePermission) permissions.get(name);
+ }
+ if (x != null) {
+ // we have a direct hit!
+ effective |= x.getActionsMask();
+ if ((effective & desired) == desired) {
+ return true;
+ }
+ }
+ // work our way up the tree...
+ int last;
+ int offset = name.length() - 1;
+ while ((last = name.lastIndexOf(".", offset)) != -1) {
+ name = name.substring(0, last + 1) + "*";
+ synchronized (this) {
+ x = (WirePermission) permissions.get(name);
+ }
+ if (x != null) {
+ effective |= x.getActionsMask();
+ if ((effective & desired) == desired) {
+ return (true);
+ }
+ }
+ offset = last - 1;
+ }
+ // we don't have to check for "*" as it was already checked
+ // at the top (all_allowed), so we just return false
+ return false;
+ }
+
+ /**
+ * Returns an enumeration of all the Permission objects in the container.
+ *
+ * @return Enumeration of all the Permission objects.
+ */
+ public Enumeration elements() {
+ return permissions.elements();
+ }
+}
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/package.html b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/package.html
new file mode 100644
index 0000000..36d1d82
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Wire Admin Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.wireadmin; version="[1.0,2.0)"
+</pre>
+</BODY>
+
diff --git a/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/packageinfo b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/eclipse/plugins/org.eclipse.osgi.services/src/org/osgi/service/wireadmin/packageinfo
@@ -0,0 +1 @@
+version 1.0
hooks/post-receive
--
eclipse - Powerful IDE written in java - Debian package.
More information about the pkg-java-commits
mailing list