Hi Richard, sounds good, but, honestly, that's too much Java EE for me. I'm willing to try it, but I maybe won't understand it. It would be great if you could provide a typical and complete example to use and modify for similar tasks.
Thank you, Armin On 6/13/14, Richard Eckart de Castilho <r...@apache.org> wrote: > Hi Armin, > > I'll answer in-line below. > > On 04.06.2014, at 10:04, armin.weg...@bka.bund.de wrote: > >> Hello Richard! >> >> I would like to have a writer that writes all mentions of a given type. >> The type is given by name as a AE parameter. The way the mentions are >> formatted should be interchangeable. So the formatter varies and should be >> encapsulated as a AE resource (or maybe not?). >> >> public class AnnotationWriter extends CasConsumer_ImplBase { >> public static final String PARA_TYPE_NAME = "typeName"; >> >> /** >> * The name of the type whose mentions are to be written. >> */ >> @ConfigurationParameter(name = PARA_TYPE_NAME, mandatory = true) >> private String mTypeName; >> >> /** >> * The type whose mentions are to be written. >> */ >> private Type mType; >> >> public static final String RES_ANNOTATION_FORMATTER = >> "annotationFormatter"; >> @ExternalResource(key = RES_ANNOTATION_FORMATTER, mandatory = true) >> private AnnotationFormatter mFormatter; >> >> @Override >> public void typeSystemInit(final TypeSystem typeSystem) throws >> AnalysisEngineProcessException { >> super.typeSystemInit(typeSystem); >> mType = typeSystem.getType(typeName); >> } >> >> @Override >> public final void process(final CAS cas) throws >> AnalysisEngineProcessException { >> /* >> * Write all annotations of the given type. >> */ >> try (final Writer writer = // build a writer) { >> for (final AnnotationFS annotation : >> CasUtil.select(cas, type)) { >> >> writer.append(mAnnotationFormatter.format(annotation)); >> } >> } catch (IOException cause) { >> throw new AnalysisEngineProcessException(cause); >> } >> } >> } >> >> This is the interface for all formatters. >> >> public interface AnnotationFormatter { >> String format(final AnnotationFS annotation); >> } >> >> >> This is a concrete implementation of a formatter. The problem is that this >> is not an external resource. There is no file, no dictionary, no data base >> connection, or what ever. It is just a simple object. Most likely, this is >> not how a UIMA resource should be used. > > You are probably right that the original authors of the shard resources > mechanism didn't have the use-case of using a the shared resources as a > generic strategy pattern in mind. I personally think that this is a > perfectly valid use-case. > >> public class TsvAnnotationFormatter extends Resource_ImplBase implements >> AnnotationFormatter { >> public static final String PARA_FEATURE_NAMES = "featureNames"; >> >> /** >> * This would be nice but does not work. >> */ >> @ConfigurationParameter(name = PARA_FEATURE_NAMES, mandatory = true) >> private String[] mFeatureNames; >> >> @Override >> public final String format(final AnnotationFS annotation) { >> // Pretty print the given features' values. >> } >> } >> >> As you said, String[] works fine with SharedResourceObject. But >> SharedResourceObject demands a real resource to be loaded which I don't >> have. > > I would see that differently. The SharedResourceObject *allows* to load a > real resources, but you can choose to pass in dummy value (maybe even null). > But I feel with you. Since some time, I have been playing with the idea of > changing the uimaFIT Resource_ImplBase to implement SharedResourceObject > (for the better parameter support) and turning the load(DataResource aData) > basically into a no-op so that subclasses do not have to implement it. > >> There is a simple solution to this: Omit the pseudo resource and make >> featureNames a parameter of AnnotationWriter. I can still use the >> formatter interface but only internally to the writer. But I have to code >> a new writer for each annotation formatter. That works fine but is not the >> kind of modularization I would like to have. > > There is another way of implementing strategies that are not aware of UIMA > and that do not implement any of the UIMA interfaces. uimaFIT provides the > concept of a ResourceLocator. Such a locator is basically a factory that > knows how to instantiate the kind of non-UIMA objects that you want to use > in your analysis engine. An example is given in Section 7.2 of the uimaFIT > manual [1]. > > I have been playing with the idea of implementing a generic JavaBeanInjector > based on the ResourceLocator support, e.g. > > AnalysisEngineDescription desc = createEngineDescription( > MyAnalysisEngine2.class, > MyAnalysisEngine2.RES_BEAN, > createExternalResourceDescription(JavaBeanInjector.class, > JavaBeanInjector.PARAM_CLASS, MyJavaBeanClass.class > "field1", "value1", > ...)); > > The AE would look like this: > > static final String RES_BEAN = "bean"; > @ExternalResource(key = RES_BEAN) > MyJavaBeanClass bean; // Could also use an interface here > > It should be easy to implement such a JavaBeanInjector if you want to try > this approach. Basically the JavaBeanInjector would use the Java reflection > API to instantiate the class and fill in the fields. Using helpers from > Spring or Apache Commons, it should be possible to do this with just a few > lines of code. > > What do you think? > > Cheers, > > -- Richard > > [1] http://uima.apache.org/d/uimafit-current/tools.uimafit.book.html#d5e519 > >