Just realized that I could have applied the same pattern to the BaseMapData and not use the implementation class there either.
Alain On Sun, Aug 12, 2018 at 8:58 AM Alain Picard <[email protected]> wrote: > To David, > > Your comment got me thinking some more about this. And given that I have > about 25 different variations and each has 3 variants, that would mean > introducing somewhere like 75 "marker" interfaces. > > Here's what I did: > > A number of key classes are generated and sometimes partly modified by > hand. So in the "main" such class I have: > /** > * This class is generated by Iris-Mapping. > * > * @generated > */ > @Component( > property = { > IBaseMapData.CONFIG_MAPPING_ID + "=" + > "com.castortech.iris.mapping.project.baModel.asset", > IBaseMapData.CONFIG_MAPPING_NAME + "=" + > BaModelAssetMapData.TABLE_NAME, > IBaseMapData.CONFIG_MAPPING_XL_READER + "=" + > "com.castortech.iris.mapping.maps.project.baModel.asset.BaModelAssetXlReader", > IBaseMapData.CONFIG_MAPPING_XL_WRITER + "=" + > "com.castortech.iris.mapping.maps.project.baModel.asset.BaModelAssetXlWriter" > }, > service=BaModelAssetMapData.class > ) > public final class BaModelAssetMapData extends > BaseMapData<BaModelAssetMapTable, BaModelAssetMapRecord> { > public static final String TABLE_NAME = "Asset"; //$NON-NLS-1$ > public static final String PROP_TABLE_NAME = > MappingConstants.CONFIG_TABLE_NAME + "=" + TABLE_NAME; //$NON-NLS-1$ > public static final String TARGET_TABLE_NAME = "(" + > MappingConstants.CONFIG_TABLE_NAME + "=" + TABLE_NAME + ")"; //$NON-NLS-1$ > //$NON-NLS-2$ //$NON-NLS-3$ > ... > > and then I will have: > @Component(property=BaModelAssetMapData.PROP_TABLE_NAME) > public final class AssetXlExporter implements BaXlExportContent { > @Reference > private BaXlExportUtils<BaModelAssetXlWriter, BaModelAssetMapTable, > BaModelAssetMapRecord> exporter; > > @Reference(target=BaModelAssetMapData.TARGET_TABLE_NAME) > private ExportTable<BaModelAssetMapTable> exportTable; > > and in another location where the exporter is used as a reference: > .... > @Reference(target=BaModelAssetMapData.TARGET_TABLE_NAME) > private AssetXlExporter assetXlExporter; > ... > > To me this avoids the previous issue of exposing the implementation class > and using generated constants, allows to have readable code where > annotations don't become unreadable. > > Does it make sense? > > Alain > > On Sun, Aug 12, 2018 at 8:22 AM David Leangen <[email protected]> wrote: > >> >> Hi Alain, >> >> Maybe there is a way of having 25 different interfaces in your API >> instead? >> >> Or, if they are private, maybe you don’t even need to use services? >> >> Are you able to share your code? Would be helpful to have a little more >> information. >> >> >> Cheers, >> =David >> >> >> >> On Aug 12, 2018, at 6:58, Alain Picard <[email protected]> wrote: >> >> On Sat, Aug 11, 2018 at 4:10 PM David Leangen <[email protected]> wrote: >> >>> >>> Hi Alain, >>> >>> What is it you are trying to accomplish? Is there a reason you are >>> exposing the implementation class? >>> >>> Maybe you know this already, but the “usual” practice is to expose an >>> interface in your API (and export the containing package), and to keep the >>> implementation private. >>> >> Yes, absolutely, and that's why I'm asking. I have about 25 different >> implementation of the interfaces that are most often referenced directly >> from a matching component (i.e. for the same table) and a few cases where >> they are invoked generically. Here all of those are in a single bundle so >> this is more like a "private" API and the use of a class is not a real >> problem. But I didn't feel like using @Reference(target=(tableName=x) for >> each case. Hence my question. >> >> Alain >> >>> >>> Also: >>> >>> > Collection<ServiceReference<T>> servRefs = >>> bcontext.getServiceReferences(target, props.get("filter")); //filter to be >>> like: "(target >>> > servRef = servRefs.isEmpty() ? null : >>> servRefs.iterator().next(); >>> >>> Did some text get cut out of your post? >>> >>> If you can explain a little more what you are trying to do I think that >>> would be helpful. >>> >>> >>> Cheers, >>> =David >>> >>> >>> > On Aug 12, 2018, at 1:27, Alain Picard via osgi-dev < >>> [email protected]> wrote: >>> > >>> > Looking for confirmation or insight in how best to specify components >>> and references, so that the same component can be invoked directly or more >>> generically through its interface. >>> > >>> > Let's say that I have some components, 1 per table to do some export >>> function: >>> > >>> > @Component( >>> > property= MappingConstants.CONFIG_TABLE_NAME + "=BigTable", >>> > service= { BigTableXlExporter.class, XlExportContent.class } >>> > ) >>> > public final class BigTableXlExporter implements XlExportContent {...} >>> > >>> > and in another component I can get a specific reference with: >>> > @Component(service=SomeComp.class) >>> > public final class SomeComp >>> > @Reference >>> > private BigTableXlExporter exporter; >>> > ... >>> > } >>> > >>> > and in another case i could get a more generic invocation (as part of >>> config or through a factory: >>> > @Component(service=GenericComp.class) >>> > public final class GenericComp >>> > @Activate >>> > private void init(Map<String,Object> props, BundleContext bcontext) >>> { >>> > ServiceReference servRef; >>> > try { >>> > Collection<ServiceReference<T>> servRefs = >>> bcontext.getServiceReferences(target, props.get("filter")); //filter to be >>> like: "(target >>> > servRef = servRefs.isEmpty() ? null : >>> servRefs.iterator().next(); >>> > } >>> > catch (InvalidSyntaxException e) { >>> > throw new IllegalArgumentException("Invalid Filter Syntax >>> Exception", e); >>> > } >>> > >>> > //do something with ref.... >>> > } >>> > } >>> > >>> > Does this make sense or are there better ways to do this. >>> > >>> > Alain >>> > >>> > _______________________________________________ >>> > OSGi Developer Mail List >>> > [email protected] >>> > https://mail.osgi.org/mailman/listinfo/osgi-dev >>> >>> >>
_______________________________________________ OSGi Developer Mail List [email protected] https://mail.osgi.org/mailman/listinfo/osgi-dev
