Tapestry
  1. Tapestry
  2. TAPESTRY-1462

LinkFactoryImpl caches context path and servlet path

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Fixed
    • Affects Version/s: 4.0, 4.1
    • Fix Version/s: 4.1.2
    • Component/s: None
    • Labels:
      None

      Description

      The class org.apache.tapestry.services.impl.LinkFactoryImpl caches the context path and the servlet path, two values that can differ for every request.
      The class has the web request injected and should use the values from there.

        Activity

        Hide
        Christian Haselbach added a comment -

        Workaround if you need to construct the link according to the correct context path of the request (and not the very first request that ever happened since the start of the application):
        Create a new class which is a copy of LinkFactoryImpl and replace the method constructLink():

        public ILink constructLink(IEngineService service, boolean post, Map parameters,
        boolean stateful)

        { finalizeParameters(service, parameters); IEngine engine = _requestCycle.getEngine(); ServiceEncoding serviceEncoding = createServiceEncoding(parameters); // Give persistent property strategies a chance to store extra data // into the link. if (stateful) _persistenceStrategySource.addParametersForPersistentProperties(serviceEncoding, post); String contextPath = _request.getContextPath(); String fullServletPath = contextPath + serviceEncoding.getServletPath(); return new EngineServiceLink(_requestCycle, fullServletPath, engine.getOutputEncoding(), _codec, _request, parameters, stateful); }


        Furthermore, remove the method finalizeParameters(), because it uses a class that is not public (ImplMessages).

        Then register it in your hivemodule.xml:
        <implementation service-id="tapestry.url.LinkFactory">
        <invoke-factory service-id="hivemind.BuilderFactory" model="singleton" >
        <construct class="your.path.AlternativeLinkFactoryImpl" >
        <set-object property="dataSqueezer" value="infrastructure:dataSqueezer" />
        <set-configuration property="contributions" configuration-id="tapestry.url.ServiceEncoders" />
        <set-object property="servletPath" value="app-property:org.apache.tapestry.servlet-path" />
        <set-object property="contextPath" value="infrastructure:contextPath" />
        <set-object property="request" value="infrastructure:request" />
        <set-object property="requestCycle" value="infrastructure:requestCycle" />
        <set-service property="persistenceStrategySource" service-id="tapestry.persist.PropertyPersistenceStrategySource" />
        </construct>
        </invoke-factory>
        </implementation>

        Show
        Christian Haselbach added a comment - Workaround if you need to construct the link according to the correct context path of the request (and not the very first request that ever happened since the start of the application): Create a new class which is a copy of LinkFactoryImpl and replace the method constructLink(): — public ILink constructLink(IEngineService service, boolean post, Map parameters, boolean stateful) { finalizeParameters(service, parameters); IEngine engine = _requestCycle.getEngine(); ServiceEncoding serviceEncoding = createServiceEncoding(parameters); // Give persistent property strategies a chance to store extra data // into the link. if (stateful) _persistenceStrategySource.addParametersForPersistentProperties(serviceEncoding, post); String contextPath = _request.getContextPath(); String fullServletPath = contextPath + serviceEncoding.getServletPath(); return new EngineServiceLink(_requestCycle, fullServletPath, engine.getOutputEncoding(), _codec, _request, parameters, stateful); } — Furthermore, remove the method finalizeParameters(), because it uses a class that is not public (ImplMessages). Then register it in your hivemodule.xml: <implementation service-id="tapestry.url.LinkFactory"> <invoke-factory service-id="hivemind.BuilderFactory" model="singleton" > <construct class="your.path.AlternativeLinkFactoryImpl" > <set-object property="dataSqueezer" value="infrastructure:dataSqueezer" /> <set-configuration property="contributions" configuration-id="tapestry.url.ServiceEncoders" /> <set-object property="servletPath" value="app-property:org.apache.tapestry.servlet-path" /> <set-object property="contextPath" value="infrastructure:contextPath" /> <set-object property="request" value="infrastructure:request" /> <set-object property="requestCycle" value="infrastructure:requestCycle" /> <set-service property="persistenceStrategySource" service-id="tapestry.persist.PropertyPersistenceStrategySource" /> </construct> </invoke-factory> </implementation>
        Hide
        Jesse Kuhnert added a comment -

        Context path is request each time - though servlet path is still cached as that value isn't as straightforward.

        Show
        Jesse Kuhnert added a comment - Context path is request each time - though servlet path is still cached as that value isn't as straightforward.

          People

          • Assignee:
            Jesse Kuhnert
            Reporter:
            Christian Haselbach
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development