001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.markup.html.basic;
018
019import org.apache.wicket.IGenericComponent;
020import org.apache.wicket.markup.ComponentTag;
021import org.apache.wicket.markup.MarkupStream;
022import org.apache.wicket.markup.html.WebComponent;
023import org.apache.wicket.markup.parser.XmlTag.TagType;
024import org.apache.wicket.model.IModel;
025import org.apache.wicket.model.Model;
026import org.apache.wicket.util.lang.Classes;
027
028/**
029 * A Label component that is used to render an enum value. The value rendered will be the result
030 * of a i18n resource lookup of the following form:
031 * {@code <value.getClass().getSimpleName()>.<value.name()>}, this format can be changed by
032 * overriding {@link #resourceKey(Enum)}
033 * 
034 * @author igor.vaynberg
035 * @param <T>
036 *            enum type
037 */
038public class EnumLabel<T extends Enum<T>> extends WebComponent implements IGenericComponent<T, EnumLabel<T>>
039{
040        private static final long serialVersionUID = 1L;
041
042        /**
043         * Constructor
044         * 
045         * @param id
046         *            See Component
047         */
048        public EnumLabel(final String id)
049        {
050                super(id);
051        }
052
053        /**
054         * Convenience constructor. Same as Label(String, new Model&lt;String&gt;(String))
055         * 
056         * @param id
057         *            See Component
058         * @param value
059         *            Enum value to render
060         * 
061         * @see org.apache.wicket.Component#Component(String, IModel)
062         */
063        public EnumLabel(final String id, T value)
064        {
065                this(id, new Model<T>(value));
066        }
067
068        /**
069         * @param id
070         * @param model
071         * @see org.apache.wicket.Component#Component(String, IModel)
072         */
073        public EnumLabel(final String id, IModel<T> model)
074        {
075                super(id, model);
076        }
077
078        @Override
079        public void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag)
080        {
081                replaceComponentTagBody(markupStream, openTag, getStringValue());
082        }
083
084        /**
085         * Converts model object into the display value
086         * 
087         * @return display value
088         */
089        private String getStringValue()
090        {
091                T value = getModelObject();
092                String converted = value != null ? getString(resourceKey(value)) : nullValue();
093                return getDefaultModelObjectAsString(converted);
094        }
095
096        /**
097         * Converts enum value into a resource key that should be used to lookup the text the label will
098         * display
099         * 
100         * @param value
101         * @return resource key
102         */
103        protected String resourceKey(T value)
104        {
105                return Classes.simpleName(value.getDeclaringClass()) + '.' + value.name();
106        }
107
108        /**
109         * @return value that should be displayed if model object is {@code null}
110         */
111        protected String nullValue()
112        {
113                return "";
114        }
115
116        @Override
117        protected void onComponentTag(ComponentTag tag)
118        {
119                super.onComponentTag(tag);
120                // always transform the tag to <span></span> so even labels defined as <span/> render
121                tag.setType(TagType.OPEN);
122        }
123}