Added @Field Annotation to support auto initilaize params from config
Project: http://git-wip-us.apache.org/repos/asf/tika/repo Commit: http://git-wip-us.apache.org/repos/asf/tika/commit/aad23d9e Tree: http://git-wip-us.apache.org/repos/asf/tika/tree/aad23d9e Diff: http://git-wip-us.apache.org/repos/asf/tika/diff/aad23d9e Branch: refs/heads/master Commit: aad23d9e848b8d8e9a5a7a1f4359ef4a2dbdba24 Parents: c6eefbd Author: Thamme Gowda <[email protected]> Authored: Wed Jun 1 16:28:23 2016 -0700 Committer: Thamme Gowda <[email protected]> Committed: Wed Jun 1 16:28:23 2016 -0700 ---------------------------------------------------------------------- .../main/java/org/apache/tika/config/Field.java | 43 +++++ .../java/org/apache/tika/config/ParamField.java | 167 ++++++++++++++++ .../java/org/apache/tika/config/TikaConfig.java | 7 +- .../org/apache/tika/utils/AnnotationUtils.java | 131 +++++++++++++ .../tika/parser/DummyParametrizedParser.java | 97 ++++++++++ .../tika/parser/ParametrizedParserTest.java | 67 +++++++ .../apache/tika/utils/AnnotationUtilsTest.java | 190 +++++++++++++++++++ .../tika/config/TIKA-1986-parametrized.xml | 37 ++++ 8 files changed, 738 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tika/blob/aad23d9e/tika-core/src/main/java/org/apache/tika/config/Field.java ---------------------------------------------------------------------- diff --git a/tika-core/src/main/java/org/apache/tika/config/Field.java b/tika-core/src/main/java/org/apache/tika/config/Field.java new file mode 100644 index 0000000..f4fe3f2 --- /dev/null +++ b/tika-core/src/main/java/org/apache/tika/config/Field.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.config; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Field annotation is a contract for binding {@link Param} value from + * Tika Configuration to any instance of {@link org.apache.tika.base.Configurable} + * services + * @since Apache Tika 1.14 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.METHOD}) +public @interface Field{ + /** + * + * @return name of the Field + */ + String name() default ParamField.DEFAULT; + + /** + * @return whether this field is required or not + */ + boolean required() default false; +} http://git-wip-us.apache.org/repos/asf/tika/blob/aad23d9e/tika-core/src/main/java/org/apache/tika/config/ParamField.java ---------------------------------------------------------------------- diff --git a/tika-core/src/main/java/org/apache/tika/config/ParamField.java b/tika-core/src/main/java/org/apache/tika/config/ParamField.java new file mode 100644 index 0000000..96063dc --- /dev/null +++ b/tika-core/src/main/java/org/apache/tika/config/ParamField.java @@ -0,0 +1,167 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.config; + +import java.lang.reflect.*; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +/** + * This class stores metdata for {@link Field} annotation are used to map them + * to {@link Param} at runtime + * + * @since Apache Tika 1.14 + */ +public class ParamField { + + public static final String DEFAULT = "#default"; + + //NOTE: since (primitive type) is NOT AssignableFrom (BoxedType), + // we just use boxed type for everything! + // Example : short.class.isAssignableFrom(Short.class) ? false + private static final Map<Class<?>, Class<?>> PRIMITIVE_MAP + = new HashMap<Class<?>, Class<?>>(){{ + put(int.class, Integer.class); + put(short.class, Short.class); + put(boolean.class, Boolean.class); + put(long.class, Long.class); + put(float.class, Float.class); + put(double.class, Double.class); + }}; + + private java.lang.reflect.Field field; + private Method setter; + private String name; + private Class<?> type; + private boolean required; + + /** + * Creates a ParamField object + * @param member a field or method which has {@link Field} annotation + */ + public ParamField(AccessibleObject member){ + if (member instanceof java.lang.reflect.Field) { + field = (java.lang.reflect.Field) member; + } else { + setter = (Method) member; + } + + Field annotation = member.getAnnotation(Field.class); + required = annotation.required(); + if (annotation.name().equals(DEFAULT)) { + if (field != null){ + name = field.getName(); + } else { + String funcName = setter.getName(); + if (funcName.startsWith("set")) { + name = funcName.replaceFirst("^set", ""); + } + } + } + name = retrieveParamName(annotation); + type = retrieveType(); + } + + public java.lang.reflect.Field getField() { + return field; + } + + public Method getSetter() { + return setter; + } + + public String getName() { + return name; + } + + public Class<?> getType() { + return type; + } + + public boolean isRequired() { + return required; + } + + /** + * Sets given value to the annotated field of bean + * @param bean bean with annotation for field + * @param value value of field + * @throws IllegalAccessException when it occurs + * @throws InvocationTargetException when it occurs + */ + public void assignValue(Object bean, Object value) + throws IllegalAccessException, InvocationTargetException { + if (field != null) { + field.set(bean, value); + } else { + setter.invoke(bean, value); + } + } + + private Class retrieveType() { + Class type; + if (field != null) { + type = field.getType(); + } else { + Class[] params = setter.getParameterTypes(); + if (params.length != 1) { + //todo:Tika config exception + String msg = "Invalid setter method. Must have one and only one parameter. "; + if (setter.getName().startsWith("get")) { + msg += "Perhaps the annotation is misplaced on " + + setter.getName() +" while a set'X' is expected?"; + } + throw new RuntimeException(msg); + } + type = params[0]; + } + if (type.isPrimitive() && PRIMITIVE_MAP.containsKey(type)){ + type = PRIMITIVE_MAP.get(type); //primitive types have hard time + } + return type; + } + + private String retrieveParamName(Field annotation) { + String name; + if (annotation.name().equals(DEFAULT)) { + if (field != null) { + name = field.getName(); + } else { + String setterName = setter.getName(); + if (setterName.startsWith("set") && setterName.length() > 3) { + name = setterName.substring(3, 4).toLowerCase(Locale.ROOT) + + setterName.substring(4); + } else { + name = setter.getName(); + } + } + } else { + name = annotation.name(); + } + return name; + } + + @Override + public String toString() { + return "ParamField{" + + "name='" + name + '\'' + + ", type=" + type + + ", required=" + required + + '}'; + } +} http://git-wip-us.apache.org/repos/asf/tika/blob/aad23d9e/tika-core/src/main/java/org/apache/tika/config/TikaConfig.java ---------------------------------------------------------------------- diff --git a/tika-core/src/main/java/org/apache/tika/config/TikaConfig.java b/tika-core/src/main/java/org/apache/tika/config/TikaConfig.java index 17b735e..853cdf0 100644 --- a/tika-core/src/main/java/org/apache/tika/config/TikaConfig.java +++ b/tika-core/src/main/java/org/apache/tika/config/TikaConfig.java @@ -59,6 +59,7 @@ import org.apache.tika.parser.DefaultParser; import org.apache.tika.parser.ParseContext; import org.apache.tika.parser.Parser; import org.apache.tika.parser.ParserDecorator; +import org.apache.tika.utils.AnnotationUtils; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -567,8 +568,12 @@ public class TikaConfig { loaded = decorate(loaded, element); //if the instance is configurable, then call configure() if (loaded instanceof Configurable){ + Map<String, Param<?>> params = getParams(element); + //Assigning the params to bean fields/setters + AnnotationUtils.assignFieldParams(loaded, params); + //invoking the configure() hook ParseContext context = new ParseContext(); - context.getParams().putAll(getParams(element)); + context.getParams().putAll(params); ((Configurable) loaded).configure(context); // initialize here } // All done with setup http://git-wip-us.apache.org/repos/asf/tika/blob/aad23d9e/tika-core/src/main/java/org/apache/tika/utils/AnnotationUtils.java ---------------------------------------------------------------------- diff --git a/tika-core/src/main/java/org/apache/tika/utils/AnnotationUtils.java b/tika-core/src/main/java/org/apache/tika/utils/AnnotationUtils.java new file mode 100644 index 0000000..08e004b --- /dev/null +++ b/tika-core/src/main/java/org/apache/tika/utils/AnnotationUtils.java @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.utils; + +import org.apache.tika.config.Field; +import org.apache.tika.config.Param; +import org.apache.tika.config.ParamField; +import org.apache.tika.config.TikaConfig; +import org.apache.tika.exception.TikaConfigException; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AccessibleObject; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * This class contains utilities for dealing with tika annotations + * @since Apache Tika 1.14 + */ +public class AnnotationUtils { + + /** + * Cache for annotations for Bean classes which have {@link Field} + */ + private static final Map<Class<?>, List<ParamField>> PARAM_INFO = + new HashMap<>(); + + /** + * Collects all the fields and methods for an annotation + * @param clazz bean class with annotations + * @param annotation annotation class + * @return list of accessible objects such as fields and methods + */ + private static List<AccessibleObject> collectInfo( + Class<?> clazz, Class<? extends Annotation> annotation) { + + Class superClazz = clazz; + List<AccessibleObject> members = new ArrayList<>(); + List<AccessibleObject> annotatedMembers = new ArrayList<>(); + //walk through the inheritance chain + while (superClazz != null && superClazz != Object.class) { + members.addAll(Arrays.asList(superClazz.getDeclaredFields())); + members.addAll(Arrays.asList(superClazz.getDeclaredMethods())); + superClazz = superClazz.getSuperclass(); + } + + for (final AccessibleObject member : members) { + if (member.isAnnotationPresent(annotation)) { + AccessController.doPrivileged(new PrivilegedAction<Void>(){ + @Override + public Void run() { + member.setAccessible(true); + return null; + } + }); + annotatedMembers.add(member); + } + } + return annotatedMembers; + } + + /** + * Assigns the param values to bean + * @throws TikaConfigException when an error occurs while assigning params + */ + public static void assignFieldParams(Object bean, Map<String, Param<?>> params) throws TikaConfigException { + Class<?> beanClass = bean.getClass(); + if (!PARAM_INFO.containsKey(beanClass)) { + synchronized (TikaConfig.class){ + if (!PARAM_INFO.containsKey(beanClass)) { + List<AccessibleObject> aObjs = collectInfo(beanClass, + org.apache.tika.config.Field.class); + List<ParamField> fields = new ArrayList<>(aObjs.size()); + + for (AccessibleObject aObj : aObjs) { + fields.add(new ParamField(aObj)); + } + PARAM_INFO.put(beanClass, fields); + } + } + } + + List<ParamField> fields = PARAM_INFO.get(beanClass); + for (ParamField field : fields) { + Param<?> param = params.get(field.getName()); + if (param != null){ + if (field.getType().isAssignableFrom(param.getType())) { + try { + field.assignValue(bean, param.getValue()); + } catch (Exception e) { + throw new TikaConfigException(e.getMessage(), e); + } + } else { + String msg = String.format("Value '%s' of type '%s' cant be" + + " assigned to field '%s' of defined type '%s'", + param.getValue(), param.getValue().getClass(), + field.getName(), field.getType()); + throw new TikaConfigException(msg); + } + } else if (field.isRequired()){ + //param not supplied but field is declared as required? + String msg = String.format("Param %s is required for %s," + + " but it is not given in config.", field.getName(), + bean.getClass().getName()); + throw new TikaConfigException(msg); + } else { + //FIXME: SLF4j is not showing up for import, fix it and send this to LOG.debug + //LOG.debug("Param not supplied, field is not mandatory"); + } + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tika/blob/aad23d9e/tika-core/src/test/java/org/apache/tika/parser/DummyParametrizedParser.java ---------------------------------------------------------------------- diff --git a/tika-core/src/test/java/org/apache/tika/parser/DummyParametrizedParser.java b/tika-core/src/test/java/org/apache/tika/parser/DummyParametrizedParser.java new file mode 100644 index 0000000..383a80b --- /dev/null +++ b/tika-core/src/test/java/org/apache/tika/parser/DummyParametrizedParser.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.parser; + +import org.apache.tika.config.Field; +import org.apache.tika.exception.TikaException; +import org.apache.tika.metadata.Metadata; +import org.apache.tika.mime.MediaType; +import org.xml.sax.ContentHandler; +import org.xml.sax.SAXException; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.net.URI; +import java.net.URL; +import java.util.HashSet; +import java.util.Set; + +/** + * A test Parsers to test {@link Field} + * @since Apache Tika 1.14 + */ +public class DummyParametrizedParser extends AbstractParser + implements ConfigurableParser { + + private static Set<MediaType> MIMES = new HashSet<>(); + static { + MIMES.add(MediaType.TEXT_PLAIN); + MIMES.add(MediaType.TEXT_HTML); + MIMES.add(MediaType.APPLICATION_XML); + MIMES.add(MediaType.OCTET_STREAM); + } + + @Field(name = "testparam") private String testParam; + @Field private short xshort; + @Field private int xint; + @Field private long xlong; + @Field(name = "xbigint") private BigInteger xbigInt; + @Field private float xfloat; + @Field private double xdouble; + @Field private boolean xbool; + @Field private URL xurl; + @Field private URI xuri; + + @Field private String missing = "default"; + + private String inner = "inner"; + private File xfile; + + @Field + public void setXfile(File xfile){ + this.xfile = xfile; + } + + @Override + public Set<MediaType> getSupportedTypes(ParseContext context) { + + return MIMES; + } + + @Override + public void parse(InputStream stream, ContentHandler handler, + Metadata metadata, ParseContext context) + throws IOException, SAXException, TikaException { + + metadata.add("testparam", testParam); + metadata.add("xshort", xshort + ""); + metadata.add("xint", xint + ""); + metadata.add("xlong", xlong + ""); + metadata.add("xbigint", xbigInt + ""); + metadata.add("xfloat", xfloat + ""); + metadata.add("xdouble", xdouble + ""); + metadata.add("xbool", xbool + ""); + metadata.add("xuri", xuri + ""); + metadata.add("xurl", xurl + ""); + metadata.add("xfile", xfile + ""); + + metadata.add("inner", inner + ""); + metadata.add("missing", missing + ""); + } +} http://git-wip-us.apache.org/repos/asf/tika/blob/aad23d9e/tika-core/src/test/java/org/apache/tika/parser/ParametrizedParserTest.java ---------------------------------------------------------------------- diff --git a/tika-core/src/test/java/org/apache/tika/parser/ParametrizedParserTest.java b/tika-core/src/test/java/org/apache/tika/parser/ParametrizedParserTest.java new file mode 100644 index 0000000..290f819 --- /dev/null +++ b/tika-core/src/test/java/org/apache/tika/parser/ParametrizedParserTest.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.parser; + +import org.apache.tika.Tika; +import org.apache.tika.config.TikaConfig; +import org.apache.tika.metadata.Metadata; +import org.junit.Assert; +import org.junit.Test; + +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +public class ParametrizedParserTest { + + private static final String TIKA_CFG_FILE = "org/apache/tika/config/TIKA-1986-parametrized.xml"; + private static final Map<String, String> expcted = new HashMap<String, String>() { + { + put("testparam", "testparamval"); + put("xshort", "1000"); + put("xint", "999999999"); + put("xlong", "9999999999999"); + put("xbigint", "99999999999999999999999999999999999999999999999"); + put("xfloat", "10.2"); + put("xbool", "true"); + put("xdouble", "4.6"); + put("xurl", "http://apache.org"); + put("xfile", "/"); + put("xuri", "tika://customuri?param=value"); + + put("inner", "inner"); + put("missing", "default"); + } + }; + + + @Test + public void testConfigurableParserTypes() throws Exception { + URL configFileUrl = getClass().getClassLoader().getResource(TIKA_CFG_FILE); + assert configFileUrl != null; + TikaConfig config = new TikaConfig(configFileUrl); + Tika tika = new Tika(config); + Metadata md = new Metadata(); + tika.parse(configFileUrl.openStream(), md); + + for (Map.Entry<String, String> entry : expcted.entrySet()) { + Assert.assertEquals("mismatch for " + entry.getKey(), entry.getValue(), md.get(entry.getKey())); + } + } + + +} http://git-wip-us.apache.org/repos/asf/tika/blob/aad23d9e/tika-core/src/test/java/org/apache/tika/utils/AnnotationUtilsTest.java ---------------------------------------------------------------------- diff --git a/tika-core/src/test/java/org/apache/tika/utils/AnnotationUtilsTest.java b/tika-core/src/test/java/org/apache/tika/utils/AnnotationUtilsTest.java new file mode 100644 index 0000000..eaa3549 --- /dev/null +++ b/tika-core/src/test/java/org/apache/tika/utils/AnnotationUtilsTest.java @@ -0,0 +1,190 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.tika.utils; + +import aQute.bnd.annotation.metatype.Configurable; +import org.apache.tika.config.Field; +import org.apache.tika.config.Param; +import org.apache.tika.exception.TikaConfigException; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + + +/** + * @since 6/1/16 + */ +public class AnnotationUtilsTest { + + @Test + public void testMisMatchType() { + + class MyParser extends Configurable { + @Field(required = true) int config; + } + + Map<String, Param<?>> params = new HashMap<>(); + try { + params.put("config", new Param<>("config", 1)); + + MyParser bean = new MyParser(); + AnnotationUtils.assignFieldParams(bean, params); + Assert.assertEquals(bean.config, 1); + } catch (TikaConfigException e) { + e.printStackTrace(); + Assert.fail("Exception Not expected"); + } + + params.clear(); + try { + params.put("config", new Param<>("config", "a string value")); + AnnotationUtils.assignFieldParams(new MyParser(), params); + Assert.fail("Exception expected"); + } catch (TikaConfigException e) { + //expected + } + } + + @Test + public void testPrimitiveAndBoxedTypes() { + + class MyParser extends Configurable { + @Field(required = true) int config; + @Field(required = true, name = "config") Integer config2; + } + + Map<String, Param<?>> params = new HashMap<>(); + try { + MyParser bean = new MyParser(); + int val = 100; + params.put("config", new Param<>("config", val)); + AnnotationUtils.assignFieldParams(bean, params); + Assert.assertTrue(bean.config == bean.config2); + Assert.assertTrue(bean.config == val); + } catch (TikaConfigException e) { + e.printStackTrace(); + Assert.fail("Exception Not expected"); + } + + } + + @Test + public void testRequiredParam() { + + class MyParser extends Configurable { + @Field(required = true) String config; + } + + Map<String, Param<?>> params = new HashMap<>(); + String someval = "someval"; + params.put("config", new Param<>("config", someval)); + try { + MyParser bean = new MyParser(); + AnnotationUtils.assignFieldParams(bean, params); + Assert.assertEquals(bean.config, someval); + } catch (TikaConfigException e) { + e.printStackTrace(); + Assert.fail("Exception Not expected"); + } + + params.clear(); + try { + AnnotationUtils.assignFieldParams(new MyParser(), params); + Assert.fail("Exception expected"); + } catch (TikaConfigException e) { + //expected + } + } + + + @Test + public void testParserInheritance() { + + class Parent { + @Field(required = true) int overridden; + @Field(required = true) int parentField; + + } + + class Child extends Parent { + @Field(required = true) int overridden; + @Field(required = true) int childField; + } + + int val = 1; + Map<String, Param<?>> params = new HashMap<>(); + params.put("overridden", new Param<>("oevrriden", val)); + params.put("parentField", new Param<>("parentField", val)); + params.put("childField", new Param<>("childField", val)); + + try { + Child child = new Child(); + AnnotationUtils.assignFieldParams(child, params); + Assert.assertEquals(child.overridden, val); + Assert.assertEquals(child.parentField, val); + Assert.assertEquals(child.childField, val); + } catch (TikaConfigException e) { + e.printStackTrace(); + Assert.fail("Exception Not expected"); + } + + try { + params.remove("parentField"); + AnnotationUtils.assignFieldParams(new Child(), params); + Assert.fail("Exception expected, parent class field not set"); + } catch (TikaConfigException e) { + //expected + } + } + + + + @Test + public void testParamValueInheritance() { + + class Bean { + @Field(required = true) CharSequence field; + } + + Bean parser = new Bean(); + Map<String, Param<?>> params = new HashMap<>(); + try { + String val = "someval"; + params.put("field", new Param<String>("field", String.class, val)); + AnnotationUtils.assignFieldParams(parser, params); + Assert.assertEquals(val, parser.field); + } catch (Exception e){ + e.printStackTrace(); + Assert.fail("Exception not expected, string is assignable to CharSequence"); + } + + try { + Date val = new Date(); + params.put("field", new Param<Date>("field", Date.class, val)); + AnnotationUtils.assignFieldParams(parser, params); + Assert.fail("Exception expected, Date is not assignable to CharSequence."); + } catch (TikaConfigException e){ + //expected + + } + + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tika/blob/aad23d9e/tika-core/src/test/resources/org/apache/tika/config/TIKA-1986-parametrized.xml ---------------------------------------------------------------------- diff --git a/tika-core/src/test/resources/org/apache/tika/config/TIKA-1986-parametrized.xml b/tika-core/src/test/resources/org/apache/tika/config/TIKA-1986-parametrized.xml new file mode 100644 index 0000000..6689a19 --- /dev/null +++ b/tika-core/src/test/resources/org/apache/tika/config/TIKA-1986-parametrized.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<properties> + <parsers> + <parser class="org.apache.tika.parser.DummyParametrizedParser"> + <params> + <param name="testparam" type="string">testparamval</param> + <param name="xshort" type="short">1000</param> + <param name="xint" type="int">999999999</param> + <param name="xlong" type="long">9999999999999</param> + <param name="xbigint" type="bigint">99999999999999999999999999999999999999999999999</param> + <param name="xfloat" type="float">10.2</param> + <param name="xbool" type="bool">true</param> + <param name="xdouble" type="double">4.6</param> + <param name="xurl" type="url">http://apache.org</param> + <param name="xfile" type="file">/</param> + <param name="xuri" type="uri">tika://customuri?param=value</param> + </params> + </parser> + + </parsers> +</properties>
