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.core.request.mapper;
018
019import org.apache.wicket.Application;
020import org.apache.wicket.core.util.lang.WicketObjects;
021import org.apache.wicket.request.IRequestMapper;
022import org.apache.wicket.request.Url;
023import org.apache.wicket.request.Url.QueryParameter;
024import org.apache.wicket.request.component.IRequestablePage;
025import org.apache.wicket.request.mapper.AbstractMapper;
026import org.apache.wicket.request.mapper.info.PageComponentInfo;
027import org.apache.wicket.util.lang.Args;
028import org.apache.wicket.util.string.Strings;
029
030/**
031 * Convenience class for implementing page/components related encoders.
032 *
033 * @author Matej Knopp
034 */
035public abstract class AbstractComponentMapper extends AbstractMapper implements IRequestMapper
036{
037        /**
038         * Construct.
039         */
040        public AbstractComponentMapper()
041        {
042        }
043
044        protected IMapperContext getContext()
045        {
046                return Application.get().getMapperContext();
047        }
048
049        /**
050         * Extracts the {@link PageComponentInfo} from the URL. The {@link PageComponentInfo} is encoded
051         * as the very first query parameter and the parameter consists of name only (no value).
052         *
053         * @param url
054         *
055         * @return PageComponentInfo instance if one was encoded in URL, <code>null</code> otherwise.
056         */
057        protected PageComponentInfo getPageComponentInfo(final Url url)
058        {
059                return MapperUtils.getPageComponentInfo(url);
060        }
061
062        /**
063         * Encodes the {@link PageComponentInfo} instance as the first query string parameter to the
064         * URL.
065         *
066         * @param url
067         * @param info
068         */
069        protected void encodePageComponentInfo(Url url, PageComponentInfo info)
070        {
071                Args.notNull(url, "url");
072
073                if (info != null)
074                {
075                        String s = info.toString();
076                        if (!Strings.isEmpty(s))
077                        {
078                                QueryParameter parameter = new QueryParameter(s, "");
079                                url.getQueryParameters().add(parameter);
080                        }
081                }
082        }
083
084        /**
085         * Loads page class with given name.
086         *
087         * @param name
088         * @return class
089         */
090        protected Class<? extends IRequestablePage> getPageClass(String name)
091        {
092                String cleanedClassName = cleanClassName(name);
093                return WicketObjects.resolveClass(cleanedClassName);
094        }
095
096        /**
097         * Cleans the class name from any extra information that may be there.
098         *
099         * @param className
100         *              The raw class name parsed from the url
101         * @return The cleaned class name
102         */
103        protected String cleanClassName(String className)
104        {
105                Args.notEmpty(className, "className");
106
107                if (Strings.indexOf(className, ';') > -1)
108                {
109                        // remove any path parameters set manually by the user. WICKET-5500
110                        className = Strings.beforeFirst(className, ';');
111                }
112
113                return className;
114        }
115
116        /**
117         * {@inheritDoc}
118         *
119         * Removes the first query parameter only if {@link PageComponentInfo#parse(String)} returns
120         * non-null instance
121         */
122        @Override
123        protected void removeMetaParameter(final Url urlCopy)
124        {
125                if (MapperUtils.parsePageComponentInfoParameter(urlCopy.getQueryParameters().get(0)) != null)
126                {
127                        urlCopy.getQueryParameters().remove(0);
128                }
129        }
130
131}