001/** 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved 005 * 006 * The contents of this file are subject to the terms 007 * of the Common Development and Distribution License 008 * (the License). You may not use this file except in 009 * compliance with the License. 010 * 011 * You can obtain a copy of the License at 012 * https://opensso.dev.java.net/public/CDDLv1.0.html or 013 * opensso/legal/CDDLv1.0.txt 014 * See the License for the specific language governing 015 * permission and limitations under the License. 016 * 017 * When distributing Covered Code, include this CDDL 018 * Header Notice in each file and include the License file 019 * at opensso/legal/CDDLv1.0.txt. 020 * If applicable, add the following below the CDDL Header, 021 * with the fields enclosed by brackets [] replaced by 022 * your own identifying information: 023 * "Portions Copyrighted [year] [name of copyright owner]" 024 * 025 * $Id: Utils.java,v 1.9 2008/11/10 22:56:59 veiming Exp $ 026 * 027 * Portions Copyright 2013-2016 ForgeRock AS. 028 */ 029 030package com.sun.identity.liberty.ws.soapbinding; 031 032import static org.forgerock.openam.utils.Time.*; 033 034import java.io.ByteArrayInputStream; 035 036import java.text.MessageFormat; 037 038import java.util.ArrayList; 039import java.util.Date; 040import java.util.HashMap; 041import java.util.HashSet; 042import java.util.Iterator; 043import java.util.List; 044import java.util.Map; 045import java.util.ResourceBundle; 046import java.util.Set; 047import java.util.StringTokenizer; 048 049import javax.xml.bind.Marshaller; 050import javax.xml.bind.Unmarshaller; 051import javax.xml.bind.JAXBContext; 052import javax.xml.bind.JAXBException; 053import javax.xml.bind.NotIdentifiableEvent; 054import javax.xml.bind.PropertyException; 055import javax.xml.bind.ValidationEvent; 056import javax.xml.bind.helpers.DefaultValidationEventHandler; 057import javax.xml.namespace.QName; 058import javax.xml.soap.MessageFactory; 059import javax.xml.soap.SOAPMessage; 060import javax.xml.soap.MimeHeaders; 061 062import org.w3c.dom.Document; 063import org.w3c.dom.Element; 064 065import com.sun.identity.common.PeriodicCleanUpMap; 066import com.sun.identity.common.SystemTimerPool; 067import com.sun.identity.common.TaskRunnable; 068import com.sun.identity.liberty.ws.util.ProviderManager; 069import com.sun.identity.liberty.ws.util.ProviderUtil; 070import com.sun.identity.shared.debug.Debug; 071import com.sun.identity.shared.locale.Locale; 072import com.sun.identity.shared.configuration.SystemPropertiesManager; 073import com.sun.identity.shared.xml.XMLUtils; 074 075/** 076 * This class contains utility methods. 077 * 078 * @supported.api 079 */ 080 081public class Utils { 082 static final String NAMESPACE_PREFIX_MAPPING_LIST_PROP = 083 "com.sun.identity.liberty.ws.jaxb.namespacePrefixMappingList"; 084 static final String JAXB_PACKAGE_LIST_PROP = 085 "com.sun.identity.liberty.ws.jaxb.packageList"; 086 087 088 static final String DEFAULT_JAXB_PACKAGES = 089 "com.sun.identity.liberty.ws.common.jaxb.soap:" + 090 "com.sun.identity.liberty.ws.common.jaxb.assertion:" + 091 "com.sun.identity.liberty.ws.common.jaxb.protocol:" + 092 "com.sun.identity.liberty.ws.common.jaxb.ac:" + 093 "com.sun.identity.liberty.ws.disco.jaxb:" + 094 "com.sun.identity.liberty.ws.disco.jaxb11:" + 095 "com.sun.identity.liberty.ws.disco.plugins.jaxb:" + 096 "com.sun.identity.liberty.ws.interaction.jaxb:" + 097 "com.sun.identity.liberty.ws.meta.jaxb:" + 098 "com.sun.identity.liberty.ws.paos.jaxb:" + 099 "com.sun.identity.liberty.ws.common.jaxb.ps:" + 100 "com.sun.identity.liberty.ws.common.jaxb.security:" + 101 "com.sun.identity.liberty.ws.soapbinding.jaxb:" + 102 "com.sun.identity.liberty.ws.soapbinding.jaxb11:" + 103 "com.sun.identity.liberty.ws.idpp.jaxb:" + 104 "com.sun.identity.liberty.ws.idpp.plugin.jaxb:" + 105 "com.sun.identity.liberty.ws.common.jaxb.secext:" + 106 "com.sun.identity.liberty.ws.common.jaxb.utility:" + 107 "com.sun.identity.liberty.ws.common.jaxb.xmlenc:" + 108 "com.sun.identity.liberty.ws.common.jaxb.xmlsig"; 109 110 static com.sun.identity.liberty.ws.common.jaxb.soap.ObjectFactory soapOF = 111 new com.sun.identity.liberty.ws.common.jaxb.soap.ObjectFactory(); 112 113 static com.sun.identity.liberty.ws.soapbinding.jaxb.ObjectFactory soapBOF = 114 new com.sun.identity.liberty.ws.soapbinding.jaxb.ObjectFactory(); 115 116 static com.sun.identity.liberty.ws.common.jaxb.secext.ObjectFactory secOF = 117 new com.sun.identity.liberty.ws.common.jaxb.secext.ObjectFactory(); 118 119 static final QName FAULT_CODE_SERVER = 120 new QName(SOAPBindingConstants.NS_SOAP, "Server"); 121 static String faultStringServerError = null; 122 static Debug debug = null; 123 public static ResourceBundle bundle = null; 124 125 static MessageFactory messageFactory = null; 126 127 static HashMap nsPrefix = new HashMap(); 128 static String jaxbPackages = null; 129 static JAXBContext jc = null; 130 131 static final String STALE_TIME_LIMIT_PROP = 132 "com.sun.identity.liberty.ws.soap.staleTimeLimit"; 133 static int stale_time_limit = 300000; // millisec 134 135 static final String SUPPORTED_ACTORS_PROP = 136 "com.sun.identity.liberty.ws.soap.supportedActors"; 137 static final String LIBERTY_WSF_VERSION = 138 "com.sun.identity.liberty.wsf.version"; 139 static Set supportedActors = new HashSet(); 140 141 static final String MESSAGE_ID_CACHE_CLEANUP_INTERVAL_PROP = 142 "com.sun.identity.liberty.ws.soap.messageIDCacheCleanupInterval"; 143 static int message_ID_cleanup_interval = 60000; // millisec 144 private static Map messageIDMap = null; 145 146 static { 147 bundle = Locale.getInstallResourceBundle("libSOAPBinding"); 148 faultStringServerError = bundle.getString("ServerError"); 149 debug = Debug.getInstance("libIDWSF"); 150 151 try { 152 messageFactory = MessageFactory.newInstance(); 153 } catch (Exception ex) { 154 debug.error("Utils.static: Unable to create SOAP Message Factory", 155 ex); 156 } 157 158 String tmpNSPre = 159 SystemPropertiesManager.get(NAMESPACE_PREFIX_MAPPING_LIST_PROP); 160 if (tmpNSPre != null && tmpNSPre.length() > 0) { 161 StringTokenizer stz = new StringTokenizer(tmpNSPre, "|"); 162 while(stz.hasMoreTokens()) { 163 String token = stz.nextToken().trim(); 164 int index = token.indexOf('='); 165 if (index != -1 && index != 0 && index != token.length() - 1) { 166 String prefix = token.substring(0, index); 167 String ns = token.substring(index + 1); 168 if (debug.messageEnabled()) { 169 debug.message("Utils.static: add ns = " + ns + 170 ", prefix = " + prefix); 171 } 172 nsPrefix.put(ns, prefix); 173 } else { 174 if (debug.warningEnabled()) { 175 debug.warning("Utils.static: Invalid syntax " + 176 "for Namespace Prefix Mapping List: " + 177 token); 178 } 179 } 180 } 181 } 182 183 String tmpJaxbPkgs = SystemPropertiesManager.get(JAXB_PACKAGE_LIST_PROP); 184 if (tmpJaxbPkgs != null && tmpJaxbPkgs.length() > 0) { 185 jaxbPackages = DEFAULT_JAXB_PACKAGES + ":" + tmpJaxbPkgs; 186 } else { 187 jaxbPackages = DEFAULT_JAXB_PACKAGES; 188 } 189 if (debug.messageEnabled()) { 190 debug.message("Utils.static: jaxbPackages = " + jaxbPackages); 191 } 192 193 try { 194 jc = JAXBContext.newInstance(jaxbPackages); 195 } catch (JAXBException jaxbe) { 196 Utils.debug.error("Utils.static:", jaxbe); 197 } 198 199 String tmpstr = SystemPropertiesManager.get(STALE_TIME_LIMIT_PROP); 200 if (tmpstr != null) { 201 try { 202 stale_time_limit = Integer.parseInt(tmpstr); 203 } catch (Exception ex) { 204 if (debug.warningEnabled()) { 205 debug.warning("Utils.static: Unable to get stale time " + 206 "limit. Default value will be used"); 207 } 208 } 209 } 210 211 tmpstr = SystemPropertiesManager.get(SUPPORTED_ACTORS_PROP); 212 if (tmpstr != null) { 213 StringTokenizer stz = new StringTokenizer(tmpstr, "|"); 214 while(stz.hasMoreTokens()) { 215 String token = stz.nextToken(); 216 if (token.length() > 0) { 217 supportedActors.add(token); 218 } 219 } 220 } 221 tmpstr = 222 SystemPropertiesManager.get(MESSAGE_ID_CACHE_CLEANUP_INTERVAL_PROP); 223 if (tmpstr != null) { 224 try { 225 message_ID_cleanup_interval = Integer.parseInt(tmpstr); 226 } catch (Exception ex) { 227 if (debug.warningEnabled()) { 228 debug.warning("Utils.CleanUpThread.static: Unable to" + 229 " get stale time limit. Default value " + 230 "will be used"); 231 } 232 } 233 } 234 messageIDMap = new PeriodicCleanUpMap( 235 message_ID_cleanup_interval, stale_time_limit); 236 SystemTimerPool.getTimerPool().schedule((TaskRunnable) messageIDMap, 237 new Date(((currentTimeMillis() + message_ID_cleanup_interval) 238 / 1000) * 1000)); 239 } 240 241 /** 242 * Returns JAXB namespace prefix mapping. Key is the namespace and value 243 * is the prefix. 244 * 245 * @return a Map of JAXB namespace prefix mapping 246 * @supported.api 247 */ 248 static public Map getNamespacePrefixMapping() { 249 return nsPrefix; 250 } 251 252 /** 253 * Returns a String of JAXB packages seperated by ":". 254 * 255 * @return a String of JAXB packages seperated by ":". 256 * @supported.api 257 */ 258 public static String getJAXBPackages() { 259 return jaxbPackages; 260 } 261 262 /** 263 * Converts Document to SOAPMessage 264 * 265 * @param doc the source Document 266 * @return SOAPMessage 267 * @throws SOAPBindingException if an error occurs while converting 268 * the document 269 * @supported.api 270 */ 271 public static SOAPMessage DocumentToSOAPMessage(Document doc) 272 throws SOAPBindingException { 273 SOAPMessage msg = null; 274 try { 275 MimeHeaders mimeHeaders = new MimeHeaders(); 276 mimeHeaders.addHeader("Content-Type", "text/xml"); 277 278 String xmlstr = XMLUtils.print(doc); 279 if (debug.messageEnabled()) { 280 debug.message("Utils.DocumentToSOAPMessage: xmlstr = " + 281 xmlstr); 282 } 283 msg = messageFactory.createMessage( 284 mimeHeaders, 285 new ByteArrayInputStream( 286 xmlstr.getBytes(SOAPBindingConstants.DEFAULT_ENCODING))); 287 } catch (Exception e) { 288 debug.error("Utils.DocumentToSOAPMessage", e); 289 throw new SOAPBindingException(e.getMessage()); 290 } 291 return msg; 292 } 293 294 /** 295 * Converts a list of JAXB objects to a list of 296 * <code>org.w3c.dom.Element</code> 297 * 298 * @param jaxbObjs a list of JAXB objects 299 * @return a list of <code>org.w3c.dom.Element</code> 300 * @throws JAXBException if an error occurs while converting JAXB objects. 301 * 302 * @supported.api 303 */ 304 public static List convertJAXBToElement(List jaxbObjs) 305 throws JAXBException{ 306 List result = new ArrayList(); 307 if (jaxbObjs != null && !jaxbObjs.isEmpty()) { 308 Iterator iter = jaxbObjs.iterator(); 309 while(iter.hasNext()) { 310 result.add(convertJAXBToElement(iter.next())); 311 } 312 } 313 return result; 314 } 315 316 /** 317 * Converts a JAXB object to a <code>org.w3c.dom.Element</code>. 318 * 319 * @param jaxbObj a JAXB object 320 * @return a <code>org.w3c.dom.Element</code> 321 * @throws JAXBException if an error occurs while converting JAXB object. 322 * @supported.api 323 */ 324 public static Element convertJAXBToElement(Object jaxbObj) 325 throws JAXBException { 326 Marshaller m = jc.createMarshaller(); 327 try { 328 m.setProperty("com.sun.xml.bind.namespacePrefixMapper", 329 new NamespacePrefixMapperImpl()); 330 } catch(PropertyException ex) { 331 debug.error("Utils.convertJAXBToElement", ex); 332 } 333 Document doc = null; 334 try { 335 doc = XMLUtils.newDocument(); 336 } catch (Exception ex) { 337 debug.error("Utils.convertJAXBToElement:", ex); 338 } 339 m.marshal(jaxbObj, doc); 340 return doc.getDocumentElement(); 341 } 342 343 /** 344 * Converts a JAXB object to a <code>org.w3c.dom.Element</code>. 345 * 346 * @param jaxbObj a JAXB object 347 * @return a <code>org.w3c.dom.Element</code> 348 * @throws JAXBException if an error occurs while converting JAXB object. 349 * @supported.api 350 */ 351 public static Element convertJAXBToElement(Object jaxbObj, 352 boolean checkIdref) throws JAXBException { 353 Marshaller m = jc.createMarshaller(); 354 try { 355 m.setProperty("com.sun.xml.bind.namespacePrefixMapper", 356 new NamespacePrefixMapperImpl()); 357 358 } catch(PropertyException ex) { 359 debug.error("Utils.convertJAXBToElement", ex); 360 } 361 362 if (!checkIdref) { 363 m.setEventHandler( 364 new DefaultValidationEventHandler() { 365 public boolean handleEvent(ValidationEvent event) { 366 if (event instanceof NotIdentifiableEvent) { 367 return true; 368 } 369 return super.handleEvent(event); 370 } 371 }); 372 } 373 374 Document doc = null; 375 try { 376 doc = XMLUtils.newDocument(); 377 } catch (Exception ex) { 378 debug.error("Utils.convertJAXBToElement:", ex); 379 } 380 m.marshal(jaxbObj, doc); 381 return doc.getDocumentElement(); 382 } 383 384 /** 385 * Converts a list of <code>org.w3c.dom.Element</code> to a list of 386 * JAXB objects. 387 * 388 * @param elements a list of <code>org.w3c.dom.Element</code> 389 * @return a list of JAXB objects 390 * @throws JAXBException if an error occurs while converting 391 * <code>org.w3c.dom.Element</code>. 392 * @supported.api 393 */ 394 public static List convertElementToJAXB(List elements) 395 throws JAXBException{ 396 List result = new ArrayList(); 397 if (elements != null && !elements.isEmpty()) { 398 Iterator iter = elements.iterator(); 399 while(iter.hasNext()) { 400 result.add(convertElementToJAXB((Element)iter.next())); 401 } 402 } 403 return result; 404 } 405 406 /** 407 * Converts a <code>org.w3c.dom.Element</code> to a JAXB object. 408 * 409 * @param element a <code>org.w3c.dom.Element</code>. 410 * @return a JAXB object 411 * @throws JAXBException if an error occurs while converting 412 * <code>org.w3c.dom.Element</code> 413 * @supported.api 414 */ 415 public static Object convertElementToJAXB(Element element) 416 throws JAXBException { 417 Unmarshaller u = jc.createUnmarshaller(); 418 return u.unmarshal(element); 419 } 420 421 /** 422 * Converts a value of XML boolean type to Boolean object. 423 * 424 * @param str a value of XML boolean type 425 * @return a Boolean object 426 * @throws Exception if there is a syntax error 427 * @supported.api 428 */ 429 public static Boolean StringToBoolean(String str) throws Exception { 430 if (str == null) { 431 return null; 432 } 433 434 if (str.equals("true") || str.equals("1")) { 435 return Boolean.TRUE; 436 } 437 438 if (str.equals("false") || str.equals("0")) { 439 return Boolean.FALSE; 440 } 441 442 throw new Exception(); 443 } 444 445 /** 446 * Converts a Boolean object to a String representing XML boolean. 447 * 448 * @param bool a Boolean object. 449 * @return a String representing the boolean value. 450 * @supported.api 451 */ 452 public static String BooleanToString(Boolean bool) { 453 if (bool == null) { 454 return ""; 455 } 456 457 return bool.booleanValue() ? "1" : "0"; 458 } 459 460 /** 461 * Converts a string value to a QName. The prefix of the string value 462 * is resolved to a namespace relative to the element. 463 * 464 * @param str the String to be converted. 465 * @param element the Element object. 466 * @return the QName Object. 467 * @supported.api 468 */ 469 public static QName convertStringToQName(String str,Element element) { 470 if (str == null) { 471 return null; 472 } 473 474 String prefix = ""; 475 String localPart; 476 int index = str.indexOf(":"); 477 if (index == -1) { 478 localPart = str; 479 } else { 480 prefix = str.substring(0, index); 481 localPart = str.substring(index + 1); 482 } 483 String ns = getNamespaceForPrefix(prefix, element); 484 return new QName(ns, localPart); 485 } 486 487 488 /** 489 * Gets the XML namespace URI that is mapped to the specified prefix, in 490 * the context of the DOM element e 491 * 492 * @param prefix The namespace prefix to map 493 * @param e The DOM element in which to calculate the prefix binding 494 * @return The XML namespace URI mapped to prefix in the context of e 495 */ 496 public static String getNamespaceForPrefix(String prefix, Element e) { 497 return e.lookupNamespaceURI(prefix); 498 } 499 500 /** 501 * Enforces message processiong rules defined in the spec. 502 * 503 * @param message a message 504 * @param requestMessageID the request messageID if we are checking a 505 * response message or null if we are checking a 506 * request message 507 * @param isServer true if this is a server 508 * @throws SOAPBindingException if the message violates rules on client. 509 * @throws SOAPFaultException if the message violates rules on server. 510 */ 511 public static void enforceProcessingRules(Message message, String requestMessageID, 512 boolean isServer) 513 throws SOAPBindingException, SOAPFaultException { 514 CorrelationHeader corrH = message.getCorrelationHeader(); 515 String messageID = corrH.getMessageID(); 516 checkCorrelationHeader(corrH, requestMessageID, isServer); 517 checkProviderHeader(message.getProviderHeader(), messageID, isServer); 518 checkProcessingContextHeader(message.getProcessingContextHeader(), 519 messageID, isServer); 520 checkConsentHeader(message.getConsentHeader(), messageID, isServer); 521 List usagHs = message.getUsageDirectiveHeaders(); 522 if (usagHs != null && !usagHs.isEmpty()) { 523 Iterator iter = usagHs.iterator(); 524 while(iter.hasNext()) { 525 UsageDirectiveHeader usagH = (UsageDirectiveHeader)iter.next(); 526 checkUsageDirectiveHeader(usagH, messageID, isServer); 527 } 528 } 529 } 530 531 /** 532 * Enforces message Correlation header processiong rules defined 533 * in the spec. 534 * 535 * @param corrH a Correlation header 536 * @param requestMessageID the request messageID if we are checking a 537 * response message or null if we are checking a 538 * request message 539 * @param isServer true if this is a server 540 * @throws SOAPBindingException if the Correlation header violates rules 541 * on client side 542 * @throws SOAPFaultException if the Correlation header violates rules 543 * on server side 544 */ 545 static void checkCorrelationHeader(CorrelationHeader corrH, 546 String requestMessageID, boolean isServer) 547 throws SOAPBindingException, SOAPFaultException { 548 if (corrH == null) { 549 if (isServer) { 550 SOAPFault sf = new SOAPFault(FAULT_CODE_SERVER, 551 faultStringServerError, null, 552 new SOAPFaultDetail( 553 SOAPFaultDetail.ID_STAR_MSG_NOT_UNSTD,null,null)); 554 throw new SOAPFaultException(new Message(sf)); 555 } else { 556 throw new SOAPBindingException( 557 bundle.getString("CorrelationHeaderNull")); 558 } 559 } 560 561 String messageID = corrH.getMessageID(); 562 563 try { 564 checkActorAndMustUnderstand(corrH.getActor(), 565 corrH.getMustUnderstand(), 566 messageID, isServer); 567 } catch (SOAPFaultException sfe) { 568 sfe.getSOAPFaultMessage().getSOAPFault().getDetail() 569 .setCorrelationHeader(corrH); 570 throw sfe; 571 } 572 573 Date timestamp = corrH.getTimestamp(); 574 Date now = newDate(); 575 if ((now.getTime() - timestamp.getTime()) > stale_time_limit) { 576 if (isServer) { 577 SOAPFaultDetail sfd = 578 new SOAPFaultDetail(SOAPFaultDetail.STALE_MSG, 579 messageID, null); 580 sfd.setCorrelationHeader(corrH); 581 SOAPFault sf = new SOAPFault(FAULT_CODE_SERVER, 582 faultStringServerError, null, sfd); 583 throw new SOAPFaultException(new Message(sf)); 584 585 } else { 586 throw new SOAPBindingException(bundle.getString("staleMsg")); 587 } 588 } 589 590 Long prevMsgIDTime = (Long)messageIDMap.get(messageID); 591 long currentTime = currentTimeMillis(); 592 if (prevMsgIDTime != null && 593 currentTime - prevMsgIDTime.longValue() < stale_time_limit) { 594 595 if (isServer) { 596 SOAPFaultDetail sfd = 597 new SOAPFaultDetail(SOAPFaultDetail.DUPLICATE_MSG, 598 messageID, null); 599 sfd.setCorrelationHeader(corrH); 600 SOAPFault sf = new SOAPFault(FAULT_CODE_SERVER, 601 faultStringServerError, null, sfd); 602 throw new SOAPFaultException(new Message(sf)); 603 604 } else { 605 throw new SOAPBindingException(bundle.getString("dupMsg")); 606 } 607 } else { 608 synchronized (messageIDMap) { 609 if (debug.messageEnabled()) { 610 debug.message("Utils.checkCorrelationHeader: adding " + 611 "messageID: " + messageID); 612 } 613 messageIDMap.put(messageID, new Long(currentTime)); 614 } 615 } 616 617 String refToMessageID = corrH.getRefToMessageID(); 618 if (refToMessageID != null && requestMessageID != null && 619 !refToMessageID.equals(requestMessageID)) { 620 621 if (isServer) { 622 SOAPFaultDetail sfd = 623 new SOAPFaultDetail( 624 SOAPFaultDetail.INVALID_REF_TO_MSG_ID,messageID, null); 625 sfd.setCorrelationHeader(corrH); 626 SOAPFault sf = new SOAPFault(FAULT_CODE_SERVER, 627 faultStringServerError, null, sfd); 628 throw new SOAPFaultException(new Message(sf)); 629 630 } else { 631 throw new SOAPBindingException(bundle.getString("invalidRef")); 632 } 633 } 634 } 635 636 /** 637 * Enforces message Provider header processing rules defined 638 * in the spec. 639 * 640 * @param provH a Correlation header 641 * @param messageID the messageID in Correlation header 642 * @param isServer true if this is a server 643 * @throws SOAPBindingException if the Provider header violates rules 644 * on client side 645 * @throws SOAPFaultException if the Provider header violates rules 646 * on server side 647 */ 648 static void checkProviderHeader(ProviderHeader provH, 649 String messageID,boolean isServer) 650 throws SOAPBindingException, SOAPFaultException { 651 652 if (provH == null) { 653 return; 654 } 655 656 try { 657 checkActorAndMustUnderstand(provH.getActor(), 658 provH.getMustUnderstand(), 659 messageID, isServer); 660 } catch (SOAPFaultException sfe) { 661 sfe.getSOAPFaultMessage().getSOAPFault().getDetail() 662 .setProviderHeader(provH); 663 throw sfe; 664 } 665 666 if (isServer && SOAPBindingService.enforceOnlyKnownProviders()) { 667 String providerID = provH.getProviderID(); 668 ProviderManager providerManager = ProviderUtil.getProviderManager(); 669 670 if (!providerManager.containsProvider(providerID)) { 671 SOAPFaultDetail sfd = new SOAPFaultDetail( 672 SOAPFaultDetail.PROVIDER_ID_NOT_VALID, messageID, null); 673 sfd.setProviderHeader(provH); 674 SOAPFault sf = new SOAPFault(FAULT_CODE_SERVER, 675 faultStringServerError, null, sfd); 676 throw new SOAPFaultException(new Message(sf)); 677 } 678 679 String affID = provH.getAffiliationID(); 680 if ((affID != null) && 681 (!providerManager.isAffiliationMember(providerID, affID))) { 682 683 SOAPFaultDetail sfd = new SOAPFaultDetail( 684 SOAPFaultDetail.AFFILIATION_ID_NOT_VALID, messageID, null); 685 sfd.setProviderHeader(provH); 686 SOAPFault sf = new SOAPFault(FAULT_CODE_SERVER, 687 faultStringServerError, null, sfd); 688 throw new SOAPFaultException(new Message(sf)); 689 } 690 } 691 } 692 693 /** 694 * Enforces message Processing Context header processiong rules defined 695 * in the spec. 696 * @param procH a Processing Context header 697 * @param messageID the messageID in Correlation header 698 * @param isServer true if this is a server 699 * @throws SOAPBindingException if the Processing Context header 700 * violates rules on client side 701 * @throws SOAPFaultException if the Processing Context header violates 702 * rules on server side 703 */ 704 static void checkProcessingContextHeader(ProcessingContextHeader procH, 705 String messageID, boolean isServer) 706 throws SOAPBindingException, SOAPFaultException { 707 if (procH == null) { 708 return; 709 } 710 711 try { 712 checkActorAndMustUnderstand(procH.getActor(), 713 procH.getMustUnderstand(), 714 messageID, isServer); 715 } catch (SOAPFaultException sfe) { 716 sfe.getSOAPFaultMessage().getSOAPFault().getDetail() 717 .setProcessingContextHeader(procH); 718 throw sfe; 719 } 720 721 if (isServer) { 722 SOAPFaultDetail sfd = 723 new SOAPFaultDetail(SOAPFaultDetail.PROC_CTX_URI_NOT_UNSTD, 724 messageID, null); 725 sfd.setProcessingContextHeader(procH); 726 SOAPFault sf = new SOAPFault(FAULT_CODE_SERVER, 727 faultStringServerError, null, sfd); 728 throw new SOAPFaultException(new Message(sf)); 729 } else { 730 throw new SOAPBindingException( 731 bundle.getString("ProcessingContextUnsupported")); 732 } 733 } 734 735 /** 736 * Enforces message Consent header processiong rules defined in the spec. 737 * 738 * @param consH a Consent header 739 * @param messageID the messageID in Correlation header 740 * @param isServer true if this is a server 741 * @throws SOAPBindingException if the Consent header violates rules on 742 * client side 743 * @throws SOAPFaultException if the Consent header violates rules 744 * on server side 745 */ 746 static void checkConsentHeader(ConsentHeader consH,String messageID, 747 boolean isServer) throws SOAPBindingException, SOAPFaultException { 748 if (consH == null) { 749 return; 750 } 751 752 try { 753 checkActorAndMustUnderstand(consH.getActor(), 754 consH.getMustUnderstand(), 755 messageID, isServer); 756 } catch (SOAPFaultException sfe) { 757 sfe.getSOAPFaultMessage().getSOAPFault().getDetail() 758 .setConsentHeader(consH); 759 throw sfe; 760 } 761 } 762 763 /** 764 * Enforces message Usage Directive header processiong rules defined in 765 * the spec. 766 * 767 * @param usagH a Usage Directive header 768 * @param messageID the messageID in Correlation header 769 * @param isServer true if this is a server 770 * @throws SOAPBindingException if the Usage Directive header violates 771 * rules on client side 772 * @throws SOAPFaultException if the Usage Directive header violates 773 * rules on server side 774 */ 775 static void checkUsageDirectiveHeader(UsageDirectiveHeader usagH, 776 String messageID,boolean isServer) 777 throws SOAPBindingException, SOAPFaultException { 778 if (usagH == null) { 779 return; 780 } 781 782 try { 783 checkActorAndMustUnderstand(usagH.getActor(), 784 usagH.getMustUnderstand(), 785 messageID, isServer); 786 } catch (SOAPFaultException sfe) { 787 List usagHs = new ArrayList(); 788 usagHs.add(usagH); 789 sfe.getSOAPFaultMessage().getSOAPFault().getDetail() 790 .setUsageDirectiveHeaders(usagHs); 791 throw sfe; 792 } 793 } 794 795 /** 796 * Checks 'actor' and 'mustUnderstand' attribute of a header. 797 * 798 * @param actor the value of 'actor' attribute of a header. 799 * @param mustUnderstand the value of 'mustUnderstand' attribute of a 800 * header. 801 * @param messageID the messageID in Correlation header. 802 * @param isServer true if this is a server. 803 * @throws SOAPBindingException if the actor and mustUnderstand violates 804 * rules on client side 805 * @throws SOAPFaultException if the actor and mustUnderstand violates 806 * rules on server side 807 */ 808 static void checkActorAndMustUnderstand(String actor,Boolean mustUnderstand, 809 String messageID,boolean isServer) 810 throws SOAPBindingException, SOAPFaultException { 811 if (actor != null && !supportedActors.contains(actor)) { 812 if (isServer) { 813 SOAPFaultDetail sfd = 814 new SOAPFaultDetail(SOAPFaultDetail.BOGUS_ACTOR, 815 messageID, null); 816 SOAPFault sf = new SOAPFault(FAULT_CODE_SERVER, 817 faultStringServerError, null, sfd); 818 throw new SOAPFaultException(new Message(sf)); 819 } else { 820 throw new SOAPBindingException( 821 bundle.getString("bogusActor")); 822 } 823 } 824 825 if (mustUnderstand != null && !mustUnderstand.booleanValue()) { 826 if (isServer) { 827 SOAPFaultDetail sfd = 828 new SOAPFaultDetail(SOAPFaultDetail.BOGUS_MUST_UNSTND, 829 messageID, null); 830 SOAPFault sf = new SOAPFault(FAULT_CODE_SERVER, 831 faultStringServerError, null, sfd); 832 throw new SOAPFaultException(new Message(sf)); 833 } else { 834 throw new SOAPBindingException( 835 bundle.getString("bogusMustUnderstand")); 836 } 837 } 838 } 839 840 /** 841 * Gets localized string from resource bundle. 842 * 843 * @param key a key to a resource bundle 844 * @param params parameters to MessageFormat 845 * @return a localized string. 846 * @supported.api 847 */ 848 public static String getString(String key, Object[] params) { 849 return MessageFormat.format(bundle.getString(key), params); 850 } 851 852 /** 853 * Returns the default web services version. 854 * 855 * @return the default web services version. 856 */ 857 public static String getDefaultWSFVersion() { 858 return SystemPropertiesManager.get(LIBERTY_WSF_VERSION, 859 SOAPBindingConstants.WSF_11_VERSION); 860 } 861 862}