title: Implementing a Locale provider that works in JSF and JAX-RS
body: <p>I've been joyfully using omnifaces' <code>Faces.getLocale()</code> to aquire the locale used by the currently logged in user (which in turn gets this from a <code>&lt;f:view&gt;</code> definition). I really like the fallback approach from view to client to system default locale as it fits the requirements for locale selection in my application:</p>
  
  <ol>
  <li>If a user is logged in, use his language preference (obtained from the backend entity)</li>
  <li>If no user preference can be found, use the highest ranking language from the <code>Accept-Languages</code> HTTP header</li>
  <li>If no locale has been selected by now, use the system default.</li>
  </ol>
  
  <p>Now I've started using JAX-RS (resteasy implementation) and find it quite difficult to write a service that will provide my backend code with the current user's locale.</p>
  
  <p>I can't use <code>Faces.getLocale()</code>, since that requires a <code>FacesContext</code> which isn't present during JAX-RS request processing.</p>
  
  <p>I can't use the <code>@Context SecurityContext</code> annotation in a <code>@Provider</code> (which would give me the user preferred locale) or <code>@Context HttpHeaders</code> (access to the client locale) since JAX-RS only injects those when it uses the provider itself, not when my backend code instantiates the class.</p>
  
  <p>And I don't want to litter my method signatures with <code>Locale</code> parameters, since virtually <em>everything</em> requires a locale to be present.</p>
  
  <p>To have a concrete example: I have a vcard generator that generates little NOTE fields depending on the user's preferred locale. I can both call the vcard generating method via JSF/EL:</p>
  
  <pre><code>&lt;h:commandLink action="#{vcfGenerator.forPerson(person)}" 
      value="Go" target="_blank" /&gt;
  </code></pre>
  
  <p>And via a REST service:</p>
  
  <pre><code>@GET @Path('person/{id:[1-9][0-9]*}/vcard')
  @Produces('text/vcard')
  String exportVcard(@PathParam('id') Long personId, @Context HttpHeaders headers) {
      VcfGenerator exporter = Component.getInstance(VcfGenerator) as VcfGenerator
  
      Person person = entityManager.find(Person, personId)
      if (! person)
          return Response.noContent().build()
  
      def locale = headers.acceptableLanguages[0] ?: Locale.ROOT
      return exporter.generateVCF(person, locale).toString()
  }
  </code></pre>
  
  <p>This works (<code>VcfGenerator</code> has a set of JSF-only methods that use <code>Faces.getLocale()</code>), but is a pain to maintain. So instead of passing the <code>Locale</code> object, I'd like to say:</p>
  
  <pre><code>Vcard generateVCF(Person person) {
      Locale activeLocale = LocaleProvider.instance().getContext(VcfGenerator.class)
      ResourceBundle bundle = ResourceBundle.getBundle("messages", activeLocale, new MyControl())
      // use bundle to construct the vcard
  }
  </code></pre>
  
  <p>Has anyone done similar work and can share insights?</p>