package com.rectang.xsm.pages; import com.rectang.xsm.*; import com.rectang.xsm.io.XSMDocument; import com.rectang.xsm.pages.cms.PageSettings; import com.rectang.xsm.pages.admin.Upgrade; import com.rectang.xsm.pages.admin.xsm.Admin; import com.rectang.xsm.pages.admin.xsm.Setup; import com.rectang.xsm.pages.cms.Edit; import com.rectang.xsm.pages.nav.LinkEdit; import com.rectang.xsm.panels.ContentPanel; import com.rectang.xsm.panels.XSMFeedbackPanel; import com.rectang.xsm.site.DocumentPage; import com.rectang.xsm.site.Site; import com.rectang.xsm.wicket.VelocityPanel; import org.apache.velocity.VelocityContext; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink; import org.apache.wicket.authorization.AuthorizationException; import org.apache.wicket.behavior.HeaderContributor; import org.apache.wicket.markup.DefaultMarkupResourceStreamProvider; import org.apache.wicket.markup.IMarkupCacheKeyProvider; import org.apache.wicket.markup.IMarkupResourceStreamProvider; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.WebPage; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.util.resource.IResourceStream; import org.apache.wicket.util.resource.StringResourceStream; import org.apache.wicket.*; import org.apache.wicket.markup.html.image.Image; import org.apache.wicket.markup.html.link.BookmarkablePageLink; import java.io.StringWriter; import java.util.Map; /** * Created by IntelliJ IDEA. * * @author Andrew Williams * @version $Id: XSMPage.java 832 2011-09-26 21:45:04Z andy $ * @since 2.0 */ public abstract class XSMPage extends WebPage implements IMarkupResourceStreamProvider, IMarkupCacheKeyProvider { private HeaderContributor style, layout; private PageParameters parameters; private boolean layedOut = false; public XSMPage( PageParameters parameters ) { this.parameters = parameters; // test that the system is installed, if not then load the setup page to show the user what's wrong... if ( !Config.isInstalled() ) { if ( this instanceof Setup ) { return; } else { throw new RestartResponseAtInterceptPageException( Setup.class ); } } if ( this instanceof Secure ) { UserData user = getXSMSession().getUser(); if ( user == null && !(this instanceof Register) ) { if ( !(this instanceof Login) ) { if ( this instanceof Logout ) { PageParameters siteParams = new PageParameters(); if ( parameters.getString( "sitename" ) != null ) { siteParams.add( "sitename", parameters.getString( "sitename" ) ); } setResponsePage( Login.class, siteParams ); } else { PageParameters siteParams = new PageParameters(); if ( parameters.getString( "sitename" ) != null ) { siteParams.add( "sitename", parameters.getString( "sitename" ) ); } Page page = getSession().getPageFactory().newPage( Login.class, siteParams ); throw new RestartResponseAtInterceptPageException( page ); } } return; } Site site = getXSMSession().getSite(); if ( site != null ) { // check for site upgrades if ( site.needsUpgrade() && !(this instanceof Upgrade) ) { throw new RestartResponseAtInterceptPageException( com.rectang.xsm.pages.admin.Upgrade.class ); } } Secure securePage = (Secure) this; if ( securePage.getLevel() == AccessControl.ADMIN && (user == null || !user.isXSMAdmin()) ) { throw new AuthorizationException( "You must be an admin to access this page" ) { }; } else if ( securePage.getLevel() == AccessControl.MANAGER && (user == null || !user.isSiteAdmin()) ) { throw new AuthorizationException( "You must be a site admin to access this page" ) { }; } } } public PageParameters getPageParameters() { return parameters; } protected void onBeforeRender() { if ( !layedOut ) { layedOut = true; layout(); } super.onBeforeRender(); // provide a default style if no site can be found if ( getXSMSession().getSite() == null ) { add( style = HeaderContributor.forCss( XSMApplication.class, "publish/layout/menu-left.css" ) ); add( layout = HeaderContributor.forCss( XSMApplication.class, "publish/style/grey.css" ) ); } else if ( getBehaviors().contains( style ) ) { remove( style ); remove( layout ); } } public IResourceStream getMarkupResourceStream( MarkupContainer markupContainer, Class aClass ) { if ( aClass.equals( XSMPage.class ) ) { return new StringResourceStream( evaluateVelocityTemplate() ); } else { return new DefaultMarkupResourceStreamProvider().getMarkupResourceStream( markupContainer, aClass ); } } // TODO improve this "never cache" code with something that stores it until change needed... public String getCacheKey( MarkupContainer markupContainer, Class aClass ) { return null; } /** * Evaluates the template and returns the result. * @return the result of evaluating the velocity template */ private String evaluateVelocityTemplate() { XSMDocument doc = null; com.rectang.xsm.site.Page page = null; if ( this instanceof com.rectang.xsm.pages.cms.Page ) { page = ((com.rectang.xsm.pages.cms.Page) this).getXSMPage(); if ( page instanceof DocumentPage ) { doc = XSMDocument.getXSMDoc( ((XSMSession) getSession()).getSite(), (DocumentPage) page ); } } final Map<String, Object> map = Engine.getContext( doc, page, null, null, getXSMSession().getSite(), "<wicket:child></wicket:child>", getXSMSession().getUser() ); map.put( "editing", "true" ); map.put( "theme", Theme.getTheme( getXSMSession().getUser() ) ); // create a Velocity context object using the model if set final VelocityContext ctx = new VelocityContext( map ); // create a writer for capturing the Velocity output StringWriter writer = new StringWriter(); try { // execute the velocity script and capture the output in writer Engine.process( getXSMSession().getSite(), ctx, writer ); // replace the tag's body the Velocity output return writer.toString(); } catch ( Exception e ) { e.printStackTrace(); // TODO handle displaying this error for debug return null; } } public void layout() { UserData user = getXSMSession().getUser(); if ( parameters.getString( "sitename" ) != null ) { ((XSMSession) getSession()).setRequestedSite( parameters.getString( "sitename" ) ); } WebMarkupContainer container = new WebMarkupContainer( "page-buttons" ); container.setVisible( getXSMSession().isUserLoggedIn() ); add( container ); if ( getCMSEditPage() != null ) { Link link = new PluginLink( "editPlugin", getCMSEditPage(), getPageParameters(), "edit" ); container.add( link.setVisible( !isCMSPageEditing() ) ); } else { container.add( new WebMarkupContainer( "editPlugin" ).setVisible( false ) ); } if ( isCMSPageEditing() ) { AjaxSubmitLink ajaxlink = new SubmitPluginLink( "savePlugin", this, "save" ); container.add( ajaxlink.setVisible( isCMSPageEditing() ) ); } else { container.add( new WebMarkupContainer( "savePlugin" ).setVisible( false ) ); } Link link = new PluginLink( "pagePlugin", PageSettings.class, getPageParameters(), "pagesettings" ); container.add( link.setVisible( this instanceof com.rectang.xsm.pages.cms.DocumentPage ) ); container.setVisible( isCMSPage() ); container = new WebMarkupContainer( "user-buttons" ); container.setVisible( getXSMSession().isUserLoggedIn() ); add( container ); link = new PluginLink( "profilePlugin", Profile.class, "profile" ); container.add( link ); link = new PluginLink( "preferencesPlugin", Preferences.class, "preferences" ); container.add( link ); link = new PluginLink( "logoutPlugin", Logout.class, "logout" ); container.add( link ); container = new WebMarkupContainer( "admin-buttons" ); container.setVisible( user != null && user.isSiteAdmin() ); add( container ); link = new PluginLink( "sitePlugin", com.rectang.xsm.pages.admin.Site.class, "site" ); container.add( link ); container = new WebMarkupContainer( "xsmadmin-buttons" ); container.setVisible( user != null && user.isSiteAdmin() ); add( container ); link = new PluginLink( "adminPlugin", Admin.class, "admin" ); container.add( link ); add( new PluginLink( "helpPlugin", Help.class, "help" ) ); if ( user == null ) { add( new VelocityPanel( "xsm-tree", "#publishedNav()" ) ); } else { String page = parameters.getString( "page" ); add( new ContentPanel( "xsm-tree", getXSMSession(), page ) ); } add( new XSMFeedbackPanel( "feedback" ) ); } public XSMSession getXSMSession() { XSMSession sess = (XSMSession) getSession(); return sess; } public static class PluginLink extends BookmarkablePageLink { public PluginLink( String id, Class link, String img ) { super( id, link ); addImage( img ); } public PluginLink( String id, Class link, PageParameters params, String img ) { super( id, link, params ); addImage( img ); } private void addImage( String img ) { add( new Image( "pluginImage", new ResourceReference( this.getClass(), "buttons/" + img + ".png" ) ) ); } } public static class SubmitPluginLink extends AjaxSubmitLink { public SubmitPluginLink( String id, XSMPage page, String img ) { super( id, getFormForEditPage( page ) ); addImage( img ); } private void addImage( String img ) { add( new Image( "pluginImage", new ResourceReference( this.getClass(), "buttons/" + img + ".png" ) ) ); } private static Form getFormForEditPage( XSMPage page ) { if ( page instanceof Edit ) { return ((Edit) page).getEditForm(); } else if ( page instanceof LinkEdit ) { return ((LinkEdit) page).getEditForm(); } return null; } @Override protected void onSubmit( AjaxRequestTarget ajaxRequestTarget, Form<?> form ) { } } public boolean isCMSPage() { return getCMSEditPage() != null; } public Class<? extends Page> getCMSEditPage() { return null; } public boolean isCMSPageEditing() { return getCMSEditPage() != null && this.getClass().isAssignableFrom( getCMSEditPage() ); } }