001    /*
002     * Apache License
003     * Version 2.0, January 2004
004     * http://www.apache.org/licenses/
005     *
006     * Copyright 2008-2010 by chenillekit.org
007     *
008     * Licensed under the Apache License, Version 2.0 (the "License");
009     * you may not use this file except in compliance with the License.
010     * You may obtain a copy of the License at
011     *
012     * http://www.apache.org/licenses/LICENSE-2.0
013     */
014    
015    package org.chenillekit.tapestry.core.services.impl;
016    
017    import java.util.Collections;
018    import java.util.Comparator;
019    import java.util.List;
020    import java.util.Map;
021    
022    import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
023    import org.apache.tapestry5.services.Request;
024    
025    import org.chenillekit.tapestry.core.ChenilleKitCoreConstants;
026    import org.chenillekit.tapestry.core.services.URIAssetAliasManager;
027    
028    /**
029     * @version $Id: URIAssetAliasManagerImpl.java 700 2010-10-15 20:49:38Z homburgs $
030     */
031    public class URIAssetAliasManagerImpl implements URIAssetAliasManager
032    {
033        private final Request request;
034    
035        /**
036         * Map from alias to path.
037         */
038        private final Map<String, String> aliasToPathPrefix = CollectionFactory.newMap();
039    
040        /**
041         * Map from path to alias.
042         */
043        private final Map<String, String> pathPrefixToAlias = CollectionFactory.newMap();
044    
045        private final List<String> sortedAliases;
046    
047        private final List<String> sortedPathPrefixes;
048    
049        /**
050         * Configuration is a map of aliases (short names) to complete names. Keys and values should end with a slash, but
051         * one will be provided as necessary, so don't both.
052         */
053        @SuppressWarnings({"JavaDoc"})
054        public URIAssetAliasManagerImpl(Request request, Map<String, String> configuration)
055        {
056            this.request = request;
057    
058            for (Map.Entry<String, String> e : configuration.entrySet())
059            {
060                String alias = withSlash(e.getKey());
061                String path = withSlash(e.getValue());
062    
063                aliasToPathPrefix.put(alias, path);
064                pathPrefixToAlias.put(path, alias);
065            }
066    
067            Comparator<String> sortDescendingByLength = new Comparator<String>()
068            {
069                public int compare(String o1, String o2)
070                {
071                    return o2.length() - o1.length();
072                }
073            };
074    
075            sortedAliases = CollectionFactory.newList(aliasToPathPrefix.keySet());
076            Collections.sort(sortedAliases, sortDescendingByLength);
077    
078            sortedPathPrefixes = CollectionFactory.newList(aliasToPathPrefix.values());
079            Collections.sort(sortedPathPrefixes, sortDescendingByLength);
080        }
081    
082        private String withSlash(String input)
083        {
084            if (input.endsWith("/")) return input;
085    
086            return input + "/";
087        }
088    
089        public String toClientURL(String resourcePath)
090        {
091            return toCompleteClientURI(resourcePath);
092        }
093    
094        private String toCompleteClientURI(String resourcePath)
095        {
096            StringBuilder builder = new StringBuilder(request.getContextPath());
097            builder.append(ChenilleKitCoreConstants.URI_PATH_PREFIX);
098    
099            for (String pathPrefix : sortedPathPrefixes)
100            {
101                if (resourcePath.startsWith(pathPrefix))
102                {
103                    String alias = pathPrefixToAlias.get(pathPrefix);
104                    builder.append(alias);
105                    builder.append(resourcePath.substring(pathPrefix.length()));
106    
107                    return builder.toString();
108                }
109            }
110    
111            // No alias available as a prefix (kind of unlikely, but whatever).
112    
113            builder.append(resourcePath);
114    
115            return builder.toString();
116        }
117    
118        public String toResourcePath(String clientURL)
119        {
120            String basePath = clientURL.substring(ChenilleKitCoreConstants.URI_PATH_PREFIX.length());
121    
122            for (String alias : sortedAliases)
123            {
124                if (basePath.startsWith(alias))
125                    return aliasToPathPrefix.get(alias) + basePath.substring(alias.length());
126            }
127    
128            return basePath;
129        }
130    }