1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.student.r2.common.class1.search;
17
18 import org.apache.log4j.Logger;
19 import org.kuali.student.r1.common.dictionary.old.dto.FieldDescriptor;
20 import org.kuali.student.r2.core.search.dto.*;
21 import org.kuali.student.r2.core.search.dto.CrossSearchTypeInfo;
22 import org.kuali.student.r2.core.search.dto.QueryParamInfo;
23 import org.kuali.student.r2.core.search.dto.SearchCriteriaTypeInfo;
24 import org.kuali.student.r2.core.search.dto.SearchResultTypeInfo;
25 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
26 import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
27 import org.springframework.beans.factory.xml.ParserContext;
28 import org.w3c.dom.Attr;
29 import org.w3c.dom.Document;
30 import org.w3c.dom.Element;
31 import org.w3c.dom.Node;
32
33 import javax.xml.parsers.DocumentBuilder;
34 import javax.xml.parsers.DocumentBuilderFactory;
35 import java.util.HashSet;
36 import java.util.List;
37
38 public class SearchBeanDefinitionParser extends
39 AbstractSingleBeanDefinitionParser {
40 private static final Logger logger = Logger.getLogger(SearchBeanDefinitionParser.class);
41
42 @Override
43 protected Class<?> getBeanClass(Element element) {
44
45 if (element.getLocalName().equals("fieldDescriptor")) {
46 return FieldDescriptor.class;
47 }
48 if (element.getLocalName().equals("searchCriteriaTypeInfo")) {
49 return SearchCriteriaTypeInfo.class;
50 }
51 if (element.getLocalName().equals("queryParam")) {
52 return QueryParamInfo.class;
53 }
54 if (element.getLocalName().equals("searchType")) {
55 return SearchTypeInfo.class;
56 }
57 if (element.getLocalName().equals("resultColumn")) {
58 return ResultColumnInfo.class;
59 }
60 if (element.getLocalName().equals("searchResultTypeInfo")) {
61 return SearchResultTypeInfo.class;
62 }
63
64
65 if (element.getLocalName().equals("crossSearchType")) {
66 return CrossSearchTypeInfo.class;
67 }
68 if (element.getLocalName().equals("subSearch")) {
69 return SubSearchInfo.class;
70 }
71 if (element.getLocalName().equals("subSearchParamMappings")) {
72 return SubSearchParamMappingInfo.class;
73 }
74 if (element.getLocalName().equals("joinCriteria")) {
75 return JoinCriteriaInfo.class;
76 }
77 if (element.getLocalName().equals("comparison")) {
78 return JoinComparisonInfo.class;
79 }
80 if (element.getLocalName().equals("leftHandSide")) {
81 return ComparisonParamInfo.class;
82 }
83 if (element.getLocalName().equals("rightHandSide")) {
84 return ComparisonParamInfo.class;
85 }
86 if (element.getLocalName().equals("joinResultMapping")) {
87 return JoinResultMappingInfo.class;
88 }
89
90 return super.getBeanClass(element);
91 }
92
93 @Override
94 protected void doParse(Element element, ParserContext pc, BeanDefinitionBuilder builder) {
95
96 if(!"fieldDescriptor".equals(element.getLocalName())&&element.hasAttribute("id")){
97 builder.addPropertyValue("key", element.getAttributes().getNamedItem("id").getTextContent());
98 }
99
100 if("fieldDescriptor".equals(element.getLocalName())&&element.hasAttribute("parent")){
101 builder.setParentName(element.getAttributes().getNamedItem("parent").getTextContent());
102 }
103
104
105 if("queryParam".equals(element.getLocalName())&&element.hasAttribute("optional")){
106 builder.addPropertyValue("optional", "true".equals(element.getAttribute("optional"))?true:false);
107 }
108
109
110 if(element.hasAttributes()){
111 for(int i = 0;i<element.getAttributes().getLength();i++){
112 Attr attr = (Attr) element.getAttributes().item(i);
113 if("abstract".equals(attr.getName())){
114 builder.setAbstract(true);
115 }else if(!"id".equals(attr.getName())&&!"parent".equals(attr.getName())){
116 String fieldName = resolveFieldName(element.getLocalName(),attr.getName());
117 builder.addPropertyValue(fieldName, attr.getValue());
118 }
119 }
120 }
121
122
123 HashSet<String> visitedNodes = new HashSet<String>();
124
125 for(int i = 0;i<element.getChildNodes().getLength();i++){
126 Node node = element.getChildNodes().item(i);
127
128 if(Node.ELEMENT_NODE == node.getNodeType()){
129 String localName=node.getLocalName();
130 if(!visitedNodes.contains(localName)){
131 if(isWrappedList(node.getLocalName())){
132 List<?> refList = pc.getDelegate().parseListElement((Element) node, pc.getContainingBeanDefinition());
133 builder.addPropertyValue(node.getLocalName(),refList);
134 }else if(isUnwrappedList(node.getLocalName())){
135 Element childList=getChildList(element,node.getLocalName());
136 visitedNodes.add(node.getLocalName());
137 List<?> refList = pc.getDelegate().parseListElement(childList, pc.getContainingBeanDefinition());
138 if(refList!=null&&!refList.isEmpty()){
139 String fieldName=resolveFieldName(element.getLocalName(),node.getLocalName());
140 builder.addPropertyValue(fieldName,refList);
141 }
142 }else{
143 Element childElement = getFirstChildElement(node);
144 if(childElement!=null){
145 if("ref".equals(childElement.getLocalName())){
146 Object childBean = pc.getDelegate().parsePropertySubElement(childElement, pc.getContainingBeanDefinition());
147 builder.addPropertyValue(node.getLocalName(), childBean);
148 }else{
149 Object childBean = pc.getDelegate().parsePropertySubElement((Element)node, pc.getContainingBeanDefinition());
150 builder.addPropertyValue(node.getLocalName(), childBean);
151 }
152 }else{
153 if(("ref".equals(node.getLocalName())&&"queryParam".equals(element.getLocalName()))){
154 Object childBean = pc.getDelegate().parsePropertySubElement((Element)node, pc.getContainingBeanDefinition());
155 builder.addPropertyValue("fieldDescriptor", childBean);
156 }else if("leftHandSide".equals(node.getLocalName())
157 ||"rightHandSide".equals(node.getLocalName())
158 ||"joinCriteria".equals(node.getLocalName())){
159 Object childBean = pc.getDelegate().parsePropertySubElement((Element)node, pc.getContainingBeanDefinition());
160 builder.addPropertyValue(node.getLocalName(), childBean);
161 }else{
162 builder.addPropertyValue(node.getLocalName(), node.getTextContent());
163 }
164 }
165 }
166 }
167 }
168 }
169 }
170
171 private boolean isUnwrappedList(String localName) {
172 return localName.equals("subSearchParamMappings")||
173 localName.equals("comparison")||
174 localName.equals("subSearch")||
175 localName.equals("joinResultMapping");
176 }
177
178
179 private String resolveFieldName(String parentName, String nodeName) {
180 if("comparison".equals(nodeName)){
181 return "comparisons";
182 }
183 if("subSearch".equals(nodeName)){
184 return "subSearches";
185 }
186 if("joinResultMapping".equals(nodeName)){
187 return "joinResultMappings";
188 }
189 if("joinCriteria".equals(parentName)&&"type".equals(nodeName)){
190 return "joinType";
191 }
192
193 return nodeName;
194 }
195
196
197
198 private Element getChildList(Element element, String localName) {
199 try{
200
201 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
202 DocumentBuilder builder = dbf.newDocumentBuilder();
203 Document doc = builder.newDocument();
204
205 Element root = doc.createElement("listRoot");
206
207 for(int i = 0;i<element.getChildNodes().getLength();i++){
208 Node node = element.getChildNodes().item(i);
209 if(Node.ELEMENT_NODE == node.getNodeType() && localName.equals(node.getLocalName())){
210
211
212 Node copied = doc.importNode(node, true);
213 root.appendChild(copied);
214 }
215 if(Node.ELEMENT_NODE == node.getNodeType() && (localName+"Ref").equals(node.getLocalName())){
216
217
218 Element ref = doc.createElement("ref");
219 ref.setAttribute("bean", ((Element)node).getAttribute("bean"));
220 root.appendChild(ref);
221 }
222 }
223
224 return root;
225 }catch(Exception e){
226 logger.error("Exception occured: ", e);
227 }
228 return null;
229 }
230
231 private Element getFirstChildElement(Node node) {
232 for(int i = 0;i<node.getChildNodes().getLength();i++){
233 Node childNode = node.getChildNodes().item(i);
234 if(Node.ELEMENT_NODE == childNode.getNodeType()){
235 return (Element) childNode;
236 }
237 }
238
239 return null;
240 }
241
242 private boolean isWrappedList(String localName) {
243 return localName.equals("queryParams")||
244 localName.equals("resultColumns");
245 }
246
247 @Override
248 protected String getParentName(Element element) {
249 if(element.hasAttribute("parent")){
250 return element.getAttribute("parent");
251 }
252 return super.getParentName(element);
253 }
254
255 @Override
256 protected boolean shouldGenerateIdAsFallback() {
257 return true;
258 }
259 }