001// Licensed under the Apache License, Version 2.0 (the "License");
002// you may not use this file except in compliance with the License.
003// You may obtain a copy of the License at
004//
005// http://www.apache.org/licenses/LICENSE-2.0
006//
007// Unless required by applicable law or agreed to in writing, software
008// distributed under the License is distributed on an "AS IS" BASIS,
009// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
010// See the License for the specific language governing permissions and
011// limitations under the License.
012
013package org.apache.tapestry5.internal.pageload;
014
015import org.apache.tapestry5.SymbolConstants;
016import org.apache.tapestry5.commons.util.CollectionFactory;
017import org.apache.tapestry5.commons.util.ExceptionUtils;
018import org.apache.tapestry5.ioc.OperationTracker;
019import org.apache.tapestry5.ioc.annotations.Symbol;
020import org.apache.tapestry5.ioc.services.ThreadLocale;
021import org.apache.tapestry5.services.ComponentSource;
022import org.apache.tapestry5.services.LocalizationSetter;
023import org.apache.tapestry5.services.pageload.PagePreloader;
024import org.slf4j.Logger;
025
026import java.util.Collection;
027import java.util.List;
028
029public class PagePreloaderImpl implements PagePreloader
030{
031    private final Logger logger;
032
033    private final List<String> pageNames = CollectionFactory.newList();
034
035    private final OperationTracker tracker;
036
037    private final ComponentSource componentSource;
038
039    private final ThreadLocale threadLocale;
040
041    private final LocalizationSetter localizationSetter;
042
043    public PagePreloaderImpl(Logger logger,
044                             OperationTracker tracker,
045                             ComponentSource componentSource, Collection<String> configuration,
046                             ThreadLocale threadLocale,
047                             LocalizationSetter localizationSetter)
048    {
049        this.tracker = tracker;
050        this.componentSource = componentSource;
051        this.logger = logger;
052        this.threadLocale = threadLocale;
053        this.localizationSetter = localizationSetter;
054
055        pageNames.addAll(configuration);
056    }
057
058    @Override
059    public void preloadPages()
060    {
061        if (pageNames.isEmpty())
062        {
063            return;
064        }
065
066        logger.info(String.format("Preloading %,d pages.", pageNames.size()));
067
068        threadLocale.setLocale(localizationSetter.getSupportedLocales().get(0));
069
070        final long startNanos = System.nanoTime();
071
072        try
073        {
074            for (final String pageName : pageNames)
075            {
076                tracker.run(String.format("Preloading page '%s'.", pageName), new Runnable()
077                        {
078                            @Override
079                            public void run()
080                            {
081                                componentSource.getPage(pageName);
082                            }
083                        }
084                );
085            }
086        } catch (Exception ex)
087        {
088            // Report the exception, and just give up at this point.
089            logger.error(ExceptionUtils.toMessage(ex), ex);
090
091            return;
092        }
093
094        final double elapsedNanos = System.nanoTime() - startNanos;
095
096        logger.info(String.format("Preloaded %,d pages in %.2f seconds.",
097                pageNames.size(),
098                elapsedNanos * 10E-10d));
099    }
100}