You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by mc...@apache.org on 2012/06/07 23:57:43 UTC
svn commit: r1347815 [5/19] - in /felix/trunk/bundleplugin: ./
src/main/java/aQute/ src/main/java/aQute/bnd/
src/main/java/aQute/bnd/annotation/
src/main/java/aQute/bnd/annotation/component/
src/main/java/aQute/bnd/annotation/metatype/ src/main/java/aQ...
Added: felix/trunk/bundleplugin/src/main/java/aQute/bnd/help/syntax.properties
URL: http://svn.apache.org/viewvc/felix/trunk/bundleplugin/src/main/java/aQute/bnd/help/syntax.properties?rev=1347815&view=auto
==============================================================================
--- felix/trunk/bundleplugin/src/main/java/aQute/bnd/help/syntax.properties (added)
+++ felix/trunk/bundleplugin/src/main/java/aQute/bnd/help/syntax.properties Thu Jun 7 21:57:32 2012
@@ -0,0 +1,342 @@
+Add=Holders of DmtPermission with the Add action present can create new nodes in the DMT, that is they are authorized to execute the createInteriorNode() and createLeafNode() methods of the DmtSession.
+Delete=Holders of DmtPermission with the Delete action present can delete nodes from the DMT, that is they are authorized to execute the deleteNode() method of the DmtSession.
+Exec=Holders of DmtPermission with the Exec action present can execute nodes in the DMT, that is they are authorized to call the execute() method of the DmtSession.
+Get=Holders of DmtPermission with the Get action present can query DMT node value or properties, that is they are authorized to execute the isLeafNode(), getNodeAcl(), getEffectiveNodeAcl(), getMetaNode(), getNodeValue(), getChildNodeNames(), getNodeTitle(), getNodeVersion(), getNodeTimeStamp(), getNodeSize() and getNodeType() methods of the DmtSession.
+Replace=Holders of DmtPermission with the Replace action present can update DMT node value or properties, that is they are authorized to execute the setNodeAcl(), setNodeTitle(), setNodeValue(), setNodeType() and renameNode() methods of the DmtSession.
+get=The action string get.
+register=The action string register.
+export=The action string export.
+exportonly=The action string exportonly.
+import=The action string import.
+System Bundle=Location identifier of the OSGi system bundle , which is defined to be "System Bundle".
+system.bundle=Alias for the symbolic name of the OSGi system bundle .
+Bundle-Category=Manifest header identifying the bundle's category.
+Bundle-ClassPath=Manifest header identifying a list of directories and embedded JAR files, which are bundle resources used to extend the bundle's classpath.
+Bundle-Copyright=Manifest header identifying the bundle's copyright information.
+Bundle-Description=Manifest header containing a brief description of the bundle's functionality.
+Bundle-Name=Manifest header identifying the bundle's name.
+Bundle-NativeCode=Manifest header identifying a number of hardware environments and the native language code libraries that the bundle is carrying for each of these environments.
+Export-Package=Manifest header identifying the packages that the bundle offers to the Framework for export.
+Export-Service=Manifest header identifying the fully qualified class names of the services that the bundle may register (used for informational purposes only).
+Import-Package=Manifest header identifying the packages on which the bundle depends.
+DynamicImport-Package=Manifest header identifying the packages that the bundle may dynamically import during execution.
+Import-Service=Manifest header identifying the fully qualified class names of the services that the bundle requires (used for informational purposes only).
+Bundle-Vendor=Manifest header identifying the bundle's vendor.
+Bundle-Version=Manifest header identifying the bundle's version.
+Bundle-DocURL=Manifest header identifying the bundle's documentation URL, from which further information about the bundle may be obtained.
+Bundle-ContactAddress=Manifest header identifying the contact address where problems with the bundle may be reported; for example, an email address.
+Bundle-Activator=Manifest header attribute identifying the bundle's activator class.
+Bundle-UpdateLocation=Manifest header identifying the location from which a new bundle version is obtained during a bundle update operation.
+specification-version=Manifest header attribute identifying the version of a package specified in the Export-Package or Import-Package manifest header.
+processor=Manifest header attribute identifying the processor required to run native bundle code specified in the Bundle-NativeCode manifest header).
+osname=Manifest header attribute identifying the operating system required to run native bundle code specified in the Bundle-NativeCode manifest header).
+osversion=Manifest header attribute identifying the operating system version required to run native bundle code specified in the Bundle-NativeCode manifest header).
+language=Manifest header attribute identifying the language in which the native bundle code is written specified in the Bundle-NativeCode manifest header.
+Bundle-RequiredExecutionEnvironment=Manifest header identifying the required execution environment for the bundle.
+Bundle-SymbolicName=Manifest header identifying the bundle's symbolic name.
+singleton=Manifest header directive identifying whether a bundle is a singleton.
+fragment-attachment=Manifest header directive identifying if and when a fragment may attach to a host bundle.
+always=Manifest header directive value identifying a fragment attachment type of always.
+resolve-time=Manifest header directive value identifying a fragment attachment type of resolve-time.
+never=Manifest header directive value identifying a fragment attachment type of never.
+Bundle-Localization=Manifest header identifying the base name of the bundle's localization entries.
+OSGI-INF/l10n/bundle=Default value for the Bundle-Localization manifest header.
+Require-Bundle=Manifest header identifying the symbolic names of other bundles required by the bundle.
+bundle-version=Manifest header attribute identifying a range of versions for a bundle specified in the Require-Bundle or Fragment-Host manifest headers.
+Fragment-Host=Manifest header identifying the symbolic name of another bundle for which that the bundle is a fragment.
+selection-filter=Manifest header attribute is used for selection by filtering based upon system properties.
+Bundle-ManifestVersion=Manifest header identifying the bundle manifest version.
+version=Manifest header attribute identifying the version of a package specified in the Export-Package or Import-Package manifest header.
+bundle-symbolic-name=Manifest header attribute identifying the symbolic name of a bundle that exports a package specified in the Import-Package manifest header.
+resolution=Manifest header directive identifying the resolution type in the Import-Package or Require-Bundle manifest header.
+mandatory=Manifest header directive value identifying a mandatory resolution type.
+optional=Manifest header directive value identifying an optional resolution type.
+uses=Manifest header directive identifying a list of packages that an exported package uses.
+include=Manifest header directive identifying a list of classes to include in the exported package.
+exclude=Manifest header directive identifying a list of classes to exclude in the exported package..
+mandatory=Manifest header directive identifying names of matching attributes which must be specified by matching Import-Package statements in the Export-Package manifest header.
+visibility=Manifest header directive identifying the visibility of a required bundle in the Require-Bundle manifest header.
+private=Manifest header directive value identifying a private visibility type.
+reexport=Manifest header directive value identifying a reexport visibility type.
+extension=Manifest header directive identifying the type of the extension fragment.
+framework=Manifest header directive value identifying the type of extension fragment.
+bootclasspath=Manifest header directive value identifying the type of extension fragment.
+Bundle-ActivationPolicy=Manifest header identifying the bundle's activation policy.
+lazy=Bundle activation policy declaring the bundle must be activated when the first class load is made from the bundle.
+org.osgi.framework.version=Framework environment property identifying the Framework version.
+org.osgi.framework.vendor=Framework environment property identifying the Framework implementation vendor.
+org.osgi.framework.language=Framework environment property identifying the Framework implementation language (see ISO 639 for possible values).
+org.osgi.framework.os.name=Framework environment property identifying the Framework host-computer's operating system.
+org.osgi.framework.os.version=Framework environment property identifying the Framework host-computer's operating system version number.
+org.osgi.framework.processor=Framework environment property identifying the Framework host-computer's processor name.
+org.osgi.framework.executionenvironment=Framework environment property identifying execution environments provided by the Framework.
+org.osgi.framework.bootdelegation=Framework environment property identifying packages for which the Framework must delegate class loading to the parent class loader of the bundle.
+org.osgi.framework.system.packages=Framework environment property identifying packages which the system bundle must export.
+org.osgi.framework.system.packages.extra=Framework environment property identifying extra packages which the system bundle must export from the current execution environment.
+org.osgi.supports.framework.extension=Framework environment property identifying whether the Framework supports framework extension bundles.
+org.osgi.supports.bootclasspath.extension=Framework environment property identifying whether the Framework supports bootclasspath extension bundles.
+org.osgi.supports.framework.fragment=Framework environment property identifying whether the Framework supports fragment bundles.
+org.osgi.supports.framework.requirebundle=Framework environment property identifying whether the Framework supports the Require-Bundle manifest header.
+org.osgi.framework.security=Specifies the type of security manager the framework must use.
+osgi=Specifies that a security manager that supports all security aspects of the OSGi core specification including postponed conditions must be installed.
+org.osgi.framework.storage=Specified the persistent storage area used by the framework.
+org.osgi.framework.storage.clean=Specifies if and when the persistent storage area for the framework should be cleaned.
+onFirstInit=Specifies that the framework storage area must be cleaned before the framework is initialized for the first time.
+org.osgi.framework.library.extensions=Specifies a comma separated list of additional library file extensions that must be used when a bundle's class loader is searching for native libraries.
+org.osgi.framework.command.execpermission=Specifies an optional OS specific command to set file permissions on extracted native code.
+org.osgi.framework.trust.repositories=Specifies the trust repositories used by the framework.
+org.osgi.framework.windowsystem=Specifies the current windowing system.
+org.osgi.framework.startlevel.beginning=Specifies the beginning start level of the framework.
+org.osgi.framework.bundle.parent=Specifies the parent class loader type for all bundle class loaders.
+boot=Specifies to use of the boot class loader as the parent class loader for all bundle class loaders.
+app=Specifies to use the application class loader as the parent class loader for all bundle class loaders.
+ext=Specifies to use the extension class loader as the parent class loader for all bundle class loaders.
+framework=Specifies to use the framework class loader as the parent class loader for all bundle class loaders.
+objectClass=Service property identifying all of the class names under which a service was registered in the Framework.
+service.id=Service property identifying a service's registration number.
+service.pid=Service property identifying a service's persistent identifier.
+service.ranking=Service property identifying a service's ranking number.
+service.vendor=Service property identifying a service's vendor.
+service.description=Service property identifying a service's description.
+provide=The action string provide.
+require=The action string require.
+host=The action string host.
+fragment=The action string fragment.
+class=The action string class.
+execute=The action string execute.
+extensionLifecycle=The action string extensionLifecycle.
+lifecycle=The action string lifecycle.
+listener=The action string listener.
+metadata=The action string metadata.
+resolve=The action string resolve.
+resource=The action string resource.
+startlevel=The action string startlevel.
+context=The action string context.
+service.pid=The property key for the identifier of the application being scheduled.
+schedule.id=The property key for the schedule identifier.
+org.osgi.triggeringevent=The key for the startup argument used to pass the event object that triggered the schedule to launch the application instance.
+org/osgi/application/timer=The topic name for the virtual timer topic.
+year=The name of the year attribute of a virtual timer event.
+month=The name of the month attribute of a virtual timer event.
+day_of_month=The name of the day of month attribute of a virtual timer event.
+day_of_week=The name of the day of week attribute of a virtual timer event.
+hour_of_day=The name of the hour of day attribute of a virtual timer event.
+minute=The name of the minute attribute of a virtual timer event.
+service.pid=The property key for the unique identifier (PID) of the application instance.
+application.descriptor=The property key for the pid of the corresponding application descriptor.
+application.state=The property key for the state of this application instance.
+application.supports.exitvalue=The property key for the supports exit value property of this application instance.
+RUNNING=The application instance is running.
+STOPPING=The application instance is being stopped.
+application.name=The property key for the localized name of the application.
+application.icon=The property key for the localized icon of the application.
+service.pid=The property key for the unique identifier (PID) of the application.
+application.version=The property key for the version of the application.
+service.vendor=The property key for the name of the application vendor.
+application.visible=The property key for the visibility property of the application.
+application.launchable=The property key for the launchable property of the application.
+application.locked=The property key for the locked property of the application.
+application.description=The property key for the localized description of the application.
+application.documentation=The property key for the localized documentation of the application.
+application.copyright=The property key for the localized copyright notice of the application.
+application.license=The property key for the localized license of the application.
+application.container=The property key for the application container of the application.
+application.location=The property key for the location of the application.
+lifecycle=Allows the lifecycle management of the target applications.
+schedule=Allows scheduling of the target applications.
+lock=Allows setting/unsetting the locking state of the target applications.
+bundle.version=The version property defining the bundle on whose behalf a module context event has been issued.
+extender.bundle=The extender bundle property defining the extender bundle processing the module context for which an event has been issued.
+extender.bundle.id=The extender bundle id property defining the id of the extender bundle processing the module context for which an event has been issued.
+extender.bundle.symbolicName=The extender bundle symbolic name property defining the symbolic name of the extender bundle processing the module context for which an event has been issued.
+org/osgi/service/blueprint=Topic prefix for all events issued by the Blueprint Service
+org/osgi/service/blueprint/context/CREATING=Topic for Blueprint Service CREATING events
+org/osgi/service/blueprint/context/CREATED=Topic for Blueprint Service CREATED events
+org/osgi/service/blueprint/context/DESTROYING=Topic for Blueprint Service DESTROYING events
+org/osgi/service/blueprint/context/DESTROYED=Topic for Blueprint Service DESTROYED events
+org/osgi/service/blueprint/context/WAITING=Topic for Blueprint Service WAITING events
+org/osgi/service/blueprint/context/FAILURE=Topic for Blueprint Service FAILURE events
+singleton=
+prototype=
+bundle=
+cm.target=A service property to limit the Managed Service or Managed Service Factory configuration dictionaries a Configuration Plugin service receives.
+service.cmRanking=A service property to specify the order in which plugins are invoked.
+configure=The action string configure.
+service.factoryPid=Service property naming the Factory PID in the configuration dictionary.
+service.bundleLocation=Service property naming the location of the bundle that is associated with a a Configuration object.
+osgi.converter.classes=This property is a string, or array of strings, and defines the classes or interfaces that this converter recognizes.
+osgi.command.scope=The scope of commands provided by this service.
+osgi.command.function=A String, array, or list of method names that may be called for this command provider.
+Service-Component=Manifest header specifying the XML documents within a bundle that contain the bundle's Service Component descriptions.
+component.name=A component property for a component configuration that contains the name of the component as specified in the name attribute of the component element.
+component.id=A component property that contains the generated id for a component configuration.
+component.factory=A service registration property for a Component Factory that contains the value of the factory attribute.
+.target=The suffix for reference target properties.
+allow=This string is used to indicate that a row in the Conditional Permission Table should return an access decision of "allow" if the conditions are all satisfied and at least one of the permissions is implied.
+deny=This string is used to indicate that a row in the Conditional Permission Table should return an access decision of "deny" if the conditions are all satisfied and at least one of the permissions is implied.
+deploymentpackage.name=The name of the Deployment Package.
+deploymentpackage.readablename=The human readable name of the DP localized to the default locale.
+deploymentpackage.currentversion=The currently installed version of the Deployment Package.
+deploymentpackage.nextversion=The version of DP after the successful completion of the install operation (used in INSTALL event only).
+install=Constant String to the "install" action.
+list=Constant String to the "list" action.
+uninstall=Constant String to the "uninstall" action.
+uninstall_forced=Constant String to the "uninstall_forced" action.
+cancel=Constant String to the "cancel" action.
+metadata=Constant String to the "metadata" action.
+privatearea=Constant String to the "privatearea" action.
+-1=Return value from DriverSelector.select, if no Driver service should be attached to the Device service.
+DRIVER_ID=Property (named "DRIVER_ID") identifying a driver.
+DEVICE_CATEGORY=Property (named "DEVICE_CATEGORY") containing a human readable description of the device categories implemented by a device.
+DEVICE_SERIAL=Property (named "DEVICE_SERIAL") specifying a device's serial number.
+DEVICE_DESCRIPTION=Property (named "DEVICE_DESCRIPTION") containing a human readable string describing the actual hardware device.
+service.interface=Mandatory ServiceRegistration property which contains a collection of full qualified interface names offered by the advertised service endpoint.
+service.interface.version=Optional ServiceRegistration property which contains a collection of interface names with their associated version attributes separated by SEPARATOR e.g.
+osgi.remote.endpoint.interface=Optional ServiceRegistration property which contains a collection of interface names with their associated (non-Java) endpoint interface names separated by SEPARATOR e.g.: 'my.company.foo|MyWebService my.company.zoo|MyWebService'. This (non-Java) endpoint interface name is usually a communication protocol specific interface, for instance a web service interface name.
+service.properties=Optional ServiceRegistration property which contains a map of properties of the published service.
+osgi.remote.endpoint.location=Optional property of the published service identifying its location.
+osgi.remote.endpoint.id=Optional property of the published service uniquely identifying its endpoint.
+|=Separator constant for association of interface-specific values with the particular interface name.
+osgi.remote.discovery.product=Service Registration property for the name of the Discovery product.
+osgi.remote.discovery.product.version=Service Registration property for the version of the Discovery product.
+osgi.remote.discovery.vendor=Service Registration property for the Discovery product vendor name.
+osgi.remote.discovery.supported_protocols=Service Registration property that lists the discovery protocols used by this Discovery service.
+osgi.discovery.interest.interfaces=Optional ServiceRegistration property which contains service interfaces this tracker is interested in.
+osgi.discovery.interest.filters=Optional ServiceRegistration property which contains filters for services this tracker is interested in.
+osgi.remote.distribution.product=Service Registration property for the name of the Distribution Provider product.
+osgi.remote.distribution.product.version=Service Registration property for the version of the Distribution Provider product.
+osgi.remote.distribution.vendor=Service Registration property for the Distribution Provider product vendor name.
+osgi.remote.distribition.supported_intents=Service Registration property that lists the intents supported by this DistributionProvider.
+publish=The action string publish.
+subscribe=The action string subscribe.
+event.topics=Service registration property (named event.topics) specifying the Event topics of interest to a Event Handler service.
+event.filter=Service Registration property (named event.filter) specifying a filter to further select Event s of interest to a Event Handler service.
+bundle.signer=The Distinguished Names of the signers of the bundle relevant to the event.
+bundle.symbolicName=The Bundle Symbolic Name of the bundle relevant to the event.
+bundle.id=The Bundle id of the bundle relevant to the event.
+bundle=The Bundle object of the bundle relevant to the event.
+bundle.version=The version of the bundle relevant to the event.
+event=The forwarded event object.
+exception=An exception or error.
+exception.class=The name of the exception type.
+exception.message=The exception message.
+message=A human-readable message that is usually not localized.
+service=A service reference.
+service.id=A service's id.
+service.objectClass=A service's objectClass.
+service.pid=A service's persistent identity.
+timestamp=The time when the event occurred, as reported by System.currentTimeMillis().
+exception.class=This constant was released with an incorrectly spelled name.
+CompositeServiceFilter-Import=Manifest header (named "CompositeServiceFilter-Import") identifying the service filters that are used by a composite bundle to select services that will be registered into a child framework by its associated surrogate bundle.
+CompositeServiceFilter-Export=Manifest header (named "CompositeServiceFilter-Export") identifying the service filters that are used by a surrogate bundle to select services that will be registered into a parent framework by its associated composite bundle.
+org.osgi.service.http.authentication.remote.user=HttpServletRequest attribute specifying the name of the authenticated user.
+org.osgi.service.http.authentication.type=HttpServletRequest attribute specifying the scheme used in authentication.
+org.osgi.service.useradmin.authorization=HttpServletRequest attribute specifying the Authorization object obtained from the org.osgi.service.useradmin.UserAdmin service.
+io.scheme=Service property containing the scheme(s) for which this Connection Factory can create Connection objects.
+-1=Argument for getAttributeDefinitions(int).
+OSGI-INF/metatype=Location of meta type documents.
+read=Holders of MonitorPermission with the read action present are allowed to read the value of the StatusVariables specified in the permission's target field.
+reset=Holders of MonitorPermission with the reset action present are allowed to reset the value of the StatusVariables specified in the permission's target field.
+publish=Holders of MonitorPermission with the publish action present are Monitorable services that are allowed to publish the StatusVariables specified in the permission's target field.
+startjob=Holders of MonitorPermission with the startjob action present are allowed to initiate monitoring jobs involving the StatusVariables specified in the permission's target field.
+switchevents=Holders of MonitorPermission with the switchevents action present are allowed to switch event sending on or off for the value of the StatusVariables specified in the permission's target field.
+license=
+description=
+documentation=
+copyright=
+source=
+symbolicname=
+presentationname=
+id=
+version=
+url=
+size=
+provisioning.spid=The key to the provisioning information that uniquely identifies the Service Platform.
+provisioning.reference=The key to the provisioning information that contains the location of the provision data provider.
+provisioning.agent.config=The key to the provisioning information that contains the initial configuration information of the initial Management Agent.
+provisioning.update.count=The key to the provisioning information that contains the update count of the info data.
+provisioning.start.bundle=The key to the provisioning information that contains the location of the bundle to start with AllPermission.
+provisioning.rootx509=The key to the provisioning information that contains the root X509 certificate used to establish trust with operator when using HTTPS.
+provisioning.rsh.secret=The key to the provisioning information that contains the shared secret used in conjunction with the RSH protocol.
+text/plain;charset=utf-8=MIME type to be used in the InitialProvisioning-Entries header or stored in the extra field of a ZipEntry object for String data.
+application/octet-stream=MIME type to be used in the InitialProvisioning-Entries header or stored stored in the extra field of a ZipEntry object for byte[] data.
+application/vnd.osgi.bundle=MIME type to be used in the InitialProvisioning-Entries header or stored stored in the extra field of a ZipEntry object for an installable bundle file.
+application/x-osgi-bundle=Alternative MIME type to be used in the InitialProvisioning-Entries header or stored stored in the extra field of a ZipEntry object for an installable bundle file.
+text/x-osgi-bundle-url=MIME type to be stored in the extra field of a ZipEntry for a String that represents a URL for a bundle.
+InitialProvisioning-Entries=Name of the header that specifies the (MIME) type information for the ZIP file entries.
+ui1=Unsigned 1 Byte int.
+ui2=Unsigned 2 Byte int.
+ui4=Unsigned 4 Byte int.
+i1=1 Byte int.
+i2=2 Byte int.
+i4=4 Byte int.
+int=Integer number.
+r4=4 Byte float.
+r8=8 Byte float.
+number=Same as r8.
+fixed.14.4=Same as r8 but no more than 14 digits to the left of the decimal point and no more than 4 to the right.
+float=Floating-point number.
+char=Unicode string.
+string=Unicode string.
+date=A calendar date.
+dateTime=A specific instant of time.
+dateTime.tz=A specific instant of time.
+time=An instant of time that recurs every day.
+time.tz=An instant of time that recurs every day.
+boolean=True or false.
+bin.base64=MIME-style Base64 encoded binary BLOB.
+bin.hex=Hexadecimal digits representing octets.
+uri=Universal Resource Identifier.
+uuid=Universally Unique ID.
+UPnP.service.type=Property key for the optional service type uri.
+UPnP.service.id=Property key for the optional service id.
+upnp.filter=Key for a service property having a value that is an object of type org.osgi.framework.Filter and that is used to limit received events.
+UPnP=Constant for the value of the service property DEVICE_CATEGORY used for all UPnP devices.
+UPnP.export=The UPnP.export service property is a hint that marks a device to be picked up and exported by the UPnP Service.
+UPnP.device.UDN=Property key for the Unique Device Name (UDN) property.
+UPnP.device.UDN=Property key for the Unique Device ID property.
+UPnP.device.type=Property key for the UPnP Device Type property.
+UPnP.device.manufacturer=Mandatory property key for the device manufacturer's property.
+UPnP.device.modelName=Mandatory property key for the device model name.
+UPnP.device.friendlyName=Mandatory property key for a short user friendly version of the device name.
+UPnP.device.manufacturerURL=Optional property key for a URL to the device manufacturers Web site.
+UPnP.device.modelDescription=Optional (but recommended) property key for a String object with a long description of the device for the end user.
+UPnP.device.modelNumber=Optional (but recommended) property key for a String class typed property holding the model number of the device.
+UPnP.device.modelURL=Optional property key for a String typed property holding a string representing the URL to the Web site for this model.
+UPnP.device.serialNumber=Optional (but recommended) property key for a String typed property holding the serial number of the device.
+UPnP.device.UPC=Optional property key for a String typed property holding the Universal Product Code (UPC) of the device.
+UPnP.presentationURL=Optional (but recommended) property key for a String typed property holding a string representing the URL to a device representation Web page.
+UPnP.device.parentUDN=The property key that must be set for all embedded devices.
+UPnP.device.childrenUDN=The property key that must be set for all devices containing other embedded devices.
+url.handler.protocol=Service property naming the protocols serviced by a URLStreamHandlerService.
+url.content.mimetype=Service property naming the MIME types serviced by a java.net.ContentHandler.
+admin=The permission name "admin".
+changeProperty=The action string "changeProperty".
+changeCredential=The action string "changeCredential".
+getCredential=The action string "getCredential".
+user.anyone=The name of the predefined role, user.anyone, that all users and groups belong to.
+produce=The action string for the produce action.
+consume=The action string for the consume action.
+wireadmin.pid=Wire property key (named wireadmin.pid) specifying the persistent identity (PID) of this Wire object.
+wireadmin.producer.composite=A service registration property for a Producer service that is composite.
+wireadmin.consumer.composite=A service registration property for a Consumer service that is composite.
+wireadmin.producer.scope=Service registration property key (named wireadmin.producer.scope) specifying a list of names that may be used to define the scope of this Wire object.
+wireadmin.consumer.scope=Service registration property key (named wireadmin.consumer.scope) specifying a list of names that may be used to define the scope of this Wire object.
+wireadmin.producer.pid=Wire property key (named wireadmin.producer.pid) specifying the service.pid of the associated Producer service.
+wireadmin.consumer.pid=Wire property key (named wireadmin.consumer.pid) specifying the service.pid of the associated Consumer service.
+wireadmin.filter=Wire property key (named wireadmin.filter) specifying a filter used to control the delivery rate of data between the Producer and the Consumer service.
+wirevalue.current=Wire object's filter attribute (named wirevalue.current) representing the current value.
+wirevalue.previous=Wire object's filter attribute (named wirevalue.previous) representing the previous value.
+wirevalue.delta.absolute=Wire object's filter attribute (named wirevalue.delta.absolute) representing the absolute delta.
+wirevalue.delta.relative=Wire object's filter attribute (named wirevalue.delta.relative) representing the relative delta.
+wirevalue.elapsed=Wire object's filter attribute (named wirevalue.elapsed) representing the elapsed time, in ms, between this filter evaluation and the last update of the Consumer service.
+wireadmin.producer.filters=Service Registration property (named wireadmin.producer.filters).
+wireadmin.consumer.flavors=Service Registration property (named wireadmin.consumer.flavors) specifying the list of data types understood by this Consumer service.
+wireadmin.producer.flavors=Service Registration property (named wireadmin.producer.flavors) specifying the list of data types available from this Producer service.
+wireadmin.events=Service Registration property (named wireadmin.events) specifying the WireAdminEvent type of interest to a Wire Admin Listener service.
+javax.xml.parsers.SAXParserFactory=Filename containing the SAX Parser Factory Class name.
+javax.xml.parsers.DocumentBuilderFactory=Filename containing the DOM Parser Factory Class name.
+/META-INF/services/javax.xml.parsers.SAXParserFactory=Fully qualified path name of SAX Parser Factory Class Name file
+/META-INF/services/javax.xml.parsers.DocumentBuilderFactory=Fully qualified path name of DOM Parser Factory Class Name file
+parser.validating=Service property specifying if factory is configured to support validating parsers.
+parser.namespaceAware=Service property specifying if factory is configured to support namespace aware parsers.
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/help/syntax.properties
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/help/syntax.properties
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: felix/trunk/bundleplugin/src/main/java/aQute/bnd/help/syntax.xml
URL: http://svn.apache.org/viewvc/felix/trunk/bundleplugin/src/main/java/aQute/bnd/help/syntax.xml?rev=1347815&view=auto
==============================================================================
--- felix/trunk/bundleplugin/src/main/java/aQute/bnd/help/syntax.xml (added)
+++ felix/trunk/bundleplugin/src/main/java/aQute/bnd/help/syntax.xml Thu Jun 7 21:57:32 2012
@@ -0,0 +1,2 @@
+
+Bundle-Name\\s*(:|=)\\s*
\ No newline at end of file
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/help/syntax.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/help/syntax.xml
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/Make.java
URL: http://svn.apache.org/viewvc/felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/Make.java?rev=1347815&view=auto
==============================================================================
--- felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/Make.java (added)
+++ felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/Make.java Thu Jun 7 21:57:32 2012
@@ -0,0 +1,97 @@
+package aQute.bnd.make;
+
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.regex.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+import aQute.libg.header.*;
+
+public class Make {
+ Builder builder;
+ Map<Instruction, Map<String, String>> make;
+
+ public Make(Builder builder) {
+ this.builder = builder;
+ }
+
+ public Resource process(String source) {
+ Map<Instruction, Map<String, String>> make = getMakeHeader();
+ builder.trace("make " + source);
+
+ for (Map.Entry<Instruction, Map<String, String>> entry : make.entrySet()) {
+ Instruction instr = entry.getKey();
+ Matcher m = instr.getMatcher(source);
+ if (m.matches() || instr.isNegated()) {
+ Map<String, String> arguments = replace(m, entry.getValue());
+ List<MakePlugin> plugins = builder.getPlugins(MakePlugin.class);
+ for (MakePlugin plugin : plugins) {
+ try {
+ Resource resource = plugin.make(builder, source, arguments);
+ if (resource != null) {
+ builder.trace("Made " + source + " from args " + arguments + " with "
+ + plugin);
+ return resource;
+ }
+ } catch (Exception e) {
+ builder.error("Plugin " + plugin + " generates error when use in making "
+ + source + " with args " + arguments, e);
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private Map<String, String> replace(Matcher m, Map<String, String> value) {
+ Map<String, String> newArgs = Processor.newMap();
+ for (Map.Entry<String, String> entry : value.entrySet()) {
+ String s = entry.getValue();
+ s = replace(m, s);
+ newArgs.put(entry.getKey(), s);
+ }
+ return newArgs;
+ }
+
+ String replace(Matcher m, CharSequence s) {
+ StringBuilder sb = new StringBuilder();
+ int max = '0' + m.groupCount() + 1;
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (c == '$' && i < s.length() - 1) {
+ c = s.charAt(++i);
+ if (c >= '0' && c <= max) {
+ int index = c - '0';
+ String replacement = m.group(index);
+ if (replacement != null)
+ sb.append(replacement);
+ } else {
+ if (c == '$')
+ i++;
+ sb.append(c);
+ }
+ } else
+ sb.append(c);
+ }
+ return sb.toString();
+ }
+
+ Map<Instruction, Map<String, String>> getMakeHeader() {
+ if (make != null)
+ return make;
+ make = Processor.newMap();
+
+ String s = builder.getProperty(Builder.MAKE);
+ Parameters make = builder.parseHeader(s);
+
+ for (Entry<String, Attrs> entry : make.entrySet()) {
+ String pattern = Processor.removeDuplicateMarker(entry.getKey());
+
+ Instruction instr = new Instruction(pattern);
+ this.make.put(instr, entry.getValue());
+ }
+
+ return this.make;
+ }
+}
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/Make.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/Make.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/MakeBnd.java
URL: http://svn.apache.org/viewvc/felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/MakeBnd.java?rev=1347815&view=auto
==============================================================================
--- felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/MakeBnd.java (added)
+++ felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/MakeBnd.java Thu Jun 7 21:57:32 2012
@@ -0,0 +1,65 @@
+package aQute.bnd.make;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.bnd.build.*;
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+
+public class MakeBnd implements MakePlugin, Constants {
+ final static Pattern JARFILE = Pattern.compile("(.+)\\.(jar|ipa)");
+
+ public Resource make(Builder builder, String destination,
+ Map<String, String> argumentsOnMake) throws Exception {
+ String type = argumentsOnMake.get("type");
+ if (!"bnd".equals(type))
+ return null;
+
+ String recipe = argumentsOnMake.get("recipe");
+ if (recipe == null) {
+ builder.error("No recipe specified on a make instruction for "
+ + destination);
+ return null;
+ }
+ File bndfile = builder.getFile(recipe);
+ if (bndfile.isFile()) {
+ // We do not use a parent because then we would
+ // build ourselves again. So we can not blindly
+ // inherit the properties.
+ Builder bchild = builder.getSubBuilder();
+ bchild.removeBundleSpecificHeaders();
+
+ // We must make sure that we do not include ourselves again!
+ bchild.setProperty(Analyzer.INCLUDE_RESOURCE, "");
+ bchild.setProperty(Analyzer.INCLUDERESOURCE, "");
+ bchild.setProperties(bndfile, builder.getBase());
+
+ Jar jar = bchild.build();
+ Jar dot = builder.getTarget();
+
+ if (builder.hasSources()) {
+ for (String key : jar.getResources().keySet()) {
+ if (key.startsWith("OSGI-OPT/src"))
+ dot.putResource(key, jar.getResource(key));
+ }
+ }
+ builder.getInfo(bchild, bndfile.getName() +": ");
+ String debug = bchild.getProperty(DEBUG);
+ if (Processor.isTrue(debug)) {
+ if ( builder instanceof ProjectBuilder ) {
+ ProjectBuilder pb = (ProjectBuilder) builder;
+ File target = pb.getProject().getTarget();
+ String bsn = bchild.getBsn();
+ File output = new File(target, bsn+".jar");
+ jar.write(output);
+ pb.getProject().getWorkspace().changedFile(output);
+ }
+ }
+ return new JarResource(jar);
+ } else
+ return null;
+ }
+
+}
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/MakeBnd.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/MakeBnd.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/MakeCopy.java
URL: http://svn.apache.org/viewvc/felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/MakeCopy.java?rev=1347815&view=auto
==============================================================================
--- felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/MakeCopy.java (added)
+++ felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/MakeCopy.java Thu Jun 7 21:57:32 2012
@@ -0,0 +1,45 @@
+package aQute.bnd.make;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+
+public class MakeCopy implements MakePlugin {
+
+ public Resource make(Builder builder, String destination,
+ Map<String, String> argumentsOnMake) throws Exception {
+ String type = argumentsOnMake.get("type");
+ if (!type.equals("copy"))
+ return null;
+
+ String from = argumentsOnMake.get("from");
+ if (from == null) {
+ String content = argumentsOnMake.get("content");
+ if (content == null)
+ throw new IllegalArgumentException(
+ "No 'from' or 'content' field in copy "
+ + argumentsOnMake);
+ return new EmbeddedResource(content.getBytes("UTF-8"),0);
+ } else {
+
+ File f = builder.getFile(from);
+ if (f.isFile())
+ return new FileResource(f);
+ else {
+ try {
+ URL url = new URL(from);
+ return new URLResource(url);
+ } catch(MalformedURLException mfue) {
+ // We ignore this
+ }
+ throw new IllegalArgumentException(
+ "Copy source does not exist " + from
+ + " for destination " + destination);
+ }
+ }
+ }
+
+}
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/MakeCopy.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/MakeCopy.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/calltree/CalltreeResource.java
URL: http://svn.apache.org/viewvc/felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/calltree/CalltreeResource.java?rev=1347815&view=auto
==============================================================================
--- felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/calltree/CalltreeResource.java (added)
+++ felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/calltree/CalltreeResource.java Thu Jun 7 21:57:32 2012
@@ -0,0 +1,173 @@
+package aQute.bnd.make.calltree;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Clazz.MethodDef;
+
+/**
+ * Create an XML call tree of a set of classes. The structure of the XML is:
+ *
+ * <pre>
+ * calltree ::= <using> <usedby>
+ * using ::= <method> *
+ * usedby ::= <method> *
+ * method ::= <ref>
+ * </pre>
+ *
+ * The <code>using</code> element contains methods in the set of classes and
+ * their references. The <code>usedby</code> element contains the used methods
+ * and their references to the set of classes. The <code>ref</code> element
+ * contains the class, the method name, the descriptor, and a pretty print
+ * version of the method.
+ *
+ * The XML does not contain an XML processor instruction to make it easier to
+ * include in other XML. The encoding is always UTF-8.
+ *
+ * This class can be used as a resource, just add it to a JAR and the data is
+ * generated when the resource is written (saving time when the JAR is up to
+ * date and does not have to be generated). However, the actual write method is
+ * a static method and can be called as well:
+ * {@link #writeCalltree(PrintWriter, Collection)}.
+ */
+public class CalltreeResource extends WriteResource {
+ Collection<Clazz> classes;
+
+ /**
+ * Create a resource for inclusion that will print a call tree.
+ *
+ * @param values the classes for which the call tree is generated.
+ */
+ public CalltreeResource(Collection<Clazz> values) {
+ this.classes = values;
+ System.err.println(values);
+ }
+
+ /**
+ * We set the last modified to 0 so this resource does not force
+ * a new JAR if all other resources are up to date.
+ */
+ public long lastModified() {
+ return 0;
+ }
+
+ /**
+ * The write method is called to write the resource. We just call the static
+ * method.
+ */
+ public void write(OutputStream out) throws Exception {
+ OutputStreamWriter osw = new OutputStreamWriter(out, Constants.DEFAULT_CHARSET);
+ PrintWriter pw = new PrintWriter(osw);
+ try {
+ writeCalltree(pw, classes);
+ } finally {
+ pw.flush();
+ }
+ }
+
+ /**
+ * Print the call tree in XML.
+ *
+ * @param out The output writer
+ * @param classes The set of classes
+ * @throws IOException Any errors
+ */
+ public static void writeCalltree(PrintWriter out, Collection<Clazz> classes)
+ throws Exception {
+
+ final Map<Clazz.MethodDef, Set<Clazz.MethodDef>> using = new TreeMap<Clazz.MethodDef, Set<Clazz.MethodDef>>(COMPARATOR);
+ final Map<Clazz.MethodDef, Set<Clazz.MethodDef>> usedby = new TreeMap<Clazz.MethodDef, Set<Clazz.MethodDef>>(COMPARATOR);
+
+ ClassDataCollector cd = new ClassDataCollector() {
+ Clazz.MethodDef source;
+
+ // Before a method is parsed
+ public void method(Clazz.MethodDef source) {
+ this.source = source;
+ xref(using, source, null);
+ xref(usedby, source, null);
+ }
+
+ // For any reference in the previous method.
+ public void reference(Clazz.MethodDef reference) {
+ xref(using, source, reference);
+ xref(usedby, reference, source);
+ }
+ };
+ for (Clazz clazz : classes) {
+ clazz.parseClassFileWithCollector(cd);
+ }
+
+ out.println("<calltree>");
+ xref(out, "using", using);
+ xref(out, "usedby", usedby);
+ out.println("</calltree>");
+ }
+
+ /*
+ * Add a new reference
+ */
+ static Comparator<Clazz.MethodDef> COMPARATOR = new Comparator<Clazz.MethodDef>() {
+
+ public int compare(MethodDef a, MethodDef b) {
+ int r =a.getName().compareTo(b.getName());
+ return r != 0 ? r : a.getDescriptor().toString().compareTo(b.getDescriptor().toString());
+ }
+ };
+ private static void xref(
+ Map<Clazz.MethodDef, Set<Clazz.MethodDef>> references,
+ Clazz.MethodDef source, Clazz.MethodDef reference) {
+ Set<Clazz.MethodDef> set = references.get(source);
+ if (set == null)
+ references.put(source, set=new TreeSet<Clazz.MethodDef>(COMPARATOR));
+ if ( reference != null)
+ set.add(reference);
+ }
+
+ /*
+ * Print out either using or usedby sets
+ */
+ private static void xref(PrintWriter out, String group,
+ Map<Clazz.MethodDef, Set<Clazz.MethodDef>> references) {
+ out.println(" <" + group + ">");
+ for (Map.Entry<Clazz.MethodDef, Set<Clazz.MethodDef>> entry : references
+ .entrySet()) {
+ Clazz.MethodDef source = entry.getKey();
+ Set<Clazz.MethodDef> refs = entry.getValue();
+ method(out, "method", source, ">");
+ for (Clazz.MethodDef ref : refs) {
+ method(out, "ref", ref, "/>");
+ }
+ out.println(" </method>");
+ }
+ out.println(" </" + group + ">");
+ }
+
+ /*
+ * Print out a method.
+ */
+ private static void method(PrintWriter out, String element,
+ Clazz.MethodDef source, String closeElement) {
+ out.println(" <" + element + " class='" + source.getContainingClass().getFQN() + "'"
+ + getAccess(source.getAccess()) +
+ ( source.isConstructor() ? "" : " name='" + source.getName() + "'") + " descriptor='" + source.getDescriptor() + "' pretty='"
+ + source.toString() + "'" + closeElement);
+ }
+
+ private static String getAccess(int access) {
+ StringBuilder sb = new StringBuilder();
+ if ( Modifier.isPublic(access) )
+ sb.append(" public='true'");
+ if ( Modifier.isStatic(access) )
+ sb.append(" static='true'");
+ if ( Modifier.isProtected(access) )
+ sb.append(" protected='true'");
+ if ( Modifier.isInterface(access) )
+ sb.append(" interface='true'");
+
+ return sb.toString();
+ }
+
+}
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/calltree/CalltreeResource.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/calltree/CalltreeResource.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/component/ComponentAnnotationReader.java
URL: http://svn.apache.org/viewvc/felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/component/ComponentAnnotationReader.java?rev=1347815&view=auto
==============================================================================
--- felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/component/ComponentAnnotationReader.java (added)
+++ felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/component/ComponentAnnotationReader.java Thu Jun 7 21:57:32 2012
@@ -0,0 +1,351 @@
+package aQute.bnd.make.component;
+
+import static aQute.lib.osgi.Constants.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.bnd.annotation.component.*;
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Clazz.MethodDef;
+import aQute.lib.osgi.Descriptors.TypeRef;
+import aQute.libg.reporter.*;
+
+public class ComponentAnnotationReader extends ClassDataCollector {
+ String EMPTY[] = new String[0];
+ private static final String V1_1 = "1.1.0"; // "1.1.0"
+ static Pattern BINDDESCRIPTOR = Pattern
+ .compile("\\(L([^;]*);(Ljava/util/Map;|Lorg/osgi/framework/ServiceReference;)*\\)V");
+ static Pattern BINDMETHOD = Pattern.compile("(set|bind|add)(.)(.*)");
+
+ static Pattern ACTIVATEDESCRIPTOR = Pattern
+ .compile("\\(((Lorg/osgi/service/component/ComponentContext;)|(Lorg/osgi/framework/BundleContext;)|(Ljava/util/Map;))*\\)V");
+ static Pattern OLDACTIVATEDESCRIPTOR = Pattern
+ .compile("\\(Lorg/osgi/service/component/ComponentContext;\\)V");
+
+
+ static Pattern OLDBINDDESCRIPTOR = Pattern.compile("\\(L([^;]*);\\)V");
+ static Pattern REFERENCEBINDDESCRIPTOR = Pattern
+ .compile("\\(Lorg/osgi/framework/ServiceReference;\\)V");
+
+ static String[] ACTIVATE_ARGUMENTS = {
+ "org.osgi.service.component.ComponentContext", "org.osgi.framework.BundleContext",
+ Map.class.getName(), "org.osgi.framework.BundleContext" };
+ static String[] OLD_ACTIVATE_ARGUMENTS = { "org.osgi.service.component.ComponentContext" };
+
+ Reporter reporter = new Processor();
+ MethodDef method;
+ TypeRef className;
+ Clazz clazz;
+ TypeRef interfaces[];
+ Set<String> multiple = new HashSet<String>();
+ Set<String> optional = new HashSet<String>();
+ Set<String> dynamic = new HashSet<String>();
+
+ Map<String, String> map = new TreeMap<String, String>();
+ Set<String> descriptors = new HashSet<String>();
+ List<String> properties = new ArrayList<String>();
+ String version = null;
+
+ // TODO make patterns for descriptors
+
+ ComponentAnnotationReader(Clazz clazz) {
+ this.clazz = clazz;
+ }
+
+ public void setReporter(Reporter reporter) {
+ this.reporter = reporter;
+ }
+
+ public Reporter getReporter() {
+ return this.reporter;
+ }
+
+ public static Map<String, String> getDefinition(Clazz c) throws Exception {
+ return getDefinition(c, new Processor());
+ }
+
+ public static Map<String, String> getDefinition(Clazz c, Reporter reporter) throws Exception {
+ ComponentAnnotationReader r = new ComponentAnnotationReader(c);
+ r.setReporter(reporter);
+ c.parseClassFileWithCollector(r);
+ r.finish();
+ return r.map;
+ }
+
+ public void annotation(Annotation annotation) {
+ String fqn = annotation.getName().getFQN();
+
+ if (fqn.equals(Component.class.getName())) {
+ set(COMPONENT_NAME, annotation.get(Component.NAME), "<>");
+ set(COMPONENT_FACTORY, annotation.get(Component.FACTORY), false);
+ setBoolean(COMPONENT_ENABLED, annotation.get(Component.ENABLED), true);
+ setBoolean(COMPONENT_IMMEDIATE, annotation.get(Component.IMMEDIATE), false);
+ setBoolean(COMPONENT_SERVICEFACTORY, annotation.get(Component.SERVICEFACTORY), false);
+
+ if (annotation.get(Component.DESIGNATE) != null) {
+ String configs = annotation.get(Component.DESIGNATE);
+ if (configs != null) {
+ set(COMPONENT_DESIGNATE, Clazz.objectDescriptorToFQN(configs), "");
+ }
+ }
+
+ if (annotation.get(Component.DESIGNATE_FACTORY) != null) {
+ String configs = annotation.get(Component.DESIGNATE_FACTORY);
+ if (configs != null) {
+ set(COMPONENT_DESIGNATEFACTORY, Clazz.objectDescriptorToFQN(configs), "");
+ }
+ }
+
+ setVersion((String) annotation.get(Component.VERSION));
+
+ String configurationPolicy = annotation.get(Component.CONFIGURATION_POLICY);
+ if (configurationPolicy != null)
+ set(COMPONENT_CONFIGURATION_POLICY, configurationPolicy.toLowerCase(), "");
+
+ doProperties(annotation);
+
+ Object[] provides = (Object[]) annotation.get(Component.PROVIDE);
+ String[] p;
+ if (provides == null) {
+ // Use the found interfaces, but convert from internal to
+ // fqn.
+ if (interfaces != null) {
+ List<String> result = new ArrayList<String>();
+ for (int i = 0; i < interfaces.length; i++) {
+ if (!interfaces[i].getBinary().equals("scala/ScalaObject"))
+ result.add(interfaces[i].getFQN());
+ }
+ p = result.toArray(EMPTY);
+ } else
+ p = EMPTY;
+ } else {
+ // We have explicit interfaces set
+ p = new String[provides.length];
+ for (int i = 0; i < provides.length; i++) {
+ p[i] = descriptorToFQN(provides[i].toString());
+ }
+ }
+ if (p.length > 0) {
+ set(COMPONENT_PROVIDE, Processor.join(Arrays.asList(p)), "<>");
+ }
+
+ } else if (fqn.equals(Activate.class.getName())) {
+ if (!checkMethod())
+ setVersion(V1_1);
+
+ // TODO ... use the new descriptor to do better check
+
+ if (!ACTIVATEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches())
+ reporter.error(
+ "Activate method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
+ className, method.getDescriptor());
+
+ if (method.getName().equals("activate")
+ && OLDACTIVATEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches()) {
+ // this is the default!
+ } else {
+ setVersion(V1_1);
+ set(COMPONENT_ACTIVATE, method, "<>");
+ }
+
+ } else if (fqn.equals(Deactivate.class.getName())) {
+ if (!checkMethod())
+ setVersion(V1_1);
+
+ if (!ACTIVATEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches())
+ reporter.error(
+ "Deactivate method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
+ className, method.getDescriptor());
+ if (method.getName().equals("deactivate")
+ && OLDACTIVATEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches()) {
+ // This is the default!
+ } else {
+ setVersion(V1_1);
+ set(COMPONENT_DEACTIVATE, method, "<>");
+ }
+ } else if (fqn.equals(Modified.class.getName())) {
+ set(COMPONENT_MODIFIED, method, "<>");
+ setVersion(V1_1);
+ } else if (fqn.equals(Reference.class.getName())) {
+
+ String name = (String) annotation.get(Reference.class.getName());
+ String bind = method.getName();
+ String unbind = null;
+
+ if (name == null) {
+ Matcher m = BINDMETHOD.matcher(method.getName());
+ if (m.matches()) {
+ name = m.group(2).toLowerCase() + m.group(3);
+ } else {
+ name = method.getName().toLowerCase();
+ }
+ }
+ String simpleName = name;
+
+ unbind = annotation.get(Reference.UNBIND);
+
+ if (bind != null) {
+ name = name + "/" + bind;
+ if (unbind != null)
+ name = name + "/" + unbind;
+ }
+ String service = annotation.get(Reference.SERVICE);
+
+ if (service != null) {
+ service = Clazz.objectDescriptorToFQN(service);
+ } else {
+ // We have to find the type of the current method to
+ // link it to the referenced service.
+ Matcher m = BINDDESCRIPTOR.matcher(method.getDescriptor().toString());
+ if (m.matches()) {
+ service = Descriptors.binaryToFQN(m.group(1));
+ } else
+ throw new IllegalArgumentException(
+ "Cannot detect the type of a Component Reference from the descriptor: "
+ + method.getDescriptor());
+ }
+
+ // Check if we have a target, this must be a filter
+ String target = annotation.get(Reference.TARGET);
+ if (target != null) {
+ Verifier.verifyFilter(target, 0);
+ service = service + target;
+ }
+
+ Integer c = annotation.get(Reference.TYPE);
+ if (c != null && !c.equals(0) && !c.equals((int) '1')) {
+ service = service + (char) c.intValue();
+ }
+
+ if (map.containsKey(name))
+ reporter.error(
+ "In component %s, Multiple references with the same name: %s. Previous def: %s, this def: %s",
+ name, map.get(name), service, "");
+ map.put(name, service);
+
+ if (isTrue(annotation.get(Reference.MULTIPLE)))
+ multiple.add(simpleName);
+ if (isTrue(annotation.get(Reference.OPTIONAL)))
+ optional.add(simpleName);
+ if (isTrue(annotation.get(Reference.DYNAMIC)))
+ dynamic.add(simpleName);
+
+ if (!checkMethod())
+ setVersion(V1_1);
+ else if (REFERENCEBINDDESCRIPTOR.matcher(method.getDescriptor().toString()).matches()
+ || !OLDBINDDESCRIPTOR.matcher(method.getDescriptor().toString()).matches())
+ setVersion(V1_1);
+ }
+ }
+
+ private void setVersion(String v) {
+ if (v == null)
+ return;
+
+ if (version == null)
+ version = v;
+ else if (v.compareTo(version) > 0) // we're safe to 9.9.9
+ version = v;
+ }
+
+ private boolean checkMethod() {
+ return Modifier.isPublic(method.getAccess()) || Modifier.isProtected(method.getAccess());
+ }
+
+ static Pattern PROPERTY_PATTERN = Pattern.compile("[^=]+=.+");
+
+ private void doProperties(aQute.lib.osgi.Annotation annotation) {
+ Object[] properties = annotation.get(Component.PROPERTIES);
+
+ if (properties != null) {
+ for (Object o : properties) {
+ String p = (String) o;
+ if (PROPERTY_PATTERN.matcher(p).matches())
+ this.properties.add(p);
+ else
+ throw new IllegalArgumentException("Malformed property '" + p + "' on: "
+ + annotation.get(Component.NAME));
+ }
+ }
+ }
+
+ private boolean isTrue(Object object) {
+ if (object == null)
+ return false;
+ return (Boolean) object;
+ }
+
+ private void setBoolean(String string, Object object, boolean b) {
+ if (object == null)
+ object = b;
+
+ Boolean bb = (Boolean) object;
+ if (bb == b)
+ return;
+
+ map.put(string, bb.toString());
+ }
+
+ private void set(String string, Object object, Object deflt) {
+ if (object == null || object.equals(deflt))
+ return;
+
+ map.put(string, object.toString());
+ }
+
+ /**
+ * Skip L and ; and replace / for . in an object descriptor.
+ *
+ * A string like Lcom/acme/Foo; becomes com.acme.Foo
+ *
+ * @param string
+ * @return
+ */
+
+ private String descriptorToFQN(String string) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 1; i < string.length() - 1; i++) {
+ char c = string.charAt(i);
+ if (c == '/')
+ c = '.';
+ sb.append(c);
+ }
+ return sb.toString();
+ }
+
+ @Override public void classBegin(int access, TypeRef name) {
+ className = name;
+ }
+
+ @Override public void implementsInterfaces(TypeRef[] interfaces) {
+ this.interfaces = interfaces;
+ }
+
+ @Override public void method(Clazz.MethodDef method) {
+ this.method = method;
+ descriptors.add(method.getName());
+ }
+
+ void set(String name, Collection<String> l) {
+ if (l.size() == 0)
+ return;
+
+ set(name, Processor.join(l), "<>");
+ }
+
+ public void finish() {
+ set(COMPONENT_MULTIPLE, multiple);
+ set(COMPONENT_DYNAMIC, dynamic);
+ set(COMPONENT_OPTIONAL, optional);
+ set(COMPONENT_IMPLEMENTATION, clazz.getFQN(), "<>");
+ set(COMPONENT_PROPERTIES, properties);
+ if (version != null) {
+ set(COMPONENT_VERSION, version, "<>");
+ reporter.trace("Component %s is v1.1", map);
+ }
+ set(COMPONENT_DESCRIPTORS, descriptors);
+ }
+
+}
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/component/ComponentAnnotationReader.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/component/ComponentAnnotationReader.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/component/ServiceComponent.java
URL: http://svn.apache.org/viewvc/felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/component/ServiceComponent.java?rev=1347815&view=auto
==============================================================================
--- felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/component/ServiceComponent.java (added)
+++ felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/component/ServiceComponent.java Thu Jun 7 21:57:32 2012
@@ -0,0 +1,626 @@
+package aQute.bnd.make.component;
+
+import java.io.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.regex.*;
+
+import aQute.bnd.annotation.component.*;
+import aQute.bnd.make.metatype.*;
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Clazz.QUERY;
+import aQute.lib.osgi.Descriptors.TypeRef;
+import aQute.libg.header.*;
+import aQute.libg.version.*;
+
+/**
+ * This class is an analyzer plugin. It looks at the properties and tries to
+ * find out if the Service-Component header contains the bnd shortut syntax. If
+ * not, the header is copied to the output, if it does, an XML file is created
+ * and added to the JAR and the header is modified appropriately.
+ */
+public class ServiceComponent implements AnalyzerPlugin {
+
+ public boolean analyzeJar(Analyzer analyzer) throws Exception {
+
+ ComponentMaker m = new ComponentMaker(analyzer);
+
+ Map<String, Map<String, String>> l = m.doServiceComponent();
+
+ analyzer.setProperty(Constants.SERVICE_COMPONENT, Processor.printClauses(l));
+
+ analyzer.getInfo(m, "Service-Component: ");
+ m.close();
+
+ return false;
+ }
+
+ private static class ComponentMaker extends Processor {
+ Analyzer analyzer;
+
+ ComponentMaker(Analyzer analyzer) {
+ super(analyzer);
+ this.analyzer = analyzer;
+ }
+
+ /**
+ * Iterate over the Service Component entries. There are two cases:
+ * <ol>
+ * <li>An XML file reference</li>
+ * <li>A FQN/wildcard with a set of attributes</li>
+ * </ol>
+ *
+ * An XML reference is immediately expanded, an FQN/wildcard is more
+ * complicated and is delegated to
+ * {@link #componentEntry(Map, String, Map)}.
+ *
+ * @throws Exception
+ */
+ Map<String, Map<String, String>> doServiceComponent() throws Exception {
+ Map<String, Map<String, String>> serviceComponents = newMap();
+ String header = getProperty(SERVICE_COMPONENT);
+ Parameters sc = parseHeader(header);
+
+ for (Entry<String, Attrs> entry : sc.entrySet()) {
+ String name = entry.getKey();
+ Map<String, String> info = entry.getValue();
+
+ try {
+ if (name.indexOf('/') >= 0 || name.endsWith(".xml")) {
+ // Normal service component, we do not process it
+ serviceComponents.put(name, EMPTY);
+ } else {
+ componentEntry(serviceComponents, name, info);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ error("Invalid Service-Component header: %s %s, throws %s", name, info, e);
+ }
+ }
+ return serviceComponents;
+ }
+
+ /**
+ * Parse an entry in the Service-Component header. This header supports
+ * the following types:
+ * <ol>
+ * <li>An FQN + attributes describing a component</li>
+ * <li>A wildcard expression for finding annotated components.</li>
+ * </ol>
+ * The problem is the distinction between an FQN and a wildcard because
+ * an FQN can also be used as a wildcard.
+ *
+ * If the info specifies {@link Constants#NOANNOTATIONS} then wildcards
+ * are an error and the component must be fully described by the info.
+ * Otherwise the FQN/wildcard is expanded into a list of classes with
+ * annotations. If this list is empty, the FQN case is interpreted as a
+ * complete component definition. For the wildcard case, it is checked
+ * if any matching classes for the wildcard have been compiled for a
+ * class file format that does not support annotations, this can be a
+ * problem with JSR14 who silently ignores annotations. An error is
+ * reported in such a case.
+ *
+ * @param serviceComponents
+ * @param name
+ * @param info
+ * @throws Exception
+ * @throws IOException
+ */
+ private void componentEntry(Map<String, Map<String, String>> serviceComponents,
+ String name, Map<String, String> info) throws Exception, IOException {
+
+ boolean annotations = !Processor.isTrue(info.get(NOANNOTATIONS));
+ boolean fqn = Verifier.isFQN(name);
+
+ if (annotations) {
+
+ // Annotations possible!
+
+ Collection<Clazz> annotatedComponents = analyzer.getClasses("",
+ QUERY.ANNOTATED.toString(), Component.class.getName(), //
+ QUERY.NAMED.toString(), name //
+ );
+
+ if (fqn) {
+ if (annotatedComponents.isEmpty()) {
+
+ // No annotations, fully specified in header
+
+ createComponentResource(serviceComponents, name, info);
+ } else {
+
+ // We had a FQN so expect only one
+
+ for (Clazz c : annotatedComponents) {
+ annotated(serviceComponents, c, info);
+ }
+ }
+ } else {
+
+ // We did not have an FQN, so expect the use of wildcards
+
+ if (annotatedComponents.isEmpty())
+ checkAnnotationsFeasible(name);
+ else
+ for (Clazz c : annotatedComponents) {
+ annotated(serviceComponents, c, info);
+ }
+ }
+ } else {
+ // No annotations
+ if (fqn)
+ createComponentResource(serviceComponents, name, info);
+ else
+ error("Set to %s but entry %s is not an FQN ", NOANNOTATIONS, name);
+
+ }
+ }
+
+ /**
+ * Check if annotations are actually feasible looking at the class
+ * format. If the class format does not provide annotations then it is
+ * no use specifying annotated components.
+ *
+ * @param name
+ * @return
+ * @throws Exception
+ */
+ private Collection<Clazz> checkAnnotationsFeasible(String name) throws Exception {
+ Collection<Clazz> not = analyzer.getClasses("", QUERY.NAMED.toString(), name //
+ );
+
+ if (not.isEmpty())
+ if ( "*".equals(name))
+ return not;
+ else
+ error("Specified %s but could not find any class matching this pattern", name);
+
+ for (Clazz c : not) {
+ if (c.getFormat().hasAnnotations())
+ return not;
+ }
+
+ warning("Wildcards are used (%s) requiring annotations to decide what is a component. Wildcard maps to classes that are compiled with java.target < 1.5. Annotations were introduced in Java 1.5",
+ name);
+
+ return not;
+ }
+
+ void annotated(Map<String, Map<String, String>> components, Clazz c,
+ Map<String, String> info) throws Exception {
+ // Get the component definition
+ // from the annotations
+ Map<String, String> map = ComponentAnnotationReader.getDefinition(c, this);
+
+ // Pick the name, the annotation can override
+ // the name.
+ String localname = map.get(COMPONENT_NAME);
+ if (localname == null)
+ localname = c.getFQN();
+
+ // Override the component info without manifest
+ // entries. We merge the properties though.
+
+ String merged = Processor.merge(info.remove(COMPONENT_PROPERTIES),
+ map.remove(COMPONENT_PROPERTIES));
+ if (merged != null && merged.length() > 0)
+ map.put(COMPONENT_PROPERTIES, merged);
+ map.putAll(info);
+ createComponentResource(components, localname, map);
+ }
+
+ private void createComponentResource(Map<String, Map<String, String>> components,
+ String name, Map<String, String> info) throws IOException {
+
+ // We can override the name in the parameters
+ if (info.containsKey(COMPONENT_NAME))
+ name = info.get(COMPONENT_NAME);
+
+ // Assume the impl==name, but allow override
+ String impl = name;
+ if (info.containsKey(COMPONENT_IMPLEMENTATION))
+ impl = info.get(COMPONENT_IMPLEMENTATION);
+
+ TypeRef implRef = analyzer.getTypeRefFromFQN(impl);
+ // Check if such a class exists
+ analyzer.referTo(implRef);
+
+ boolean designate = designate(name, info.get(COMPONENT_DESIGNATE), false)
+ || designate(name, info.get(COMPONENT_DESIGNATEFACTORY), true);
+
+ // If we had a designate, we want a default configuration policy of
+ // require.
+ if (designate && info.get(COMPONENT_CONFIGURATION_POLICY) == null)
+ info.put(COMPONENT_CONFIGURATION_POLICY, "require");
+
+ // We have a definition, so make an XML resources
+ Resource resource = createComponentResource(name, impl, info);
+ analyzer.getJar().putResource("OSGI-INF/" + name + ".xml", resource);
+
+ components.put("OSGI-INF/" + name + ".xml", EMPTY);
+
+ }
+
+ /**
+ * Create a Metatype and Designate record out of the given
+ * configurations.
+ *
+ * @param name
+ * @param config
+ */
+ private boolean designate(String name, String config, boolean factory) {
+ if (config == null)
+ return false;
+
+ for (String c : Processor.split(config)) {
+ TypeRef ref = analyzer.getTypeRefFromFQN(c);
+ Clazz clazz = analyzer.getClassspace().get(ref);
+ if (clazz != null) {
+ analyzer.referTo(ref);
+ MetaTypeReader r = new MetaTypeReader(clazz, analyzer);
+ r.setDesignate(name, factory);
+ String rname = "OSGI-INF/metatype/" + name + ".xml";
+
+ analyzer.getJar().putResource(rname, r);
+ } else {
+ analyzer.error(
+ "Cannot find designated configuration class %s for component %s", c,
+ name);
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Create the resource for a DS component.
+ *
+ * @param list
+ * @param name
+ * @param info
+ * @throws UnsupportedEncodingException
+ */
+ Resource createComponentResource(String name, String impl, Map<String, String> info)
+ throws IOException {
+ String namespace = getNamespace(info);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ PrintWriter pw = new PrintWriter(new OutputStreamWriter(out, Constants.DEFAULT_CHARSET));
+ pw.println("<?xml version='1.0' encoding='utf-8'?>");
+ if (namespace != null)
+ pw.print("<scr:component xmlns:scr='" + namespace + "'");
+ else
+ pw.print("<component");
+
+ doAttribute(pw, name, "name");
+ doAttribute(pw, info.get(COMPONENT_FACTORY), "factory");
+ doAttribute(pw, info.get(COMPONENT_IMMEDIATE), "immediate", "false", "true");
+ doAttribute(pw, info.get(COMPONENT_ENABLED), "enabled", "true", "false");
+ doAttribute(pw, info.get(COMPONENT_CONFIGURATION_POLICY), "configuration-policy",
+ "optional", "require", "ignore");
+ doAttribute(pw, info.get(COMPONENT_ACTIVATE), "activate", JIDENTIFIER);
+ doAttribute(pw, info.get(COMPONENT_DEACTIVATE), "deactivate", JIDENTIFIER);
+ doAttribute(pw, info.get(COMPONENT_MODIFIED), "modified", JIDENTIFIER);
+
+ pw.println(">");
+
+ // Allow override of the implementation when people
+ // want to choose their own name
+ pw.println(" <implementation class='" + (impl == null ? name : impl) + "'/>");
+
+ String provides = info.get(COMPONENT_PROVIDE);
+ boolean servicefactory = Processor.isTrue(info.get(COMPONENT_SERVICEFACTORY));
+
+ if (servicefactory && Processor.isTrue(info.get(COMPONENT_IMMEDIATE))) {
+ // TODO can become error() if it is up to me
+ warning("For a Service Component, the immediate option and the servicefactory option are mutually exclusive for %(%s)",
+ name, impl);
+ }
+ provide(pw, provides, servicefactory, impl);
+ properties(pw, info);
+ reference(info, pw);
+
+ if (namespace != null)
+ pw.println("</scr:component>");
+ else
+ pw.println("</component>");
+
+ pw.close();
+ byte[] data = out.toByteArray();
+ out.close();
+ return new EmbeddedResource(data, 0);
+ }
+
+ private void doAttribute(PrintWriter pw, String value, String name, String... matches) {
+ if (value != null) {
+ if (matches.length != 0) {
+ if (matches.length == 1 && matches[0].equals(JIDENTIFIER)) {
+ if (!Verifier.isIdentifier(value))
+ error("Component attribute %s has value %s but is not a Java identifier",
+ name, value);
+ } else {
+
+ if (!Verifier.isMember(value, matches))
+ error("Component attribute %s has value %s but is not a member of %s",
+ name, value, Arrays.toString(matches));
+ }
+ }
+ pw.print(" ");
+ pw.print(name);
+ pw.print("='");
+ pw.print(value);
+ pw.print("'");
+ }
+ }
+
+ /**
+ * Check if we need to use the v1.1 namespace (or later).
+ *
+ * @param info
+ * @return
+ */
+ private String getNamespace(Map<String, String> info) {
+ String version = info.get(COMPONENT_VERSION);
+ if (version != null) {
+ try {
+ Version v = new Version(version);
+ return NAMESPACE_STEM + "/v" + v;
+ } catch (Exception e) {
+ error("version: specified on component header but not a valid version: "
+ + version);
+ return null;
+ }
+ }
+ for (String key : info.keySet()) {
+ if (SET_COMPONENT_DIRECTIVES_1_1.contains(key)) {
+ return NAMESPACE_STEM + "/v1.1.0";
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Print the Service-Component properties element
+ *
+ * @param pw
+ * @param info
+ */
+ void properties(PrintWriter pw, Map<String, String> info) {
+ Collection<String> properties = split(info.get(COMPONENT_PROPERTIES));
+ for (Iterator<String> p = properties.iterator(); p.hasNext();) {
+ String clause = p.next();
+ int n = clause.indexOf('=');
+ if (n <= 0) {
+ error("Not a valid property in service component: " + clause);
+ } else {
+ String type = null;
+ String name = clause.substring(0, n);
+ if (name.indexOf('@') >= 0) {
+ String parts[] = name.split("@");
+ name = parts[1];
+ type = parts[0];
+ } else if (name.indexOf(':') >= 0) {
+ String parts[] = name.split(":");
+ name = parts[0];
+ type = parts[1];
+ }
+ String value = clause.substring(n + 1).trim();
+ // TODO verify validity of name and value.
+ pw.print(" <property name='");
+ pw.print(name);
+ pw.print("'");
+
+ if (type != null) {
+ if (VALID_PROPERTY_TYPES.matcher(type).matches()) {
+ pw.print(" type='");
+ pw.print(type);
+ pw.print("'");
+ } else {
+ warning("Invalid property type '" + type + "' for property " + name);
+ }
+ }
+
+ String parts[] = value.split("\\s*(\\||\\n)\\s*");
+ if (parts.length > 1) {
+ pw.println(">");
+ for (String part : parts) {
+ pw.println(part);
+ }
+ pw.println("</property>");
+ } else {
+ pw.print(" value='");
+ pw.print(parts[0]);
+ pw.println("'/>");
+ }
+ }
+ }
+ }
+
+ /**
+ * @param pw
+ * @param provides
+ */
+ void provide(PrintWriter pw, String provides, boolean servicefactory, String impl) {
+ if (provides != null) {
+ if (!servicefactory)
+ pw.println(" <service>");
+ else
+ pw.println(" <service servicefactory='true'>");
+
+ StringTokenizer st = new StringTokenizer(provides, ",");
+ while (st.hasMoreTokens()) {
+ String interfaceName = st.nextToken();
+ TypeRef ref = analyzer.getTypeRefFromFQN(interfaceName);
+ pw.println(" <provide interface='" + interfaceName + "'/>");
+ analyzer.referTo(ref);
+
+ // TODO verifies the impl. class extends or implements the
+ // interface
+ }
+ pw.println(" </service>");
+ } else if (servicefactory)
+ warning("The servicefactory:=true directive is set but no service is provided, ignoring it");
+ }
+
+ public final static Pattern REFERENCE = Pattern.compile("([^(]+)(\\(.+\\))?");
+
+ /**
+ * @param info
+ * @param pw
+ */
+
+ void reference(Map<String, String> info, PrintWriter pw) {
+ Collection<String> dynamic = new ArrayList<String>(split(info.get(COMPONENT_DYNAMIC)));
+ Collection<String> optional = new ArrayList<String>(split(info.get(COMPONENT_OPTIONAL)));
+ Collection<String> multiple = new ArrayList<String>(split(info.get(COMPONENT_MULTIPLE)));
+
+ Collection<String> descriptors = split(info.get(COMPONENT_DESCRIPTORS));
+
+ for (Map.Entry<String, String> entry : info.entrySet()) {
+
+ // Skip directives
+ String referenceName = entry.getKey();
+ if (referenceName.endsWith(":")) {
+ if (!SET_COMPONENT_DIRECTIVES.contains(referenceName))
+ error("Unrecognized directive in Service-Component header: "
+ + referenceName);
+ continue;
+ }
+
+ // Parse the bind/unbind methods from the name
+ // if set. They are separated by '/'
+ String bind = null;
+ String unbind = null;
+
+ boolean unbindCalculated = false;
+
+ if (referenceName.indexOf('/') >= 0) {
+ String parts[] = referenceName.split("/");
+ referenceName = parts[0];
+ bind = parts[1];
+ if (parts.length > 2) {
+ unbind = parts[2];
+ } else {
+ unbindCalculated = true;
+ if (bind.startsWith("add"))
+ unbind = bind.replaceAll("add(.+)", "remove$1");
+ else
+ unbind = "un" + bind;
+ }
+ } else if (Character.isLowerCase(referenceName.charAt(0))) {
+ unbindCalculated = true;
+ bind = "set" + Character.toUpperCase(referenceName.charAt(0))
+ + referenceName.substring(1);
+ unbind = "un" + bind;
+ }
+
+ String interfaceName = entry.getValue();
+ if (interfaceName == null || interfaceName.length() == 0) {
+ error("Invalid Interface Name for references in Service Component: "
+ + referenceName + "=" + interfaceName);
+ continue;
+ }
+
+ // If we have descriptors, we have analyzed the component.
+ // So why not check the methods
+ if (descriptors.size() > 0) {
+ // Verify that the bind method exists
+ if (!descriptors.contains(bind))
+ error("The bind method %s for %s not defined", bind, referenceName);
+
+ // Check if the unbind method exists
+ if (!descriptors.contains(unbind)) {
+ if (unbindCalculated)
+ // remove it
+ unbind = null;
+ else
+ error("The unbind method %s for %s not defined", unbind, referenceName);
+ }
+ }
+ // Check tje cardinality by looking at the last
+ // character of the value
+ char c = interfaceName.charAt(interfaceName.length() - 1);
+ if ("?+*~".indexOf(c) >= 0) {
+ if (c == '?' || c == '*' || c == '~')
+ optional.add(referenceName);
+ if (c == '+' || c == '*')
+ multiple.add(referenceName);
+ if (c == '+' || c == '*' || c == '?')
+ dynamic.add(referenceName);
+ interfaceName = interfaceName.substring(0, interfaceName.length() - 1);
+ }
+
+ // Parse the target from the interface name
+ // The target is a filter.
+ String target = null;
+ Matcher m = REFERENCE.matcher(interfaceName);
+ if (m.matches()) {
+ interfaceName = m.group(1);
+ target = m.group(2);
+ }
+ TypeRef ref = analyzer.getTypeRefFromFQN(interfaceName);
+ analyzer.referTo(ref);
+
+ pw.printf(" <reference name='%s'", referenceName);
+ pw.printf(" interface='%s'", interfaceName);
+
+ String cardinality = optional.contains(referenceName) ? "0" : "1";
+ cardinality += "..";
+ cardinality += multiple.contains(referenceName) ? "n" : "1";
+ if (!cardinality.equals("1..1"))
+ pw.print(" cardinality='" + cardinality + "'");
+
+ if (bind != null) {
+ pw.printf(" bind='%s'", bind);
+ if (unbind != null) {
+ pw.printf(" unbind='%s'", unbind);
+ }
+ }
+
+ if (dynamic.contains(referenceName)) {
+ pw.print(" policy='dynamic'");
+ }
+
+ if (target != null) {
+ // Filter filter = new Filter(target);
+ // if (filter.verify() == null)
+ // pw.print(" target='" + filter.toString() + "'");
+ // else
+ // error("Target for " + referenceName
+ // + " is not a correct filter: " + target + " "
+ // + filter.verify());
+ pw.print(" target='" + escape(target) + "'");
+ }
+ pw.println("/>");
+ }
+ }
+ }
+
+ /**
+ * Escape a string, do entity conversion.
+ */
+ static String escape(String s) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ switch (c) {
+ case '<':
+ sb.append("<");
+ break;
+ case '>':
+ sb.append(">");
+ break;
+ case '&':
+ sb.append("&");
+ break;
+ case '\'':
+ sb.append(""");
+ break;
+ default:
+ sb.append(c);
+ break;
+ }
+ }
+ return sb.toString();
+ }
+
+}
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/component/ServiceComponent.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/component/ServiceComponent.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/coverage/Coverage.java
URL: http://svn.apache.org/viewvc/felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/coverage/Coverage.java?rev=1347815&view=auto
==============================================================================
--- felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/coverage/Coverage.java (added)
+++ felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/coverage/Coverage.java Thu Jun 7 21:57:32 2012
@@ -0,0 +1,99 @@
+package aQute.bnd.make.coverage;
+
+import java.io.*;
+import java.util.*;
+
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Clazz.MethodDef;
+import aQute.lib.osgi.Descriptors.TypeRef;
+
+/**
+ * This class can create a coverage table between two classspaces. The
+ * destination class space is used to create a table of methods. All source
+ * methods that refer to a specific dest are then filled into the table.
+ *
+ */
+public class Coverage {
+
+ /**
+ * Create a cross reference table from source to dest.
+ *
+ * @param source
+ * The methods that refer to dest
+ * @param dest
+ * The methods that are being referred to
+ * @return A mapping of source methods to destination methods.
+ * @throws IOException
+ */
+ public static Map<MethodDef, List<MethodDef>> getCrossRef(
+ Collection<Clazz> source, Collection<Clazz> dest)
+ throws Exception {
+ final Map<MethodDef, List<MethodDef>> catalog = buildCatalog(dest);
+ crossRef(source, catalog);
+ return catalog;
+ }
+
+ private static void crossRef(Collection<Clazz> source,
+ final Map<MethodDef, List<MethodDef>> catalog) throws Exception {
+ for (final Clazz clazz : source) {
+ clazz.parseClassFileWithCollector(new ClassDataCollector() {
+ MethodDef source;
+
+ public void implementsInterfaces(TypeRef names[]) {
+ MethodDef def = clazz.getMethodDef(0,
+ "<implements>", "()V");
+ // TODO
+ for (TypeRef interfaceName : names) {
+ for (Map.Entry<MethodDef, List<MethodDef>> entry : catalog
+ .entrySet()) {
+ String catalogClass = entry.getKey().getContainingClass().getFQN();
+ List<MethodDef> references = entry.getValue();
+
+ if (catalogClass.equals(interfaceName.getFQN())) {
+ references.add(def);
+ }
+ }
+ }
+ }
+
+ // Method definitions
+ public void method(MethodDef source) {
+ this.source = source;
+ }
+
+ public void reference(MethodDef reference) {
+ List<MethodDef> references = catalog.get(reference);
+ if (references != null) {
+ references.add(source);
+ }
+ }
+ });
+ }
+ }
+
+ private static Map<MethodDef, List<MethodDef>> buildCatalog(
+ Collection<Clazz> sources) throws Exception {
+ final Map<MethodDef, List<MethodDef>> catalog = new TreeMap<MethodDef, List<MethodDef>>(new Comparator<MethodDef>() {
+ public int compare(MethodDef a, MethodDef b) {
+ return a.getName().compareTo(b.getName());
+ }
+ });
+ for (final Clazz clazz : sources) {
+ clazz.parseClassFileWithCollector(new ClassDataCollector() {
+
+ public boolean classStart(int access, TypeRef name) {
+ return clazz.isPublic();
+ }
+
+ public void method(MethodDef source) {
+ if (source.isPublic()
+ || source.isProtected())
+ catalog.put(source, new ArrayList<MethodDef>());
+ }
+
+ });
+ }
+ return catalog;
+ }
+
+}
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/coverage/Coverage.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: felix/trunk/bundleplugin/src/main/java/aQute/bnd/make/coverage/Coverage.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision