001    package org.apache.myfaces.tobago.renderkit;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one or more
005     * contributor license agreements.  See the NOTICE file distributed with
006     * this work for additional information regarding copyright ownership.
007     * The ASF licenses this file to You under the Apache License, Version 2.0
008     * (the "License"); you may not use this file except in compliance with
009     * the License.  You may obtain a copy of the License at
010     *
011     *      http://www.apache.org/licenses/LICENSE-2.0
012     *
013     * Unless required by applicable law or agreed to in writing, software
014     * distributed under the License is distributed on an "AS IS" BASIS,
015     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016     * See the License for the specific language governing permissions and
017     * limitations under the License.
018     */
019    
020    import org.apache.myfaces.tobago.component.SupportsMarkup;
021    import org.apache.myfaces.tobago.config.Configurable;
022    import org.apache.myfaces.tobago.context.Markup;
023    import org.apache.myfaces.tobago.context.ResourceManager;
024    import org.apache.myfaces.tobago.context.ResourceManagerFactory;
025    import org.apache.myfaces.tobago.util.ComponentUtils;
026    import org.slf4j.Logger;
027    import org.slf4j.LoggerFactory;
028    
029    import javax.faces.FacesException;
030    import javax.faces.component.UIComponent;
031    import javax.faces.component.UIInput;
032    import javax.faces.component.ValueHolder;
033    import javax.faces.context.FacesContext;
034    import javax.faces.convert.Converter;
035    import javax.faces.convert.ConverterException;
036    import javax.faces.el.ValueBinding;
037    import javax.faces.render.Renderer;
038    import java.io.IOException;
039    import java.util.Locale;
040    
041    public class RendererBase extends Renderer {
042    
043      private static final Logger LOG = LoggerFactory.getLogger(RendererBase.class);
044    
045      private ResourceManager resourceManager;
046    
047      /**
048       * Hook to e. g. register resources, etc.
049       */
050      public void prepareRender(FacesContext facesContext, UIComponent component) throws IOException {
051    
052        if (component instanceof SupportsMarkup) {
053          final SupportsMarkup supportsMarkup = (SupportsMarkup) component;
054          Markup markup = ComponentUtils.updateMarkup(component, supportsMarkup.getMarkup());
055          supportsMarkup.setCurrentMarkup(markup);
056        }
057      }
058    
059      public boolean getPrepareRendersChildren() {
060        return false;
061      }
062    
063      public void prepareRendersChildren(FacesContext context, UIComponent component) {
064      }
065    
066      /**
067       * @deprecated todo: should be done in the StyleClasses class.
068       */
069      @Deprecated
070      protected String getRendererName(String rendererType) {
071        return rendererType.substring(0, 1).toLowerCase(Locale.ENGLISH) + rendererType.substring(1);
072      }
073    
074      /**
075       * @deprecated since 1.5.0, please use getResourceManager().getThemeMeasure()
076       */
077      @Deprecated
078      public int getConfiguredValue(FacesContext facesContext, UIComponent component, String key) {
079        return getResourceManager().getThemeMeasure(facesContext, (Configurable) component, key).getPixel();
080      }
081    
082      protected Object getCurrentValueAsObject(UIInput input) {
083        Object submittedValue = input.getSubmittedValue();
084        if (submittedValue != null) {
085          return submittedValue;
086        }
087        return getValue(input);
088      }
089    
090      protected String getCurrentValue(
091          FacesContext facesContext, UIComponent component) {
092    
093        if (component instanceof UIInput) {
094          Object submittedValue = ((UIInput) component).getSubmittedValue();
095          if (submittedValue != null) {
096            return (String) submittedValue;
097          }
098        }
099        String currentValue = null;
100        Object currentObj = getValue(component);
101        if (currentObj != null) {
102          currentValue = getFormattedValue(facesContext, component, currentObj);
103        }
104        return currentValue;
105      }
106    
107      protected String getFormattedValue(FacesContext context, UIComponent component, Object currentValue)
108          throws ConverterException {
109    
110        if (currentValue == null) {
111          return "";
112        }
113    
114        if (!(component instanceof ValueHolder)) {
115          return currentValue.toString();
116        }
117    
118        Converter converter = ((ValueHolder) component).getConverter();
119    
120        if (converter == null) {
121          if (currentValue instanceof String) {
122            return (String) currentValue;
123          }
124          Class converterType = currentValue.getClass();
125          converter = context.getApplication().createConverter(converterType);
126        }
127    
128        if (converter == null) {
129          return currentValue.toString();
130        } else {
131          return converter.getAsString(context, component, currentValue);
132        }
133      }
134    
135      protected Object getValue(UIComponent component) {
136        if (component instanceof ValueHolder) {
137          Object value = ((ValueHolder) component).getValue();
138          if (LOG.isDebugEnabled()) {
139            LOG.debug("component.getValue() returned " + value);
140          }
141          return value;
142        } else {
143          return null;
144        }
145      }
146    
147      public Converter getConverter(FacesContext context, UIComponent component) {
148        Converter converter = null;
149        if (component instanceof ValueHolder) {
150          converter = ((ValueHolder) component).getConverter();
151        }
152        if (converter == null) {
153          ValueBinding valueBinding = component.getValueBinding("value");
154          if (valueBinding != null) {
155            Class converterType = valueBinding.getType(context);
156            if (converterType == null || converterType == String.class
157                || converterType == Object.class) {
158              return null;
159            }
160            try {
161              converter = context.getApplication().createConverter(converterType);
162            } catch (FacesException e) {
163              LOG.error("No Converter found for type " + converterType);
164            }
165          }
166        }
167        return converter;
168      }
169    
170      @Override
171      public Object getConvertedValue(FacesContext context, UIComponent component, Object submittedValue)
172          throws ConverterException {
173        if (!(submittedValue instanceof String)) {
174          return submittedValue;
175        }
176        Converter converter = getConverter(context, component);
177        if (converter != null) {
178          return converter.getAsObject(context, component, (String) submittedValue);
179        } else {
180          return submittedValue;
181        }
182      }
183    
184      public void onComponentCreated(FacesContext facesContext, UIComponent component, UIComponent parent) {
185      }
186      
187      protected synchronized ResourceManager getResourceManager() {
188        if (resourceManager == null) {
189          resourceManager = ResourceManagerFactory.getResourceManager(FacesContext.getCurrentInstance());
190        }
191        return resourceManager;
192      }
193    }