<?xml version="1.0" encoding="utf-8"?>

<!--
    This file is the descriptor for the cafesip reference jiplets.
    The file contains configuration information for these jiplets that the
    jiplet container reads and sets up the jiplet objects accordingly.
    This file must be placed inside the JIP-INF directory and must be called
    "jip.xml". 
-->

<!--
    "jip-app" is the root element. 
-->
<jip-app
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://www.cafesip.org/xsd/jip_2.0.xsd"> 
  
  <!--
    "display-name" is the name of the jiplet application (context). Management
    applications like the jiplet console can display this information.
  -->  
  <display-name>This application performs four tasks. 
    (1) Listens for REGISTER messages, authenticates the user and keeps
    track of the location for registered users.
    (2) When a SIP request message is received for a user who has already 
    registered, it forwards the message to the location of the user. It also
    forwards the response to the end point.
    (3) It records all the received request messages into a database.
	(4) It manages buddy lists for registered users and notifies them
	of buddy login/logout.
    
    In all, this application provides a very simple location, proxy, and presence service.  
    </display-name>
  
  <!--
    The context-mapping element contains the mapping information for the context.
    This maping information is used to select this context when a SIP request message
    is received by the jiplet container.
    -->
  <context-mappings>
  <!--
    The "context-mapping" element contains mapping information that is used by 
    the jiplet container to route SIP request messages to this context. When a
    SIP request message is received, a selection criteria is applied to 
    determine which context will handle the request message. The selection 
    criteria is specified by the "mapping" sub-element. The "mapping" element
    consists of an "expression" specified in XML format as shown below. For
    example, an expression can state something like:
    
        If the SIP request message's URI belongs to the "cafesip.org" domain 
                            AND
        the "from" header field matches the reqular expression "*@quik-j.com",
        
        then the SIP request message is handled by this context.
    
    The expression is defined in XML format using the following syntax:
    
    There are two types of expressions: (1) simple and (2)complex. A simple 
    expression is specified using an element that specifies the operation
    and two sub-elements "var" and "value" that specifies the type of SIP
    message fields and its value to be compared against. 
    The following simple operations are currently supported:
        
            "equals" - if the field specified by "var" exactly matches the value.
            "equals-ignore-case" - if the field specified by "var" matches the
                value in a case -insensitive manner (Hello = HELLO).
            "contains" - If the field specified by "var" contains the string
                specified by the "value". 
            "contains-ignore-case" - If the field specified by "var" contains 
                the string specified by the "value" in a case insensitive manner.
            "exists" - if the field specified by "var" exists. This type of 
                element does not have an associated "value".
            "matches" - If the field specified by "var" matches the "value"
                specified as a regular expression.
            "subdomain-of" - If the field specified by "var" is a sub-domain 
                of the "value". For example, homes.cafesip.org is a sub-domain
                of cafesip.org.
            
    The following "var" fields are supported. They correspond to fields in
    the SIP request message:
        "request.method"
        "request.uri"
        "request.uri.host"
        "request.uri.port"
        "request.uri.scheme"
        "request.uri.user"
        "request.from"
        "request.from.uri"
        "request.from.display-name"
        "request.from.host"
        "request.from.port"
        "request.from.scheme"
        "request.from.user"
        "request.to"
        "request.to.uri"
        "request.to.display-name"
        "request.to.host"
        "request.to.port"
        "request.to.scheme"
        "request.to.user"
        
    The complex expressions are specified using the elements "and", "or" or 
    "not". Each complex expression may consist of one or more simple elements
    and one or more complex elements. The following is a complete example with
    simple and complex elements:
    
        <mapping>
            <or>
                <subdomain-of>
                    <var>request.uri</var>
                    <value>cafesip.org</value>
                </subdomain-of>
                
                <and>
                    <equals>
                        <var>request.from</var>
                        <value>sip:amit@cafesip.org</value>
                    </equals>
                    
                    <equals>
                        <var>request.to</var>
                        <value>sip:becky@cafesip.org</value>
                    </equals>
                    
                    <not>
                        <equals>
                           <var>request.from.display-name</var>
                            <value>Amit Chatterjee</value>                            
                        </equals>
                    </not>
                </and>
            </or>
        </mapping>
        
    The attribute "connector", below, specifies the connector name for which
    the selection criteria is application.  
  -->
      <context-mapping connector="sip-connector">
        <mapping>
            <or>
                <subdomain-of>
                    <var>request.uri.host</var>
                    <value>cafesip.org</value>               
                </subdomain-of>
                
                <subdomain-of>
                    <var>request.to.host</var>
                    <value>cafesip.org</value>                               
                </subdomain-of>
                
                <subdomain-of>
                    <var>request.from.host</var>
                    <value>cafesip.org</value>                               
                </subdomain-of>            
            </or>
        </mapping>  
      </context-mapping>
  </context-mappings>  
  <!--
    For each jiplet, there must be a "jiplet" element specified as shown 
    below. 
  -->
  <jiplet>
    
    <!--
        The "jiplet-name" element contains the name of the jiplet. It is displayed
        by jiplet console/management interfaces.  
    -->    
    <jiplet-name>ExampleSIPRegistrarJiplet</jiplet-name>
    
    <!--
        The "jiplet-description" element contains the description of the jiplet. 
        It is displayed by jiplet console/management interfaces.
    -->
    <jiplet-description>This jiplet will receive REGISTER messages, authenticate
        the users and store the locations of the users.</jiplet-description>
    
    <!--
        The "jiplet-class" element contains the fully qualified class name
        of the jiplet class. The jiplet class must extends org.cafesip.jiplet.Jiplet
        class.
    -->
    <jiplet-class>org.cafesip.reference.jiplet.SipRegistrar</jiplet-class>
    
    <!--
        The "jiplet-connector" element contains the name of the connector
        associated with this jiplet. If this element is not specified, the
        default connector is used/
    -->    
    <jiplet-connector>sip-connector</jiplet-connector>
    
    <!--
        The "startup-order" specifies the order in which the jiplets in this 
        context is specified. A lower value means earlier start.
      -->
    <startup-order>0</startup-order>
        
    <!--
        The following element contains the "init" parameters.
      -->
    <init-params>
        <!-- 
        Add one or more init params. The params will be accessible from
        the init() method of the jiplet.  
        -->        
        <init-param>       
          <param-name>sample-param</param-name>
          <param-value>some value</param-value>
        </init-param> 
    </init-params>
    
  </jiplet>
  
  <jiplet>
    <jiplet-name>ExampleSIPRecorderJiplet</jiplet-name>
    
    <jiplet-description>This jiplet will receive all request messages 
        and record them into a database</jiplet-description>
        
    <jiplet-class>org.cafesip.reference.jiplet.SipRecorder</jiplet-class>
        
    <startup-order>1</startup-order>
        
    <init-params>
        <!-- 
        Add one or more init params. The params will be accessible from
        the init() method of the jiplet.  
        -->        
        <init-param>       
          <param-name>jdbcDriver</param-name>
          <param-value>com.mysql.jdbc.Driver</param-value>
        </init-param>
        
        <init-param>       
          <param-name>dbUrl</param-name>
          <param-value>jdbc:mysql://localhost/test</param-value>
        </init-param>
        
        <init-param>       
          <param-name>dbUser</param-name>
          <param-value>nobody</param-value>
        </init-param>
                       
    </init-params>    
  </jiplet>
  
  <!--
    This jiplet proxies SIP request and response messages to appropriate 
    registered users. The jiplet container comes with a full-fledged proxy
    functionality that can be accessed by using the SipCommunicator class. It
    gets even easier than that. The org.cafesip.jiplet.sip.ProxyJiplet
    jiplet is a part of the jiplet container package that implements the
    proxy functionality for you if your proxying requirements are standard.
    Instead of writing your own, you can use the the ProxyJiplet class.
    
    The proxy jiplet is a standard jiplet and its mapping, security constraints
    and other parameters can be configured the same way as any other jiplets.
    
    The jiplet element below demonstrates how to use the ProxyJiplet that
    comes with the jiplet container. The init-params allow you to customize
    the proxy operation. For more details on the init-params, see the javadoc
    for the class org.cafesip.jiplet.sip.ProxyJiplet.
    -->
  <jiplet>    
    <jiplet-name>ExampleSIPProxyJiplet</jiplet-name>
    
    <jiplet-description>This jiplet will receive SIP request messages 
        (normal traffic messages, not REGISTER or SUBSCRIBE)
        and forward them to the registered users. It will also
        forward the responses back to the end point.
    </jiplet-description>
        
    <jiplet-class>org.cafesip.jiplet.sip.ProxyJiplet</jiplet-class>
    
    <startup-order>2</startup-order>  
    
    <init-params>        
        <init-param>
            <param-name>stateful</param-name>
            <param-value>true</param-value>
        </init-param>
        
        <init-param>
            <param-name>addRecordRoute</param-name>
            <param-value>true</param-value>
        </init-param>

        <init-param>
            <param-name>locationRegister</param-name>
            <param-value>org.cafesip.reference.jiplet.LocationDatabase</param-value>
        </init-param>

        <init-param>
            <param-name>locationRegisterParam</param-name>
            <param-value>NOTHING</param-value>
        </init-param>
        
        <init-param>
            <param-name>forwardLocation</param-name>
            <param-value>ExampleSIPRecorderJiplet</param-value>
        </init-param>        
    </init-params>    
    
  </jiplet>  

  <!--
    This jiplet has been written to demonstrate how a jiplet can interact with 
    the JAIN-SIP API. The example implements a very primitive stateless proxy 
    that proxies receives SIP requests to registered users and proxies the 
    response to the appropriate party.
    
    However, the jiplet container already comes with a proxy API. This API enables
    you to create applications that can proxy requests and responses by making
    a single API call. So, the example proxy is really unnecessary. Instead,
    you must use the org.cafesip.jiplet.sip.ProxyJiplet instead. This jiplet
    is a part of the jiplet container and implements a full-fledged proxy. To
    understand how to use the ProxyJiplet, see the uncommented 
    ExampleSIPProxyJiplet jiplet definition above.
    
    Uncomment the following if you want to use the example proxy jiplet
    In that case, comment out the org.cafesip.jiplet.sip.ProxyJiplet above. 
    
  <jiplet>
    <jiplet-name>ExampleSIPProxyJiplet</jiplet-name>
    
    <jiplet-description>This jiplet will receive SIP request messages 
        (normal traffic messages, not REGISTER or SUBSCRIBE)
        and forward them to the registered users. It will also
        forward the responses back to the end point.</jiplet-description>
        
    <jiplet-class>org.cafesip.reference.jiplet.SipProxy</jiplet-class>
        
    <startup-order>2</startup-order>  
  </jiplet>
  -->
  
  <jiplet>
    <jiplet-name>ExamplePresenceServiceJiplet</jiplet-name>
    
    <jiplet-description>This jiplet will receive REGISTER and SUBSCRIBE messages, 
		set up and manage the corresponding watcher/buddy lists, and send NOTIFICATION
		messages to users when watchee (presentity) presence status changes.</jiplet-description>
    
    <jiplet-class>org.cafesip.reference.jiplet.SipPresence</jiplet-class>
    
    <jiplet-connector>sip-connector</jiplet-connector>
    
    <startup-order>3</startup-order>
        
  <!--
        <init-params>
        Add one or more init params. The params will be accessible from
        the init() method of the jiplet.  
        <init-param>       
          <param-name>sample-param</param-name>
          <param-value>some value</param-value>
        </init-param> 
    </init-params>
	-->
    
  </jiplet>

  <!--
    The "jiplet-mapping" element specifies the mapping information that is
    used by the jiplet container to route incoming SIP requests to one or
    more jiplets. The "mapping" sub-element is the same as the "context-mapping"
    element described above. The attribute "jiplet" contains the name of the 
    jiplet and must match with the "jiplet-name" element described above.
    
    Note: When a SIP request message is received, unless the context is
    selected as per the "context-mapping" element above, the jiplets will not
    be selected.  
    -->  
    
  <!-- 
    The SIP registrar jiplet is only interested in listening to REGISTER
    request message.
    -->  
  <jiplet-mapping jiplet="ExampleSIPRegistrarJiplet">
    <mapping>
        <equals ignore-case="true">
            <var>request.method</var>
            <value>REGISTER</value>               
        </equals>
    </mapping>  
  </jiplet-mapping>
  
  <!--
    The SIP proxy jiplet is interested in listening to all request messages
    except the REGISTER and SUBSCRIBE messages.
    -->
  <jiplet-mapping jiplet="ExampleSIPProxyJiplet">
    <mapping>
		<and>
            <not>
                <equals ignore-case="true">
                    <var>request.method</var>
                    <value>REGISTER</value>               
                </equals>            
            </not>
			<not>
				<equals ignore-case="true">
					<var>request.method</var>
					<value>SUBSCRIBE</value>               
				</equals>            
			</not>
			<not>
				<equals ignore-case="true">
					<var>request.method</var>
					<value>PUBLISH</value>               
				</equals>            
			</not>
		</and>
    </mapping>  
  </jiplet-mapping>  
  
  <!--
	The SIP presence jiplet is interested in listening to SUBSCRIBE
	messages. (REGISTRATION messages will be forwarded to it by the
	SipRegistrar and should not be in this mapping.) SUBSCRIBE messages
	destined for this jiplet will require authentication.
	-->
	<jiplet-mapping jiplet="ExamplePresenceServiceJiplet">
    <mapping>
		<or>
            <equals ignore-case="true">
                <var>request.method</var>
                <value>SUBSCRIBE</value>               
            </equals>
            <equals ignore-case="true">
                <var>request.method</var>
                <value>PUBLISH</value>               
            </equals>
        </or>
    </mapping>  
  </jiplet-mapping> 

    <!--
        This comment demonstrates how to use naming from a jiplet application.
        The jiplet container supports naming context very similar to that
        of the servlet specification. Basically, it supports 
        resource-ref, resource-env-entry, env-entry, ejb-ref and ejb-local-ref
        elements in the deployment descriptors. 
        
        The following section shows the example of each section.   
 
  
    <resource-ref>
       <res-ref-name>mail/SipExchange/Mail</res-ref-name> 
       <res-type>javax.mail.Session</res-type> 
       <res-auth>Container</res-auth> 
    </resource-ref>

    <resource-ref>
       <res-ref-name>mail/SipExchange/Mail</res-ref-name> 
       <res-type>javax.mail.Session</res-type> 
       <res-auth>Container</res-auth> 
    </resource-ref>

    <resource-env-ref>
       <res-env-ref-name>mail/SipExchange/Mail</res-env-ref-name> 
       <res-env-type>javax.mail.Session</res-env-type> 
    </resource-env-ref>

    <env-entry>
       <env-entry-name>foo/bar</env-entry-name> 
       <env-entry-value>foo/bar</env-entry-value>
       <env-entry-type>java.lang.String</env-entry-type> 
    </env-entry>

    <ejb-ref>
        <ejb-ref-name>ejb/SipExchange/CdrRegistrar</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <home>org.cafesip.sipexchange.ejbs.cdr.CdrRegistrarHome</home>
        <remote>org.cafesip.sipexchange.ejbs.cdr.CdrRegistrar</remote>
        <ejb-link>CdrRegistrar</ejb-link>
    </ejb-ref>
    
    <ejb-local-ref>
        <ejb-ref-name>ejb/SipExchange/CdrRegistrar</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <home>org.cafesip.sipexchange.ejbs.cdr.CdrRegistrarHome</home>
        <remote>org.cafesip.sipexchange.ejbs.cdr.CdrRegistrar</remote>
        <ejb-link>CdrRegistrar</ejb-link>
    </ejb-local-ref>      
    -->
     
  <!--
    The security constraint specifies the authentication and authorization
    mechanism that is applicable to a jiplet or a group of jiplets belonging
    to this context. The server applies the security constraint when a SIP
    request message is received and only when the authentication and authorization
    criteria is satisfied, the request message is delvered to the jiplet. This
    enables the jiplet not to worry about the security and let the container
    handle it.
    
    One <security-constraint> element is required for a group of jiplets (resource
    collection) that requires a common auth mechanism. If a jiplet does not
    require any security constraint to be applied, there is no need for a 
    security-constraint element.
    
    The <jiplet-resource-collection> element specifies the resource collection.
    Each collection is specified by a unique name specified by the <jiplet-resource-name>
    element. This is followed by a <jiplet-names> element containing one or more
    jiplet names specified in the <jiplet-name> element. The jiplet name must
    match with that of the jiplet name specified above.
  
    The <auth-constraint> element specifies the constraint parameters applicable
    for the resource collection. The "realm" attribute specifies the 
    auth database. The database must be configured (see server.xml for details)
    and the realm name must match with the configured database. If a realm
    name is not specified, the default realm specified in the server.xml is
    used. The <role-name> sub-element specifies a valid role. Multiple role-name
    elements may be specified to specify multiple roles. After the user
    has been authenticated, the database provides a list of roles that this user has 
    been granted. Only if one of the roles matches that of the roles specified 
    in the role-name element, the SIP request is passed on to the jiplet. 
    -->     
  <security-constraint>
    <jiplet-resource-collection>        
        <jiplet-resource-name>User Presence and Location</jiplet-resource-name>        
        <jiplet-names>
            <jiplet-name>ExampleSIPRegistrarJiplet</jiplet-name>
			<jiplet-name>ExamplePresenceServiceJiplet</jiplet-name>
        </jiplet-names>                  
    </jiplet-resource-collection>
    
    <auth-constraint realm="subscribers.cafesip.org">
        <role-name>user</role-name>
    </auth-constraint> 
  </security-constraint>  
    
</jip-app>