001/*
002 * (C) Copyright 2006-2007 Nuxeo SAS <http://nuxeo.com> and others
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Jean-Marc Orliaguet, Chalmers
011 *
012 * $Id$
013 */
014
015package org.nuxeo.theme.negotiation;
016
017import java.util.List;
018
019import javax.servlet.http.HttpServletRequest;
020
021import org.nuxeo.theme.Manager;
022import org.nuxeo.theme.types.TypeFamily;
023
024public abstract class AbstractNegotiator implements Negotiator {
025
026    private static final String SPEC_PREFIX = "nxtheme://theme";
027
028    // FIXME: can be called 'web' under webengine
029    private static final String DEFAULT_NEGOTIATION_STRATEGY = "default";
030
031    protected final String strategy;
032
033    protected final Object context;
034
035    protected final HttpServletRequest request;
036
037    public abstract String getTemplateEngineName();
038
039    protected AbstractNegotiator(String strategy, Object context, HttpServletRequest request) {
040        this.strategy = strategy;
041        this.context = context;
042        this.request = request;
043    }
044
045    public final String getSpec() throws NegotiationException {
046        return String.format("%s/%s/%s/%s/%s/%s/%s", SPEC_PREFIX, negotiate("engine"), negotiate("mode"),
047                getTemplateEngineName(), negotiate("theme"), negotiate("perspective"), negotiate("collection"));
048    }
049
050    public final synchronized String negotiate(String object) throws NegotiationException {
051        if (strategy == null) {
052            throw new NegotiationException("No negotiation strategy is set.");
053        }
054        NegotiationType negotiation = (NegotiationType) Manager.getTypeRegistry().lookup(TypeFamily.NEGOTIATION,
055                String.format("%s/%s", strategy, object));
056        // Try with the 'default' strategy
057        if (negotiation == null) {
058            negotiation = (NegotiationType) Manager.getTypeRegistry().lookup(TypeFamily.NEGOTIATION,
059                    String.format("%s/%s", DEFAULT_NEGOTIATION_STRATEGY, object));
060        }
061        if (negotiation == null) {
062            throw new NegotiationException("Could not obtain negotiation for: " + strategy + " (strategy) " + object
063                    + " (object)");
064        }
065        final List<Scheme> schemes = negotiation.getSchemes();
066
067        String outcome = null;
068        if (schemes != null) {
069            for (Scheme scheme : negotiation.getSchemes()) {
070                outcome = scheme.getOutcome(context);
071                if (outcome != null) {
072                    break;
073                }
074            }
075        }
076        if (outcome == null) {
077            throw new NegotiationException("No negotiation outcome found for:  " + strategy + " (strategy) " + object
078                    + " (object)");
079        } else {
080            // add result to the request
081            request.setAttribute(NEGOTIATION_RESULT_PREFIX + object, outcome);
082        }
083        return outcome;
084    }
085}