Return-Path: X-Original-To: apmail-uima-user-archive@www.apache.org Delivered-To: apmail-uima-user-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 2F45D10EF3 for ; Fri, 13 Jun 2014 09:26:10 +0000 (UTC) Received: (qmail 2335 invoked by uid 500); 13 Jun 2014 09:26:05 -0000 Delivered-To: apmail-uima-user-archive@uima.apache.org Received: (qmail 2290 invoked by uid 500); 13 Jun 2014 09:26:05 -0000 Mailing-List: contact user-help@uima.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: user@uima.apache.org Delivered-To: mailing list user@uima.apache.org Received: (qmail 2276 invoked by uid 99); 13 Jun 2014 09:26:05 -0000 Received: from minotaur.apache.org (HELO minotaur.apache.org) (140.211.11.9) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 13 Jun 2014 09:26:04 +0000 Received: from localhost (HELO [10.0.1.6]) (127.0.0.1) (smtp-auth username rec, mechanism plain) by minotaur.apache.org (qpsmtpd/0.29) with ESMTP; Fri, 13 Jun 2014 09:26:04 +0000 Content-Type: text/plain; charset=iso-8859-1 Mime-Version: 1.0 (Mac OS X Mail 7.3 \(1878.2\)) Subject: Re: uimafit - String[] parameter in Resource_ImplBase From: Richard Eckart de Castilho In-Reply-To: Date: Fri, 13 Jun 2014 11:25:59 +0200 Content-Transfer-Encoding: quoted-printable Message-Id: References: To: user@uima.apache.org X-Mailer: Apple Mail (2.1878.2) Hi Armin, I'll answer in-line below. On 04.06.2014, at 10:04, Armin.Wegner@bka.bund.de wrote: > Hello Richard! >=20 > 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?). >=20 > public class AnnotationWriter extends CasConsumer_ImplBase { > public static final String PARA_TYPE_NAME =3D "typeName"; >=20 > /** > * The name of the type whose mentions are to be written. > */ > @ConfigurationParameter(name =3D PARA_TYPE_NAME, mandatory =3D = true) > private String mTypeName; >=20 > /** > * The type whose mentions are to be written. > */ > private Type mType; >=20 > public static final String RES_ANNOTATION_FORMATTER =3D = "annotationFormatter"; > @ExternalResource(key =3D RES_ANNOTATION_FORMATTER, mandatory =3D = true) > private AnnotationFormatter mFormatter; >=20 > @Override > public void typeSystemInit(final TypeSystem typeSystem) throws = AnalysisEngineProcessException { > super.typeSystemInit(typeSystem); > mType =3D typeSystem.getType(typeName); > } > =09 > @Override > public final void process(final CAS cas) throws = AnalysisEngineProcessException { > /* > * Write all annotations of the given type. > */ > try (final Writer writer =3D // build a writer) { > for (final AnnotationFS annotation : = CasUtil.select(cas, type)) { > = writer.append(mAnnotationFormatter.format(annotation)); > } > } catch (IOException cause) { > throw new AnalysisEngineProcessException(cause); > } > } > } >=20 > This is the interface for all formatters. >=20 > public interface AnnotationFormatter { > String format(final AnnotationFS annotation); > } >=20 >=20 > 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 =3D = "featureNames"; >=20 > /** > * This would be nice but does not work. > */ > @ConfigurationParameter(name =3D PARA_FEATURE_NAMES, mandatory =3D= true) > private String[] mFeatureNames; > =09 > @Override > public final String format(final AnnotationFS annotation) { > // Pretty print the given features' values. > } > }=20 >=20 > 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 =3D 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 =3D "bean"; @ExternalResource(key =3D 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