View Javadoc
1   package net.sf.sapjcosupport;
2   
3   import org.apache.commons.beanutils.ConvertUtils;
4   import org.apache.log4j.Logger;
5   
6   import java.lang.reflect.Field;
7   import java.text.DateFormat;
8   import java.text.ParseException;
9   import java.text.SimpleDateFormat;
10  import java.util.*;
11  
12  /**
13   * This class implements the SAP <b>Search Help</b> functionality.
14   * <p/>
15   * As any subclass of <code>SapJcoInterface</code>, a value object is associated with this
16   * implementation: {@link SapSearchHelpVO}. This is a temporary value object, that can be mapped
17   * to the value object of your choice automagically.
18   * <br/>
19   * To do so, call the 'persistentObject' method with the class of the desired value object.
20   *
21   * @author Jo Vandermeeren
22   * @since Mar 21, 2006 - 11:08:01 AM
23   */
24  public abstract class SapSearchHelp extends SapJcoInterface {
25      protected final Logger log = Logger.getLogger(getClass());
26      protected static final DateFormat SAP_DATE_FORMATTER = new SimpleDateFormat("yyyyMMdd");
27  
28      /**
29       * Performs the actual search. Call this method after you have set all necessary properties.
30       * <br/>
31       * If the persistent object class was not set, instances of <code>SearchHelpVO</code> are returned.
32       * <p/>
33       * Each field in the 'javaFieldSelection' list should correspond with a field at the same position in the 'sapFieldSelection' list.
34       *
35       * @param searchHelpName     name of the SAP search help
36       * @param selectionMethod    name of the selection method for the search help
37       * @param maximumResults     maximum results to return
38       * @param criteria           list of {@link SearchCriterion} objects
39       * @param persistentObject   value object class
40       * @param javaFieldSelection list of the names of the Java value object fields
41       * @param sapFieldSelection  list of the names of the SAP function fields
42       * @return List containing the search results as instances of the same type as specified by 'persistentObject'.
43       * @throws IllegalArgumentException if the lists are null, empty or of different size; if the 'searchHelpName' or selectionMethod parameters are null
44       */
45      public List search(String searchHelpName, String selectionMethod, int maximumResults, List criteria, Class persistentObject, List javaFieldSelection, List sapFieldSelection) {
46          int sapSearchHelpVOFieldCount = SapSearchHelpVO.getFieldCount();
47          if (javaFieldSelection == null || sapFieldSelection == null || sapFieldSelection.size() == 0 || sapFieldSelection.size() > sapSearchHelpVOFieldCount)
48          {
49              throw new IllegalArgumentException("Field lists should not be null, should contain at least 1, and max. " + sapSearchHelpVOFieldCount + " elements");
50          }
51          if (javaFieldSelection.size() != sapFieldSelection.size()) {
52              throw new IllegalArgumentException("For each item in the SAP field list, the java field list should have a value at the same position");
53          }
54          Map searchInput = new HashMap(5);
55          if (searchHelpName == null) {
56              throw new IllegalArgumentException("You have to specify the searchHelpName");
57          }
58          if (selectionMethod == null) {
59              throw new IllegalArgumentException("You have to specify the selectionMethod");
60          }
61          searchInput.put("SEARCHHELPNAME", searchHelpName);
62          searchInput.put("SEARCHHELPMETHOD", selectionMethod);
63          searchInput.put("MAX_ROWS", String.valueOf(maximumResults));
64  
65          // Prepare SELECTIONCRITERIA table
66          List selectionCriteria = new ArrayList(criteria.size());
67          for (Iterator i = criteria.iterator(); i.hasNext();) {
68              SearchCriterion criterion = (SearchCriterion) i.next();
69              if (criterion != null) {
70                  selectionCriteria.add(criterion.toMap());
71              }
72          }
73          searchInput.put("SELECTIONCRITERIA", selectionCriteria);
74  
75          // Prepare FIELDLIST table
76          searchInput.put("FIELDLIST", sapFieldSelection);
77  
78          // Execute search
79          List results = (List) retrieve(SapSearchHelpVO.class, searchInput, null);
80  
81          // Process results, just return the internal value objects if no custom peristent class is specified
82          if (persistentObject == null) {
83              return results;
84          }
85          List persistentObjects = new ArrayList(results.size());
86          for (Iterator i = results.iterator(); i.hasNext();) {
87              SapSearchHelpVO vo = (SapSearchHelpVO) i.next();
88              Object object = convertSearchHelpVO(vo, persistentObject, javaFieldSelection);
89              if (object != null) {
90                  persistentObjects.add(object);
91              }
92              i.remove();
93          }
94          return persistentObjects;
95      }
96  
97      /**
98       * Helper method to convert SearchHelpVO instances to instances of the same type as specified by 'persistentObject'.
99       *
100      * @param valueObject        search result (internal format)
101      * @param persistentObject   class of the desired value object; must have a defined zero-args constructor
102      * @param javaFieldSelection fields
103      * @return instance of the same type as specified by 'persistentObject'.
104      */
105     private Object convertSearchHelpVO(SapSearchHelpVO valueObject, Class persistentObject, List javaFieldSelection) {
106         Class valueObjectClass = valueObject.getClass();
107         try {
108             Object instance = persistentObject.newInstance();
109             int i = 0;
110             for (Iterator valueIterator = valueObject.iterator(); i < javaFieldSelection.size() && valueIterator.hasNext(); i++)
111             {
112                 Object value = valueIterator.next();
113                 if (value == null) {
114                     continue;
115                 }
116                 String fieldName = (String) javaFieldSelection.get(i);
117                 Field field = persistentObject.getDeclaredField(fieldName);
118                 field.setAccessible(true);
119                 Object convertedValue = null;
120                 if (Date.class.equals(field.getType())) {
121                     try {
122                         convertedValue = SAP_DATE_FORMATTER.parse((String) value);
123                     } catch (ParseException e) {
124                         log.warn("Unable to parse " + value + " as a date for field " + field.getName());
125                     }
126                 } else {
127                     convertedValue = ConvertUtils.convert((String) value, field.getType());
128                 }
129                 field.set(instance, convertedValue);
130             }
131             return instance;
132         } catch (InstantiationException e) {
133             log.warn("Can not instantiate class " + persistentObject.getClass(), e);
134         } catch (IllegalAccessException e) {
135             log.warn("Can not set a field in class " + persistentObject.getClass() + " or get field in class " + valueObjectClass, e);
136         } catch (NoSuchFieldException e) {
137             log.warn("Can not find a field in class " + persistentObject + " or in class " + valueObjectClass, e);
138         }
139         return null;
140     }
141 }