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