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;
018
019import java.util.Locale;
020
021import org.apache.wicket.Application;
022import org.apache.wicket.MarkupContainer;
023import org.apache.wicket.util.resource.IResourceStream;
024import org.apache.wicket.core.util.resource.locator.IResourceStreamLocator;
025import org.slf4j.Logger;
026import org.slf4j.LoggerFactory;
027
028
029/**
030 * Wicket default implementation for loading the markup resource stream associated with a
031 * MarkupContainer.
032 * 
033 * @author Jonathan Locke
034 * @author Juergen Donnerstag
035 */
036public class DefaultMarkupResourceStreamProvider implements IMarkupResourceStreamProvider
037{
038
039        /** Log for reporting. */
040        private static final Logger log = LoggerFactory.getLogger(DefaultMarkupResourceStreamProvider.class);
041
042        /**
043         * Constructor.
044         */
045        public DefaultMarkupResourceStreamProvider()
046        {
047        }
048
049        /**
050         * Create a new markup resource stream for the container.
051         * <p>
052         * Note: it will only called once, the IResourceStream will be cached by MarkupCache.
053         * <p>
054         * Note: IResourceStreamLocators should be used in case the strategy to find a markup resource
055         * should be extended for ALL components of your application.
056         * 
057         * @see org.apache.wicket.core.util.resource.locator.IResourceStreamLocator
058         * @see org.apache.wicket.markup.DefaultMarkupResourceStreamProvider
059         * 
060         * @param container
061         * @param containerClass
062         *            The container the markup should be associated with
063         * @return A IResourceStream if the resource was found
064         */
065        @Override
066        public IResourceStream getMarkupResourceStream(final MarkupContainer container,
067                Class<?> containerClass)
068        {
069                // Get locator to search for the resource
070                final IResourceStreamLocator locator = Application.get()
071                        .getResourceSettings()
072                        .getResourceStreamLocator();
073
074                String style = container.getStyle();
075                String variation = container.getVariation();
076                Locale locale = container.getLocale();
077
078                MarkupType markupType = container.getMarkupType();
079                String ext = (markupType != null ? markupType.getExtension() : null);
080
081                // Markup is associated with the containers class. Walk up the class
082                // hierarchy up to MarkupContainer to find the containers markup
083                // resource.
084                while (containerClass != MarkupContainer.class)
085                {
086                        String path = containerClass.getName().replace('.', '/');
087                        IResourceStream resourceStream = locator.locate(containerClass, path, style,
088                                variation, locale, ext, false);
089
090                        // Did we find it already?
091                        if (resourceStream != null)
092                        {
093                                return new MarkupResourceStream(resourceStream, new ContainerInfo(containerClass, container), containerClass);
094                        }
095
096                        // Walk up the class hierarchy one level, if markup has not
097                        // yet been found
098                        containerClass = containerClass.getSuperclass();
099                }
100
101                return null;
102        }
103}