001/*
002 * (C) Copyright 2006-2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Jean-Marc Orliaguet, Chalmers
018 *     Anahide Tchertchian
019 */
020package org.nuxeo.ecm.web.resources.jsf.component;
021
022import java.io.IOException;
023import java.util.HashMap;
024import java.util.Map;
025
026import javax.faces.component.UIComponentBase;
027import javax.faces.component.UIOutput;
028import javax.faces.context.FacesContext;
029import javax.faces.context.ResponseWriter;
030
031import org.apache.commons.lang3.StringUtils;
032import org.nuxeo.runtime.api.Framework;
033import org.nuxeo.theme.styling.service.descriptors.IconDescriptor;
034
035/**
036 * Component rendering a favicon link.
037 *
038 * @since 7.4
039 */
040public class UIFavicon extends UIComponentBase {
041
042    public static final String COMPONENT_TYPE = UIFavicon.class.getName();
043
044    // local cache of icons
045    protected static Map<String, String> iconsMime = new HashMap<>();
046
047    public static enum PropertyKeys {
048        value, name, src, mimetype, sizes
049    }
050
051    @Override
052    public String getFamily() {
053        return UIOutput.COMPONENT_FAMILY;
054    }
055
056    public IconDescriptor getValue() {
057        return (IconDescriptor) getStateHelper().eval(PropertyKeys.value);
058    }
059
060    public void setValue(IconDescriptor value) {
061        getStateHelper().put(PropertyKeys.value, value);
062    }
063
064    public String getName() {
065        return (String) getStateHelper().eval(PropertyKeys.name);
066    }
067
068    public void setName(String name) {
069        getStateHelper().put(PropertyKeys.name, name);
070    }
071
072    public String getSrc() {
073        return (String) getStateHelper().eval(PropertyKeys.src);
074    }
075
076    public void setSrc(String src) {
077        getStateHelper().put(PropertyKeys.src, src);
078    }
079
080    public String getMimetype() {
081        return (String) getStateHelper().eval(PropertyKeys.mimetype);
082    }
083
084    public void setMimetype(String mimetype) {
085        getStateHelper().put(PropertyKeys.mimetype, mimetype);
086    }
087
088    public String getSizes() {
089        return (String) getStateHelper().eval(PropertyKeys.sizes);
090    }
091
092    public void setSizes(String sizes) {
093        getStateHelper().put(PropertyKeys.sizes, sizes);
094    }
095
096    public String getRendererType() {
097        return null;
098    }
099
100    @Override
101    public void encodeEnd(FacesContext context) throws IOException {
102        if (context == null) {
103            throw new NullPointerException();
104        }
105        if (!isRendered()) {
106            popComponentFromEL(context);
107            return;
108        }
109
110        String src;
111        String mt = null;
112        String name;
113        String sizes;
114        IconDescriptor icon = getValue();
115        if (icon != null) {
116            src = icon.getValue();
117            name = icon.getName();
118            sizes = icon.getSizes();
119        } else {
120            src = getSrc();
121            mt = getMimetype();
122            name = getName();
123            sizes = getSizes();
124        }
125        if (StringUtils.isBlank(mt)) {
126            mt = getMimetype(src);
127        }
128
129        ResponseWriter writer = context.getResponseWriter();
130        writer.startElement("link", this);
131        writer.writeAttribute("rel", name, "rel");
132        writer.writeAttribute("type", mt, "rel");
133        String encodedSrc = context.getApplication().getViewHandler().getResourceURL(context, src);
134        writer.writeURIAttribute("href", encodedSrc, "href");
135        if (StringUtils.isBlank(sizes)) {
136            writer.writeAttribute("sizes", sizes, "sizes");
137        }
138        writer.endElement("link");
139
140        popComponentFromEL(context);
141    }
142
143    protected static String getMimetype(String ico) {
144        String mt = null;
145        if (iconsMime.containsKey(ico)) {
146            mt = iconsMime.get(ico);
147        } else {
148            mt = resolveMimetype(ico);
149            if (!Framework.isDevModeSet()) {
150                // cache value
151                iconsMime.put(ico, mt);
152            }
153        }
154        return mt;
155    }
156
157    protected static String resolveMimetype(String ico) {
158        int index = ico.lastIndexOf(".");
159        if (index > 0) {
160            // Handle only gif and png
161            String ext = ico.substring(1 + index);
162            switch (ext) {
163            case "gif":
164                return "image/gif";
165            case "png":
166                return "image/png";
167            }
168        }
169        return "image/x-icon";
170    }
171
172}