📄 autolinkresolver.java
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.wicket.markup.resolver;import java.util.HashMap;import java.util.HashSet;import java.util.Map;import java.util.Set;import org.apache.wicket.Component;import org.apache.wicket.MarkupContainer;import org.apache.wicket.Page;import org.apache.wicket.PageParameters;import org.apache.wicket.ResourceReference;import org.apache.wicket.application.IClassResolver;import org.apache.wicket.markup.ComponentTag;import org.apache.wicket.markup.MarkupStream;import org.apache.wicket.markup.html.PackageResource;import org.apache.wicket.markup.html.WebMarkupContainer;import org.apache.wicket.markup.html.link.BookmarkablePageLink;import org.apache.wicket.markup.html.link.ExternalLink;import org.apache.wicket.markup.parser.filter.WicketLinkTagHandler;import org.apache.wicket.protocol.http.RequestUtils;import org.apache.wicket.util.lang.Packages;import org.apache.wicket.util.string.Strings;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * The AutoLinkResolver is responsible to handle automatic link resolution. Tags are marked * "autolink" by the MarkupParser for all tags with href attribute, such as anchor and link tags * with no explicit wicket id. E.g. <a href="Home.html"> * <p> * If href points to a *.html file, a BookmarkablePageLink will automatically be created, except for * absolute paths, where an ExternalLink is created. * <p> * If href points to a *.html file, it resolves the given URL by searching for a page class, either * relative or absolute, specified by the href attribute of the tag. If relative the href URL must * be relative to the package containing the associated page. An exception is thrown if no Page * class was found. * <p> * If href is no *.html file a static reference to the resource is created. * * @see org.apache.wicket.markup.parser.filter.WicketLinkTagHandler * * @author Juergen Donnerstag * @author Eelco Hillenius */public final class AutoLinkResolver implements IComponentResolver{ /** * Abstract implementation that has a helper method for creating a resource reference. */ public static abstract class AbstractAutolinkResolverDelegate implements IAutolinkResolverDelegate { /** * Creates a new auto component that references a package resource. * * @param container * the parent container * @param autoId * the automatically generated id for the auto component * @param pathInfo * the path info object that contains information about the link reference * @param attribute * the attribute to replace the value of * @return a new auto component or null if the path was absolute */ protected final Component newPackageResourceReferenceAutoComponent( final MarkupContainer container, final String autoId, final PathInfo pathInfo, final String attribute) { if (!pathInfo.absolute) { // Href is relative. Create a resource reference pointing at // this file // <wicket:head> components are handled differently. We can // not use the container, because it is the container the // header has been added to (e.g. the Page). What we need // however, is the component (e.g. a Panel) which // contributed it. Class clazz = container.getMarkupStream().getContainerClass(); // However if the markup stream is a merged markup stream // (inheritance), // than we need the class of the markup file which contained the // tag. if (container.getMarkupStream().getTag().getMarkupClass() != null) { clazz = container.getMarkupStream().getTag().getMarkupClass(); } // Create the component implementing the link ResourceReferenceAutolink autoLink = new ResourceReferenceAutolink(autoId, clazz, pathInfo.reference, attribute); if (autoLink.resourceReference != null) { // if the resource reference is null, it means that it the // reference was not found as a package resource return autoLink; } } // else we can't have absolute resource references, at least not at // this time // fall back on default processing return null; } } /** * Autolink components delegate component resolution to their parent components. Reason: * autolink tags don't have wicket:id and users wouldn't know where to add the component to. * * @author Juergen Donnerstag */ public final static class AutolinkBookmarkablePageLink extends BookmarkablePageLink { private static final long serialVersionUID = 1L; private final String anchor; /** * When using <wicket:link> to let Wicket lookup for pages and create the related links, * it's not possible to change the "setAutoEnable" property, which defaults to true. This * affects the prototype because, sometimes designers _want_ links to be enabled. */ public static boolean autoEnable = true; /** * Construct * * @see BookmarkablePageLink#BookmarkablePageLink(String, Class, PageParameters) * * @param id * @param pageClass * @param parameters * @param anchor */ public AutolinkBookmarkablePageLink(final String id, final Class pageClass, final PageParameters parameters, final String anchor) { super(id, pageClass, parameters); this.anchor = anchor; setAutoEnable(autoEnable); } /** * @see org.apache.wicket.MarkupContainer#isTransparentResolver() */ public boolean isTransparentResolver() { return true; } /** * * @see org.apache.wicket.markup.html.link.BookmarkablePageLink#getURL() */ protected CharSequence getURL() { CharSequence url = super.getURL(); if (anchor != null) { url = url + anchor; } return url; } } /** * Interface to delegate the actual resolving of auto components to. */ public static interface IAutolinkResolverDelegate { /** * Returns a new auto component based on the pathInfo object. The auto component must have * the autoId assigned as it's id. Should return null in case the component could not be * created as expected and the default resolving should take place. * * @param container * the parent container * @param autoId * the automatically generated id for the auto component * @param pathInfo * the path info object that contains information about the link reference * @return a new auto component or null in case this method couldn't resolve to a proper * auto component */ Component newAutoComponent(final MarkupContainer container, final String autoId, final PathInfo pathInfo); } /** * Encapsulates different aspects of a path. For instance, the path * <code>org.apache.wicket.markup.html.tree.Tree/tree.css</code> has extension * <code>css</code>, is relative (absolute == true) and has no page parameters. */ public static final class PathInfo { /** whether the reference is absolute. */ private final boolean absolute; /** An optional anchor like #top */ private final String anchor; /** The extension if any. */ private final String extension; /** The optional page parameters. */ private final PageParameters pageParameters; /** The path excluding any parameters. */ private final String path; /** The original reference (e.g the full value of a href attribute). */ private final String reference; /** * Construct. * * @param reference * the original reference (e.g the full value of a href attribute) */ public PathInfo(final String reference) { this.reference = reference; // If href contains URL query parameters .. String infoPath; // get the query string int queryStringPos = reference.indexOf("?"); if (queryStringPos != -1) { final String queryString = reference.substring(queryStringPos + 1); pageParameters = new PageParameters(); RequestUtils.decodeParameters(queryString, pageParameters); infoPath = reference.substring(0, queryStringPos); } else { pageParameters = null; infoPath = reference; } absolute = (infoPath.startsWith("/") || infoPath.startsWith("\\")); // remove file extension, but remember it String extension = null; int pos = infoPath.lastIndexOf("."); if (pos != -1) { extension = infoPath.substring(pos + 1); infoPath = infoPath.substring(0, pos); } String anchor = null; if (extension != null) { pos = extension.indexOf('#'); if (pos != -1) { anchor = extension.substring(pos); extension = extension.substring(0, pos); } } path = infoPath; this.extension = extension; this.anchor = anchor; } /** * Gets the anchor (e.g. #top) * * @return anchor */ public final String getAnchor() { return anchor; } /** * Gets extension. * * @return extension */ public final String getExtension() { return extension; } /** * Gets pageParameters. * * @return pageParameters */ public final PageParameters getPageParameters() { return pageParameters; } /** * Gets path. * * @return path */ public final String getPath() { return path; } /** * Gets reference. * * @return reference */ public final String getReference() { return reference; } /** * Gets absolute. * * @return absolute */ public final boolean isAbsolute() { return absolute; } } /** * Resolves to anchor/ link components. */ private static final class AnchorResolverDelegate extends AbstractAutolinkResolverDelegate { /** the attribute to fetch. */ private static final String attribute = "href"; /** * Set of supported extensions for creating bookmarkable page links. Anything that is not in * this list will be handled as a resource reference. */ private final Set supportedPageExtensions = new HashSet(4); /** * Construct. */ public AnchorResolverDelegate() { // Initialize supported list of file name extension which'll create // bookmarkable pages supportedPageExtensions.add("html"); supportedPageExtensions.add("xml"); supportedPageExtensions.add("wml"); supportedPageExtensions.add("svg"); } /** * @see org.apache.wicket.markup.resolver.AutoLinkResolver.IAutolinkResolverDelegate#newAutoComponent(org.apache.wicket.MarkupContainer, * java.lang.String, org.apache.wicket.markup.resolver.AutoLinkResolver.PathInfo) */ public Component newAutoComponent(final MarkupContainer container, final String autoId, PathInfo pathInfo) { if ((pathInfo.extension != null) && supportedPageExtensions.contains(pathInfo.extension)) { // Obviously a href like href="myPkg.MyLabel.html" will do as // well. Wicket will not throw an exception. It accepts it. String infoPath = Strings.replaceAll(pathInfo.path, "/", ".").toString(); Page page = container.getPage(); final IClassResolver defaultClassResolver = page.getApplication() .getApplicationSettings().getClassResolver(); String className; if (!infoPath.startsWith(".")) { // Href is relative. Resolve the url given relative to the // current page className = Packages.extractPackageName(page.getClass()) + "." + infoPath; } else { // Href is absolute. If class with the same absolute path // exists, use it. Else don't change the href. className = infoPath.substring(1); } try { final Class clazz = defaultClassResolver.resolveClass(className); return new AutolinkBookmarkablePageLink(autoId, clazz, pathInfo.pageParameters, pathInfo.anchor); } catch (ClassNotFoundException ex) { log.warn("Did not find corresponding java class: " + className); // fall through
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -