| 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 | } |