You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by "Jochen Kemnade (JIRA)" <ji...@apache.org> on 2014/05/16 12:21:28 UTC

[jira] [Updated] (TAP5-901) Generics return wrong type when subclassing page

     [ https://issues.apache.org/jira/browse/TAP5-901?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Jochen Kemnade updated TAP5-901:
--------------------------------

    Labels: generics patch  (was: generics)

> Generics return wrong type when subclassing page
> ------------------------------------------------
>
>                 Key: TAP5-901
>                 URL: https://issues.apache.org/jira/browse/TAP5-901
>             Project: Tapestry 5
>          Issue Type: Bug
>    Affects Versions: 5.1.0.4
>            Reporter: Mike Leonardo
>              Labels: generics, patch
>         Attachments: tap5-901-patch.txt
>
>
> I have a custom library that has the following classes:
> {{{
> public abstract class AbstractViewPage<T extends StaticPage<T, V>, V extends StaticPageVersion> {
> 	private static final Pattern ID = Pattern.compile("^\\d+$");
> 	@InjectDao(StaticPage.class) private Dao<T> dao;
> 	@Inject private Response response;
> 	private T page;
> 	void onActivate(String key) throws IOException {
> 		if (ID.matcher(key).matches())
> 			page = dao.get(Long.parseLong(key));
> 		else {
> 			page = dao.get(eq("name", key));
> 		}
> 		
> 		if (page != null && page.getLive() == null)
> 			page = null;
> 		
> 		if (page == null)
> 			response.sendError(404, "Page not found");
> 	}
> 	
> 	public T getPage() {
> 		return page;
> 	}
> 	public void setPage(T page) {
> 		this.page = page;
> 	}
> 	/** Returns the versioned content to display. */
> 	public V getContent() {
> 		if (page == null)
> 			return null;
> 		
> 		return page.getLive();
> 	}
> }
> }}}
> {{{
> /** Displays a static page */
> @Public
> public class Page extends AbstractViewPage<IFPStaticPage, IFPStaticPageVersion> {
> 	
> 	@Inject private IAuth auth;
> 	@Inject private HttpServletRequest request;
> 	@Inject private HttpServletResponse response;
> 	
> 	Object onActivate() {
> 		IFPStaticPage page = getPage();
> 		if (page != null && page.isRestricted() && auth.getAccount(request, response) == null)
> 			return "start";
> 		
> 		return null;
> 	}
> 	
> 	public boolean isTopLevel() {
> 		return getPage() == getPage().getSectionPage();
> 	}
> 	
> 	void onEndElementFromBreadcrumb(Element e) {
> 		if ("a".equals(e.getName()))
> 			e.getContainer().raw("&nbsp;&nbsp;&rsaquo;&nbsp;&nbsp;");
> 	}
> 	
> }
> }}}
> As you can see, based on generics the method "getContent" should return a IFPStaticPageVersion.
> This works fine when I use this Page.class directly.
> Recently I wanted to extend this Page.class to add a few features specific to one project. When I extended this class (no template so that it would use the Page.class template) I ended up getting an error on the subclass. The error occurred because getContent returned a completely different class instead of IFPStaticPageVersion. 
> I work around I found to fix this is to override the getContent method so that it explicitly defines the return type. But I had to do this in both Page.class and the subclass (Page2.class). Here's my addition to both classes: 
> {{{
> 	@Override
> 	public IFPStaticPageVersion getContent() {
> 		return super.getContent();
> 	}	
> }}}
> Obviously I shouldn't have to do this to get the correct class back (especially not to both Page.class AND Page2.class.
>  



--
This message was sent by Atlassian JIRA
(v6.2#6252)