Changeset 976


Ignore:
Timestamp:
08/14/10 15:10:12 (18 months ago)
Author:
kasper
Message:

Made it possible to configure jobs using "configurable bean" acting as a prototype for actual executed beans

Location:
AnalyzerBeans/trunk/src
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • AnalyzerBeans/trunk/src/main/java/org/eobjects/analyzer/annotations/Configured.java

    r974 r976  
    5050         */ 
    5151        String value() default ""; 
     52         
     53        boolean required() default true; 
    5254} 
  • AnalyzerBeans/trunk/src/main/java/org/eobjects/analyzer/beans/ConvertToNumberTransformer.java

    r966 r976  
    3939        } 
    4040 
     41        public void setInput(InputColumn<String> input) { 
     42                this.input = input; 
     43        } 
    4144} 
  • AnalyzerBeans/trunk/src/main/java/org/eobjects/analyzer/beans/valuedist/ValueDistributionAnalyzer.java

    r957 r976  
    1919 
    2020@AnalyzerBean("Value distribution") 
    21 public class ValueDistributionAnalyzer implements RowProcessingAnalyzer<ValueDistributionResult> { 
     21public class ValueDistributionAnalyzer implements 
     22                RowProcessingAnalyzer<ValueDistributionResult> { 
    2223 
    2324        private static final Logger logger = LoggerFactory 
     
    3031        @Inject 
    3132        @Configured("Record unique values") 
    32         boolean _recordUniqueValues; 
     33        boolean _recordUniqueValues = true; 
    3334 
    3435        @Inject 
    35         @Configured("Top n most frequent values") 
     36        @Configured(value = "Top n most frequent values", required = false) 
    3637        Integer _topFrequentValues; 
    3738 
    3839        @Inject 
    39         @Configured("Bottom n most frequent values") 
     40        @Configured(value = "Bottom n most frequent values", required = false) 
    4041        Integer _bottomFrequentValues; 
    4142 
  • AnalyzerBeans/trunk/src/main/java/org/eobjects/analyzer/data/MetaModelInputColumn.java

    r967 r976  
    11package org.eobjects.analyzer.data; 
     2 
     3import org.eobjects.analyzer.util.ReflectionUtils; 
    24 
    35import dk.eobjects.metamodel.schema.Column; 
     
    1315                } 
    1416                _column = column; 
     17        } 
     18 
     19        @SuppressWarnings("unchecked") 
     20        public <E> InputColumn<E> narrow(Class<E> e) { 
     21                Class<?> javaEquivalentClass = _column.getType() 
     22                                .getJavaEquivalentClass(); 
     23                if (ReflectionUtils.is(javaEquivalentClass, e)) { 
     24                        return (InputColumn<E>) this; 
     25                } 
     26                throw new IllegalArgumentException( 
     27                                "Can only narrow this column to supertypes of: " 
     28                                                + javaEquivalentClass); 
    1529        } 
    1630 
     
    5670                return DataTypeFamily.UNDEFINED; 
    5771        } 
    58          
     72 
    5973        @Override 
    6074        public String toString() { 
  • AnalyzerBeans/trunk/src/main/java/org/eobjects/analyzer/descriptors/ConfiguredPropertyDescriptor.java

    r962 r976  
    44 
    55        public boolean isInputColumn(); 
     6 
     7        public boolean isRequired(); 
    68} 
  • AnalyzerBeans/trunk/src/main/java/org/eobjects/analyzer/descriptors/ConfiguredPropertyDescriptorImpl.java

    r974 r976  
    3131                return result; 
    3232        } 
     33         
     34        @Override 
     35        public boolean isRequired() { 
     36                Configured configured = getAnnotation(Configured.class); 
     37                if (configured == null) { 
     38                        return true; 
     39                } 
     40                return configured.required(); 
     41        } 
    3342} 
  • AnalyzerBeans/trunk/src/main/java/org/eobjects/analyzer/job/AbstractBeanJobBuilder.java

    r975 r976  
    55import java.util.HashMap; 
    66import java.util.Map; 
     7import java.util.Set; 
    78 
    89import org.eobjects.analyzer.descriptors.BeanDescriptor; 
    910import org.eobjects.analyzer.descriptors.ConfiguredPropertyDescriptor; 
    1011import org.eobjects.analyzer.util.ReflectionUtils; 
     12import org.slf4j.Logger; 
     13import org.slf4j.LoggerFactory; 
    1114 
    1215@SuppressWarnings("unchecked") 
    1316class AbstractBeanJobBuilder<D extends BeanDescriptor<E>, E, B> { 
    1417 
    15         private Map<ConfiguredPropertyDescriptor, Object> _properties = new HashMap<ConfiguredPropertyDescriptor, Object>(); 
     18        private final Logger logger = LoggerFactory.getLogger(getClass()); 
     19 
    1620        private D _descriptor; 
     21        private E _configurableBean; 
    1722 
    1823        public AbstractBeanJobBuilder(D descriptor, Class<?> builderClass) { 
     24                if (descriptor == null) { 
     25                        throw new IllegalArgumentException("descriptor cannot be null"); 
     26                } 
     27                if (builderClass == null) { 
     28                        throw new IllegalArgumentException("builderClass cannot be null"); 
     29                } 
    1930                _descriptor = descriptor; 
    2031                if (!ReflectionUtils.is(getClass(), builderClass)) { 
    2132                        throw new IllegalArgumentException( 
    2233                                        "Builder class does not correspond to actual class of builder"); 
     34                } 
     35                try { 
     36                        _configurableBean = _descriptor.getBeanClass().newInstance(); 
     37                } catch (Exception e) { 
     38                        throw new IllegalArgumentException( 
     39                                        "Could not instantiate bean class: " 
     40                                                        + _descriptor.getBeanClass(), e); 
    2341                } 
    2442        } 
     
    2846        } 
    2947 
     48        public E getConfigurableBean() { 
     49                return _configurableBean; 
     50        } 
     51 
    3052        public boolean isConfigured() { 
    3153                for (ConfiguredPropertyDescriptor configuredProperty : _descriptor 
    3254                                .getConfiguredProperties()) { 
    33                         if (!getConfiguredProperties().containsKey(configuredProperty)) { 
    34                                 return false; 
     55                        if (configuredProperty.isRequired()) { 
     56                                if (!getConfiguredProperties().containsKey(configuredProperty)) { 
     57                                        logger.debug("Configured property is not set: " 
     58                                                        + configuredProperty); 
     59                                        return false; 
     60                                } 
    3561                        } 
    3662                } 
     
    86112                        } 
    87113                } 
    88                 _properties.put(configuredProperty, value); 
     114 
     115                configuredProperty.setValue(_configurableBean, value); 
    89116                return (B) this; 
    90117        } 
    91118 
    92119        public Map<ConfiguredPropertyDescriptor, Object> getConfiguredProperties() { 
    93                 return Collections.unmodifiableMap(_properties); 
     120                Map<ConfiguredPropertyDescriptor, Object> map = new HashMap<ConfiguredPropertyDescriptor, Object>(); 
     121                Set<ConfiguredPropertyDescriptor> configuredProperties = getDescriptor() 
     122                                .getConfiguredProperties(); 
     123                for (ConfiguredPropertyDescriptor propertyDescriptor : configuredProperties) { 
     124                        Object value = propertyDescriptor.getValue(getConfigurableBean()); 
     125                        if (value != null) { 
     126                                map.put(propertyDescriptor, value); 
     127                        } 
     128                } 
     129                return Collections.unmodifiableMap(map); 
    94130        } 
    95131} 
  • AnalyzerBeans/trunk/src/main/java/org/eobjects/analyzer/job/AbstractBeanWithInputColumnsBuilder.java

    r975 r976  
    11package org.eobjects.analyzer.job; 
    22 
     3import java.lang.reflect.Array; 
    34import java.util.ArrayList; 
    45import java.util.Collection; 
    56import java.util.Collections; 
    6 import java.util.HashMap; 
    77import java.util.List; 
    8 import java.util.Map; 
    98 
    109import org.eobjects.analyzer.data.DataTypeFamily; 
     
    1211import org.eobjects.analyzer.descriptors.BeanDescriptor; 
    1312import org.eobjects.analyzer.descriptors.ConfiguredPropertyDescriptor; 
     13import org.eobjects.analyzer.util.CollectionUtils; 
    1414 
    1515@SuppressWarnings("unchecked") 
    1616class AbstractBeanWithInputColumnsBuilder<D extends BeanDescriptor<E>, E, B> 
    1717                extends AbstractBeanJobBuilder<D, E, B> { 
    18  
    19         private List<InputColumn<?>> _inputColumns = new ArrayList<InputColumn<?>>(); 
    2018 
    2119        public AbstractBeanWithInputColumnsBuilder(D descriptor, 
     
    4442                        } 
    4543                } 
    46                 _inputColumns.add(inputColumn); 
     44 
     45                ConfiguredPropertyDescriptor configuredPropertyForInput = getDescriptor() 
     46                                .getConfiguredPropertyForInput(); 
     47                Object inputColumns = configuredPropertyForInput 
     48                                .getValue(getConfigurableBean()); 
     49                if (inputColumns == null) { 
     50                        if (configuredPropertyForInput.isArray()) { 
     51                                inputColumns = new InputColumn[] { inputColumn }; 
     52                        } else { 
     53                                inputColumns = inputColumn; 
     54                        } 
     55                } else { 
     56                        inputColumns = CollectionUtils.array(InputColumn.class, inputColumns, inputColumn); 
     57                } 
     58                configuredPropertyForInput 
     59                                .setValue(getConfigurableBean(), inputColumns); 
     60 
    4761                return (B) this; 
    4862        } 
     
    6377 
    6478        public B removeInputColumn(InputColumn<?> inputColumn) { 
    65                 _inputColumns.remove(inputColumn); 
    66                 // TODO: Notify consumers 
     79                ConfiguredPropertyDescriptor configuredPropertyForInput = getDescriptor() 
     80                                .getConfiguredPropertyForInput(); 
     81                Object inputColumns = configuredPropertyForInput 
     82                                .getValue(getConfigurableBean()); 
     83                if (inputColumns != null) { 
     84                        if (inputColumns == inputColumn) { 
     85                                inputColumns = null; 
     86                        } else { 
     87                                if (inputColumns.getClass().isArray()) { 
     88                                        inputColumns = CollectionUtils.arrayRemove(inputColumns, 
     89                                                        inputColumn); 
     90                                } 
     91                        } 
     92                        configuredPropertyForInput.setValue(getConfigurableBean(), 
     93                                        inputColumns); 
     94                } 
    6795                return (B) this; 
    6896        } 
    6997 
    7098        public List<InputColumn<?>> getInputColumns() { 
    71                 return Collections.unmodifiableList(_inputColumns); 
    72         } 
    73  
    74         public boolean isConfigured() { 
    75                 if (_inputColumns.isEmpty()) { 
    76                         // no input given 
    77                         return false; 
    78                 } 
    79  
    80                 if (!super.isConfigured()) { 
    81                         return false; 
    82                 } 
    83  
    8499                ConfiguredPropertyDescriptor configuredPropertyForInput = getDescriptor() 
    85100                                .getConfiguredPropertyForInput(); 
    86                 if (!configuredPropertyForInput.isArray()) { 
    87                         if (_inputColumns.size() != 1) { 
    88                                 // exactly one input column is required 
    89                                 return false; 
     101                Object inputColumns = configuredPropertyForInput 
     102                                .getValue(getConfigurableBean()); 
     103                if (inputColumns == null) { 
     104                        return Collections.emptyList(); 
     105                } 
     106                List<InputColumn<?>> result; 
     107                if (inputColumns.getClass().isArray()) { 
     108                        int length = Array.getLength(inputColumns); 
     109                        result = new ArrayList<InputColumn<?>>(length); 
     110                        for (int i = 0; i < length; i++) { 
     111                                result.add((InputColumn<?>) Array.get(inputColumns, i)); 
    90112                        } 
     113                } else { 
     114                        result = new ArrayList<InputColumn<?>>(1); 
     115                        result.add((InputColumn<?>) inputColumns); 
    91116                } 
    92                 return true; 
    93         } 
    94  
    95         @Override 
    96         public Map<ConfiguredPropertyDescriptor, Object> getConfiguredProperties() { 
    97                 Map<ConfiguredPropertyDescriptor, Object> properties = new HashMap<ConfiguredPropertyDescriptor, Object>( 
    98                                 super.getConfiguredProperties()); 
    99  
    100                 // explicitly add the input columns (because they are handled as a 
    101                 // separate variable in this builder 
    102                 List<InputColumn<?>> inputColumns = getInputColumns(); 
    103                 properties.put(getDescriptor().getConfiguredPropertyForInput(), 
    104                                 inputColumns.toArray(new InputColumn<?>[inputColumns.size()])); 
    105  
    106                 return Collections.unmodifiableMap(properties); 
     117                return Collections.unmodifiableList(result); 
    107118        } 
    108119} 
  • AnalyzerBeans/trunk/src/main/java/org/eobjects/analyzer/job/ImmutableAnalyzerJob.java

    r975 r976  
    33import org.eobjects.analyzer.data.InputColumn; 
    44import org.eobjects.analyzer.descriptors.AnalyzerBeanDescriptor; 
     5import org.eobjects.analyzer.util.CollectionUtils; 
    56 
    67final class ImmutableAnalyzerJob implements AnalyzerJob { 
     
    2728        @Override 
    2829        public InputColumn<?>[] getInput() { 
    29                 return (InputColumn<?>[]) _beanConfiguration.getProperty(_descriptor 
     30                Object property = _beanConfiguration.getProperty(_descriptor 
    3031                                .getConfiguredPropertyForInput()); 
     32                return (InputColumn<?>[]) CollectionUtils.arrayOf(InputColumn.class, 
     33                                property); 
    3134        } 
    3235 
  • AnalyzerBeans/trunk/src/main/java/org/eobjects/analyzer/job/ImmutableTransformerJob.java

    r975 r976  
    99import org.eobjects.analyzer.data.MutableInputColumn; 
    1010import org.eobjects.analyzer.descriptors.TransformerBeanDescriptor; 
     11import org.eobjects.analyzer.util.CollectionUtils; 
    1112 
    1213final class ImmutableTransformerJob implements TransformerJob { 
     
    3738        @Override 
    3839        public InputColumn<?>[] getInput() { 
    39                 return (InputColumn<?>[]) _beanConfiguration.getProperty(_descriptor 
     40                Object property = _beanConfiguration.getProperty(_descriptor 
    4041                                .getConfiguredPropertyForInput()); 
     42                return CollectionUtils.arrayOf(InputColumn.class, property); 
    4143        } 
    4244 
  • AnalyzerBeans/trunk/src/main/java/org/eobjects/analyzer/util/CollectionUtils.java

    r962 r976  
    11package org.eobjects.analyzer.util; 
    22 
     3import java.lang.reflect.Array; 
    34import java.util.ArrayList; 
    45import java.util.HashSet; 
     
    1112                // prevent instantiation 
    1213        } 
    13          
     14 
    1415        public static <T> List<T> list(T... elements) { 
    1516                return list(ArrayList.class, elements); 
     
    2930                } 
    3031        } 
    31          
     32 
    3233        public static <T> Set<T> set(T... elements) { 
    3334                return set(HashSet.class, elements); 
     
    4647                } 
    4748        } 
     49 
     50        @SuppressWarnings("unchecked") 
     51        public static <E> E[] array(E[] existingArray, E... elements) { 
     52                if (existingArray == null) { 
     53                        return elements; 
     54                } 
     55                Object result = Array.newInstance(elements.getClass() 
     56                                .getComponentType(), existingArray.length + elements.length); 
     57                System.arraycopy(existingArray, 0, result, 0, existingArray.length); 
     58                System.arraycopy(elements, 0, result, existingArray.length, 
     59                                elements.length); 
     60                return (E[]) result; 
     61        } 
     62 
     63        @SuppressWarnings("unchecked") 
     64        public static <E> E[] array(Class<E> elementClass, Object existingArray, E... elements) { 
     65                if (existingArray == null) { 
     66                        return elements; 
     67                } 
     68                E[] result; 
     69                if (existingArray.getClass().isArray()) { 
     70                        int length = Array.getLength(existingArray); 
     71                        result = (E[]) Array.newInstance(elementClass, length + elements.length); 
     72                        System.arraycopy(existingArray, 0, result, 0, length); 
     73                        System.arraycopy(elements, 0, result, length, elements.length); 
     74                } else { 
     75                        result = (E[]) Array.newInstance(elementClass, 1 + elements.length); 
     76                        result[0] = (E) existingArray; 
     77                        System.arraycopy(elements, 0, result, 1, elements.length); 
     78                } 
     79 
     80                return result; 
     81        } 
     82 
     83        public static <E> E[] arrayRemove(E[] array, E elementToRemove) { 
     84                boolean found = false; 
     85                @SuppressWarnings("unchecked") 
     86                E[] result = (E[]) Array.newInstance(array.getClass() 
     87                                .getComponentType(), array.length - 1); 
     88                int nextIndex = 0; 
     89                for (E e : array) { 
     90                        if (e == elementToRemove) { 
     91                                found = true; 
     92                        } else { 
     93                                result[nextIndex] = e; 
     94                                nextIndex++; 
     95                        } 
     96                } 
     97                if (!found) { 
     98                        return array; 
     99                } 
     100                return result; 
     101        } 
     102 
     103        public static Object arrayRemove(Object array, Object elementToRemove) { 
     104                boolean found = false; 
     105                int oldLength = Array.getLength(array); 
     106                Object result = Array.newInstance(array.getClass().getComponentType(), 
     107                                oldLength - 1); 
     108                int nextIndex = 0; 
     109                for (int i = 0; i < oldLength; i++) { 
     110                        Object e = Array.get(array, i); 
     111                        if (e == elementToRemove) { 
     112                                found = true; 
     113                        } else { 
     114                                Array.set(result, nextIndex, e); 
     115                                nextIndex++; 
     116                        } 
     117                } 
     118                if (!found) { 
     119                        return array; 
     120                } 
     121                return result; 
     122        } 
     123 
     124        @SuppressWarnings("unchecked") 
     125        public static <E> E[] arrayOf(Class<E> elementClass, Object arrayOrElement) { 
     126                if (arrayOrElement == null) { 
     127                        return null; 
     128                } 
     129                if (arrayOrElement.getClass().isArray()) { 
     130                        return (E[]) arrayOrElement; 
     131                } 
     132                Object result = Array.newInstance(elementClass, 1); 
     133                Array.set(result, 0, arrayOrElement); 
     134                return (E[]) result; 
     135        } 
    48136} 
  • AnalyzerBeans/trunk/src/test/java/org/eobjects/analyzer/job/TransformerJobBuilderTest.java

    r975 r976  
    11package org.eobjects.analyzer.job; 
     2 
     3import junit.framework.TestCase; 
    24 
    35import org.eobjects.analyzer.beans.ConvertToNumberTransformer; 
    46import org.eobjects.analyzer.beans.TokenizerTransformer; 
    57import org.eobjects.analyzer.data.DataTypeFamily; 
     8import org.eobjects.analyzer.data.InputColumn; 
     9import org.eobjects.analyzer.data.TransformedInputColumn; 
     10import org.eobjects.analyzer.descriptors.AnnotationBasedTransformerBeanDescriptor; 
    611import org.eobjects.analyzer.test.TestHelper; 
    712 
    813import dk.eobjects.metamodel.schema.Column; 
    914import dk.eobjects.metamodel.schema.ColumnType; 
    10  
    11 import junit.framework.TestCase; 
    1215 
    1316public class TransformerJobBuilderTest extends TestCase { 
     
    8588                assertTrue(tjb.isConfigured()); 
    8689        } 
     90 
     91        public void testConfigureByConfigurableBean() throws Exception { 
     92                IdGenerator IdGenerator = new PrefixedIdGenerator(""); 
     93 
     94                AnnotationBasedTransformerBeanDescriptor<ConvertToNumberTransformer> descriptor = AnnotationBasedTransformerBeanDescriptor 
     95                                .create(ConvertToNumberTransformer.class); 
     96                TransformerJobBuilder<ConvertToNumberTransformer> builder = new TransformerJobBuilder<ConvertToNumberTransformer>( 
     97                                descriptor, IdGenerator); 
     98                assertFalse(builder.isConfigured()); 
     99 
     100                ConvertToNumberTransformer configurableBean = builder 
     101                                .getConfigurableBean(); 
     102                InputColumn<String> input = new TransformedInputColumn<String>("foo", 
     103                                DataTypeFamily.STRING, IdGenerator); 
     104                configurableBean.setInput(input); 
     105 
     106                assertTrue(builder.isConfigured()); 
     107                Object object = builder.getConfiguredProperties().get( 
     108                                descriptor.getConfiguredPropertyForInput()); 
     109                assertEquals("TransformedInputColumn[id=-1,name=foo,type=STRING]", 
     110                                object.toString()); 
     111        } 
    87112} 
Note: See TracChangeset for help on using the changeset viewer.