1 package org.kuali.ole.sys.batch;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashMap;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Stack;
9
10 import org.apache.commons.beanutils.PropertyUtils;
11 import org.apache.log4j.Logger;
12
13
14
15
16 public class FlatFileParseTrackerImpl implements FlatFileParseTracker {
17 static Logger LOG = Logger.getLogger(FlatFileParseTrackerImpl.class);
18 protected FlatFileSpecification classIdentifier;
19 protected Stack<Object> parseStack;
20 protected List<Object> parsedParentObjects;
21 protected Map<Class<?>, FlatFileChildMapEntry> childrenMap;
22 protected int completedLineCount = 0;
23
24
25
26
27
28
29 public void initialize(FlatFileSpecification flatFileClassIdentifier) {
30 this.classIdentifier = flatFileClassIdentifier;
31 this.parseStack = new Stack<Object>();
32 this.parsedParentObjects = new ArrayList<Object>();
33 constructChildrenMap();
34 }
35
36
37
38
39
40 protected void constructChildrenMap() {
41 childrenMap = new HashMap<Class<?>, FlatFileChildMapEntry>();
42
43 for (FlatFileObjectSpecification specification : classIdentifier.getObjectSpecifications()) {
44 if (specification.getParentBusinessObjectClass() != null) {
45 final FlatFileChildMapEntry entry = new FlatFileChildMapEntry(specification.getParentBusinessObjectClass(), specification.getParentTargetProperty());
46 childrenMap.put(specification.getBusinessObjectClass(), entry);
47 }
48 }
49 }
50
51
52
53
54
55
56 public Object getObjectToParseInto(String lineToParse) {
57 final Class<?> lineClass = classIdentifier.determineClassForLine(lineToParse);
58
59 if (lineClass == null) {
60
61 return null;
62 }
63
64 try {
65 Object parseIntoObject = lineClass.newInstance();
66 parseStack.push(parseIntoObject);
67 return parseIntoObject;
68 } catch (InstantiationException ie) {
69 throw new RuntimeException("Could not instantiate object of class "+lineClass.getName()+" in FlatFileParse", ie);
70 } catch (IllegalAccessException iae) {
71 throw new RuntimeException("Illegal access attempting to instantiate object of class "+lineClass.getName()+" in FlatFileParse", iae);
72 }
73 }
74
75
76
77
78
79 @SuppressWarnings("unchecked")
80 public void completeLineParse() {
81 completedLineCount += 1;
82 if (LOG.isDebugEnabled()) {
83 LOG.debug("Completing parse of line: "+completedLineCount);
84 }
85
86 Object currentObject = parseStack.pop();
87 final FlatFileChildMapEntry entry = getEntryForParsedIntoObject(currentObject);
88
89 final Class<?> parentClass = (entry == null) ? null : entry.getParentBeanClass();
90 final String propertyName = (entry == null) ? null : entry.getPropertyName();
91
92 while (!parseStack.isEmpty()) {
93 Object checkingObject = parseStack.pop();
94 if (parentClass != null && parentClass.isAssignableFrom(checkingObject.getClass())) {
95 try {
96 if (Collection.class.isAssignableFrom(PropertyUtils.getPropertyType(
97 checkingObject, propertyName))) {
98 Collection childrenList = ((Collection) PropertyUtils.getProperty(
99 checkingObject, propertyName));
100 childrenList.add(currentObject);
101 } else {
102 PropertyUtils.setProperty(checkingObject, propertyName,currentObject);
103 }
104 parseStack.push(checkingObject);
105 parseStack.push(currentObject);
106 return;
107 } catch (Exception e) {
108 LOG.error(e.getMessage() + "occured when completing line parse; attempting to set object of type "+currentObject.getClass().getName()+" to the following parent: "+parentClass.getName()+"#"+propertyName, e);
109 throw new RuntimeException(e.getMessage() + "occured when completing line parse; attempting to set object of type "+currentObject.getClass().getName()+" to the following parent: "+parentClass.getName()+"#"+propertyName,e);
110 }
111 }
112 }
113 if (parentClass == null) {
114 parseStack.push(currentObject);
115 parsedParentObjects.add(currentObject);
116 } else {
117 throw new IllegalStateException("A line of class "+currentObject.getClass().getName()+" cannot exist without a proper parent");
118 }
119 }
120
121
122
123
124
125
126 public FlatFileChildMapEntry getEntryForParsedIntoObject(Object parsedIntoObject) {
127 final FlatFileChildMapEntry entry = childrenMap.get(parsedIntoObject.getClass());
128 return entry;
129 }
130
131
132
133
134 public List<Object> getParsedObjects() {
135 return parsedParentObjects;
136 }
137
138
139
140
141
142 private class FlatFileChildMapEntry {
143 protected Class<?> parentBeanClass;
144 protected String propertyName;
145
146 public FlatFileChildMapEntry() {
147 super();
148 }
149
150 public FlatFileChildMapEntry(Class<?> parentBeanClass, String propertyName) {
151 this();
152 this.parentBeanClass = parentBeanClass;
153 this.propertyName = propertyName;
154 }
155
156 public Class<?> getParentBeanClass() {
157 return parentBeanClass;
158 }
159
160 public String getPropertyName() {
161 return propertyName;
162 }
163 }
164 }