| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| GroupXmlJAXBParser | 
 | 
 | 2.4285714285714284;2.429 | ||||
| GroupXmlJAXBParser$DataNamespaceURIFilter | 
 | 
 | 2.4285714285714284;2.429 | 
| 1 |  /* | |
| 2 |   * Copyright 2007-2008 The Kuali Foundation | |
| 3 |   * | |
| 4 |   * Licensed under the Educational Community License, Version 2.0 (the "License"); | |
| 5 |   * you may not use this file except in compliance with the License. | |
| 6 |   * You may obtain a copy of the License at | |
| 7 |   * | |
| 8 |   * http://www.opensource.org/licenses/ecl2.php | |
| 9 |   * | |
| 10 |   * Unless required by applicable law or agreed to in writing, software | |
| 11 |   * distributed under the License is distributed on an "AS IS" BASIS, | |
| 12 |   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 13 |   * See the License for the specific language governing permissions and | |
| 14 |   * limitations under the License. | |
| 15 |   */ | |
| 16 |  package org.kuali.rice.kew.xml; | |
| 17 | ||
| 18 |  import java.io.IOException; | |
| 19 |  import java.io.InputStream; | |
| 20 |  import java.util.ArrayList; | |
| 21 |  import java.util.List; | |
| 22 | ||
| 23 |  import javax.xml.bind.JAXBContext; | |
| 24 |  import javax.xml.bind.Unmarshaller; | |
| 25 |  import javax.xml.bind.UnmarshallerHandler; | |
| 26 |  import javax.xml.bind.util.ValidationEventCollector; | |
| 27 |  import javax.xml.parsers.SAXParserFactory; | |
| 28 |  import javax.xml.validation.Schema; | |
| 29 | ||
| 30 |  import org.apache.commons.lang.StringUtils; | |
| 31 |  import org.apache.log4j.Logger; | |
| 32 |  import org.kuali.rice.core.xml.CoreNamespaceConstants; | |
| 33 |  import org.kuali.rice.core.xml.dto.DataXmlDto; | |
| 34 |  import org.kuali.rice.core.xml.schema.RiceSchemaValidationEventCollector; | |
| 35 |  import org.kuali.rice.core.xml.schema.RiceXmlSchemaFactory; | |
| 36 |  import org.xml.sax.Attributes; | |
| 37 |  import org.xml.sax.InputSource; | |
| 38 |  import org.xml.sax.SAXException; | |
| 39 |  import org.xml.sax.XMLFilter; | |
| 40 |  import org.xml.sax.helpers.XMLFilterImpl; | |
| 41 | ||
| 42 | ||
| 43 |  /** | |
| 44 |   * Parses groups from XML using JAXB. | |
| 45 |   * | |
| 46 |   * @see KimGroups | |
| 47 |   * | |
| 48 |   * @author Kuali Rice Team (rice.collab@kuali.org)  | |
| 49 |   * | |
| 50 |   */ | |
| 51 | 0 |  public class GroupXmlJAXBParser implements XmlConstants { | 
| 52 | 0 |      private static final Logger LOG = Logger.getLogger(GroupXmlJAXBParser.class); | 
| 53 | private static final String DEFAULT_GROUP_DESCRIPTION = ""; | |
| 54 | private static final String DEFAULT_GROUP_SCHEMA_NAME = "Groups-1.0.3.xsd"; | |
| 55 | ||
| 56 | public DataXmlDto parse(InputStream in) throws IOException { | |
| 57 | 0 |          DataXmlDto groupsXmlDto = new DataXmlDto(); | 
| 58 | JAXBContext jaxbContext; | |
| 59 | Unmarshaller unmarshaller; | |
| 60 | ||
| 61 |                  try { | |
| 62 | 0 |                          jaxbContext = JAXBContext.newInstance(DataXmlDto.class); | 
| 63 | 0 |                          unmarshaller = jaxbContext.createUnmarshaller(); | 
| 64 | 0 |                  }catch (Exception ex) { | 
| 65 | 0 |                          throw new RuntimeException("Error creating JAXB unmarshaller", ex); | 
| 66 | 0 |                  } | 
| 67 | ||
| 68 | 0 |                  if (in == null) { | 
| 69 | 0 |                          LOG.warn("###############################"); | 
| 70 | 0 |                          LOG.warn("#"); | 
| 71 | 0 |                          LOG.warn("# XML Import input stream not found!"); | 
| 72 | 0 |                          LOG.warn("#"); | 
| 73 | 0 |                          LOG.warn("###############################"); | 
| 74 |                  } else { | |
| 75 |                          try { | |
| 76 | ||
| 77 | 0 |                                  groupsXmlDto = unmarshal(unmarshaller, in); | 
| 78 | ||
| 79 | 0 |                          } catch (Exception ex) { | 
| 80 | 0 |                                  LOG.error(ex.getMessage()); | 
| 81 | 0 |                                  throw new RuntimeException("Error parsing XML input stream", ex); | 
| 82 | 0 |                          } | 
| 83 | ||
| 84 | } | |
| 85 | 0 |                  return groupsXmlDto; | 
| 86 | } | |
| 87 | ||
| 88 |          /** | |
| 89 |           *  | |
| 90 |           * This method returns a list of xmlfilters.  The order here matters. The fist element gets processed  | |
| 91 |           * first. FIFO. | |
| 92 |           *  | |
| 93 |           * @return | |
| 94 |           */ | |
| 95 |          public List<XMLFilter> getXMLFilterList(){ | |
| 96 | ||
| 97 | 0 |                  List<XMLFilter> lRet = new ArrayList<XMLFilter>(); | 
| 98 | ||
| 99 | 0 |                  lRet.add(new DataNamespaceURIFilter());                 | 
| 100 | 0 |                  lRet.add(new GroupNamespaceURITransformationFilterPOC()); | 
| 101 | 0 |                  lRet.add(new GroupNamespaceURIMemberTransformationFilterPOC()); | 
| 102 | 0 |                  lRet.add(new GroupNamespaceURIFilter()); | 
| 103 | ||
| 104 | 0 |                  return lRet; | 
| 105 | } | |
| 106 | ||
| 107 |          /** | |
| 108 |           *  | |
| 109 |           * This method takes in a list of xml filters and appends them together via | |
| 110 |           * parent child relationships.  The end result is one xml filter that can be applied to the parse. | |
| 111 |           *  | |
| 112 |           * @param filters | |
| 113 |           * @return | |
| 114 |           * @throws Exception | |
| 115 |           */ | |
| 116 | public XMLFilter getXMLFilter(List<XMLFilter> filters) throws Exception{ | |
| 117 | 0 |                   SAXParserFactory spf = SAXParserFactory.newInstance(); | 
| 118 | 0 |               spf.setNamespaceAware(true); | 
| 119 | 0 |               XMLFilter previous = null; | 
| 120 | 0 |               XMLFilter current = null; | 
| 121 | ||
| 122 | 0 |               for(int i=0; i< filters.size();i++) | 
| 123 |               {                      | |
| 124 | 0 |                       if(i==0){ | 
| 125 | 0 |                               previous = filters.get(i); | 
| 126 | 0 |                               previous.setParent(spf.newSAXParser().getXMLReader()); | 
| 127 |                       }else{ | |
| 128 | 0 |                               current = filters.get(i); | 
| 129 | 0 |                               current.setParent(previous); | 
| 130 | 0 |                               previous = current; | 
| 131 | } | |
| 132 | } | |
| 133 | 0 |               return current; | 
| 134 | } | |
| 135 | ||
| 136 | protected DataXmlDto unmarshal(Unmarshaller unmarshaller, InputStream in) throws Exception { | |
| 137 | ||
| 138 | 0 |          UnmarshallerHandler handler = unmarshaller.getUnmarshallerHandler(); | 
| 139 | 0 |          Schema groupSchema = RiceXmlSchemaFactory.getSchema(DEFAULT_GROUP_SCHEMA_NAME); | 
| 140 | 0 |          unmarshaller.setSchema(groupSchema); | 
| 141 | 0 |          ValidationEventCollector vec = new RiceSchemaValidationEventCollector(); | 
| 142 | 0 |          unmarshaller.setEventHandler(vec);         | 
| 143 | ||
| 144 | 0 |          XMLFilter filter = this.getXMLFilter(this.getXMLFilterList()); | 
| 145 | 0 |          filter.setContentHandler(handler); | 
| 146 | ||
| 147 | 0 |          filter.parse(new InputSource(in)); | 
| 148 | ||
| 149 | ||
| 150 | 0 |          return (DataXmlDto)handler.getResult(); | 
| 151 | } | |
| 152 | ||
| 153 |  //    protected GroupXmlDto unmarshalNew(Unmarshaller unmarshaller, InputStream in) throws Exception { | |
| 154 |  //        SAXParserFactory spf = SAXParserFactory.newInstance(); | |
| 155 |  //        spf.setNamespaceAware(true); | |
| 156 |  // | |
| 157 |  //        XMLFilter filter = new TestGroupNamespaceURIFilter(); | |
| 158 |  //        filter.setParent(spf.newSAXParser().getXMLReader()); | |
| 159 |  // | |
| 160 |  //        unmarshaller.setListener(new Unmarshaller.Listener() { | |
| 161 |  //                         | |
| 162 |  //                        public void afterUnmarshal(Object target, Object parent) { | |
| 163 |  //                                GroupXmlDto gxd = (GroupXmlDto)target; | |
| 164 |  //                                //super.afterUnmarshal(target, parent); | |
| 165 |  //                        } | |
| 166 |  //                }); | |
| 167 |  //         | |
| 168 |  //         | |
| 169 |  //        UnmarshallerHandler handler = unmarshaller.getUnmarshallerHandler(); | |
| 170 |  //        filter.setContentHandler(handler); | |
| 171 |  // | |
| 172 |  //        filter.parse(new InputSource(in)); | |
| 173 |  // | |
| 174 |  //        return (GroupXmlDto)handler.getResult(); | |
| 175 |  //    } | |
| 176 |  // | |
| 177 |  //    protected GroupInfo generateGroupInfo(GroupXmlDto groupDto){ | |
| 178 |  //            IdentityManagementService identityManagementService = KIMServiceLocator.getIdentityManagementService(); | |
| 179 |  //             | |
| 180 |  //            List<String> errors = new ArrayList<String>(); | |
| 181 |  //            GroupInfo gi = new GroupInfo(); | |
| 182 |  //            List<KimTypeAttributeInfo> typeAttributes = null; | |
| 183 |  //             | |
| 184 |  //            if(isBlank(groupDto.getNamespaceCode())){ | |
| 185 |  //                    errors.add("Namespace must have a value."); | |
| 186 |  //            }else{ | |
| 187 |  //                    gi.setNamespaceCode(groupDto.getNamespaceCode()); | |
| 188 |  //            } | |
| 189 |  //             | |
| 190 |  //            if(groupDto.getKimType() != null){ | |
| 191 |  //                    KimTypeInfo kimTypeInfo = null; | |
| 192 |  //                    if(!isBlank(groupDto.getKimType().getKimTypeId())){ | |
| 193 |  //                             kimTypeInfo = KIMServiceLocator.getTypeInfoService().getKimType(groupDto.getKimType().getKimTypeId()); | |
| 194 |  //                    } | |
| 195 |  //                    if(!isBlank(groupDto.getKimType().getName()) && !isBlank(groupDto.getKimType().getNamespaceCode())){ | |
| 196 |  //                            kimTypeInfo = KIMServiceLocator.getTypeInfoService().getKimTypeByName(groupDto.getKimType().getNamespaceCode(), groupDto.getKimType().getName()); | |
| 197 |  //                    } | |
| 198 |  //                     | |
| 199 |  //                    if (kimTypeInfo == null) { | |
| 200 |  //                    errors.add("Invalid typeId or type name and namespace specified."); | |
| 201 |  //            } else  { | |
| 202 |  //                    gi.setKimTypeId(kimTypeInfo.getKimTypeId()); | |
| 203 |  //                    typeAttributes = kimTypeInfo.getAttributeDefinitions(); | |
| 204 |  //            }             | |
| 205 |  //            } else{ | |
| 206 |  //                    KimTypeInfo kimTypeDefault = KIMServiceLocator.getTypeInfoService().getKimTypeByName(KimConstants.KIM_TYPE_DEFAULT_NAMESPACE, KimConstants.KIM_TYPE_DEFAULT_NAME); | |
| 207 |  //            if (kimTypeDefault != null) { | |
| 208 |  //                    gi.setKimTypeId(kimTypeDefault.getKimTypeId()); | |
| 209 |  //                    typeAttributes = kimTypeDefault.getAttributeDefinitions(); | |
| 210 |  //            } else { | |
| 211 |  //                    errors.add("Failed to locate the 'Default' group type!  Please ensure that it's in your database."); | |
| 212 |  //            } | |
| 213 |  //            } | |
| 214 |  //             | |
| 215 |  //            //Active Indicator | |
| 216 |  //        gi.setActive(groupDto.isActive()); | |
| 217 |  //         | |
| 218 |  //      //Get list of attribute keys | |
| 219 |  //        List<String> validAttributeKeys = new ArrayList<String>(); | |
| 220 |  //        for (KimTypeAttributeInfo attribute : typeAttributes) { | |
| 221 |  //            validAttributeKeys.add(attribute.getAttributeName()); | |
| 222 |  //        } | |
| 223 |  //        //Group attributes | |
| 224 |  //        if (groupDto.getAttributes() != null) { | |
| 225 |  //                AttributeSet attributeSet = new AttributeSet(); | |
| 226 |  //            for (String key : groupDto.getAttributes().keySet() ) { | |
| 227 |  //                String value = groupDto.getAttributes().get(key); | |
| 228 |  //                attributeSet.put(key, value); | |
| 229 |  //                if (!validAttributeKeys.contains(key)) { | |
| 230 |  //                    errors.add("Invalid attribute specified."); | |
| 231 |  //                } | |
| 232 |  //            } | |
| 233 |  //            if (attributeSet.size() > 0) { | |
| 234 |  //                gi.setAttributes(attributeSet); | |
| 235 |  //            } | |
| 236 |  //        } | |
| 237 |  //         | |
| 238 |  //        // Group Members | |
| 239 |  //        for(GroupMembershipXmlDto groupMember : groupDto.getMembers()){ | |
| 240 |  //                 | |
| 241 |  //                GroupMembershipInfo gmi = new GroupMembershipInfo(groupDto.getGroupId(), null, null, null, null, null); | |
| 242 |  //                if(!isBlank(groupMember.getMemberId())){ | |
| 243 |  //                        KimPrincipal principal = identityManagementService.getPrincipal(groupMember.getMemberId()); | |
| 244 |  //                        gmi.setMemberId(principal.getPrincipalId()); | |
| 245 |  //                        gmi.setMemberTypeCode(KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE); | |
| 246 |  //                } | |
| 247 |  //                if(!isBlank(groupMember.getMemberName())){ | |
| 248 |  //                        KimPrincipal principal = identityManagementService.getPrincipalByPrincipalName(groupMember.getMemberName()); | |
| 249 |  //                        gmi.setMemberId(principal.getPrincipalId()); | |
| 250 |  //                        gmi.setMemberTypeCode(KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE); | |
| 251 |  //                } | |
| 252 |  //                if(groupMember.getGroupName() != null){ | |
| 253 |  //                        Group group = identityManagementService.getGroupByName(groupMember.getGroupName().getNamespaceCode(),groupMember.getGroupName().getName()); | |
| 254 |  //                        gmi.setMemberId(group.getGroupId()); | |
| 255 |  //                        gmi.setMemberTypeCode(KimGroupMemberTypes.GROUP_MEMBER_TYPE); | |
| 256 |  //                } | |
| 257 |  //                if(groupMember.getGroupName() != null){ | |
| 258 |  //                        Group group = identityManagementService.getGroupByName(groupMember.getGroupName().getNamespaceCode(),groupMember.getGroupName().getName()); | |
| 259 |  //                        gmi.setMemberId(group.getGroupId()); | |
| 260 |  //                        gmi.setMemberTypeCode(KimGroupMemberTypes.GROUP_MEMBER_TYPE); | |
| 261 |  //                } | |
| 262 |  //                 | |
| 263 |  //                /** | |
| 264 |  //            if (principal != null) { | |
| 265 |  //                addPrincipalToGroup(groupInfo.getNamespaceCode(), groupInfo.getGroupName(), principal.getPrincipalId()); | |
| 266 |  //            } else { | |
| 267 |  //                throw new InvalidXmlException("Principal Name "+principalName+" cannot be found."); | |
| 268 |  //            } | |
| 269 |  //            **/ | |
| 270 |  //     | |
| 271 |  //        } | |
| 272 |  //             | |
| 273 |  //            return gi; | |
| 274 |  //    } | |
| 275 |  //  | |
| 276 | private boolean isBlank(Object o){ | |
| 277 | 0 |              return (o == null || "".equals(o)); | 
| 278 | } | |
| 279 | ||
| 280 | ||
| 281 | 0 |      public class DataNamespaceURIFilter extends XMLFilterImpl { | 
| 282 | ||
| 283 | public static final String DATA_URI=CoreNamespaceConstants.CORE; | |
| 284 | ||
| 285 | public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { | |
| 286 | 0 |              if("data".equals(localName)) { | 
| 287 | 0 |                  uri = DATA_URI; | 
| 288 | } | |
| 289 | ||
| 290 | 0 |              super.startElement(uri, localName, qName, atts); | 
| 291 | 0 |          } | 
| 292 | ||
| 293 | public void endElement(String uri, String localName, String qName) throws SAXException { | |
| 294 | 0 |              if(StringUtils.isBlank(uri)) { | 
| 295 | 0 |                  uri = DATA_URI; | 
| 296 | } | |
| 297 | ||
| 298 | 0 |              super.endElement(uri, localName, qName); | 
| 299 | 0 |          } | 
| 300 | } | |
| 301 | ||
| 302 | } |