001// Copyright 2007-2013 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry5.corelib.components; 016 017import org.apache.tapestry5.BindingConstants; 018import org.apache.tapestry5.Link; 019import org.apache.tapestry5.MarkupWriter; 020import org.apache.tapestry5.annotations.Parameter; 021import org.apache.tapestry5.corelib.base.AbstractLink; 022import org.apache.tapestry5.internal.InternalConstants; 023import org.apache.tapestry5.ioc.annotations.Inject; 024import org.apache.tapestry5.services.PageRenderLinkSource; 025 026/** 027 * Generates a render request link to some other page in the application. If an activation context is supplied (as the 028 * context parameter), then the context values will be encoded into the URL. If no context is supplied, then the target 029 * page itself will supply the context via a passivate event. 030 * <p/> 031 * Pages are not required to have an activation context. When a page does have an activation context, the value 032 * typically represents the identity of some object displayed or otherwise manipulated by the page. 033 * 034 * @tapestrydoc 035 */ 036public class PageLink extends AbstractLink 037{ 038 /** 039 * The page to link to. If a <code>String</code>, as usual, it should be the page logical name. 040 * If it's a <code>Class</code> instance, it's treated as the target page. 041 * If it's not a <code>String</code> nor an <code>Class</code>, the target page will be 042 * the result of calling <code>page.getClass()</code>. 043 * Notice you'll need to use the <code>prop</code> binding when passing a value which 044 * isn't a <code>String</code>. 045 */ 046 @Parameter(required = true, allowNull = false, defaultPrefix = BindingConstants.LITERAL) 047 private Object page; 048 049 /** 050 * If provided, this is the activation context for the target page (the information will be encoded into the URL). 051 * If not provided, then the target page will provide its own activation context. 052 */ 053 @Parameter 054 private Object[] context; 055 056 @Inject 057 private PageRenderLinkSource linkSource; 058 059 void beginRender(MarkupWriter writer) 060 { 061 if (isDisabled()) return; 062 063 Link link; 064 if (page instanceof String) { 065 final String pageName = (String) page; 066 link = resources.isBound("context") 067 ? linkSource.createPageRenderLinkWithContext(pageName, context == null ? InternalConstants.EMPTY_STRING_ARRAY : context) 068 : linkSource.createPageRenderLink(pageName); 069 } 070 else { 071 // If page is a Class, use it directly. If not, use its class (type) 072 Class<?> clasz = page instanceof Class<?> ? (Class<?>) page : page.getClass(); 073 link = resources.isBound("context") 074 ? linkSource.createPageRenderLinkWithContext(clasz, context == null ? InternalConstants.EMPTY_STRING_ARRAY : context) 075 : linkSource.createPageRenderLink(clasz); 076 } 077 078 writeLink(writer, link); 079 } 080 081 void afterRender(MarkupWriter writer) 082 { 083 if (isDisabled()) return; 084 085 writer.end(); // <a> 086 } 087}