001/*
002 * (C) Copyright 2006-2015 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Jean-Marc Orliaguet, Chalmers
016 *     Anahide Tchertchian
017 */
018package org.nuxeo.ecm.web.resources.jsf.component;
019
020import java.io.IOException;
021import java.util.HashMap;
022import java.util.Map;
023
024import javax.faces.component.UIComponentBase;
025import javax.faces.component.UIOutput;
026import javax.faces.context.FacesContext;
027import javax.faces.context.ResponseWriter;
028
029import org.apache.commons.lang.StringUtils;
030import org.nuxeo.runtime.api.Framework;
031import org.nuxeo.theme.styling.service.descriptors.IconDescriptor;
032
033/**
034 * Component rendering a favicon link.
035 *
036 * @since 7.4
037 */
038public class UIFavicon extends UIComponentBase {
039
040    public static final String COMPONENT_TYPE = UIFavicon.class.getName();
041
042    // local cache of icons
043    protected static Map<String, String> iconsMime = new HashMap<>();
044
045    public static enum PropertyKeys {
046        value, name, src, mimetype, sizes
047    }
048
049    @Override
050    public String getFamily() {
051        return UIOutput.COMPONENT_FAMILY;
052    }
053
054    public IconDescriptor getValue() {
055        return (IconDescriptor) getStateHelper().eval(PropertyKeys.value);
056    }
057
058    public void setValue(IconDescriptor value) {
059        getStateHelper().put(PropertyKeys.value, value);
060    }
061
062    public String getName() {
063        return (String) getStateHelper().eval(PropertyKeys.name);
064    }
065
066    public void setName(String name) {
067        getStateHelper().put(PropertyKeys.name, name);
068    }
069
070    public String getSrc() {
071        return (String) getStateHelper().eval(PropertyKeys.src);
072    }
073
074    public void setSrc(String src) {
075        getStateHelper().put(PropertyKeys.src, src);
076    }
077
078    public String getMimetype() {
079        return (String) getStateHelper().eval(PropertyKeys.mimetype);
080    }
081
082    public void setMimetype(String mimetype) {
083        getStateHelper().put(PropertyKeys.mimetype, mimetype);
084    }
085
086    public String getSizes() {
087        return (String) getStateHelper().eval(PropertyKeys.sizes);
088    }
089
090    public void setSizes(String sizes) {
091        getStateHelper().put(PropertyKeys.sizes, sizes);
092    }
093
094    public String getRendererType() {
095        return null;
096    }
097
098    @Override
099    public void encodeEnd(FacesContext context) throws IOException {
100        if (context == null) {
101            throw new NullPointerException();
102        }
103        if (!isRendered()) {
104            popComponentFromEL(context);
105            return;
106        }
107
108        String src;
109        String mt = null;
110        String name;
111        String sizes;
112        IconDescriptor icon = getValue();
113        if (icon != null) {
114            src = icon.getValue();
115            name = icon.getName();
116            sizes = icon.getSizes();
117        } else {
118            src = getSrc();
119            mt = getMimetype();
120            name = getName();
121            sizes = getSizes();
122        }
123        if (StringUtils.isBlank(mt)) {
124            mt = getMimetype(src);
125        }
126
127        ResponseWriter writer = context.getResponseWriter();
128        writer.startElement("link", this);
129        writer.writeAttribute("rel", name, "rel");
130        writer.writeAttribute("type", mt, "rel");
131        String encodedSrc = context.getApplication().getViewHandler().getResourceURL(context, src);
132        writer.writeURIAttribute("href", encodedSrc, "href");
133        if (StringUtils.isBlank(sizes)) {
134            writer.writeAttribute("sizes", sizes, "sizes");
135        }
136        writer.endElement("link");
137
138        popComponentFromEL(context);
139    }
140
141    protected static String getMimetype(String ico) {
142        String mt = null;
143        if (iconsMime.containsKey(ico)) {
144            mt = iconsMime.get(ico);
145        } else {
146            mt = resolveMimetype(ico);
147            if (!Framework.isDevModeSet()) {
148                // cache value
149                iconsMime.put(ico, mt);
150            }
151        }
152        return mt;
153    }
154
155    protected static String resolveMimetype(String ico) {
156        int index = ico.lastIndexOf(".");
157        if (index > 0) {
158            // Handle only gif and png
159            String ext = ico.substring(1 + index);
160            switch (ext) {
161            case "gif":
162                return "image/gif";
163            case "png":
164                return "image/png";
165            }
166        }
167        return "image/x-icon";
168    }
169
170}