<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsp="http://apache.org/xsp" xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx" exclude-result-prefixes="xsl">
	<!-- ========================= PARAMETER ================================ -->
	<!--
		Templates matching attributes or elements to set common
		variables used in SDX actions.

		A value could be set :
			1- by a string in XSP ;
			2- by the name of an http parameter (*Param) ;
			3- by the name of a session attribute (*Session) ;
			4- by the name of a Java variable (*String, the user has to take
			    care of types and declarations)
	-->
	<!--
		<sdx:parameters>

		Common for all actions. Order is :
			1- java variables (*String) ;
			2- sitemap parameter (*Sitemap) ;
			3- http user setted params (*Param) ;
			4- session attribute (*Session) ;
			5- default http params ;
			6- default hard coded values in xsp

		for each, 1) elements 2) attributes
	-->
	<!--
		A generic template to get a simple (non-repeatable) string param
		stored in sdx_parameter.

		This template modify the variables

		 sdx_parameter (String value of the param)
		 sdx_bool      (boolean value of the param)
		 sdx_int       (int value of the param)
		 sdx_op        (int operator value of the param)
		 sdx_name      (String name of the param)

		If the template is called from an <sdx:action/>,
		the attributes scanned could be things like @qid*, @hpp* ...

		Il the template is called from a generic <sdx:parameter/>,
		the attributes scanned are only things like @value, @valueParam, @valueString ...
		  - that's the reason for the <xsl:param name="att"/>
	-->
	<xsl:template name="sdx:parameter">
		<!-- name of parameter -->
		<xsl:param name="name"/>
		<!-- default attribute pattern to scan @name* -->
		<xsl:param name="att" select="$name"/>
		<!-- default http param, only on a call  -->
		<xsl:param name="http" select="$name"/>
		<!-- abbreviate http param -->
		<xsl:param name="abbr"/>
		<xsl:choose>
			<!--
      if called from an action, try first to find nested <sdx:parameter/>
-->
			<xsl:when test="sdx:parameter[@name=$name]">
				<xsl:apply-templates select="sdx:parameter[@name=$name][1]"/>
			</xsl:when>
			<!-- parse the current attributes -->
			<xsl:otherwise>
				<xsp:logic>
        /* sdx:parameter <xsl:value-of select="$name"/> */
    sdx_name="<xsl:value-of select="$name"/>";
    sdx_parameter=null; sdx_i=-1; sdx_bool=false; sdx_op=-1;
					<xsl:choose>
						<!-- http param defined by author app -->
						<xsl:when test="@*[name()=concat($att, 'Param')]">
							<xsl:if test="normalize-space(@*[name()=concat($att, 'Param')]) != ''">
    sdx_string="<xsl:apply-templates select="@*[name()=concat($att, 'Param')][1]" mode="escapeQuot"/>";
    sdx_parameter=sdx_getRequestParameter(sdx_string);
							</xsl:if>
						</xsl:when>
						<!-- if no http-param waited, scan default http params -->
						<xsl:otherwise>
							<!-- default name -->
							<xsl:if test="$http">
    sdx_parameter=sdx_getRequestParameter("<xsl:value-of select="$http"/>");
							</xsl:if>
							<!-- if no default name, try short name -->
							<xsl:if test="$abbr">
    if (sdx_parameter == null) sdx_parameter=sdx_getRequestParameter("<xsl:value-of select="$abbr"/>");
							</xsl:if>
						</xsl:otherwise>
					</xsl:choose>
					<!-- sitemap parameter -->
					<xsl:choose>
						<xsl:when test="@*[name()=concat($att, 'Sitemap')]">
    sdx_string="<xsl:apply-templates select="@*[name()=concat($att, 'Sitemap')][1]" mode="escapeQuot"/>";
    sdx_parameter=parameters.getParameter(sdx_string, null);
						</xsl:when>
						<xsl:otherwise>
    sdx_parameter=parameters.getParameter(sdx_name, sdx_parameter);

						</xsl:otherwise>
					</xsl:choose>
					<!-- author string overide user http param -->
					<xsl:if test="@*[name()=concat($att, 'String')]">
    if (<xsl:value-of select="normalize-space(@*[name()=concat($att, 'String')])"/> != null) sdx_parameter=String.valueOf(<xsl:value-of select="normalize-space(@*[name()=concat($att, 'String')])"/>);
					</xsl:if>
    sdx_string=null;

					<xsl:if test="@*[name()=$att]">
						<!-- get default value from author -->
    sdx_string="<xsl:apply-templates select="@*[name()=$att][1]" mode="escapeQuot"/>";
					</xsl:if>
					<xsl:if test="@*[name()=concat($att, 'Session')]">
						<!-- session - if sdx_parameter set, store it in session, else, retrieve session value -->
    /* <xsl:value-of select="concat('@', $att, 'Session=', @*[name()=concat($att, 'Session')])"/> */
    sdx_strings=new String[3];
    sdx_strings[0]="<xsl:apply-templates select="@*[name()=concat($att, 'Session')][1]" mode="escapeQuot"/>";
    sdx_strings[1]=(String)getSessionObject(session, sdx_strings[0]);
    if (false) {}
    else if (sdx_parameter == null &amp;&amp; sdx_strings[1] != null) sdx_parameter=sdx_strings[1]; // if no http but session then session
    else if ("".equals(sdx_parameter)) session.removeAttribute(sdx_strings[0]); // if http="" then session=null
    else if (sdx_parameter != null) session.setAttribute(sdx_strings[0], sdx_parameter); // if http then session=http
    else if (sdx_parameter == null &amp;&amp; sdx_string != null) session.setAttribute(sdx_strings[0], sdx_string); // if no http but author value then session=author
					</xsl:if>

    if (sdx_parameter == null || "".equals(sdx_parameter.trim())) sdx_parameter=sdx_string; // if no value then set to author default value
    try {sdx_i=Integer.parseInt(sdx_parameter);} catch ( NumberFormatException sdx_e ) {sdx_i=-1;  }; sdx_bool=sdx_boolean(sdx_parameter); if (sdx_parameter != null) sdx_op=AbstractQuery.getOperator(sdx_parameter);

			<xsl:if test="ancestor::sdx:debug">
						<sdx:debug title="PARAMETER">
							<xsp:attribute name="name">
								<xsp:expr>sdx_name</xsp:expr>
							</xsp:attribute>
							<xsp:attribute name="value">
								<xsp:expr>sdx_parameter</xsp:expr>
							</xsp:attribute>
							<xsp:attribute name="element">
								<xsl:value-of select="name()"/>
							</xsp:attribute>
							<xsp:attribute name="integer">
								<xsp:expr>sdx_i</xsp:expr>
							</xsp:attribute>
							<xsp:attribute name="operator">
								<xsp:expr>sdx_op</xsp:expr>
							</xsp:attribute>
							<xsp:attribute name="boolean">
								<xsp:expr>sdx_bool</xsp:expr>
							</xsp:attribute>
						</sdx:debug>
					</xsl:if>
				</xsp:logic>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	<!--
		<sdx:parameter/> as a match.
	-->
	<xsl:template match="sdx:page//sdx:parameter">
		<xsp:logic>
			<xsl:call-template name="sdx:parameter">
				<!-- parameter name in @name -->
				<xsl:with-param name="name" select="@name"/>
				<!-- scan the @value* atts of the element -->
				<xsl:with-param name="att" select="'value'"/>
				<!-- no default http param in this case -->
				<xsl:with-param name="http"/>
			</xsl:call-template>
			<xsl:if test="xsp:logic">
				<xsl:apply-templates select="xsp:logic"/>
				<!-- if possible, set int sdx_i, boolean sdx_bool, sdx_op -->
    try {sdx_i=Integer.parseInt(sdx_parameter);} catch ( NumberFormatException sdx_e ) {sdx_i=-1;  }; sdx_bool=Boolean.valueOf(sdx_parameter).booleanValue(); if (sdx_parameter != null) sdx_op=AbstractQuery.getOperator(sdx_parameter);
			</xsl:if>
			<xsl:if test="sdx:success">
    if (sdx_parameter != null)
    /* got param */
    {
				<xsl:apply-templates select="sdx:success/*"/>
    }
			</xsl:if>
			<xsl:if test="sdx:fallback">
    /* no param */
    if (sdx_parameter == null)
    {
				<xsl:apply-templates select="sdx:fallback/*"/>
    }
			</xsl:if>
		</xsp:logic>
	</xsl:template>
	<!-- =========================== PARAMETERS ============================= -->
	<!--
		Same logic as below, but for repeatable param.
	-->
	<xsl:template name="sdx:parameters" match="sdx:page//sdx:parameters">
		<!-- scan attributes name* -->
		<xsl:param name="name" select="@name"/>
		<!-- default http params -->
		<xsl:param name="http" select="$name"/>
		<!-- abbreviate http param -->
		<xsl:param name="abbr"/>
		<xsp:logic>
    /* sdx:parameters <xsl:value-of select="$name"/> */
    sdx_parameters=null; sdx_is=null; sdx_bools=null; sdx_ops=null;
            <xsl:choose>
				<!-- if current have <sdx:parameter/> children -->
				<xsl:when test="sdx:parameter[@name=$name]">
    sdx_parameters=new String[<xsl:value-of select="count(sdx:parameter[@name=$name])"/>];
                    	<xsl:for-each select="sdx:parameter[@name=$name]">
						<xsl:apply-templates select="."/>
    sdx_parameters[<xsl:value-of select="position()"/>-1]=sdx_parameter;
                    	</xsl:for-each>
				</xsl:when>
				<!-- parse current element attributes -->
				<xsl:otherwise>
					<xsl:choose>
						<xsl:when test="@*[name()=concat($name, 'Param')]">
							<!-- if @*Param given but with empty value, then deconnect default http param -->
							<xsl:if test="normalize-space(@*[name()=concat($name, 'Param')]) != ''"> sdx_parameters=sdx_getRequestParameters("<xsl:apply-templates select="@*[name()=concat($name, 'Param')][1]" mode="escapeQuot"/>"); </xsl:if>
						</xsl:when>
						<xsl:otherwise>
							<xsl:if test="$http"> sdx_parameters=sdx_getRequestParameters("<xsl:value-of select="$http"/>"); </xsl:if>
							<xsl:if test="$abbr"> if (sdx_parameters==null) sdx_parameters=sdx_getRequestParameters("<xsl:value-of select="$abbr"/>"); </xsl:if>
						</xsl:otherwise>
					</xsl:choose>
					<xsl:if test="@*[name()=concat($name, 'String')]">
    sdx_string=String.valueOf(<xsl:value-of select="normalize-space(@*[name()=concat($name, 'String')])"/>);
    sdx_parameters=new String[1]; sdx_parameters[0]=sdx_string;
					</xsl:if>
					<xsl:if test="@*[name()=concat($name, 'Strings')]">
    sdx_parameters=<xsl:value-of select="normalize-space(@*[name()=concat($name, 'Strings')])"/>;
					</xsl:if>
					<xsl:if test="@*[name()=concat($name, 'Session')]">
        /* <xsl:value-of select="concat('@', $name, 'Session=', @*[name()=concat($name, 'Session')])"/> */
    sdx_string="<xsl:apply-templates select="@*[name()=concat($name, 'Session')][1]" mode="escapeQuot"/>";
    if (sdx_parameters != null) session.setAttribute(sdx_string, sdx_parameters);
    else sdx_parameters=(String)getSessionObject(session, sdx_string);
					</xsl:if>
					<xsl:if test="@*[name()=$name]">
    if (sdx_parameters == null)
    {
        sdx_string="<xsl:apply-templates select="@*[name()=$name][1]" mode="escapeQuot"/>";
        sdx_object = new java.util.StringTokenizer (sdx_string.trim(), " ");
        sdx_parameters=new String[((java.util.StringTokenizer)sdx_object).countTokens()]; sdx_i=0;
        while (((java.util.StringTokenizer)sdx_object).hasMoreTokens()) {
            sdx_parameters[sdx_i]=((java.util.StringTokenizer)sdx_object).nextToken();
            sdx_i++;
        }
    }
					</xsl:if>
				</xsl:otherwise>
			</xsl:choose>
			<!-- if possible, set int[] sdx_is, boolean[] sdx_bools, int[] sdx_ops -->
    if (sdx_parameters != null)
    {
        sdx_is=new int[sdx_parameters.length]; sdx_bools=new boolean[sdx_parameters.length]; sdx_ops=new int[sdx_parameters.length];
        for (sdx_i=0; sdx_i &lt; sdx_parameters.length; sdx_i++)
        {
            try {sdx_is[sdx_i]=Integer.parseInt(sdx_parameters[sdx_i]);} catch ( NumberFormatException sdx_e ) {sdx_is[sdx_i]=-1;  };
            sdx_bools[sdx_i]=sdx_boolean(sdx_parameters[sdx_i]);
            sdx_ops[sdx_i]=AbstractQuery.getOperator(sdx_parameters[sdx_i]);
        }
    }
			<xsl:if test="ancestor::sdx:debug">
        if (sdx_name != null) { } else { sdx_name="<xsl:value-of select="$name"/>"; } // used to inform debug
				<sdx:debug title="PARAMETERS" element="{name()}">
					<xsp:attribute name="name">
						<xsp:expr>sdx_name</xsp:expr>
					</xsp:attribute>
					<xsp:expr>sdx_parameters</xsp:expr>
				</sdx:debug>
    sdx_name=null;
			</xsl:if>
		</xsp:logic>
	</xsl:template>
	<!-- =========================== LOCATIONS PARAMETERS ======================= -->
	<xsl:template name="sdx:build-locations">
		<xsl:choose>
			<xsl:when test="@*[starts-with(name(),'base')]">
				<xsl:call-template name="sdx:locations"/>
			</xsl:when>
			<xsl:when test="sdx:parameter[@name='base']">
				<xsl:call-template name="sdx:locations"/>
			</xsl:when>
			<xsl:when test="sdx:locations">
				<xsl:call-template name="sdx:locations"/>
			</xsl:when>
			<xsl:when test="sdx:location">
				<xsl:call-template name="sdx:locations"/>
			</xsl:when>
			<xsl:otherwise>
				<xsp:logic>
					<!--if the location has not been set prior to the current node we use the default behavior-->
               if (sdx_locations == null){
                   <xsl:call-template name="sdx:locations"/>
               }
               </xsp:logic>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	<xsl:template name="sdx:locations" match="sdx:locations">
		<xsl:if test="ancestor::sdx:debug">
			<sdx:debug name="sdx:locations">
				<xsl:attribute name="path"><xsl:call-template name="path"/></xsl:attribute>
			</sdx:debug>
		</xsl:if>
		<xsp:logic>
            sdx_locations = new SearchLocations(); sdx_locations.enableLogging(sdx_log);
			<xsl:choose>
                <xsl:when test="sdx:locations">
                    <xsl:choose>
                        <xsl:when test="@base">
                            <!--we have an sdx:locationS element with a base attribute-->
                            <xsl:call-template name="sdx:location"/>
                        </xsl:when>
                        <!--we expect child sdx:location elements-->
                        <xsl:otherwise>
                            <xsl:apply-templates/>
                            <!--old code causing loop that never allowed &lt;sdx:location base="baseId"/&gt; to work-->
                            <!--xsl:apply-templates select="sdx:locations | sdx:location"/-->
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:when>
                <xsl:when test="sdx:location">
                    <xsl:apply-templates select="sdx:location"/>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:call-template name="sdx:location"/>
                </xsl:otherwise>
        </xsl:choose>
      <xsl:if test="name()='sdx:locations'">
        <xsl:apply-templates select="xsp:logic"/>
      </xsl:if>
    </xsp:logic>
  </xsl:template>
  <!--
		Frédéric Glorieux. date of this comment ??? Are there still problems ?

		1. 	Bug in sdx:parameter template which doesn't allow for use hardcoded
			param attributes in xsp

		2. New sdx:location2 architecture, specifically:
			a) 	How do we make new architecture work with a list of multiple
				locations specified in the url by the parameters;

				i) app id
				ii) base id
				iii) host (optional)
				iv) port (optional)

			Basically, after talking with Martin we should handle the presence of 4(all of the above),
			3(host, app, base), 2(app,base) parameter groupings.

			b) <sdx:app> template
				i)	make sdx:app template except a parameter
				ii)	(this template could also handle both app and appByPath with one variable,
					if exception is caught and handled properly)
				iii) 	should be a larger try catch around the template java code as well, because
					if we are searching mulitple locations (multiple apps) and one is not found, then
					the page will completely stop? is this really what we want

			c) How to handle multiple bases like in sdx:bases template with new architecture
			d) New sdx_base.getIndex() method (removing the need for a cast to LuceneDocumentBase)
			e) 	Fail safe architecture, if base for location isn't found, exception should be caught and logged,
				but not thrown to ensure other bases (good ids) are searched

		3.	In general  there is some code in the taglib that is repeated see sdx:locationS template,
			which isn't necessary and can be done only once at the end of a routine

    -->
	<!--
       TOTHINK, for performances, optimize code by xsl
       could not handle default http param if no remote expressively waited
    -->
	<!--
		In refactoring Java, remember that the code may be repeated a lot
          example, put comments in xsl, not too much in generated java.
	-->
	<xsl:template match="sdx:location" name="sdx:location">
		<xsp:logic>

    /* add location from &lt;<xsl:value-of select="name()"/>/&gt; */
    sdx_location = null;
			<xsl:if test="parameter[@name='host'] or @*[contains(name(), 'host')]">
				<xsl:call-template name="sdx:parameters">
					<xsl:with-param name="name" select="'host'"/>
				</xsl:call-template>
    sdx_hosts = sdx_parameters;
     	          <xsl:call-template name="sdx:parameters">
					<xsl:with-param name="name" select="'port'"/>
				</xsl:call-template>
    sdx_ports = sdx_is;
			</xsl:if>
			<xsl:call-template name="sdx:parameters">
				<xsl:with-param name="name" select="'app'"/>
			</xsl:call-template>

    sdx_appIds = sdx_parameters;
			<xsl:call-template name="sdx:parameters">
				<xsl:with-param name="name" select="'appbypath'"/>
			</xsl:call-template>
    sdx_appbypaths = sdx_parameters;

			<xsl:call-template name="sdx:parameters">
				<xsl:with-param name="name" select="'base'"/>
			</xsl:call-template>
     sdx_baseIds = sdx_parameters;
    if (false) {} /*  strange but let it for xsl:if - DONE FG: no default http Param for remote  */
			<xsl:if test="parameter[@name='host'] or @*[contains(name(), 'host')]">
    else if (sdx_get(sdx_hosts,0) != null)
        for (sdx_i=0; sdx_i &lt; sdx_hosts.length; sdx_i++)
        {
            sdx_host=sdx_get(sdx_hosts, sdx_i);
            if (sdx_host != null)
            {
                sdx_port=sdx_get(sdx_ports, sdx_i); if (sdx_port &lt; 0) sdx_port=FrameworkImpl.SDX_DEFAULT_RMI_PORT;
                sdx_appId=sdx_get(sdx_appIds, sdx_i);
                sdx_baseId=sdx_get(sdx_baseIds, sdx_i);
			<!--
				If we have a valid host and port we try to retrieve a remote location.
			-->
				<!-- FG, is buildRMIName checking strings ? -->
                sdx_string = Utilities.buildRmiName(sdx_host, sdx_port, sdx_appId, sdx_baseId);
               <xsl:if test="ancestor::sdx:debug">
					<sdx:debug name="sdx:location">
						<xsp:attribute name="host">
							<xsp:expr>sdx_host</xsp:expr>
						</xsp:attribute>
						<xsp:attribute name="port">
							<xsp:expr>sdx_port</xsp:expr>
						</xsp:attribute>
						<xsp:attribute name="app">
							<xsp:expr>sdx_appId</xsp:expr>
						</xsp:attribute>
						<xsp:attribute name="base">
							<xsp:expr>sdx_baseId</xsp:expr>
						</xsp:attribute>
					</sdx:debug>
				</xsl:if>
				<!--
				If our variables aren't null and the sdx_locations
				object doesn't already contain this location we add it.
			-->
                if (sdx_string != null)
                    try {
                        sdx_location = Utilities.getRemoteIndex(sdx_log, sdx_string);
                        <!-- searchLocations now works with documentBases
                        if (sdx_locations != null &amp;&amp; sdx_location != null) sdx_locations.addIndex(sdx_location);
                         -->
                        if (sdx_locations != null &amp;&amp; sdx_base != null) sdx_locations.addDocumentBase(sdx_base);
                    } catch (SDXException sdx_e){ sdx_e.toSAX(contentHandler); }
            }
        }</xsl:if>
    else if ((sdx_get(sdx_appIds, 0) != null) || sdx_get(sdx_appbypaths, 0) != null || sdx_get(sdx_baseIds, 0) != null )
    {
        if (false) {}
        else if (sdx_get(sdx_appIds, 0) != null) { sdx_j=sdx_appIds.length; sdx_string="app"; }
        else if (sdx_get(sdx_appbypaths, 0) != null) { sdx_j=sdx_appbypaths.length; sdx_string="appbypath"; }
        else if (sdx_get(sdx_baseIds, 0) != null) { sdx_j=sdx_baseIds.length; sdx_string="base"; }
        for (sdx_i=0; sdx_i &lt; sdx_j; sdx_i++)
        {
            try { <!-- get an app -->
                if (false) {} /* strange but useful for xsl:if */
                else if ("base".equals(sdx_string) &amp;&amp; sdx_application != null) sdx_app=sdx_application;
                else if ("app".equals(sdx_string) &amp;&amp; sdx_get(sdx_appIds, sdx_i) != null) sdx_app=sdx_frame.getApplicationById(sdx_get(sdx_appIds, sdx_i));
                else if ("appbypath".equals(sdx_string) &amp;&amp; sdx_get(sdx_appbypaths, sdx_i) != null) sdx_app=sdx_frame.getApplicationByPath(sdx_get(sdx_appbypaths, sdx_i));
                sdx_baseId=sdx_get(sdx_baseIds, sdx_i);
                if (sdx_app == null) {}
                if (sdx_baseId == null) sdx_searchable = sdx_app.getDefaultDocumentBase();
                else sdx_searchable = sdx_app.getSearchable(sdx_baseId);
                <!-- now works with documentbases
                if (sdx_searchable != null) sdx_location = sdx_searchable.getIndex();
                if (sdx_locations != null &amp;&amp; sdx_location != null) sdx_locations.addIndex(sdx_location);
                -->
                if (sdx_locations != null &amp;&amp; sdx_searchable != null) sdx_locations.addDocumentBase((DocumentBase) sdx_searchable);
                if (sdx_searchable != null) sdx_baseId=sdx_searchable.getId();
                else sdx_baseId=sdx_baseId+" not found";
                if (sdx_app != null) sdx_string2=sdx_app.getId();
                else if ("app".equals(sdx_string)) sdx_string2=sdx_get(sdx_appIds, sdx_i)+"not found";
                else if ("appbypath".equals(sdx_string)) sdx_string2=sdx_get(sdx_appbypaths, sdx_i)+"not found";

			<xsl:if test="ancestor::sdx:debug">
				<sdx:debug title="LOCATION" element="{name()}">
					<xsp:attribute name="n">
						<xsp:expr>sdx_i</xsp:expr>
					</xsp:attribute>
					<xsp:attribute name="app">
						<xsp:expr>sdx_string2</xsp:expr>
					</xsp:attribute>
					<xsp:attribute name="base">
						<xsp:expr>sdx_baseId</xsp:expr>
					</xsp:attribute>
				</sdx:debug>
			</xsl:if>
            }
            catch (SDXException sdx_e){ sdx_e.toSAX(contentHandler); if (sdx_log != null) sdx_log.error(sdx_e.getMessage(), sdx_e.fillInStackTrace()); }
        }
    } <xsl:if test="not(@*[contains(name(), 'base')] or sdx:parameter[@name='base'])">
				<!-- don't give default base when not waited --> else if (sdx_application != null)
    {
       sdx_base=sdx_application.getDefaultDocumentBase();
       <!-- now work with documentbases
       if (sdx_base != null) sdx_location = sdx_base.getIndex();
       if (sdx_locations != null &amp;&amp; sdx_location != null) sdx_locations.addIndex(sdx_location);
       -->
       if (sdx_locations != null &amp;&amp; sdx_base != null) sdx_locations.addDocumentBase(sdx_base);
    } </xsl:if>
		</xsp:logic>
	</xsl:template>
	<!-- ======================= APP PARAMETERS ======================= -->
	<xsl:template match="sdx:app" name="sdx:app">
		<!--
			Give an app with in order :
				1- @name parameter ;
				2- default http-parameter ;
				3- named http @param ;
				4- string java @String (if not null)
        			5- publicId (app) override directory name (appbypath)
        -->
		<xsp:logic>

            sdx_app=sdx_application;
			<xsl:call-template name="sdx:parameter">
				<xsl:with-param name="name" select="'app'"/>
			</xsl:call-template>
    try {
        if (sdx_parameter != null &amp;&amp; !"".equals(sdx_parameter.trim())) sdx_app = sdx_frame.getApplicationById(sdx_parameter);
        else
        { <xsl:call-template name="sdx:parameter">
				<xsl:with-param name="name" select="'appbypath'"/>
			</xsl:call-template>
            if (sdx_parameter != null &amp;&amp; !"".equals(sdx_parameter.trim())) sdx_app = sdx_frame.getApplicationByPath(sdx_parameter);
        }
    } catch(SDXException sdx_e){ sdx_e.toSAX(contentHandler); } </xsp:logic>
	</xsl:template>
	<!-- ======================= BASE PARAMETERS ======================= -->
	<xsl:template match="sdx:base" name="sdx:base">
		<xsp:logic>
			<xsl:call-template name="sdx:app"/>
			<xsl:call-template name="sdx:parameter">
				<xsl:with-param name="name" select="'base'"/>
			</xsl:call-template>

            if (sdx_app != null)
            {
                sdx_base=sdx_app.getDefaultDocumentBase();
                /* if we still need this code, it should be fail safe, so that one bad base doesn't spoil the bunch-rbp */
            if (sdx_parameter != null) sdx_base=(DocumentBase)sdx_app.getSearchable(sdx_parameter);
            }
            if (sdx_base == null )
            {
                String[] args = new String[2];
                args[0] = sdx_parameter;
                if (sdx_app != null)
                    args[1] = sdx_app.getId();
                throw new SDXException(sdx_log, SDXExceptionCode.ERROR_UNKNOWN_DOCUMENT_BASE, args, null);
            }
        </xsp:logic>
	</xsl:template>
	<xsl:template match="sdx:bases" name="sdx:bases">
		<xsl:call-template name="sdx:app"/>
		<xsl:call-template name="sdx:parameters">
			<xsl:with-param name="name" select="'base'"/>
		</xsl:call-template>
		<xsp:logic>
            if (sdx_app != null)
            {
                if (sdx_parameters == null) sdx_parameters= new String[] {sdx_app.getDefaultDocumentBase().getId()};
                sdx_bases=new DocumentBase[sdx_parameters.length];
                for (sdx_i = 0; sdx_i &lt; sdx_parameters.length; sdx_i++)
                    if(sdx_parameters[sdx_i] != null &amp;&amp; !"".equals(sdx_parameters[sdx_i].trim() ))
                        /* if we still need this code, it should be fail safe, so that one bad base doesn't spoil the bunch-rbp */
                        sdx_bases[sdx_i]=(DocumentBase)sdx_app.getSearchable(sdx_parameters[sdx_i]);
            }
        </xsp:logic>
	</xsl:template>
	<!-- ======================= REPO PARAMETERS ======================= -->
	<xsl:template match="sdx:repo" name="sdx:repo">
		<xsp:logic>
			<xsl:call-template name="sdx:base"/>
			<xsl:call-template name="sdx:parameter">
				<xsl:with-param name="name" select="'repo'"/>
			</xsl:call-template>

            sdx_repo=null;
            if (sdx_base != null)
            {
                sdx_repo=sdx_base.getDefaultRepository();
                if (sdx_parameter != null) sdx_repo=sdx_base.getRepository(sdx_parameter);
            }
        </xsp:logic>
	</xsl:template>
	<!-- ======================= QUERY PARAMETERS =========================== -->
	<!--
		TODO
			- baseOperator	=	Attribut indiquant l'identificateur de l'opérateur de la requête de base
			- boParam		=	Attribut indiquant quel est le paramètre pour l'opérateur de la requête de base
			- fifParams		=	Les paramètres de la requête qui identifient les champs filtres
			- fivParams		=	Les paramètres de la requête qui identifient les valeurs de filtres
	-->
	<xsl:template match="sdx:hpp" name="sdx:hpp">
		<xsp:logic>
		if(sdx_application != null) sdx_app=sdx_application;
		/*search the default value of hpp in this documentbase*/
		if( (sdx_baseIds != null) &amp;&amp; (sdx_baseIds.length &gt; 0))
			if(sdx_baseId != null)
				sdx_hppDefault = sdx_app.getDocumentBase(sdx_baseId).getDefaultHitsPerPage();
			else
				sdx_hppDefault = sdx_app.getDocumentBase(sdx_baseIds[0]).getDefaultHitsPerPage();
		else
			sdx_hppDefault = sdx_app.getDefaultDocumentBase().getDefaultHitsPerPage();
		</xsp:logic>
		
		<xsl:call-template name="sdx:parameter">
			<xsl:with-param name="name" select="'hpp'"/>
		</xsl:call-template>
		
		<xsp:logic>if (sdx_parameter != null) { sdx_hpp=sdx_i; } else {sdx_hpp=sdx_hppDefault;};</xsp:logic>
	</xsl:template>
	
	
	<xsl:template match="sdx:value" name="sdx:value">
		<xsl:call-template name="sdx:parameter">
			<xsl:with-param name="name" select="'value'"/>
			<xsl:with-param name="abbr" select="'v'"/>
		</xsl:call-template>
		<xsp:logic>sdx_value=sdx_parameter;</xsp:logic>
	</xsl:template>
	<xsl:template match="sdx:values" name="sdx:values">
		<xsl:call-template name="sdx:parameters">
			<xsl:with-param name="name" select="'value'"/>
			<xsl:with-param name="abbr" select="'v'"/>
		</xsl:call-template>
		<xsp:logic>sdx_values=sdx_parameters;</xsp:logic>
		<xsl:if test="sdx:field[@*[contains(name(), 'value')]]">
        sdx_values=new String[<xsl:value-of select="count(sdx:field[@*[contains(name(), 'value')]])"/>];
			<xsl:for-each select="sdx:field[@*[contains(name(), 'value')]]">
				<xsl:call-template name="sdx:value"/>
        sdx_values[<xsl:value-of select="position()-1"/>]=sdx_value;
			</xsl:for-each>
		</xsl:if>
	</xsl:template>
	<xsl:template match="sdx:field" name="sdx:field">
		<xsl:param name="name">
			<xsl:choose>
				<xsl:when test="name()='sdx:field' and @name">
					<xsl:value-of select="@name"/>
				</xsl:when>
				<xsl:otherwise>field</xsl:otherwise>
			</xsl:choose>
		</xsl:param>
		<xsl:call-template name="sdx:parameter">
			<xsl:with-param name="name">
				<xsl:value-of select="$name"/>
			</xsl:with-param>
			<xsl:with-param name="abbr" select="'f'"/>
		</xsl:call-template>
		<xsp:logic>sdx_field=sdx_parameter;</xsp:logic>
	</xsl:template>
	<xsl:template match="sdx:fields" name="sdx:fields">
		<xsl:call-template name="sdx:parameters">
			<xsl:with-param name="name" select="'field'"/>
			<xsl:with-param name="abbr" select="'f'"/>
		</xsl:call-template>
		<xsp:logic>sdx_fields=sdx_parameters;</xsp:logic>
		<xsl:if test="sdx:field[@*[contains(name(), 'name')]]">
        sdx_fields=new String[<xsl:value-of select="count(sdx:field[@*[contains(name(), 'name')]])"/>];
			<xsl:for-each select="sdx:field[@*[contains(name(), 'name')]]">
				<xsl:call-template name="sdx:field"/>
        sdx_fields[<xsl:value-of select="position()-1"/>]=sdx_field;
			</xsl:for-each>
		</xsl:if>
	</xsl:template>
	<!--
		Dates
	-->
	<xsl:template name="sdx:from">
		<xsl:call-template name="sdx:parameter">
			<xsl:with-param name="name" select="'from'"/>
		</xsl:call-template>
		<!-- FIXME? added the else entry to remove sticky behaviour of sdx_from and sdx_to... -->
		<xsp:logic> if (sdx_parameter != null) sdx_from=fr.gouv.culture.sdx.utils.Date.parseDate(sdx_parameter); else sdx_from=null;</xsp:logic>
	</xsl:template>
	<xsl:template name="sdx:to">
		<xsl:call-template name="sdx:parameter">
			<xsl:with-param name="name" select="'to'"/>
		</xsl:call-template>
		<!-- FIXME? added the else entry to remove sticky behaviour of sdx_from and sdx_to... -->
		<xsp:logic> if (sdx_parameter != null) sdx_to=fr.gouv.culture.sdx.utils.Date.parseDate(sdx_parameter); else sdx_to=null;</xsp:logic>
	</xsl:template>
	<!-- ======================= UPLOAD PARAMETERS ========================== -->
	<xsl:template name="sdx:url">
		<xsl:call-template name="sdx:parameter">
			<xsl:with-param name="name" select="'url'"/>
		</xsl:call-template>
		<xsp:logic>
        if (sdx_parameter != null)
        {
            sdx_url=new java.net.URL (sdx_parameter);
            sdx_file = org.apache.avalon.excalibur.io.FileUtil.toFile(sdx_url);
            if (sdx_file != null &amp;&amp; sdx_file.isDirectory())
                sdx_dir = sdx_file;
        }
        else sdx_url = null;
        </xsp:logic>
	</xsl:template>
	<xsl:template name="sdx:type">
		<xsl:call-template name="sdx:parameter">
			<xsl:with-param name="name" select="'type'"/>
		</xsl:call-template>
		<xsp:logic>sdx_type=sdx_parameter;</xsp:logic>
	</xsl:template>
	<xsl:template name="sdx:xml">
		<xsl:call-template name="sdx:parameter">
			<xsl:with-param name="name" select="'xml'"/>
		</xsl:call-template>
		<xsp:logic>sdx_xml=sdx_parameter;</xsp:logic>
	</xsl:template>
	<xsl:template name="sdx:dir">
		<xsl:call-template name="sdx:parameter">
			<xsl:with-param name="name" select="'dir'"/>
		</xsl:call-template>
		<xsp:logic>
        sdx_dir=null;
        if (sdx_parameter != null) sdx_dir=new File(sdx_parameter);
        if (sdx_dir != null &amp;&amp; !sdx_dir.isDirectory()) sdx_dir=null;
        </xsp:logic>
	</xsl:template>
	<xsl:template name="sdx:file">
		<xsl:call-template name="sdx:parameter">
			<xsl:with-param name="name" select="'file'"/>
		</xsl:call-template>
		<xsp:logic>
        sdx_file=null;
        if (sdx_parameter != null) sdx_file=new File(sdx_parameter);
        if (sdx_file != null &amp;&amp; !sdx_file.canRead()) sdx_file=null;
        </xsp:logic>
	</xsl:template>
	<xsl:template name="sdx:zip">
		<xsl:call-template name="sdx:parameter">
			<xsl:with-param name="name" select="'zip'"/>
		</xsl:call-template>
		<xsp:logic>
        sdx_zip=null; sdx_object=null;
        if (sdx_parameter != null) sdx_object=new File(sdx_parameter);
        if (sdx_object != null) sdx_zip=new ZipFile((File)sdx_object);
        </xsp:logic>
	</xsl:template>
	<xsl:template name="sdx:dom">
		<xsl:if test="@domDocument">
        sdx_dom=<xsl:value-of select="@domDocument"/>;
		</xsl:if>
	</xsl:template>
	<!-- ======================== OTHER PARAMETERS ========================== -->
	<!--
		Build an id with the current id parameter,
		and with an attid parameter if there's one.
	-->
	<xsl:template name="sdx:id">
		<xsp:logic>
			<xsl:call-template name="sdx:parameter">
				<xsl:with-param name="name" select="'id'"/>
			</xsl:call-template>
        sdx_id=sdx_parameter;
			<xsl:call-template name="sdx:parameter">
				<xsl:with-param name="name" select="'attid'"/>
			</xsl:call-template>
		if (sdx_parameter != null) sdx_id = Utilities.attId(sdx_id, sdx_parameter);
		</xsp:logic>
	</xsl:template>
	<!--
		Relative Id, used for attached document.
	-->
	<xsl:template name="sdx:relid">
		<xsp:logic>
        sdx_id=null;
        <xsl:apply-templates select="@relid"/>
			<xsl:if test="not(@relidParam)">
        sdx_string=request.getParameter("relid");
        if (sdx_string !=null ) sdx_id=sdx_string;

			</xsl:if>
			<xsl:apply-templates select="@relidParam"/>
			<xsl:apply-templates select="@idString"/>
		</xsp:logic>
	</xsl:template>
	<xsl:template match="sdx:*/@relid">
		<xsp:logic>sdx_id="<xsl:apply-templates select="." mode="escapeQuot"/>";</xsp:logic>
	</xsl:template>
	<xsl:template match="sdx:*/@relidParam">
		<xsp:logic>
        sdx_string=request.getParameter("<xsl:apply-templates select="." mode="escapeQuot"/>");
        if ( sdx_string != null ) sdx_id=sdx_string;
        </xsp:logic>
	</xsl:template>
	<xsl:template match="sdx:*/@relidString">
        sdx_string=<xsl:value-of select="normalize-space(.)"/>;
        if ( sdx_string != null ) sdx_id=sdx_string;
    </xsl:template>
	<!--
		MAYDO but Java should be more powerfull

		SDX variable, @name required,
		output in a tag if no @type or @value precised,
		declared if a @type,
		setted if a @value
    <xsl:template match="sdx:variable [@name != '']">
        <xsl:variable name="value" select="sdx:value | @select | @value"/>
        <xsp:logic>
            <xsl:if test="$value != '' or @type != ''">
                <xsl:value-of select="concat(@type, ' ', @name)"/>
                <xsl:if test="$value">
                = <xsl:value-of select="$value"/>
                </xsl:if> ;
            </xsl:if>
        </xsp:logic>
        <sdx:variable>
            <xsl:attribute name="name">
                <xsl:value-of select="@name"/>
            </xsl:attribute>
            <xsp:expr>
                <xsl:value-of select="@name"/>
            </xsp:expr>
        </sdx:variable>
    </xsl:template>


    <xsl:template match="sdx:variable/sdx:value | sdx:variable/@select | sdx:variable/@value">
        <xsl:value-of select="concat(' = ', ., ' ')"/>
    </xsl:template>
    -->
	<!-- ======================= THESAURUS PARAMETERS ======================= -->
	<xsl:template match="sdx:thesaurus" name="sdx:thesaurus">
		<xsp:logic>
			<xsl:call-template name="comment"/>
    if (sdx_app==null) { <xsl:call-template name="sdx:app"/> }
			<xsl:call-template name="sdx:parameter">
				<xsl:with-param name="name" select="'th'"/>
			</xsl:call-template>
    if (sdx_app != null)
    {
        try
        {
        if (sdx_parameter != null) sdx_thesaurus = sdx_app.getThesaurus(sdx_parameter);
        } catch (SDXException sdx_e)
        {
            sdx_e.toSAX(contentHandler);
        }
        if (sdx_thesaurus != null)
        {   /* setting defaults from the thesaurus */
            sdx_relationDepth = sdx_thesaurus.getDefaultDepth();
            sdx_relations = sdx_thesaurus.getDefaultRelations();
        }
    }
			<xsl:call-template name="sdx:parameter">
				<xsl:with-param name="name" select="'depth'"/>
			</xsl:call-template>
   if (sdx_i > -1) sdx_relationDepth = sdx_i;
			<xsl:call-template name="sdx:parameters">
				<xsl:with-param name="name" select="'relation'"/>
			</xsl:call-template>
   if (sdx_thesaurus != null &amp;&amp; sdx_parameters != null)
   {
        sdx_relations = new int[sdx_parameters.length];
        for (sdx_i=0; sdx_i &lt; sdx_parameters.length;sdx_i++)
        {
            sdx_relations[sdx_i] = sdx_thesaurus.getRelationTypeInt(sdx_parameters[sdx_i]);
        }
   }
			<xsl:call-template name="sdx:parameters">
				<xsl:with-param name="name" select="'lang'"/>
			</xsl:call-template>
   sdx_relationLangs = sdx_parameters;
       </xsp:logic>
	</xsl:template>
</xsl:stylesheet>
