📄 autolinkresolver.java
字号:
} // Make sure base markup pages (inheritance) are handled correct MarkupContainer parentWithContainer = container; if (container.getParent() != null) { parentWithContainer = container.findParentWithAssociatedMarkup(); } if ((parentWithContainer instanceof Page) && !infoPath.startsWith(".") && page.getMarkupStream().isMergedMarkup()) { Class clazz = container.getMarkupStream().getTag().getMarkupClass(); if (clazz != null) { // Href is relative. Resolve the url given relative to // the current page className = Packages.extractPackageName(clazz) + "." + infoPath; try { clazz = defaultClassResolver.resolveClass(className); return new AutolinkBookmarkablePageLink(autoId, clazz, pathInfo .getPageParameters(), pathInfo.anchor); } catch (ClassNotFoundException ex) { log.warn("Did not find corresponding java class: " + className); // fall through } } } } else { // not a registered type for bookmarkable pages; create a link // to a resource instead return newPackageResourceReferenceAutoComponent(container, autoId, pathInfo, attribute); } // fallthrough 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 */ private final static class AutolinkExternalLink extends ExternalLink { private static final long serialVersionUID = 1L; /** * Construct * * @param id * @param href */ public AutolinkExternalLink(final String id, final String href) { super(id, href); } /** * @see org.apache.wicket.MarkupContainer#isTransparentResolver() */ public boolean isTransparentResolver() { return true; } } /** * Resolver that returns the proper attribute value from a component tag reflecting a URL * reference such as src or href. */ private static interface ITagReferenceResolver { /** * Gets the reference attribute value of the tag depending on the type of the tag. For * instance, anchors use the <code>href</code> attribute but script and image references * use the <code>src</code> attribute. * * @param tag * The component tag. Not for modification. * @return the tag value that constitutes the reference */ String getReference(final ComponentTag tag); } /** * Autolink component that points to a {@link ResourceReference}. Autolink component 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. */ private final static class ResourceReferenceAutolink extends WebMarkupContainer { private static final long serialVersionUID = 1L; private final String attribute; /** Resource reference */ private final ResourceReference resourceReference; /** * @param id * @param clazz * @param href * @param attribute */ public ResourceReferenceAutolink(final String id, final Class clazz, final String href, final String attribute) { super(id); this.attribute = attribute; // Check whether it is a valid resource reference if (PackageResource.exists(clazz, href, getLocale(), getStyle())) { // Create the component implementing the link resourceReference = new ResourceReference(clazz, href, getLocale(), getStyle()); } else { // The resource does not exist. Set to null and ignore when // rendering. resourceReference = null; } } /** * @see org.apache.wicket.MarkupContainer#isTransparentResolver() */ public boolean isTransparentResolver() { return true; } /** * Handles this link's tag. * * @param tag * the component tag * @see org.apache.wicket.Component#onComponentTag(ComponentTag) */ protected final void onComponentTag(final ComponentTag tag) { // Default handling for tag super.onComponentTag(tag); // only set the href attribute when the resource exists if (resourceReference != null) { // Set href to link to this link's linkClicked method CharSequence url = getRequestCycle().urlFor(resourceReference); // generate the href attribute tag.put(attribute, Strings.replaceAll(url, "&", "&")); } } } /** * Resolves to {@link ResourceReference} link components. Typically used for header * contributions like javascript and css files. */ private static final class ResourceReferenceResolverDelegate extends AbstractAutolinkResolverDelegate { private final String attribute; /** * Construct. * * @param attribute */ public ResourceReferenceResolverDelegate(final String attribute) { this.attribute = attribute; } /** * @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, final PathInfo pathInfo) { return newPackageResourceReferenceAutoComponent(container, autoId, pathInfo, attribute); } } /** * Resolver object that returns the proper attribute value from component tags. */ private static final class TagReferenceResolver implements ITagReferenceResolver { /** the attribute to fetch. */ private final String attribute; /** * Construct. * * @param attribute * the attribute to fetch */ public TagReferenceResolver(final String attribute) { this.attribute = attribute; } /** * Gets the reference attribute value of the tag depending on the type of the tag. For * instance, anchors use the <code>href</code> attribute but script and image references * use the <code>src</code> attribute. * * @param tag * The component tag. Not for modification. * @return the tag value that constitutes the reference */ public String getReference(final ComponentTag tag) { return tag.getAttributes().getString(attribute); } } /** * If no specific resolver is found, always use the href attribute for references. */ private static final TagReferenceResolver DEFAULT_ATTRIBUTE_RESOLVER = new TagReferenceResolver( "href"); /** Logging */ private static final Logger log = LoggerFactory.getLogger(AutoLinkResolver.class); private static final long serialVersionUID = 1L; /** * Autolink resolver delegates for constructing new autolinks reference keyed on tag name (such * as <script> or <a>. */ private final Map tagNameToAutolinkResolverDelegates = new HashMap(); /** * Resolver objects that know what attribute to read for getting the reference keyed on tag name * (such as <script> or <a>. */ private final Map tagNameToTagReferenceResolvers = new HashMap(); /** * Construct. */ public AutoLinkResolver() { // register tag reference resolvers TagReferenceResolver hrefTagReferenceResolver = new TagReferenceResolver("href"); TagReferenceResolver srcTagReferenceResolver = new TagReferenceResolver("src"); tagNameToTagReferenceResolvers.put("a", hrefTagReferenceResolver); tagNameToTagReferenceResolvers.put("link", hrefTagReferenceResolver); tagNameToTagReferenceResolvers.put("script", srcTagReferenceResolver); tagNameToTagReferenceResolvers.put("img", srcTagReferenceResolver); // register autolink resolver delegates tagNameToAutolinkResolverDelegates.put("a", new AnchorResolverDelegate()); tagNameToAutolinkResolverDelegates.put("link", new ResourceReferenceResolverDelegate("href")); tagNameToAutolinkResolverDelegates.put("script", new ResourceReferenceResolverDelegate( "src")); tagNameToAutolinkResolverDelegates.put("img", new ResourceReferenceResolverDelegate("src")); } /** * Register (add or replace) a new resolver with the tagName and attributeName. The resolver * will be invoked each time an appropriate tag and attribute is found. * * @param tagName * The tag name * @param attributeName * The attribute name * @param resolver * Implements what to do based on the tag and the attribute */ public final void addTagReferenceResolver(final String tagName, final String attributeName, final IAutolinkResolverDelegate resolver) { TagReferenceResolver tagReferenceResolver = new TagReferenceResolver(attributeName); tagNameToTagReferenceResolvers.put(tagName, tagReferenceResolver); tagNameToAutolinkResolverDelegates.put(tagName, resolver); } /** * Get the resolver registered for 'tagName' * * @param tagName * The tag's name * @return The resolver found. Null, if none registered */ public final IAutolinkResolverDelegate getAutolinkResolverDelegate(final String tagName) { return (IAutolinkResolverDelegate)tagNameToAutolinkResolverDelegates.get(tagName); } /** * Automatically creates a BookmarkablePageLink component. * * @see org.apache.wicket.markup.resolver.IComponentResolver#resolve(MarkupContainer, * MarkupStream, ComponentTag) * * @param markupStream * The current markupStream * @param tag * The current component tag while parsing the markup * @param container * The container parsing its markup * @return true, if componentId was handle by the resolver. False, otherwise */ public final boolean resolve(final MarkupContainer container, final MarkupStream markupStream, final ComponentTag tag) { // Must be marked as autolink tag if (tag.isAutolinkEnabled()) { // Try to find the Page matching the href // Note: to not use tag.getId() because it will be modified while // resolving the link and hence the 2nd render will fail. final Component link = resolveAutomaticLink(container, WicketLinkTagHandler.AUTOLINK_ID, tag); // Add the link to the container container.autoAdd(link, markupStream); if (log.isDebugEnabled()) { log.debug("Added autolink " + link); } // Tell the container, we resolved the id return true; } // We were not able to resolve the id return false; } /** * Resolves the given tag's page class and page parameters by parsing the tag component name and * then searching for a page class at the absolute or relative URL specified by the href * attribute of the tag. * <p> * None html references are treated similar. * * @param container * The container where the link is * @param id * the name of the component * @param tag * the component tag * @return A BookmarkablePageLink to handle the href */ private final Component resolveAutomaticLink(final MarkupContainer container, final String id, final ComponentTag tag) { final Page page = container.getPage(); // Make the id (page-)unique final String autoId = id + Integer.toString(page.getAutoIndex()); // get the tag name, which is something like 'a' or 'script' final String tagName = tag.getName(); // By setting the component name, the tag becomes a Wicket component // tag, which must have a associated Component. if (tag.getId() == null) { tag.setId(autoId); tag.setAutoComponentTag(true); } // get the reference resolver ITagReferenceResolver referenceResolver = (ITagReferenceResolver)tagNameToTagReferenceResolvers .get(tagName); if (referenceResolver == null) { // fallback on default referenceResolver = DEFAULT_ATTRIBUTE_RESOLVER; } // get the reference, which is typically the value of e.g. a href or src // attribute String reference = referenceResolver.getReference(tag); // create the path info object PathInfo pathInfo = new PathInfo(reference); // now get the resolver delegate IAutolinkResolverDelegate autolinkResolverDelegate = (IAutolinkResolverDelegate)tagNameToAutolinkResolverDelegates .get(tagName); Component autoComponent = null; if (autolinkResolverDelegate != null) { autoComponent = autolinkResolverDelegate.newAutoComponent(container, autoId, pathInfo); } if (autoComponent == null) { // resolving didn't have the desired result or there was no delegate // found; fallback on the default resolving which is a simple // component that leaves the tag unchanged autoComponent = new AutolinkExternalLink(autoId, pathInfo.reference); } return autoComponent; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -