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