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




























































Copyright © 2010-2017, ForgeRock All Rights Reserved.