// Javadoc inherited
  public XDIMEResult callOpenOnProtocol(XDIMEContextInternal context, XDIMEAttributes attributes)
      throws XDIMEException {

    // In XDIME 2 mode we are responsible for setting up the canvas.
    // As the first stage of this we deal with any per-project default
    // themes and layouts. These need to be set up before we get any
    // per-page versions.

    // Get the current project.
    MarinerPageContext pageContext = getPageContext(context);
    final RuntimeProject runtimeProject = (RuntimeProject) pageContext.getCurrentProject();

    if (runtimeProject != null) {
      // Add any project specified style sheets into the list of
      // theme style sheets. These must be added before any style
      // sheets that are specified in the head.
      addProjectStyleSheets(context, runtimeProject);

      // Extract any default layout from the project.
      // This will be overridden with an any explicit layout
      // provided in the head.
      layoutName = runtimeProject.getDefaultProjectLayoutLocation();
      if (logger.isDebugEnabled()) {
        logger.debug("Project layout: " + layoutName);
      }
    }
    // else, presumably this is only for test...?
    // todo: later: avoid test specific code paths.
    return XDIMEResult.PROCESS_ELEMENT_BODY;
  }
  /**
   * Return a <code>MarinerURL</code> (or null) for any non-cacheable urls.
   *
   * @param requestContext the mariner request context
   * @param assetGroup the assetgroup
   * @param asset the asset
   * @return a mariner url or null if none can be computed.
   * @throws RepositoryException if a repository exception occurs.
   */
  protected MarinerURL computeNoncacheableURL(
      MarinerRequestContext requestContext, AssetGroup assetGroup, Asset asset)
      throws RepositoryException {

    // If the asset is a DynamicVisualAsset and the encoding is TV then the
    // asset url consists of the device specific tv channel prefix and the
    // value appended if it is set. If the tv channel prefix is not valid in
    // a url then we have problems.
    if (asset.getClass() == DynamicVisualAsset.class) {
      DynamicVisualAsset dynamicVisualAsset = (DynamicVisualAsset) asset;
      if (dynamicVisualAsset.getEncoding() == DynamicVisualAsset.TV) {
        MarinerPageContext marinerPageContext =
            ContextInternals.getMarinerPageContext(requestContext);
        InternalDevice device = marinerPageContext.getDevice();

        String tvChannelPrefix = device.getTVChannelPrefix();
        String url = tvChannelPrefix;
        String value = dynamicVisualAsset.getValue();
        if (value != null) {
          url += value;
        }
        return new MarinerURL(url);
      }
    }
    return null;
  }
 /**
  * Method to return the Volantis bean
  *
  * @param requestContext the MarinerRequestContext
  * @return the Volantis bean
  */
 private Volantis getVolantisBean(MarinerRequestContext requestContext) {
   if (volantisBean == null) {
     MarinerPageContext marinerPageContext =
         ContextInternals.getMarinerPageContext(requestContext);
     volantisBean = marinerPageContext.getVolantisBean();
   }
   return volantisBean;
 }
  /**
   * Add any project specified style sheets into the list of theme style sheets.
   *
   * @param context
   * @param runtimeProject
   */
  private void addProjectStyleSheets(XDIMEContextInternal context, RuntimeProject runtimeProject) {

    MarinerPageContext pageContext = getPageContext(context);

    // Find any theme style sheets which are specified in the project,
    // compile them and add them to the collection of compiled theme style
    // sheets.
    List projectThemeLocations = runtimeProject.getProjectThemesLocations();
    if (projectThemeLocations != null) {
      for (Iterator themeLocations = projectThemeLocations.iterator(); themeLocations.hasNext(); ) {
        String projectThemeLocation = (String) themeLocations.next();
        if (projectThemeLocation != null) {
          if (logger.isDebugEnabled()) {
            logger.debug("Project theme: " + projectThemeLocation);
          }
          CompiledStyleSheet projectStyleSheet =
              pageContext.retrieveThemeStyleSheet(projectThemeLocation);
          if (projectStyleSheet != null) {
            themeStyleSheets.addStyleSheet(projectStyleSheet);
          }
        }
      }
    }
  }
  // Javadoc inherited.
  protected int exprElementEnd(MarinerRequestContext context, PAPIAttributes papiAttributes)
      throws PAPIException {
    IncludeAttributes attributes = (IncludeAttributes) papiAttributes;

    if (attributes.getHref() == null) {
      throw new PAPIException(exceptionLocalizer.format("include-href-missing"));
    } else {
      // @todo this is a bit duff since it relies on markup naming not to change; do this a
      // different way
      // Set up the markup that will be sent down the pipeline
      StringBuffer markup = new StringBuffer();
      InputSource inputSource;

      markup.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
      markup
          .append("<urid:fetch xmlns:urid=\"")
          .append(Namespace.URID.getURI())
          .append("\" href=\"")
          .append(attributes.getHref())
          .append("\"");

      if (attributes.getParse() != null) {
        markup.append(" parse=\"").append(attributes.getParse()).append("\"");
      }

      if (attributes.getEncoding() != null) {
        markup.append(" encoding=\"").append(attributes.getEncoding()).append("\"");
      }

      markup.append("/>");

      if (logger.isDebugEnabled()) {
        logger.debug("Set up inclusion command as: " + markup.toString());
      }

      inputSource = new InputSource(new StringReader(markup.toString()));

      // Set up and execute the pipeline to perform the required
      // inclusion
      MarinerPageContext pageContext = ContextInternals.getMarinerPageContext(context);
      XMLReader reader = MarlinSAXHelper.getXMLReader(context);
      reader.setContentHandler(MarlinSAXHelper.getContentHandler(context));
      // @todo this is nasty: we assume that the reader is actually an XMLPipelineFilter
      XMLPipelineFilter filter = (XMLPipelineFilter) reader;
      XMLPipelineContext pipelineContext = filter.getPipelineContext();

      // set the Base URI in the pipeline's context
      try {
        URL baseURI = pageContext.getAbsoluteURL(pageContext.getRequestURL(false));

        if (logger.isDebugEnabled()) {
          logger.debug("Setting Base URI " + baseURI);
        }

        pipelineContext.pushBaseURI(baseURI.toExternalForm());
      } catch (MalformedURLException e) {
        throw new PAPIException(e);
      }

      PipelineIntegrationUtilities.setUpIntegration(
          filter, pageContext.getCurrentElement(), context, pageContext.getCurrentOutputBuffer());

      if (logger.isDebugEnabled()) {
        logger.debug("Executing inclusion");
      }

      // Execute the inclusion
      try {
        reader.parse(inputSource);
      } catch (IOException e) {
        throw new PAPIException(e);
      } catch (SAXException e) {
        throw new PAPIException(e);
      } finally {
        PipelineIntegrationUtilities.tearDownIntegration(filter);
      }
    }

    if (logger.isDebugEnabled()) {
      logger.debug("Successful execution of inclusion");
    }

    return CONTINUE_PROCESSING;
  }